wrap list properties
This commit is contained in:
parent
c249eea505
commit
29213f1d87
|
@ -42,6 +42,10 @@ struct List {
|
|||
using ValueType = typename T::Value;
|
||||
using ReturnType = typename T::Return;
|
||||
|
||||
static void GetLength(ContextType ctx, ObjectType thisObject, ReturnType &ret);
|
||||
static void GetIndex(ContextType ctx, ObjectType thisObject, size_t index, ReturnType &ret);
|
||||
static void SetIndex(ContextType ctx, ObjectType thisObject, size_t index, ValueType value);
|
||||
|
||||
static void Push(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
|
||||
static void Pop(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
|
||||
static void Unshift(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
|
||||
|
@ -52,6 +56,24 @@ struct List {
|
|||
static void Sorted(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void List<T>::GetLength(ContextType ctx, ObjectType object, ReturnType &ret) {
|
||||
realm::List *list = RJSGetInternal<realm::List *>(object);
|
||||
RJSSetReturnNumber(ctx, ret, list->size());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void List<T>::GetIndex(ContextType ctx, ObjectType object, size_t index, ReturnType &ret) {
|
||||
realm::List *list = RJSGetInternal<realm::List *>(object);
|
||||
ret = RJSObjectCreate(ctx, Object(list->get_realm(), list->get_object_schema(), list->get(index)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void List<T>::SetIndex(ContextType ctx, ObjectType object, size_t index, ValueType value) {
|
||||
realm::List *list = RJSGetInternal<realm::List *>(object);
|
||||
list->set(ctx, value, index);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void List<T>::Push(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
|
||||
realm::List *list = RJSGetInternal<realm::List *>(thisObject);
|
||||
|
|
|
@ -64,6 +64,31 @@ bool CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef object, JSStringRef
|
|||
return true; \
|
||||
}
|
||||
|
||||
// for stol failure (std::invalid_argument) this could be another property that is handled externally, so ignore
|
||||
#define WRAP_INDEXED_GETTER(CLASS_NAME, METHOD_NAME) \
|
||||
JSValueRef CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* ex) { \
|
||||
JSValueRef returnValue = NULL; \
|
||||
try { \
|
||||
size_t index = RJSValidatedPositiveIndex(RJSStringForJSString(property)); \
|
||||
CLASS_NAME::METHOD_NAME(ctx, object, index, returnValue); return returnValue; \
|
||||
} \
|
||||
catch (std::out_of_range &exp) { return JSValueMakeUndefined(ctx); } \
|
||||
catch (std::invalid_argument &exp) { return NULL; } \
|
||||
catch (std::exception &e) { RJSSetException(ctx, *ex, e); return NULL; } \
|
||||
}
|
||||
|
||||
#define WRAP_INDEXED_SETTER(CLASS_NAME, METHOD_NAME) \
|
||||
bool CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef* ex) { \
|
||||
try { \
|
||||
size_t index = RJSValidatedPositiveIndex(RJSStringForJSString(property)); \
|
||||
{ CLASS_NAME::METHOD_NAME(ctx, object, index, value); return true; } \
|
||||
} \
|
||||
catch (std::out_of_range &exp) { RJSSetException(ctx, *ex, exp); } \
|
||||
catch (std::invalid_argument &exp) { *ex = RJSMakeError(ctx, "Invalid index"); } \
|
||||
catch (std::exception &e) { RJSSetException(ctx, *ex, e); } \
|
||||
return false; \
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void RJSFinalize(JSObjectRef object) {
|
||||
|
|
|
@ -24,64 +24,6 @@
|
|||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||
using namespace realm;
|
||||
|
||||
JSValueRef ListGetLength(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception) {
|
||||
try {
|
||||
List *list = RJSGetInternal<List *>(object);
|
||||
return JSValueMakeNumber(ctx, list->size());
|
||||
}
|
||||
catch (std::exception &exp) {
|
||||
if (exception) {
|
||||
*exception = RJSMakeError(ctx, exp);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
JSValueRef ListGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException) {
|
||||
try {
|
||||
List *list = RJSGetInternal<List *>(object);
|
||||
std::string indexStr = RJSStringForJSString(propertyName);
|
||||
return RJSObjectCreate(ctx, Object(list->get_realm(), list->get_object_schema(), list->get(RJSValidatedPositiveIndex(indexStr))));
|
||||
}
|
||||
catch (std::out_of_range &exp) {
|
||||
// getters for nonexistent properties in JS should always return undefined
|
||||
return JSValueMakeUndefined(ctx);
|
||||
}
|
||||
catch (std::invalid_argument &exp) {
|
||||
// for stol failure this could be another property that is handled externally, so ignore
|
||||
return NULL;
|
||||
}
|
||||
catch (std::exception &exp) {
|
||||
if (jsException) {
|
||||
*jsException = RJSMakeError(ctx, exp);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool ListSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* jsException) {
|
||||
try {
|
||||
List *list = RJSGetInternal<List *>(object);
|
||||
std::string indexStr = RJSStringForJSString(propertyName);
|
||||
if (indexStr == "length") {
|
||||
throw std::runtime_error("The 'length' property is readonly.");
|
||||
}
|
||||
|
||||
list->set(ctx, value, RJSValidatedPositiveIndex(indexStr));
|
||||
return true;
|
||||
}
|
||||
catch (std::invalid_argument &exp) {
|
||||
// for stol failure this could be another property that is handled externally, so ignore
|
||||
return false;
|
||||
}
|
||||
catch (std::exception &exp) {
|
||||
if (jsException) {
|
||||
*jsException = RJSMakeError(ctx, exp);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ListPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames) {
|
||||
List *list = RJSGetInternal<List *>(object);
|
||||
size_t size = list->size();
|
||||
|
@ -96,6 +38,9 @@ void ListPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccum
|
|||
}
|
||||
|
||||
using RJSList = realm::js::List<realm::jsc::Types>;
|
||||
WRAP_PROPERTY_GETTER(RJSList, GetLength)
|
||||
WRAP_INDEXED_GETTER(RJSList, GetIndex)
|
||||
WRAP_INDEXED_SETTER(RJSList, SetIndex)
|
||||
WRAP_CLASS_METHOD(RJSList, Push)
|
||||
WRAP_CLASS_METHOD(RJSList, Pop)
|
||||
WRAP_CLASS_METHOD(RJSList, Unshift)
|
||||
|
@ -122,12 +67,12 @@ static const JSStaticFunction RJSListFuncs[] = {
|
|||
};
|
||||
|
||||
static const JSStaticValue RJSListProps[] = {
|
||||
{"length", ListGetLength, nullptr, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"length", RJSListGetLength, nullptr, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
JSClassRef RJSListClass() {
|
||||
static JSClassRef s_listClass = RJSCreateWrapperClass<List *>("List", ListGetProperty, ListSetProperty, RJSListFuncs, ListPropertyNames, RJSCollectionClass(), RJSListProps);
|
||||
static JSClassRef s_listClass = RJSCreateWrapperClass<List *>("List", RJSListGetIndex, RJSListSetIndex, RJSListFuncs, ListPropertyNames, RJSCollectionClass(), RJSListProps);
|
||||
return s_listClass;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue