tuscany-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jsdelf...@apache.org
Subject svn commit: r1094210 - in /tuscany/sca-cpp/trunk: kernel/ modules/http/ modules/js/ modules/js/htdocs/ modules/scheme/ modules/wsgi/
Date Sun, 17 Apr 2011 22:14:19 GMT
Author: jsdelfino
Date: Sun Apr 17 22:14:18 2011
New Revision: 1094210

URL: http://svn.apache.org/viewvc?rev=1094210&view=rev
Log:
Fix representation of null values and escape control characters in JSON and HTTP query strings.

Modified:
    tuscany/sca-cpp/trunk/kernel/gc.hpp
    tuscany/sca-cpp/trunk/kernel/list.hpp
    tuscany/sca-cpp/trunk/kernel/value.hpp
    tuscany/sca-cpp/trunk/modules/http/http.hpp
    tuscany/sca-cpp/trunk/modules/http/httpd-conf
    tuscany/sca-cpp/trunk/modules/http/httpd.hpp
    tuscany/sca-cpp/trunk/modules/js/eval.hpp
    tuscany/sca-cpp/trunk/modules/js/htdocs/jsonutil.js
    tuscany/sca-cpp/trunk/modules/scheme/environment.hpp
    tuscany/sca-cpp/trunk/modules/scheme/eval-test.cpp
    tuscany/sca-cpp/trunk/modules/scheme/io.hpp
    tuscany/sca-cpp/trunk/modules/wsgi/jsonutil.py

