js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags) { jschar *chars; JSString *str; JSAtom *atom; char buf[2 * ALIGNMENT(JSString)]; /* * Avoiding the malloc in js_InflateString on shorter strings saves us * over 20,000 malloc calls on mozilla browser startup. This compares to * only 131 calls where the string is longer than a 31 char (net) buffer. * The vast majority of atomized strings are already in the hashtable. So * js_AtomizeString rarely has to copy the temp string we make. */ #define ATOMIZE_BUF_MAX 32 jschar inflated[ATOMIZE_BUF_MAX]; size_t inflatedLength = ATOMIZE_BUF_MAX - 1; if (length < ATOMIZE_BUF_MAX) { js_InflateStringToBuffer(cx, bytes, length, inflated, &inflatedLength); inflated[inflatedLength] = 0; chars = inflated; } else { inflatedLength = length; chars = js_InflateString(cx, bytes, &inflatedLength); if (!chars) return NULL; flags |= ATOM_NOCOPY; } str = ALIGN(buf, JSString); str->chars = chars; str->length = inflatedLength; atom = js_AtomizeString(cx, str, ATOM_TMPSTR | flags); if (chars != inflated && (!atom || ATOM_TO_STRING(atom)->chars != chars)) JS_free(cx, chars); return atom; }
static JSBool write_string(JSContext *cx, JSONWriteCallback callback, void *data, const jschar *buf, uint32 len) { if (!callback("e, 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)) { return JS_FALSE; } mark = i + 1; } else if (buf[i] <= 31 || buf[i] == 127) { if (!callback(&buf[mark], i - mark, data) || !callback(unicodeEscape, 4, data)) return JS_FALSE; char ubuf[3]; size_t len = JS_snprintf(ubuf, sizeof(ubuf), "%.2x", buf[i]); JS_ASSERT(len == 2); jschar wbuf[3]; size_t wbufSize = JS_ARRAY_LENGTH(wbuf); if (!js_InflateStringToBuffer(cx, ubuf, len, wbuf, &wbufSize) || !callback(wbuf, wbufSize, data)) { return JS_FALSE; } mark = i + 1; } } if (mark < len && !callback(&buf[mark], len - mark, data)) return JS_FALSE; if (!callback("e, 1, data)) return JS_FALSE; return JS_TRUE; }
static JSBool write_string(JSContext *cx, JSCharBuffer &cb, const jschar *buf, uint32 len) { if (!cb.append(quote)) return JS_FALSE; uint32 mark = 0; uint32 i; for (i = 0; i < len; ++i) { if (buf[i] == quote || buf[i] == backslash) { if (!cb.append(&buf[mark], i - mark) || !cb.append(backslash) || !cb.append(buf[i])) { return JS_FALSE; } mark = i + 1; } else if (buf[i] <= 31 || buf[i] == 127) { if (!cb.append(&buf[mark], i - mark) || !js_AppendLiteral(cb, unicodeEscape)) { return JS_FALSE; } char ubuf[3]; size_t len = JS_snprintf(ubuf, sizeof(ubuf), "%.2x", buf[i]); JS_ASSERT(len == 2); jschar wbuf[3]; size_t wbufSize = JS_ARRAY_LENGTH(wbuf); if (!js_InflateStringToBuffer(cx, ubuf, len, wbuf, &wbufSize) || !cb.append(wbuf, wbufSize)) { return JS_FALSE; } mark = i + 1; } } if (mark < len && !cb.append(&buf[mark], len - mark)) return JS_FALSE; return cb.append(quote); }