diff options
Diffstat (limited to 'src/uscxml/plugins/datamodel/ecmascript')
-rw-r--r-- | src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp | 72 | ||||
-rw-r--r-- | src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h | 8 |
2 files changed, 79 insertions, 1 deletions
diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index 2f07528..bb77944 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -85,6 +85,77 @@ JSCDataModel::~JSCDataModel() { JSGlobalContextRelease(_ctx); } +void JSCDataModel::addExtension(DataModelExtension* ext) { + if (_extensions.find(ext) != _extensions.end()) + return; + + ext->dm = this; + _extensions.insert(ext); + + JSObjectRef currScope = JSContextGetGlobalObject(_ctx); + std::list<std::string> locPath = InterpreterImpl::tokenize(ext->provides(), '.'); + std::list<std::string>::iterator locIter = locPath.begin(); + while(true) { + std::string pathComp = *locIter; + JSStringRef pathCompJS = JSStringCreateWithUTF8CString(pathComp.c_str()); + + if (++locIter != locPath.end()) { + // just another intermediate step + if (!JSObjectHasProperty(_ctx, currScope, pathCompJS)) { + JSObjectSetProperty(_ctx, currScope, pathCompJS, JSObjectMake(_ctx, NULL, NULL), kJSPropertyAttributeNone, NULL); + } + JSValueRef newScope = JSObjectGetProperty(_ctx, currScope, pathCompJS, NULL); + JSStringRelease(pathCompJS); + + + if (JSValueIsObject(_ctx, newScope)) { + currScope = JSValueToObject(_ctx, newScope, NULL); + } else { + JSStringRelease(pathCompJS); + throw "adsf"; + } + } else { + // this is the function! + JSClassRef jsExtensionClassRef = JSClassCreate(&jsExtensionClassDef); + JSObjectRef jsExtFuncObj = JSObjectMake(_ctx, jsExtensionClassRef, ext); + JSObjectSetProperty(_ctx, currScope, pathCompJS, jsExtFuncObj, kJSPropertyAttributeNone, NULL); + + JSStringRelease(pathCompJS); + break; + } + } +} + +JSValueRef JSCDataModel::jsExtension(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { + DataModelExtension* extension = (DataModelExtension*)JSObjectGetPrivate(function); + + JSStringRef memberRef; + std::string memberName; + + if (argumentCount > 0 && JSValueIsString(ctx, arguments[0])) { + memberRef = JSValueToStringCopy(ctx, arguments[0], exception); + size_t maxSize = JSStringGetMaximumUTF8CStringSize(memberRef); + char* buffer = new char[maxSize]; + JSStringGetUTF8CString(memberRef, buffer, maxSize); + JSStringRelease(memberRef); + memberName = buffer; + free(buffer); + } + + if (argumentCount > 1) { + // setter + Data data = ((JSCDataModel*)(extension->dm))->getValueAsData(arguments[1]); + extension->setValueOf(memberName, data); + return JSValueMakeNull(ctx); + } + if (argumentCount == 1) { + // getter + return ((JSCDataModel*)(extension->dm))->getDataAsValue(extension->getValueOf(memberName)); + } + + return JSValueMakeNull(ctx); +} + #if 0 typedef struct { int version; /* current (and only) version is 0 */ @@ -113,6 +184,7 @@ typedef struct { // functions need to be objects to hold private data in JSC JSClassDefinition JSCDataModel::jsInClassDef = { 0, 0, "In", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, jsIn, 0, 0, 0 }; JSClassDefinition JSCDataModel::jsPrintClassDef = { 0, 0, "print", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, jsPrint, 0, 0, 0 }; +JSClassDefinition JSCDataModel::jsExtensionClassDef = { 0, 0, "Extension", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, jsExtension, 0, 0, 0 }; JSClassDefinition JSCDataModel::jsIOProcessorsClassDef = { 0, 0, "ioProcessors", 0, 0, 0, 0, 0, jsIOProcessorHasProp, jsIOProcessorGetProp, 0, 0, jsIOProcessorListProps, 0, 0, 0, 0 }; JSClassDefinition JSCDataModel::jsInvokersClassDef = { 0, 0, "invokers", 0, 0, 0, 0, 0, jsInvokerHasProp, jsInvokerGetProp, 0, 0, jsInvokerListProps, 0, 0, 0, 0 }; diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h index 10d5999..c2ba01c 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h @@ -42,6 +42,8 @@ public: virtual ~JSCDataModel(); virtual boost::shared_ptr<DataModelImpl> create(InterpreterImpl* interpreter); + virtual void addExtension(DataModelExtension* ext); + virtual std::list<std::string> getNames() { std::list<std::string> names; names.push_back("ecmascript"); @@ -91,6 +93,8 @@ protected: static JSValueRef jsIn(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); static JSClassDefinition jsPrintClassDef; static JSValueRef jsPrint(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); + static JSClassDefinition jsExtensionClassDef; + static JSValueRef jsExtension(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); static JSClassDefinition jsIOProcessorsClassDef; static bool jsIOProcessorHasProp(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName); @@ -101,7 +105,7 @@ protected: static bool jsInvokerHasProp(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName); static JSValueRef jsInvokerGetProp(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception); static void jsInvokerListProps(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames); - + JSValueRef getNodeAsValue(const Arabica::DOM::Node<std::string>& node); JSValueRef getDataAsValue(const Data& data); Data getValueAsData(const JSValueRef value); @@ -112,6 +116,8 @@ protected: std::string _sessionId; std::string _name; + std::set<DataModelExtension*> _extensions; + Event _event; JSGlobalContextRef _ctx; }; |