Modified: tuscany/sca-cpp/trunk/kernel/gc.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/gc.hpp?rev=1094210&r1=1094209&r2=1094210&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/gc.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/gc.hpp Sun Apr 17 22:14:18 2011
@@ -36,6 +36,23 @@
 namespace tuscany
 {
 
+#ifdef WANT_MAINTAINER_MODE
+
+/**
+ * Force a core dump on assertion violation.
+ */
+bool assertOrFail(const bool expr) {
+    if (!expr)
+        *(char*)NULL = '\0';
+    return true;
+}
+
+#else
+
+#define assertOrFail(expr)
+
+#endif
+
 /**
  * Pointer to a value.
  */
@@ -117,7 +134,7 @@ private:
 apr_pool_t* mkpool() {
     apr_pool_t* p = NULL;
     apr_pool_create(&p, NULL);
-    assert(p != NULL);
+    assertOrFail(p != NULL);
     return p;
 }
 
@@ -164,7 +181,7 @@ apr_pool_t* gc_current_pool() {
 
     // Create a parent pool for the current thread
     apr_pool_create(&apr_pool, NULL);
-    assert(apr_pool != NULL);
+    assertOrFail(apr_pool != NULL);
     gc_pool_stack = apr_pool;
     return apr_pool;
 }
@@ -196,7 +213,7 @@ public:
 
     gc_scoped_pool() : gc_pool(NULL), prev(gc_current_pool()), owner(true) {
         apr_pool_create(&apr_pool, NULL);
-        assert(apr_pool != NULL);
+        assertOrFail(apr_pool != NULL);
         gc_push_pool(apr_pool);
     }
 
@@ -230,7 +247,7 @@ template<typename T> apr_status_t gc_poo
 
 template<typename T> T* gc_new(apr_pool_t* p) {
     void* gc_new_ptr = apr_palloc(p, sizeof(T));
-    assert(gc_new_ptr != NULL);
+    assertOrFail(gc_new_ptr != NULL);
     apr_pool_cleanup_register(p, gc_new_ptr, gc_pool_cleanup<T>, apr_pool_cleanup_null)
;
     return static_cast<T*>(gc_new_ptr);
 }
@@ -254,7 +271,7 @@ template<typename T> apr_status_t gc_poo
 
 template<typename T> T* gc_anew(apr_pool_t* p, size_t n) {
     size_t* gc_anew_ptr = static_cast<size_t*>(apr_palloc(p, sizeof(size_t) + sizeof(T[n])));
-    assert(gc_anew_ptr != NULL);
+    assertOrFail(gc_anew_ptr != NULL);
     *gc_anew_ptr = n;
     apr_pool_cleanup_register(p, gc_anew_ptr, gc_pool_acleanup<T>, apr_pool_cleanup_null)
;
     return (T*)(gc_anew_ptr + 1);
@@ -273,7 +290,7 @@ template<typename T> T* gc_anew(size_t n
  */
 char* gc_cnew(apr_pool_t* p, size_t n) {
     char* gc_cnew_ptr = static_cast<char*>(apr_palloc(p, n));
-    assert(gc_cnew_ptr != NULL);
+    assertOrFail(gc_cnew_ptr != NULL);
     return gc_cnew_ptr;
 }
 

Modified: tuscany/sca-cpp/trunk/kernel/list.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/list.hpp?rev=1094210&r1=1094209&r2=1094210&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/list.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/list.hpp Sun Apr 17 22:14:18 2011
@@ -301,7 +301,7 @@ template<typename T> const list<T> mklis
  */
 template<typename T> const T car(const list<T>& p) {
     // Abort if trying to access the car of a nil list
-    assert(!isNil(p.cdr));
+    assertOrFail(!isNil(p.cdr));
     return p.car;
 }
 

Modified: tuscany/sca-cpp/trunk/kernel/value.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/value.hpp?rev=1094210&r1=1094209&r2=1094210&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/value.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/value.hpp Sun Apr 17 22:14:18 2011
@@ -95,10 +95,10 @@ class value {
 public:
 
     enum ValueType {
-        Undefined, Symbol, String, List, Number, Bool, Lambda, Ptr
+        Nil, Symbol, String, List, Number, Bool, Lambda, Ptr
     };
 
-    value() : type(value::Undefined) {
+    value() : type(value::Nil) {
         debug_inc(countValues);
         debug_inc(countEValues);
         debug_watchValue();
@@ -239,8 +239,8 @@ public:
         if(this == &v)
             return true;
         switch(type) {
-        case value::Undefined:
-            return v.type == value::Undefined;
+        case value::Nil:
+            return v.type == value::Nil;
         case value::List:
             return v.type == value::List && lst()() == v.lst()();
         case value::Lambda:
@@ -448,6 +448,18 @@ const string watchValue(const value& v) 
 #endif
 
 /**
+ * Write an escaped string value to a stream.
+ */
+ostream& escvwrite(const char* s, ostream& out) {
+    if (*s == '\0')
+        return out;
+    if (*s == '\\' || *s == '"')
+        out << '\\';
+    out << *s;
+    return escvwrite(s + 1, out);
+}
+
+/**
  * Write a value to a stream.
  */
 ostream& operator<<(ostream& out, const value& v) {
@@ -459,7 +471,9 @@ ostream& operator<<(ostream& out, const 
     case value::Symbol:
         return out << v.str()();
     case value::String:
-        return out << '\"' << v.str()() << '\"';
+        out << '\"';
+        escvwrite(c_str(v.str()()), out);
+        return out << '\"';
     case value::Number:
         return out << v.num()();
     case value::Bool:
@@ -474,7 +488,7 @@ ostream& operator<<(ostream& out, const 
         return out << "gc_ptr::" << p;
     }
     default:
-        return out << "undefined";
+        return out << "nil";
     }
 }
 
@@ -489,7 +503,7 @@ const value::ValueType type(const value&
  * Returns true if a value is nil.
  */
 const bool isNil(const value& v) {
-    return type(v) == value::Undefined;
+    return type(v) == value::Nil;
 }
 
 /**

Modified: tuscany/sca-cpp/trunk/modules/http/http.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/http.hpp?rev=1094210&r1=1094209&r2=1094210&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/http.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/http.hpp Sun Apr 17 22:14:18 2011
@@ -30,6 +30,8 @@
 #include <curl/curl.h>
 #include <curl/types.h>
 #include <curl/easy.h>
+#include <apr.h>
+#include <apr_lib.h>
 #include <apr_network_io.h>
 #include <apr_portable.h>
 #include <apr_poll.h>
@@ -93,6 +95,7 @@ private:
 
     friend CURL* handle(const CURLSession& cs);
     friend apr_socket_t* sock(const CURLSession& cs);
+    friend const failable<CURL*> setup(const string& url, const CURLSession&
cs);
     friend const failable<bool> connect(const string& url, CURLSession& cs);
     friend const failable<bool> send(const char* c, const size_t l, const CURLSession&
cs);
     friend const failable<size_t> recv(char* c, const size_t l, const CURLSession&
cs);
@@ -143,6 +146,45 @@ const string apreason(apr_status_t rc) {
 }
 
 /**
+ * Escape a URI or a query argument.
+ */
+const char escape_c2x[] = "0123456789ABCDEF";
+
+const string escape(const string& unesc, const char* reserv) {
+    char* copy = (char*)apr_palloc(gc_current_pool(), 3 * length(unesc) + 3);
+    const unsigned char* s = (const unsigned char *)c_str(unesc);
+    unsigned char* d = (unsigned char*)copy;
+    unsigned c;
+    while ((c = *s)) {
+        if (!apr_isalnum(c) && !strchr(reserv, c)) {
+            *d++ = '%';
+            *d++ = escape_c2x[c >> 4];
+            *d++ = escape_c2x[c & 0xf];
+        }
+        else {
+            *d++ = (unsigned char)c;
+        }
+        ++s;
+    }
+    *d = '\0';
+    return copy;
+}
+
+const string escapeURI(const string& uri) {
+    debug(uri, "http::escapeURI::uri");
+    const string e = escape(uri, "?$-_.+!*'(),:@&=/~%");
+    debug(e, "http::escapeURI::result");
+    return e;
+}
+
+const string escapeArg(const string& arg) {
+    debug(arg, "http::escapeArg::arg");
+    const string e = escape(arg, "-_.~");
+    debug(e, "http::escapeArg::result");
+    return e;
+}
+
+/**
  * Setup a CURL session
  */
 const failable<CURL*> setup(const string& url, const CURLSession& cs) {
@@ -177,7 +219,7 @@ const failable<CURL*> setup(const string
     }
 
     // Set target URL
-    curl_easy_setopt(ch, CURLOPT_URL, c_str(url));
+    curl_easy_setopt(ch, CURLOPT_URL, c_str(escapeURI(url)));
 
     return ch;
 }
@@ -430,6 +472,22 @@ const failable<value> get(const string& 
         debug(val, "http::get::result");
         return val;
     }
+    if (contains(ct, "application/x-javascript")) {
+        // Read a JSON document enclosed in a javascript function call
+        // Extract the JSON out of the enclosing parenthesis
+        ostringstream os;
+        write(ls, os);
+        const string s = str(os);
+        const size_t fp = find(s, '(');
+        const size_t lp = find_last(s, ')');
+        const list<string> jls = mklist<string>(substr(s, fp + 1, lp - (fp +
1)));
+        debug(jls, "http::get::javascript::content");
+
+        js::JSContext cx;
+        const value val(json::jsonValues(content(json::readJSON(jls, cx))));
+        debug(val, "http::get::result");
+        return val;
+    }
     if (contains(ct, "text/xml") || contains(ct, "application/xml") || isXML(ls)) {
         // Read an XML document
         const value val(elementsToValues(readXML(ls)));
@@ -620,6 +678,23 @@ const failable<size_t> recv(char* c, con
     return recv(c, l, cs);
 }
 
+/**
+ * Converts a list of key value pairs to a query string.
+ */
+ostringstream& queryString(const list<list<value> > args, ostringstream&
os) {
+    if (isNil(args))
+        return os;
+    debug(car(args), "http::queryString::arg");
+    os << car(car(args)) << "=" << c_str(cadr(car(args)));
+    if (!isNil(cdr(args)))
+        os << "&";
+    return queryString(cdr(args), os);
+}
+
+const string queryString(const list<list<value> > args) {
+    ostringstream os;
+    return str(queryString(args, os));
+}
 
 /**
  * Filter path segment in a list of arguments.
@@ -636,21 +711,11 @@ const bool filterQuery(const value& arg)
 }
 
 /**
- * Converts a list of key value pairs to a query string.
+ * Escape a query string argument.
  */
-ostringstream& queryString(const list<list<value> > args, ostringstream&
os) {
-    if (isNil(args))
-        return os;
-    debug(car(args), "http::queryString::arg");
-    os << car(car(args)) << "=" << c_str(cadr(car(args)));
-    if (!isNil(cdr(args)))
-        os << "&";
-    return queryString(cdr(args), os);
-}
-
-const string queryString(const list<list<value> > args) {
-    ostringstream os;
-    return str(queryString(args, os));
+const value escapeQuery(const value& arg) {
+    return arg;
+    //return mklist<value>(car<value>(arg), escapeArg(cadr<value>(arg)));
 }
 
 /**
@@ -665,8 +730,7 @@ struct proxy {
         if (fun == "get") {
             const list<value> lp = filter<value>(filterPath, cadr(args));
             debug(lp, "http::queryString::arg");
-            const list<value> lq = filter<value>(filterQuery, cadr(args));
-            debug(lq, "http::get::query");
+            const list<value> lq = map<value, value>(escapeQuery, filter<value>(filterQuery,
cadr(args)));
             const value p = path(lp);
             const value q = queryString(lq);
             const failable<value> val = get(uri + p + (q != ""? string("?") + q : string("")),
cs);

Modified: tuscany/sca-cpp/trunk/modules/http/httpd-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/httpd-conf?rev=1094210&r1=1094209&r2=1094210&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/httpd-conf (original)
+++ tuscany/sca-cpp/trunk/modules/http/httpd-conf Sun Apr 17 22:14:18 2011
@@ -82,9 +82,9 @@ AddCharset utf-8 .js .css
 
 # Configure cache control
 SetEnvIf Request_URI "^/app.html$" must-revalidate
-Header onsuccess merge Cache-Control public
-Header onsuccess merge Cache-Control max-age=31536000
-Header onsuccess merge Cache-Control must-revalidate env=must-revalidate
+Header onsuccess set Cache-Control "max-age=86400" env=!must-revalidate
+Header set Cache-Control "must-revalidate, max-age=0" env=must-revalidate
+Header set Expires "Tue, 01 Jan 1980 00:00:00 GMT" env=must-revalidate
 
 # Set default document root
 DocumentRoot $htdocs

Modified: tuscany/sca-cpp/trunk/modules/http/httpd.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/httpd.hpp?rev=1094210&r1=1094209&r2=1094210&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/httpd.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/httpd.hpp Sun Apr 17 22:14:18 2011
@@ -252,6 +252,20 @@ const string unescape(const string& uri)
 }
 
 /**
+ * Unescape a list of key of value pairs representing query args.
+ */
+const list<value> unescapeArg(const list<value> a) {
+    return mklist<value>(car(a), unescape(cadr(a)));
+}
+
+const list<list<value> > unescapeArgs(const list<list<value> > args)
{
+    debug(args, "httpd::unescape::args");
+    const list<list<value> > uargs = map<list<value>, list<value>>(unescapeArg,
args);
+    debug(uargs, "httpd::unescape::result");
+    return uargs;
+}
+
+/**
  * Returns a list of key value pairs from the args in a query string.
  */
 const list<value> queryArg(const string& s) {
@@ -328,11 +342,11 @@ const failable<int> writeResult(const fa
     const string ob(str(os));
 
     // Make sure browsers come back and check for updated dynamic content
-    apr_table_setn(r->headers_out, "Expires", "Tue, 01 Jan 1980 00:00:00 GMT");
-    apr_table_setn(r->headers_out, "Cache-Control", "must-revalidate");
+    // The actual header setup is configured in httpd-conf, based on the must-revalidate
env variable
+    apr_table_set(r->subprocess_env, apr_pstrdup(r->pool, "must-revalidate"), apr_pstrdup(r->pool,
"true"));
 
     // Compute and return an Etag for the returned content
-    const string etag(ap_md5(r->pool, (const unsigned char*)c_str(ob)));
+    const string etag(ap_md5_binary(r->pool, (const unsigned char*)c_str(ob), (int)length(ob)));
 
     // Check for an If-None-Match header and just return a 304 not-modified status
     // if the Etag matches the Etag presented by the client, to save bandwith

Modified: tuscany/sca-cpp/trunk/modules/js/eval.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/eval.hpp?rev=1094210&r1=1094209&r2=1094210&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/eval.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/js/eval.hpp Sun Apr 17 22:14:18 2011
@@ -177,9 +177,10 @@ const list<value> jsPropertiesToValues(c
     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 (isNil(val) && !isList(val))
+            return jsPropertiesToValues(cons<value> (mklist<value> (element,
c_str(name), val), propertiesSoFar), o, i, cx);
+            //return jsPropertiesToValues(propertiesSoFar, o, i, cx);
         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))
@@ -257,6 +258,9 @@ const jsval valueToJSVal(const value& va
             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));
     }
+    case value::Nil: {
+        return JSVAL_NULL;
+    }
     default: {
         return JSVAL_VOID;
     }

Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/jsonutil.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/jsonutil.js?rev=1094210&r1=1094209&r2=1094210&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/htdocs/jsonutil.js (original)
+++ tuscany/sca-cpp/trunk/modules/js/htdocs/jsonutil.js Sun Apr 17 22:14:18 2011
@@ -77,6 +77,8 @@ json.jsPropertiesToValues = function(pro
  * Converts a JSON val to a value.
  */
 json.jsValToValue = function(jsv) {
+    if (jsv == null)
+        return null;
     if (isList(jsv))
         return json.jsPropertiesToValues(mklist(), jsv, reverse(range(0, jsv.length)));
     if (typeof jsv == 'object')

Modified: tuscany/sca-cpp/trunk/modules/scheme/environment.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/scheme/environment.hpp?rev=1094210&r1=1094209&r2=1094210&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/scheme/environment.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/scheme/environment.hpp Sun Apr 17 22:14:18 2011
@@ -118,8 +118,11 @@ const value definitionVariable(const val
 
 const value definitionValue(const value& exp) {
     const list<value> exps(exp);
-    if(isSymbol(car(cdr(exps))))
+    if(isSymbol(car(cdr(exps)))) {
+        if (isNil(cdr(cdr(exps))))
+            return value();
         return car(cdr(cdr(exps)));
+    }
     const list<value> lexps(car(cdr(exps)));
     return makeLambda(cdr(lexps), cdr(cdr(exps)));
 }

Modified: tuscany/sca-cpp/trunk/modules/scheme/eval-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/scheme/eval-test.cpp?rev=1094210&r1=1094209&r2=1094210&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/scheme/eval-test.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/scheme/eval-test.cpp Sun Apr 17 22:14:18 2011
@@ -72,20 +72,30 @@ bool testRead() {
 }
 
 bool testWrite() {
-    const list<value> i = list<value>()
-            + (list<value>() + "item" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"
-                + (list<value>() + "item"
-                    + (list<value>() + "name" + "Apple")
-                    + (list<value>() + "price" + "$2.99")))
-            + (list<value>() + "item" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c"
-                + (list<value>() + "item"
-                    + (list<value>() + "name" + "Orange")
-                    + (list<value>() + "price" + "$3.55")));
-    const list<value> a = cons<value>("Feed", cons<value>("feed-1234",
i));
-    ostringstream os;
-    writeValue(a, os);
-    istringstream is(str(os));
-    assert(readValue(is) == a);
+    {
+        const list<value> i = list<value>()
+                + (list<value>() + "item" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"
+                    + (list<value>() + "item"
+                        + (list<value>() + "name" + "Apple")
+                        + (list<value>() + "price" + "$2.99")))
+                + (list<value>() + "item" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c"
+                    + (list<value>() + "item"
+                        + (list<value>() + "name" + "Orange")
+                        + (list<value>() + "price" + "$3.55")));
+        const list<value> a = cons<value>("Feed", cons<value>("feed-1234",
i));
+        ostringstream os;
+        writeValue(a, os);
+        istringstream is(str(os));
+        assert(readValue(is) == a);
+    }
+    {
+        const list<value> i = mklist<value>("x", value());
+        const list<value> a = mklist<value>(i);
+        ostringstream os;
+        writeValue(a, os);
+        istringstream is(str(os));
+        assert(readValue(is) == a);
+    }
     return true;
 }
 

Modified: tuscany/sca-cpp/trunk/modules/scheme/io.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/scheme/io.hpp?rev=1094210&r1=1094209&r2=1094210&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/scheme/io.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/scheme/io.hpp Sun Apr 17 22:14:18 2011
@@ -88,14 +88,14 @@ const bool isQuote(const value& token) {
     return token == quoteSymbol;
 }
 
-const value skipComment(istream& in);
+const failable<value> skipComment(istream& in);
 const value readQuoted(istream& in);
 const value readIdentifier(const char chr, istream& in);
 const value readString(istream& in);
 const value readNumber(const char chr, istream& in);
 const value readValue(istream& in);
 
-const value readToken(istream& in) {
+const failable<value> readToken(istream& in) {
     const char firstChar = readChar(in);
     if(isWhitespace(firstChar))
         return readToken(in);
@@ -114,12 +114,12 @@ const value readToken(istream& in) {
     if(isDigit(firstChar))
         return readNumber(firstChar, in);
     if(firstChar == -1)
-        return value();
+        return mkfailure<value>();
     logStream() << "Illegal lexical syntax '" << firstChar << "'" <<
endl;
     return readToken(in);
 }
 
-const value skipComment(istream& in) {
+const failable<value> skipComment(istream& in) {
     const char nextChar = readChar(in);
     if (nextChar == '\n')
         return readToken(in);
@@ -131,8 +131,11 @@ const value readQuoted(istream& in) {
 }
 
 const list<value> readList(const list<value>& listSoFar, istream& in)
{
-    const value token = readToken(in);
-    if(isNil(token) || isRightParenthesis(token))
+    const failable<value> ftoken = readToken(in);
+    if (!hasContent(ftoken))
+        return reverse(listSoFar);
+    const value token = content(ftoken);
+    if(isRightParenthesis(token))
         return reverse(listSoFar);
     if(isLeftParenthesis(token))
         return readList(cons(value(readList(list<value> (), in)), listSoFar), in);
@@ -159,14 +162,22 @@ const value readIdentifier(const char ch
         return value((bool)false);
     if (val == "true")
         return value((bool)true);
+    if (val == "nil")
+        return value();
     return val;
 }
 
 const list<char> readStringHelper(const list<char>& listSoFar, istream&
in) {
     const char nextChar = readChar(in);
-    if(nextChar != -1 && nextChar != '"')
-        return readStringHelper(cons(nextChar, listSoFar), in);
-    return reverse(listSoFar);
+    if(nextChar == -1 || nextChar == '"')
+        return reverse(listSoFar);
+    if (nextChar == '\\') {
+        const char escapedChar = readChar(in);
+        if (escapedChar == -1)
+            return reverse(listSoFar);
+        return readStringHelper(cons(escapedChar, listSoFar), in);
+    }
+    return readStringHelper(cons(nextChar, listSoFar), in);
 }
 
 const value readString(istream& in) {
@@ -185,17 +196,23 @@ const value readNumber(const char chr, i
 }
 
 const value readValue(istream& in) {
-    const value nextToken = readToken(in);
+    const failable<value> fnextToken = readToken(in);
+    if (!hasContent(fnextToken))
+        return value();
+    const value nextToken = content(fnextToken);
     if(isLeftParenthesis(nextToken))
-        return readList(list<value> (), in);
+        return readList(list<value>(), in);
     return nextToken;
 }
 
 const value readValue(const string s) {
     istringstream in(s);
-    const value nextToken = readToken(in);
+    const failable<value> fnextToken = readToken(in);
+    if (!hasContent(fnextToken))
+        return value();
+    const value nextToken = content(fnextToken);
     if(isLeftParenthesis(nextToken))
-        return readList(list<value> (), in);
+        return readList(list<value>(), in);
     return nextToken;
 }
 

Modified: tuscany/sca-cpp/trunk/modules/wsgi/jsonutil.py
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/wsgi/jsonutil.py?rev=1094210&r1=1094209&r2=1094210&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/wsgi/jsonutil.py (original)
+++ tuscany/sca-cpp/trunk/modules/wsgi/jsonutil.py Sun Apr 17 22:14:18 2011
@@ -57,6 +57,8 @@ def jsPropertiesToValues(propertiesSoFar
 
 # Converts a JSON val to a value
 def jsValToValue(jsv):
+    if jsv is None:
+        return None
     if isinstance(jsv, dict):
         return jsPropertiesToValues((), jsv, tuple(jsv.keys()))
     if isList(jsv):



Mime
View raw message