static int json_encode_string(struct json_out *out, const char *p, size_t len) { size_t i, cl, n = 0; const char *hex_digits = "0123456789abcdef"; const char *specials = "btnvfr"; for (i = 0; i < len; i++) { unsigned char ch = ((unsigned char *) p)[i]; if (ch == '"' || ch == '\\') { n += out->printer(out, "\\", 1); n += out->printer(out, p + i, 1); } else if (ch >= '\b' && ch <= '\r') { n += out->printer(out, "\\", 1); n += out->printer(out, &specials[ch - '\b'], 1); } else if (isprint(ch)) { n += out->printer(out, p + i, 1); } else if ((cl = get_utf8_char_len(ch)) == 1) { n += out->printer(out, "\\u00", 4); n += out->printer(out, &hex_digits[(ch >> 4) % 0xf], 1); n += out->printer(out, &hex_digits[ch % 0xf], 1); } else {
// string = '"' { quoted_printable_chars } '"' static int parse_string(struct frozen *f) { int n, ch = 0, len = 0; TRY(test_and_skip(f, '"')); TRY(capture_ptr(f, f->cur, JSON_TYPE_STRING)); for (; f->cur < f->end; f->cur += len) { ch = * (unsigned char *) f->cur; len = get_utf8_char_len((unsigned char) ch); //printf("[%c] [%d]\n", ch, len); EXPECT(ch >= 32 && len > 0, JSON_STRING_INVALID); // No control chars EXPECT(len < left(f), JSON_STRING_INCOMPLETE); if (ch == '\\') { EXPECT((n = get_escape_len(f->cur + 1, left(f))) > 0, n); len += n; } else if (ch == '"') { capture_len(f, f->num_tokens - 1, f->cur); f->cur++; break; }; } return ch == '"' ? 0 : JSON_STRING_INCOMPLETE; }
/* string = '"' { quoted_printable_chars } '"' */ static int parse_string(struct frozen *f) { int n, ch = 0, len = 0; TRY(test_and_skip(f, '"')); { SET_STATE(f, f->cur, JSON_TYPE_STRING, "", 0); for (; f->cur < f->end; f->cur += len) { ch = *(unsigned char *) f->cur; len = get_utf8_char_len((unsigned char) ch); EXPECT(ch >= 32 && len > 0, JSON_STRING_INVALID); /* No control chars */ EXPECT(len < left(f), JSON_STRING_INCOMPLETE); if (ch == '\\') { EXPECT((n = get_escape_len(f->cur + 1, left(f))) > 0, n); len += n; } else if (ch == '"') { CALL_BACK(f); f->cur++; break; }; } } return ch == '"' ? 0 : JSON_STRING_INCOMPLETE; }