diff options
Diffstat (limited to 'src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp')
-rw-r--r-- | src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp | 138 |
1 files changed, 136 insertions, 2 deletions
diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index 303b7d1..4c6c23e 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -1,5 +1,8 @@ #include "uscxml/Common.h" #include "JSCDataModel.h" +#include "dom/JSCDOM.h" +#include "dom/JSCDocument.h" + #include "uscxml/Message.h" #include <glog/logging.h> @@ -22,14 +25,27 @@ JSCDataModel::JSCDataModel() { boost::shared_ptr<DataModelImpl> JSCDataModel::create(Interpreter* interpreter) { boost::shared_ptr<JSCDataModel> dm = boost::shared_ptr<JSCDataModel>(new JSCDataModel()); + + dm->_ctx = JSGlobalContextCreate(NULL); dm->_interpreter = interpreter; + Arabica::DOM::JSCDOM* dom = new Arabica::DOM::JSCDOM(); + // dom->interpreter = interpreter; + dom->xpath = new Arabica::XPath::XPath<std::string>(); + dom->xpath->setNamespaceContext(interpreter->getNSContext()); + + dm->setName(interpreter->getName()); dm->setSessionId(interpreter->getSessionId()); dm->eval("_ioprocessors = {};"); - dm->_ctx = JSGlobalContextCreate(NULL); + Arabica::DOM::JSCDocument::JSCDocumentPrivate* privData = new Arabica::DOM::JSCDocument::JSCDocumentPrivate(); + privData->arabicaThis = new Arabica::DOM::Document<std::string>(interpreter->getDocument()); + privData->dom = dom; + + JSObjectRef documentObject = JSObjectMake(dm->_ctx, Arabica::DOM::JSCDocument::getTmpl(), privData); JSObjectRef globalObject = JSContextGetGlobalObject(dm->_ctx); + JSObjectSetProperty(dm->_ctx, globalObject, JSStringCreateWithUTF8CString("document"), documentObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, NULL); return dm; } @@ -47,7 +63,7 @@ void JSCDataModel::setName(const std::string& name) { } JSCDataModel::~JSCDataModel() { -// JSGlobalContextRelease(_ctx); + JSGlobalContextRelease(_ctx); } void JSCDataModel::pushContext() { @@ -60,9 +76,84 @@ void JSCDataModel::initialize() { } void JSCDataModel::setEvent(const Event& event) { + LOG(ERROR) << "setEvent not implemented in JSC"; } Data JSCDataModel::getStringAsData(const std::string& content) { + JSValueRef result = evalAsValue(content); + Data data = getValueAsData(result); + return data; +} + +Data JSCDataModel::getValueAsData(const JSValueRef value) { + Data data; + JSValueRef exception = NULL; + switch(JSValueGetType(_ctx, value)) { + case kJSTypeUndefined: + LOG(ERROR) << "IsUndefined is unimplemented"; + break; + case kJSTypeNull: + LOG(ERROR) << "IsNull is unimplemented"; + break; + case kJSTypeBoolean: + data.atom = (JSValueToBoolean(_ctx, value) ? "true" : "false"); + break; + case kJSTypeNumber: + data.atom = toStr(JSValueToNumber(_ctx, value, &exception)); + if (exception) + handleException(exception); + break; + case kJSTypeString: { + JSStringRef stringValue = JSValueToStringCopy( _ctx, value, &exception); + if (exception) + handleException(exception); + + char* buf = (char*)malloc(JSStringGetMaximumUTF8CStringSize(stringValue)); + JSStringGetUTF8CString(stringValue, buf, sizeof(buf)); + data.atom = std::string(buf, sizeof(buf)); + free(buf); + break; + } + case kJSTypeObject: { + JSObjectRef objValue = JSValueToObject(_ctx, value, &exception); + if (exception) + handleException(exception); + std::set<std::string> propertySet; + JSPropertyNameArrayRef properties = JSObjectCopyPropertyNames(_ctx, objValue); + size_t paramCount = JSPropertyNameArrayGetCount(properties); + bool isArray = true; + for (size_t i = 0; i < paramCount; i++) { + JSStringRef stringValue = JSPropertyNameArrayGetNameAtIndex(properties, i); + char* buf = (char*)malloc(JSStringGetMaximumUTF8CStringSize(stringValue)); + JSStringGetUTF8CString(stringValue, buf, sizeof(buf)); + std::string property(buf, sizeof(buf)); + if (!isNumeric(property.c_str(), 10)) + isArray = false; + propertySet.insert(property); + free(buf); + } + std::set<std::string>::iterator propIter = propertySet.begin(); + while(propIter != propertySet.end()) { + if (isArray) { + JSValueRef nestedValue = JSObjectGetPropertyAtIndex(_ctx, objValue, strTo<int>(*propIter), &exception); + if (exception) + handleException(exception); + data.array.push_back(getValueAsData(nestedValue)); + } else { + JSStringRef jsString = JSStringCreateWithUTF8CString(propIter->c_str()); + JSValueRef nestedValue = JSObjectGetProperty(_ctx, objValue, jsString, &exception); + JSStringRelease(jsString); + if (exception) + handleException(exception); + data.compound[*propIter] = getValueAsData(nestedValue); + } + propIter++; + } + + break; + } + } + return data; } bool JSCDataModel::validate(const std::string& location, const std::string& schema) { @@ -70,21 +161,64 @@ bool JSCDataModel::validate(const std::string& location, const std::string& sche } uint32_t JSCDataModel::getLength(const std::string& expr) { + LOG(ERROR) << "I am not sure whether getLength() works :("; + JSValueRef result = evalAsValue(expr); + JSValueRef exception = NULL; + double length = JSValueToNumber(_ctx, result, &exception); + if (exception) + handleException(exception); + + return (uint32_t)length; } void JSCDataModel::eval(const std::string& expr) { + evalAsValue(expr); } bool JSCDataModel::evalAsBool(const std::string& expr) { + JSValueRef result = evalAsValue(expr); + return JSValueToBoolean(_ctx, result); } std::string JSCDataModel::evalAsString(const std::string& expr) { + JSValueRef result = evalAsValue(expr); + JSValueRef exception = NULL; + JSStringRef stringValue = JSValueToStringCopy( _ctx, result, &exception); + if (exception) + handleException(exception); + + char* data = (char*)malloc(JSStringGetMaximumUTF8CStringSize(stringValue)); + JSStringGetUTF8CString(stringValue, data, sizeof(data)); + std::string retString(data, sizeof(data)); + + JSStringRelease(stringValue); + free(data); + return retString; +} + +JSValueRef JSCDataModel::evalAsValue(const std::string& expr) { + JSStringRef scriptJS = JSStringCreateWithUTF8CString(expr.c_str()); + JSValueRef exception = NULL; + JSValueRef result = JSEvaluateScript(_ctx, scriptJS, NULL, NULL, 0, &exception); + if (exception) + handleException(exception); + + JSStringRelease(scriptJS); + return result; } void JSCDataModel::assign(const std::string& location, const Data& data) { + std::stringstream ssJSON; + ssJSON << data; + assign(location, ssJSON.str()); } void JSCDataModel::assign(const std::string& location, const std::string& expr) { + evalAsValue(location + " = " + expr); +} + +void JSCDataModel::handleException(JSValueRef exception) { + assert(false); } }
\ No newline at end of file |