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;
      }
    }
  }
}
Exemple #2
0
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;
      }
    }
  }
}