void StringBuffer::appendJsonEscape(const char *s, int len, bool loose) { if (len == 0) { append("\"\"", 2); } else { static const char digits[] = "0123456789abcdef"; int start = size(); append('"'); UTF8To16Decoder decoder(s, len, loose); for (;;) { int c = decoder.decode(); if (c == UTF8_END) { append('"'); break; } if (c == UTF8_ERROR) { // discard the part that has been already decoded. resize(start); append("null", 4); break; } ASSERT(c >= 0); unsigned short us = (unsigned short)c; switch (us) { case '"': append("\\\"", 2); break; case '\\': append("\\\\", 2); break; case '/': append("\\/", 2); break; case '\b': append("\\b", 2); break; case '\f': append("\\f", 2); break; case '\n': append("\\n", 2); break; case '\r': append("\\r", 2); break; case '\t': append("\\t", 2); break; default: if (us >= ' ' && (us & 127) == us) { append((char)us); } else { append("\\u", 2); us = REVERSE16(us); append(digits[us & ((1 << 4) - 1)]); us >>= 4; append(digits[us & ((1 << 4) - 1)]); us >>= 4; append(digits[us & ((1 << 4) - 1)]); us >>= 4; append(digits[us & ((1 << 4) - 1)]); } break; } } } }
void StringBuffer::appendJsonEscape(const char *s, int len, int options) { if (len == 0) { append("\"\"", 2); } else { static const char digits[] = "0123456789abcdef"; int start = size(); append('"'); UTF8To16Decoder decoder(s, len, options & k_JSON_FB_LOOSE); for (;;) { int c = decoder.decode(); if (c == UTF8_END) { append('"'); break; } if (c == UTF8_ERROR) { // discard the part that has been already decoded. resize(start); append("null", 4); break; } ASSERT(c >= 0); unsigned short us = (unsigned short)c; switch (us) { case '"': if (options & k_JSON_HEX_QUOT) { append("\\u0022", 6); } else { append("\\\"", 2); } break; case '\\': append("\\\\", 2); break; case '/': if (options & k_JSON_UNESCAPED_SLASHES) { append('/'); } else { append("\\/", 2); } break; case '\b': append("\\b", 2); break; case '\f': append("\\f", 2); break; case '\n': append("\\n", 2); break; case '\r': append("\\r", 2); break; case '\t': append("\\t", 2); break; case '<': if (options & k_JSON_HEX_TAG || options & k_JSON_FB_EXTRA_ESCAPES) { append("\\u003C", 6); } else { append('<'); } break; case '>': if (options & k_JSON_HEX_TAG) { append("\\u003E", 6); } else { append('>'); } break; case '&': if (options & k_JSON_HEX_AMP) { append("\\u0026", 6); } else { append('&'); } break; case '\'': if (options & k_JSON_HEX_APOS) { append("\\u0027", 6); } else { append('\''); } break; case '@': if (options & k_JSON_FB_EXTRA_ESCAPES) { append("\\u0040", 6); } else { append('@'); } break; case '%': if (options & k_JSON_FB_EXTRA_ESCAPES) { append("\\u0025", 6); } else { append('%'); } break; default: if (us >= ' ' && (us & 127) == us) { append((char)us); } else { append("\\u", 2); us = REVERSE16(us); append(digits[us & ((1 << 4) - 1)]); us >>= 4; append(digits[us & ((1 << 4) - 1)]); us >>= 4; append(digits[us & ((1 << 4) - 1)]); us >>= 4; append(digits[us & ((1 << 4) - 1)]); } break; } } } }