summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-12-08 03:52:21 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-12-08 03:52:21 +0000
commit2a70a69d92d1bd6071ff6ea76d724b458b4c2287 (patch)
treeddf28d01fbc256d858a4b1e323e5be6f082cbb81
parent47017915e45f786265f5763ebf711abfe308738c (diff)
Move JavaScript eval functions to the js module.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1043295 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--sca-cpp/trunk/etc/git-exclude1
-rw-r--r--sca-cpp/trunk/modules/http/http.hpp4
-rw-r--r--sca-cpp/trunk/modules/js/Makefile.am8
-rw-r--r--sca-cpp/trunk/modules/js/eval.hpp306
-rw-r--r--sca-cpp/trunk/modules/js/js-test.cpp52
-rw-r--r--sca-cpp/trunk/modules/json/json-test.cpp15
-rw-r--r--sca-cpp/trunk/modules/json/json.hpp275
-rw-r--r--sca-cpp/trunk/modules/oauth/mod-oauth1.cpp4
-rw-r--r--sca-cpp/trunk/modules/server/mod-eval.hpp4
9 files changed, 387 insertions, 282 deletions
diff --git a/sca-cpp/trunk/etc/git-exclude b/sca-cpp/trunk/etc/git-exclude
index 8016138976..0712e63aa4 100644
--- a/sca-cpp/trunk/etc/git-exclude
+++ b/sca-cpp/trunk/etc/git-exclude
@@ -104,4 +104,5 @@ curl-get
curl-connect
rss-test
scribe-cat
+js-test
diff --git a/sca-cpp/trunk/modules/http/http.hpp b/sca-cpp/trunk/modules/http/http.hpp
index b6ec9d4e5a..ad3ae84821 100644
--- a/sca-cpp/trunk/modules/http/http.hpp
+++ b/sca-cpp/trunk/modules/http/http.hpp
@@ -306,7 +306,7 @@ const failable<value> evalExpr(const value& expr, const string& url, const CURLS
debug(expr, "http::evalExpr::input");
// Convert expression to a JSON-RPC request
- json::JSONContext cx;
+ js::JSContext cx;
const failable<list<string> > jsreq = json::jsonRequest(1, car<value>(expr), cdr<value>(expr), cx);
if (!hasContent(jsreq))
return mkfailure<value>(reason(jsreq));
@@ -422,7 +422,7 @@ const failable<value> get(const string& url, const CURLSession& cs) {
return val;
}
if (contains(ct, "text/javascript") || contains(ct, "application/json")) {
- json::JSONContext cx;
+ js::JSContext cx;
const value val(json::jsonValues(content(json::readJSON(ls, cx))));
debug(val, "http::get::result");
return val;
diff --git a/sca-cpp/trunk/modules/js/Makefile.am b/sca-cpp/trunk/modules/js/Makefile.am
index 4086c22acf..8c88f32c0f 100644
--- a/sca-cpp/trunk/modules/js/Makefile.am
+++ b/sca-cpp/trunk/modules/js/Makefile.am
@@ -15,7 +15,15 @@
# specific language governing permissions and limitations
# under the License.
+incl_HEADERS = *.hpp
+incldir = $(prefix)/include/modules/js
+
moddir = $(prefix)/modules/js
nobase_dist_mod_DATA = htdocs/*.js htdocs/*.css
EXTRA_DIST = htdocs/*.js htdocs/*.css
+js_test_SOURCES = js-test.cpp
+js_test_LDFLAGS = -lmozjs
+
+noinst_PROGRAMS = js-test
+TESTS = js-test
diff --git a/sca-cpp/trunk/modules/js/eval.hpp b/sca-cpp/trunk/modules/js/eval.hpp
new file mode 100644
index 0000000000..3be0eea2d1
--- /dev/null
+++ b/sca-cpp/trunk/modules/js/eval.hpp
@@ -0,0 +1,306 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* $Rev$ $Date$ */
+
+#ifndef tuscany_js_hpp
+#define tuscany_js_hpp
+
+/**
+ * Javascript evaluation functions.
+ */
+
+#define XP_UNIX
+#include <jsapi.h>
+#include "string.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "element.hpp"
+#include "monad.hpp"
+
+namespace tuscany {
+namespace js {
+
+/**
+ * Report Javascript errors.
+ */
+void reportError(unused ::JSContext *cx, const char *message, JSErrorReport *report) {
+#ifdef WANT_MAINTAINER_MODE
+ cdebug << (const char*)(report->filename? report->filename : "<no filename>") << ":"
+ << (int)report->lineno << ":" << message << endl;
+#endif
+}
+
+/**
+ * Encapsulates a JavaScript runtime. Shared by multiple threads in
+ * a process.
+ */
+class JSRuntime {
+public:
+ JSRuntime() {
+ // Create JS runtime
+ rt = JS_NewRuntime(8L * 1024L * 1024L);
+ if(rt == NULL)
+ cleanup();
+ }
+
+ operator ::JSRuntime*() const {
+ return rt;
+ }
+private:
+ bool cleanup() {
+ if(rt != NULL) {
+ JS_DestroyRuntime(rt);
+ rt = NULL;
+ }
+ JS_ShutDown();
+ return true;
+ }
+
+ ::JSRuntime* rt;
+} jsRuntime;
+
+JSClass jsGlobalClass = { "global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+ JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS};
+
+/**
+ * Represents a JavaScript context. Create one per thread.
+ */
+class JSContext {
+public:
+ JSContext() {
+ // Create JS context
+ cx = JS_NewContext(jsRuntime, 8192);
+ if(cx == NULL)
+ return;
+ JS_SetOptions(cx, JSOPTION_VAROBJFIX);
+ JS_SetVersion(cx, JSVERSION_DEFAULT);
+ JS_SetErrorReporter(cx, reportError);
+
+ // Create global JS object
+ global = JS_NewObject(cx, &jsGlobalClass, NULL, NULL);
+ if(global == NULL) {
+ cleanup();
+ return;
+ }
+
+ // Populate global object with the standard globals, like Object and Array
+ if(!JS_InitStandardClasses(cx, global)) {
+ cleanup();
+ return;
+ }
+ }
+
+ ~JSContext() {
+ cleanup();
+ }
+
+ operator ::JSContext*() const {
+ return cx;
+ }
+
+ JSObject* getGlobal() const {
+ return global;
+ }
+
+private:
+ bool cleanup() {
+ if(cx != NULL) {
+ JS_DestroyContext(cx);
+ cx = NULL;
+ }
+ return true;
+ }
+
+ ::JSContext* cx;
+ JSObject* global;
+};
+
+/**
+ * Returns true if a list represents a JS array.
+ */
+const bool isJSArray(const list<value>& l) {
+ if(isNil(l))
+ return true;
+ const value v = car(l);
+ if (isSymbol(v))
+ return false;
+ if(isList(v)) {
+ if(!isNil((list<value>)v) && isSymbol(car<value>(v)))
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Converts JS properties to values.
+ */
+const list<value> jsPropertiesToValues(const list<value>& propertiesSoFar, JSObject* o, JSObject* i, const js::JSContext& cx) {
+
+ const value jsValToValue(const jsval& jsv, const js::JSContext& cx);
+
+ jsid id;
+ if(!JS_NextProperty(cx, i, &id) || id == JSVAL_VOID)
+ return propertiesSoFar;
+ jsval jsv;
+ if(!JS_GetPropertyById(cx, o, id, &jsv))
+ return propertiesSoFar;
+ const value val = jsValToValue(jsv, cx);
+
+ jsval idv;
+ JS_IdToValue(cx, id, &idv);
+ if(JSVAL_IS_STRING(idv)) {
+ if (isNil(val) && !isList(val))
+ return jsPropertiesToValues(propertiesSoFar, o, i, cx);
+ const string name = JS_GetStringBytes(JSVAL_TO_STRING(idv));
+ if (substr(name, 0, 1) == atsign)
+ return jsPropertiesToValues(cons<value>(mklist<value>(attribute, c_str(substr(name, 1)), val), propertiesSoFar), o, i, cx);
+ if (isList(val) && !isJSArray(val))
+ return jsPropertiesToValues(cons<value>(cons<value>(element, cons<value>(c_str(name), list<value>(val))), propertiesSoFar), o, i, cx);
+ return jsPropertiesToValues(cons<value> (mklist<value> (element, c_str(name), val), propertiesSoFar), o, i, cx);
+ }
+ return jsPropertiesToValues(cons(val, propertiesSoFar), o, i, cx);
+}
+
+/**
+ * Converts a JS val to a value.
+ */
+const value jsValToValue(const jsval& jsv, const js::JSContext& cx) {
+ switch(JS_TypeOfValue(cx, jsv)) {
+ case JSTYPE_STRING: {
+ return value(string(JS_GetStringBytes(JSVAL_TO_STRING(jsv))));
+ }
+ case JSTYPE_BOOLEAN: {
+ return value((bool)JSVAL_TO_BOOLEAN(jsv));
+ }
+ case JSTYPE_NUMBER: {
+ jsdouble jsd;
+ JS_ValueToNumber(cx, jsv, &jsd);
+ return value((double)jsd);
+ }
+ case JSTYPE_OBJECT: {
+ JSObject* o = JSVAL_TO_OBJECT(jsv);
+ if (o == NULL)
+ return value();
+ JSObject* i = JS_NewPropertyIterator(cx, o);
+ if(i == NULL)
+ return value(list<value> ());
+ const value pv = jsPropertiesToValues(list<value> (), o, i, cx);
+ return pv;
+ }
+ default: {
+ return value();
+ }
+ }
+}
+
+/**
+ * Converts a list of values to JS array elements.
+ */
+JSObject* valuesToJSElements(JSObject* a, const list<value>& l, int i, const js::JSContext& cx) {
+ const jsval valueToJSVal(const value& val, const js::JSContext& cx);
+ if (isNil(l))
+ return a;
+ jsval pv = valueToJSVal(car(l), cx);
+ JS_SetElement(cx, a, i, &pv);
+ return valuesToJSElements(a, cdr(l), ++i, cx);
+}
+
+/**
+ * Converts a value to a JS val.
+ */
+const jsval valueToJSVal(const value& val, const js::JSContext& cx) {
+ JSObject* valuesToJSProperties(JSObject* o, const list<value>& l, const js::JSContext& cx);
+
+ switch(type(val)) {
+ case value::String:
+ case value::Symbol: {
+ return STRING_TO_JSVAL(JS_NewStringCopyZ(cx, c_str((string)val)));
+ }
+ case value::Bool: {
+ return BOOLEAN_TO_JSVAL((bool)val);
+ }
+ case value::Number: {
+ return DOUBLE_TO_JSVAL(JS_NewDouble(cx, (double)val));
+ }
+ case value::List: {
+ if (isJSArray(val))
+ return OBJECT_TO_JSVAL(valuesToJSElements(JS_NewArrayObject(cx, 0, NULL), val, 0, cx));
+ return OBJECT_TO_JSVAL(valuesToJSProperties(JS_NewObject(cx, NULL, NULL, NULL), val, cx));
+ }
+ default: {
+ return JSVAL_VOID;
+ }
+ }
+}
+
+/**
+ * Converts a list of values to JS properties.
+ */
+JSObject* valuesToJSProperties(JSObject* o, const list<value>& l, const js::JSContext& cx) {
+ if (isNil(l))
+ return o;
+
+ // Write an attribute
+ const value token(car(l));
+
+ if (isTaggedList(token, attribute)) {
+ jsval pv = valueToJSVal(attributeValue(token), cx);
+ JS_SetProperty(cx, o, c_str(atsign + string(attributeName(token))), &pv);
+
+ } else if (isTaggedList(token, element)) {
+
+ // Write the value of an element
+ if (elementHasValue(token)) {
+ jsval pv = valueToJSVal(elementValue(token), cx);
+ JS_SetProperty(cx, o, c_str(string(elementName(token))), &pv);
+
+ } else {
+
+ // Write a parent element
+ JSObject* child = JS_NewObject(cx, NULL, NULL, NULL);
+ jsval pv = OBJECT_TO_JSVAL(child);
+ JS_SetProperty(cx, o, c_str(string(elementName(token))), &pv);
+
+ // Write its children
+ valuesToJSProperties(child, elementChildren(token), cx);
+ }
+ }
+
+ // Go on
+ return valuesToJSProperties(o, cdr(l), cx);
+}
+
+/**
+ * Evaluate a script provided as a string.
+ */
+const failable<value> evalScript(const string& s) {
+ js::JSContext cx;
+ jsval rval;
+ JSBool rc = JS_EvaluateScript(cx, cx.getGlobal(), c_str(s), (uintN)length(s), "eval.js", 1, &rval);
+ if (rc != JS_TRUE) {
+ return mkfailure<value>("Couldn't evaluate Javascript script.");
+ }
+ return jsValToValue(rval, cx);
+}
+
+}
+}
+
+#endif /* tuscany_js_hpp */
diff --git a/sca-cpp/trunk/modules/js/js-test.cpp b/sca-cpp/trunk/modules/js/js-test.cpp
new file mode 100644
index 0000000000..9cbf000ac3
--- /dev/null
+++ b/sca-cpp/trunk/modules/js/js-test.cpp
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Test JavaScript evaluation functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "eval.hpp"
+
+namespace tuscany {
+namespace js {
+
+bool testJSEval() {
+ failable<value> v = evalScript("(function testJSON(n){ return JSON.parse(JSON.stringify(n)) })(5)");
+ assert(hasContent(v));
+ assert(content(v) == value(5));
+ return true;
+}
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::js::testJSEval();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/trunk/modules/json/json-test.cpp b/sca-cpp/trunk/modules/json/json-test.cpp
index abed71a9c3..6666b3f479 100644
--- a/sca-cpp/trunk/modules/json/json-test.cpp
+++ b/sca-cpp/trunk/modules/json/json-test.cpp
@@ -31,23 +31,13 @@
namespace tuscany {
namespace json {
-bool testJSEval() {
- JSONContext cx;
- const string script("(function testJSON(n){ return JSON.parse(JSON.stringify(n)) })(5)");
- jsval rval;
- assert(JS_EvaluateScript(cx, cx.getGlobal(), c_str(script), (uintN)length(script), "testJSON.js", 1, &rval));
- const string r(JS_GetStringBytes(JS_ValueToString(cx, rval)));
- assert(r == "5");
- return true;
-}
-
ostream* jsonWriter(const string& s, ostream* os) {
(*os) << s;
return os;
}
bool testJSON() {
- const JSONContext cx;
+ const js::JSContext cx;
{
const list<value> ad = mklist<value>(mklist<value>(attribute, "city", string("san francisco")), mklist<value>(attribute, "state", string("ca")));
@@ -91,7 +81,7 @@ bool testJSON() {
}
bool testJSONRPC() {
- JSONContext cx;
+ js::JSContext cx;
{
const string lm("{\"id\": 1, \"method\": \"test\", \"params\": []}");
const list<value> e = content(readJSON(mklist(lm), cx));
@@ -166,7 +156,6 @@ bool testJSONRPC() {
int main() {
tuscany::cout << "Testing..." << tuscany::endl;
- tuscany::json::testJSEval();
tuscany::json::testJSON();
tuscany::json::testJSONRPC();
diff --git a/sca-cpp/trunk/modules/json/json.hpp b/sca-cpp/trunk/modules/json/json.hpp
index a0617b0e5e..a9dc57da15 100644
--- a/sca-cpp/trunk/modules/json/json.hpp
+++ b/sca-cpp/trunk/modules/json/json.hpp
@@ -26,194 +26,20 @@
* JSON data conversion functions.
*/
-#define XP_UNIX
-#include <jsapi.h>
#include "string.hpp"
#include "list.hpp"
#include "value.hpp"
#include "element.hpp"
#include "monad.hpp"
+#include "../js/eval.hpp"
namespace tuscany {
namespace json {
/**
- * Report JSON errors.
- */
-void reportError(unused JSContext *cx, const char *message, JSErrorReport *report) {
-#ifdef WANT_MAINTAINER_MODE
- cdebug << (const char*)(report->filename? report->filename : "<no filename>") << ":"
- << (int)report->lineno << ":" << message << endl;
-#endif
-}
-
-/**
- * Encapsulates a JavaScript runtime. Shared by multiple threads in
- * a process.
- */
-class JSONRuntime {
-public:
- JSONRuntime() {
- // Create JS runtime
- rt = JS_NewRuntime(8L * 1024L * 1024L);
- if(rt == NULL)
- cleanup();
- }
-
- operator JSRuntime*() const {
- return rt;
- }
-private:
- bool cleanup() {
- if(rt != NULL) {
- JS_DestroyRuntime(rt);
- rt = NULL;
- }
- JS_ShutDown();
- return true;
- }
-
- JSRuntime* rt;
-} jsRuntime;
-
-JSClass jsGlobalClass = { "global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
- JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS};
-
-/**
- * Represents a JavaScript context. Create one per thread.
- */
-class JSONContext {
-public:
- JSONContext() {
- // Create JS context
- cx = JS_NewContext(jsRuntime, 8192);
- if(cx == NULL)
- return;
- JS_SetOptions(cx, JSOPTION_VAROBJFIX);
- JS_SetVersion(cx, JSVERSION_DEFAULT);
- JS_SetErrorReporter(cx, reportError);
-
- // Create global JS object
- global = JS_NewObject(cx, &jsGlobalClass, NULL, NULL);
- if(global == NULL) {
- cleanup();
- return;
- }
-
- // Populate global object with the standard globals, like Object and Array
- if(!JS_InitStandardClasses(cx, global)) {
- cleanup();
- return;
- }
- }
-
- ~JSONContext() {
- cleanup();
- }
-
- operator JSContext*() const {
- return cx;
- }
-
- JSObject* getGlobal() const {
- return global;
- }
-
-private:
- bool cleanup() {
- if(cx != NULL) {
- JS_DestroyContext(cx);
- cx = NULL;
- }
- return true;
- }
-
- JSContext* cx;
- JSObject* global;
-};
-
-/**
- * Returns true if a list represents a JS array.
- */
-const bool isJSArray(const list<value>& l) {
- if(isNil(l))
- return true;
- const value v = car(l);
- if (isSymbol(v))
- return false;
- if(isList(v)) {
- if(!isNil((list<value>)v) && isSymbol(car<value>(v)))
- return false;
- }
- return true;
-}
-
-/**
- * Converts JS properties to values.
- */
-const list<value> jsPropertiesToValues(const list<value>& propertiesSoFar, JSObject* o, JSObject* i, const JSONContext& cx) {
-
- const value jsValToValue(const jsval& jsv, const JSONContext& cx);
-
- jsid id;
- if(!JS_NextProperty(cx, i, &id) || id == JSVAL_VOID)
- return propertiesSoFar;
- jsval jsv;
- if(!JS_GetPropertyById(cx, o, id, &jsv))
- return propertiesSoFar;
- const value val = jsValToValue(jsv, cx);
-
- jsval idv;
- JS_IdToValue(cx, id, &idv);
- if(JSVAL_IS_STRING(idv)) {
- if (isNil(val) && !isList(val))
- return jsPropertiesToValues(propertiesSoFar, o, i, cx);
- const string name = JS_GetStringBytes(JSVAL_TO_STRING(idv));
- if (substr(name, 0, 1) == atsign)
- return jsPropertiesToValues(cons<value>(mklist<value>(attribute, c_str(substr(name, 1)), val), propertiesSoFar), o, i, cx);
- if (isList(val) && !isJSArray(val))
- return jsPropertiesToValues(cons<value>(cons<value>(element, cons<value>(c_str(name), list<value>(val))), propertiesSoFar), o, i, cx);
- return jsPropertiesToValues(cons<value> (mklist<value> (element, c_str(name), val), propertiesSoFar), o, i, cx);
- }
- return jsPropertiesToValues(cons(val, propertiesSoFar), o, i, cx);
-}
-
-/**
- * Converts a JS val to a value.
- */
-const value jsValToValue(const jsval& jsv, const JSONContext& cx) {
- switch(JS_TypeOfValue(cx, jsv)) {
- case JSTYPE_STRING: {
- return value(string(JS_GetStringBytes(JSVAL_TO_STRING(jsv))));
- }
- case JSTYPE_BOOLEAN: {
- return value((bool)JSVAL_TO_BOOLEAN(jsv));
- }
- case JSTYPE_NUMBER: {
- jsdouble jsd;
- JS_ValueToNumber(cx, jsv, &jsd);
- return value((double)jsd);
- }
- case JSTYPE_OBJECT: {
- JSObject* o = JSVAL_TO_OBJECT(jsv);
- if (o == NULL)
- return value();
- JSObject* i = JS_NewPropertyIterator(cx, o);
- if(i == NULL)
- return value(list<value> ());
- const value pv = jsPropertiesToValues(list<value> (), o, i, cx);
- return pv;
- }
- default: {
- return value();
- }
- }
-}
-
-/**
* Consumes JSON strings and populates a JS object.
*/
-failable<bool> consume(JSONParser* parser, const list<string>& ilist, const JSONContext& cx) {
+failable<bool> consume(JSONParser* parser, const list<string>& ilist, const js::JSContext& cx) {
if (isNil(ilist))
return true;
JSString* jstr = JS_NewStringCopyZ(cx, c_str(car(ilist)));
@@ -225,7 +51,7 @@ failable<bool> consume(JSONParser* parser, const list<string>& ilist, const JSON
/**
* Convert a list of strings representing a JSON document to a list of values.
*/
-const failable<list<value> > readJSON(const list<string>& ilist, const JSONContext& cx) {
+const failable<list<value> > readJSON(const list<string>& ilist, const js::JSContext& cx) {
jsval val;
JSONParser* parser = JS_BeginJSONParse(cx, &val);
if(parser == NULL)
@@ -238,84 +64,7 @@ const failable<list<value> > readJSON(const list<string>& ilist, const JSONConte
if(!hasContent(consumed))
return mkfailure<list<value> >(reason(consumed));
- return list<value>(jsValToValue(val, cx));
-}
-
-/**
- * Converts a list of values to JS array elements.
- */
-JSObject* valuesToJSElements(JSObject* a, const list<value>& l, int i, const JSONContext& cx) {
- const jsval valueToJSVal(const value& val, const JSONContext& cx);
- if (isNil(l))
- return a;
- jsval pv = valueToJSVal(car(l), cx);
- JS_SetElement(cx, a, i, &pv);
- return valuesToJSElements(a, cdr(l), ++i, cx);
-}
-
-/**
- * Converts a value to a JS val.
- */
-const jsval valueToJSVal(const value& val, const JSONContext& cx) {
- JSObject* valuesToJSProperties(JSObject* o, const list<value>& l, const JSONContext& cx);
-
- switch(type(val)) {
- case value::String:
- case value::Symbol: {
- return STRING_TO_JSVAL(JS_NewStringCopyZ(cx, c_str((string)val)));
- }
- case value::Bool: {
- return BOOLEAN_TO_JSVAL((bool)val);
- }
- case value::Number: {
- return DOUBLE_TO_JSVAL(JS_NewDouble(cx, (double)val));
- }
- case value::List: {
- if (isJSArray(val))
- return OBJECT_TO_JSVAL(valuesToJSElements(JS_NewArrayObject(cx, 0, NULL), val, 0, cx));
- return OBJECT_TO_JSVAL(valuesToJSProperties(JS_NewObject(cx, NULL, NULL, NULL), val, cx));
- }
- default: {
- return JSVAL_VOID;
- }
- }
-}
-
-/**
- * Converts a list of values to JS properties.
- */
-JSObject* valuesToJSProperties(JSObject* o, const list<value>& l, const JSONContext& cx) {
- if (isNil(l))
- return o;
-
- // Write an attribute
- const value token(car(l));
-
- if (isTaggedList(token, attribute)) {
- jsval pv = valueToJSVal(attributeValue(token), cx);
- JS_SetProperty(cx, o, c_str(atsign + string(attributeName(token))), &pv);
-
- } else if (isTaggedList(token, element)) {
-
- // Write the value of an element
- if (elementHasValue(token)) {
- jsval pv = valueToJSVal(elementValue(token), cx);
- JS_SetProperty(cx, o, c_str(string(elementName(token))), &pv);
-
- } else {
-
- // Write a parent element
- JSObject* child = JS_NewObject(cx, NULL, NULL, NULL);
- jsval pv = OBJECT_TO_JSVAL(child);
- JS_SetProperty(cx, o, c_str(string(elementName(token))), &pv);
-
- // Write its children
- valuesToJSProperties(child, elementChildren(token), cx);
- }
- }
-
- // Go on
- return valuesToJSProperties(o, cdr(l), cx);
+ return list<value>(js::jsValToValue(val, cx));
}
/**
@@ -323,9 +72,9 @@ JSObject* valuesToJSProperties(JSObject* o, const list<value>& l, const JSONCont
*/
template<typename R> class WriteContext {
public:
- WriteContext(const lambda<R(const string&, const R)>& reduce, const R& accum, const JSONContext& cx) : cx(cx), reduce(reduce), accum(accum) {
+ WriteContext(const lambda<R(const string&, const R)>& reduce, const R& accum, const js::JSContext& cx) : cx(cx), reduce(reduce), accum(accum) {
}
- const JSONContext& cx;
+ const js::JSContext& cx;
const lambda<R(const string&, const R)> reduce;
R accum;
};
@@ -343,7 +92,7 @@ template<typename R> JSBool writeCallback(const jschar *buf, uint32 len, void *d
/**
* Convert a list of values to a JSON document.
*/
-template<typename R> const failable<R> writeJSON(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l, const JSONContext& cx) {
+template<typename R> const failable<R> writeJSON(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l, const js::JSContext& cx) {
jsval val = OBJECT_TO_JSVAL(valuesToJSProperties(JS_NewObject(cx, NULL, NULL, NULL), l, cx));
WriteContext<R> wcx(reduce, initial, cx);
@@ -355,7 +104,7 @@ template<typename R> const failable<R> writeJSON(const lambda<R(const string&, c
/**
* Convert a list of values to a list of strings representing a JSON document.
*/
-const failable<list<string> > writeJSON(const list<value>& l, const JSONContext& cx) {
+const failable<list<string> > writeJSON(const list<value>& l, const js::JSContext& cx) {
const failable<list<string> > ls = writeJSON<list<string>>(rcons<string>, list<string>(), l, cx);
if (!hasContent(ls))
return ls;
@@ -365,7 +114,7 @@ const failable<list<string> > writeJSON(const list<value>& l, const JSONContext&
/**
* Convert a list of function + params to a JSON-RPC request.
*/
-const failable<list<string> > jsonRequest(const value& id, const value& func, const value& params, json::JSONContext& cx) {
+const failable<list<string> > jsonRequest(const value& id, const value& func, const value& params, js::JSContext& cx) {
const list<value> r = mklist<value>(mklist<value>("id", id), mklist<value>("method", string(func)), mklist<value>("params", params));
return writeJSON(valuesToElements(r), cx);
}
@@ -373,20 +122,20 @@ const failable<list<string> > jsonRequest(const value& id, const value& func, co
/**
* Convert a value to a JSON-RPC result.
*/
-const failable<list<string> > jsonResult(const value& id, const value& val, JSONContext& cx) {
+const failable<list<string> > jsonResult(const value& id, const value& val, js::JSContext& cx) {
return writeJSON(valuesToElements(mklist<value>(mklist<value>("id", id), mklist<value>("result", val))), cx);
}
/**
* Convert a JSON-RPC result to a value.
*/
-const failable<value> jsonResultValue(const list<string>& s, JSONContext& cx) {
+const failable<value> jsonResultValue(const list<string>& s, js::JSContext& cx) {
const failable<list<value> > jsres = json::readJSON(s, cx);
if (!hasContent(jsres))
return mkfailure<value>(reason(jsres));
const list<value> rval(cadr<value>(elementsToValues(content(jsres))));
const value val = cadr(rval);
- if (isList(val) && !isJSArray(val))
+ if (isList(val) && !js::isJSArray(val))
return value(mklist<value>(val));
return val;
}
diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
index a417935c0a..0f190127db 100644
--- a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
+++ b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
@@ -250,7 +250,7 @@ const failable<list<value> > profileUserInfo(const value& cid, const string& inf
string b = substr(info, 0, 1);
if (b == "[") {
// Twitter JSON profile
- json::JSONContext cx;
+ js::JSContext cx;
const list<value> infov(json::jsonValues(content(json::readJSON(mklist<string>(info), cx))));
if (isNil(infov))
return mkfailure<list<value> >("Couldn't retrieve user info");
@@ -264,7 +264,7 @@ const failable<list<value> > profileUserInfo(const value& cid, const string& inf
}
if (b == "{") {
// Foursquare JSON profile
- json::JSONContext cx;
+ js::JSContext cx;
const list<value> infov(json::jsonValues(content(json::readJSON(mklist<string>(info), cx))));
if (isNil(infov))
return mkfailure<list<value> >("Couldn't retrieve user info");
diff --git a/sca-cpp/trunk/modules/server/mod-eval.hpp b/sca-cpp/trunk/modules/server/mod-eval.hpp
index c2705b0538..04d754f249 100644
--- a/sca-cpp/trunk/modules/server/mod-eval.hpp
+++ b/sca-cpp/trunk/modules/server/mod-eval.hpp
@@ -119,7 +119,7 @@ const failable<int> get(request_rec* r, const lambda<value(const list<value>&)>&
return mkfailure<int>(reason(val));
// Return JSON result
- json::JSONContext cx;
+ js::JSContext cx;
return httpd::writeResult(json::jsonResult(id, content(val), cx), "application/json-rpc", r);
}
@@ -157,7 +157,7 @@ const failable<int> post(request_rec* r, const lambda<value(const list<value>&)>
return rc;
const list<string> ls = httpd::read(r);
debug(ls, "modeval::post::input");
- json::JSONContext cx;
+ js::JSContext cx;
const list<value> json = elementsToValues(content(json::readJSON(ls, cx)));
const list<list<value> > args = httpd::postArgs(json);