diff options
author | Joshua Haberman <jhaberman@gmail.com> | 2014-12-05 13:40:44 -0800 |
---|---|---|
committer | Joshua Haberman <jhaberman@gmail.com> | 2014-12-05 13:40:44 -0800 |
commit | e257bd978d5e6278e7b188d543858852c0c4d856 (patch) | |
tree | 117aa62f6b5e6f0727cee7e43e9e1da4ef2609cd /upb/json/parser.rl | |
parent | a350b4206978f5924f17135c8177d0ea9e295edb (diff) | |
parent | 98adb44547cc6667f803e59af20ef0bd835211e6 (diff) |
Merge pull request #6 from cfallin/master
JSON printer and parser updates.
Diffstat (limited to 'upb/json/parser.rl')
-rw-r--r-- | upb/json/parser.rl | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/upb/json/parser.rl b/upb/json/parser.rl index 75860e5..92a1566 100644 --- a/upb/json/parser.rl +++ b/upb/json/parser.rl @@ -438,17 +438,37 @@ static void start_hex(upb_json_parser *p, const char *ptr) { } static void hex(upb_json_parser *p, const char *end) { - UPB_UNUSED(end); const char *start = p->text_begin; - assert(end - start == 4); + UPB_ASSERT_VAR(end, end - start == 4); uint16_t codepoint = (hexdigit(start[0]) << 12) | (hexdigit(start[1]) << 8) | (hexdigit(start[2]) << 4) | hexdigit(start[3]); - // TODO(haberman): convert to UTF-8 and emit (though if it is a high surrogate + // emit the codepoint as UTF-8. + char utf8[3]; // support \u0000 -- \uFFFF -- need only three bytes. + int length = 0; + if (codepoint < 0x7F) { + utf8[0] = codepoint; + length = 1; + } else if (codepoint < 0x07FF) { + utf8[1] = (codepoint & 0x3F) | 0x80; + codepoint >>= 6; + utf8[0] = (codepoint & 0x1F) | 0xC0; + length = 2; + } else /* codepoint < 0xFFFF */ { + utf8[2] = (codepoint & 0x3F) | 0x80; + codepoint >>= 6; + utf8[1] = (codepoint & 0x3F) | 0x80; + codepoint >>= 6; + utf8[0] = (codepoint & 0x0F) | 0xE0; + length = 3; + } + // TODO(haberman): Handle high surrogates: if codepoint is a high surrogate // we have to wait for the next escape to get the full code point). - UPB_UNUSED(codepoint); + + upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_STRING); + upb_sink_putstring(&p->top->sink, sel, utf8, length, NULL); } #define CHECK_RETURN_TOP(x) if (!(x)) goto error |