Ejemplo n.º 1
0
 VXIcharToJschar(const VXIchar * x) : cstr(NULL), len(0)
 {
   if (x == NULL) return;
   len = wcslen(x);
   cstr = new jschar[len + 1];
   if (cstr == NULL) return;
   for (unsigned int i = 0; i < len + 1; ++i)
     // We throw out any surrogate characters (0xD800 - 0xDFFF)
     cstr[i] = ((x[i] ^ 0xD800) < 0x0100) ? jschar(0xBF) : jschar(x[i]);
 }
Ejemplo n.º 2
0
JSBool
js_Stringify(JSContext *cx, jsval *vp, JSObject *replacer,
             JSONWriteCallback callback, void *data, uint32 depth)
{
    if (depth > JSON_MAX_DEPTH)
        return JS_FALSE; /* encoding error */
 
    JSBool ok = JS_TRUE;
    JSObject *obj = JSVAL_TO_OBJECT(*vp);
    JSBool isArray = JS_IsArrayObject(cx, obj);
    jschar output = jschar(isArray ? '[' : '{');
    if (!callback(&output, 1, data))
        return JS_FALSE;
    
    JSObject *iterObj = NULL;
    jsint i = 0;
    jsuint length = 0;
 
    if (isArray) {
        if (!JS_GetArrayLength(cx, obj, &length))
            return JS_FALSE;
    } else {
        if (!js_ValueToIterator(cx, JSITER_ENUMERATE, vp))
            return JS_FALSE;
        iterObj = JSVAL_TO_OBJECT(*vp);
    }
 
    jsval outputValue = JSVAL_VOID;
    JSAutoTempValueRooter tvr(cx, 1, &outputValue);
 
    jsval key;
    JSBool memberWritten = JS_FALSE;
    do {
        outputValue = JSVAL_VOID;
 
        if (isArray) {
            if ((jsuint)i >= length)
                break;
            ok = JS_GetElement(cx, obj, i++, &outputValue);
        } else {
            ok = js_CallIteratorNext(cx, iterObj, &key);
            if (!ok)
                break;
            if (key == JSVAL_HOLE)
                break;
 
            JSString *ks;
            if (JSVAL_IS_STRING(key)) {
                ks = JSVAL_TO_STRING(key);
            } else {
                ks = JS_ValueToString(cx, key);
                if (!ks) {
                    ok = JS_FALSE;
                    break;
                }
            }
 
            ok = JS_GetUCProperty(cx, obj, JS_GetStringChars(ks),
                                  JS_GetStringLength(ks), &outputValue);
        }
 
        if (!ok)
            break;
 
        // if this is an array, holes are transmitted as null
        if (isArray && outputValue == JSVAL_VOID) {
            outputValue = JSVAL_NULL;
        } else if (JSVAL_IS_OBJECT(outputValue)) {
            ok = js_TryJSON(cx, &outputValue);
            if (!ok)
                break;
        }
 
        // elide undefined values
        if (outputValue == JSVAL_VOID)
            continue;
 
        // output a comma unless this is the first member to write
        if (memberWritten) {
            output = jschar(',');
            ok = callback(&output, 1, data);
        if (!ok)
                break;
        }
        memberWritten = JS_TRUE;
 
        JSType type = JS_TypeOfValue(cx, outputValue);
 
        // Can't encode these types, so drop them
        if (type == JSTYPE_FUNCTION || type == JSTYPE_XML)
            break;
 
        // Be careful below, this string is weakly rooted.
        JSString *s;
 
        // If this isn't an array, we need to output a key
        if (!isArray) {
            s = JS_ValueToString(cx, key);
            if (!s) {
                ok = JS_FALSE;
                break;
            }
 
            ok = write_string(cx, callback, data, JS_GetStringChars(s), JS_GetStringLength(s));
            if (!ok)
                break;
 
            output = jschar(':');
            ok = callback(&output, 1, data);
            if (!ok)
                break;
        }
 
        if (!JSVAL_IS_PRIMITIVE(outputValue)) {
            // recurse
          ok = js_Stringify(cx, &outputValue, replacer, callback, data, depth + 1);
        } else {
            JSString *outputString;
            s = JS_ValueToString(cx, outputValue);
            if (!s) {
                ok = JS_FALSE;
                break;
            }
 
            if (type == JSTYPE_STRING) {
                ok = write_string(cx, callback, data, JS_GetStringChars(s), JS_GetStringLength(s));
                if (!ok)
                    break;
                
                continue;
            }
 
            if (type == JSTYPE_NUMBER) {
                if (JSVAL_IS_DOUBLE(outputValue)) {
                    jsdouble d = *JSVAL_TO_DOUBLE(outputValue);
                    if (!JSDOUBLE_IS_FINITE(d))
                        outputString = JS_NewStringCopyN(cx, "null", 4);
                    else
                        outputString = s;
                } else {
                    outputString = s;
                }
            } else if (type == JSTYPE_BOOLEAN) {
                outputString = s;
            } else if (JSVAL_IS_NULL(outputValue)) {
                outputString = JS_NewStringCopyN(cx, "null", 4);
            } else {
                ok = JS_FALSE; // encoding error
                break;
            }
 
            ok = callback(JS_GetStringChars(outputString), JS_GetStringLength(outputString), data);
        }
    } while (ok);
 
    if (iterObj) {
        // Always close the iterator, but make sure not to stomp on OK
        js_CloseIteratorState(cx, iterObj);
        // encoding error or propagate? FIXME: Bug 408838.
    }
 
    if (!ok) {
        JS_ReportError(cx, "Error during JSON encoding.");
        return JS_FALSE;
    }
 
    output = jschar(isArray ? ']' : '}');
    ok = callback(&output, 1, data);
 
    return ok;
}
Ejemplo n.º 3
0
JSBool
js_TryJSON(JSContext *cx, jsval *vp)
{
    // Checks whether the return value implements toJSON()
    JSBool ok = JS_TRUE;
    
    if (!JSVAL_IS_PRIMITIVE(*vp)) {
        JSObject *obj = JSVAL_TO_OBJECT(*vp);
        ok = js_TryMethod(cx, obj, cx->runtime->atomState.toJSONAtom, 0, NULL, vp);
    }
    
    return ok;
}
 
 
static const jschar quote = jschar('"');
static const jschar backslash = jschar('\\');
static const jschar unicodeEscape[] = {'\\', 'u', '0', '0'};
 
static JSBool
write_string(JSContext *cx, JSONWriteCallback callback, void *data, const jschar *buf, uint32 len)
{
    if (!callback(&quote, 1, data))
        return JS_FALSE;
 
    uint32 mark = 0;
    uint32 i;
    for (i = 0; i < len; ++i) {
        if (buf[i] == quote || buf[i] == backslash) {
            if (!callback(&buf[mark], i - mark, data) || !callback(&backslash, 1, data) ||
                !callback(&buf[i], 1, data)) {