summaryrefslogtreecommitdiff
path: root/upb/json
diff options
context:
space:
mode:
authorBo Yang <teboring@google.com>2018-08-09 04:17:06 +0000
committerBo Yang <teboring@google.com>2018-08-09 04:17:06 +0000
commitd4caefaade5908ad079e98290c8a850ac981d05a (patch)
treeffbea7d983af61cc9b9d9d267a3dec69dca4b7df /upb/json
parentf1d7570f305c3cc7975a87edc1313f784fc06b2b (diff)
Move logic away from ragel machine
Diffstat (limited to 'upb/json')
-rw-r--r--upb/json/parser.c388
-rw-r--r--upb/json/parser.rl209
2 files changed, 316 insertions, 281 deletions
diff --git a/upb/json/parser.c b/upb/json/parser.c
index 0f8fdfd..a815c0d 100644
--- a/upb/json/parser.c
+++ b/upb/json/parser.c
@@ -42,6 +42,27 @@ static const char *kBoolValueFullMessageName = "google.protobuf.BoolValue";
static const char *kStringValueFullMessageName = "google.protobuf.StringValue";
static const char *kBytesValueFullMessageName = "google.protobuf.BytesValue";
+/* Forward declare */
+static bool is_top_level(upb_json_parser *p);
+
+static bool is_number_wrapper_object(upb_json_parser *p);
+static bool does_number_wrapper_start(upb_json_parser *p);
+static bool does_number_wrapper_end(upb_json_parser *p);
+
+static bool is_string_wrapper_object(upb_json_parser *p);
+static bool does_string_wrapper_start(upb_json_parser *p);
+static bool does_string_wrapper_end(upb_json_parser *p);
+
+static bool is_boolean_wrapper_object(upb_json_parser *p);
+static bool does_boolean_wrapper_start(upb_json_parser *p);
+static bool does_boolean_wrapper_end(upb_json_parser *p);
+
+static void start_wrapper_object(upb_json_parser *p);
+static void end_wrapper_object(upb_json_parser *p);
+
+static bool start_subobject(upb_json_parser *p);
+static void end_subobject(upb_json_parser *p);
+
typedef struct {
upb_sink sink;
@@ -620,14 +641,27 @@ static bool end_text(upb_json_parser *p, const char *ptr) {
return capture_end(p, ptr);
}
-static void start_number(upb_json_parser *p, const char *ptr) {
+static bool start_number(upb_json_parser *p, const char *ptr) {
+ if (is_top_level(p)) {
+ if (!is_number_wrapper_object(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ } else if (does_number_wrapper_start(p)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ }
+
multipart_startaccum(p);
capture_begin(p, ptr);
+ return true;
}
static bool parse_number(upb_json_parser *p, bool is_quoted);
-static bool end_number(upb_json_parser *p, const char *ptr) {
+static bool end_number_nontop(upb_json_parser *p, const char *ptr) {
if (!capture_end(p, ptr)) {
return false;
}
@@ -640,6 +674,21 @@ static bool end_number(upb_json_parser *p, const char *ptr) {
return parse_number(p, false);
}
+static bool end_number(upb_json_parser *p, const char *ptr) {
+ if (!end_number_nontop(p, ptr)) {
+ return false;
+ }
+
+ if (does_number_wrapper_end(p)) {
+ end_wrapper_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ }
+
+ return true;
+}
+
/* |buf| is NULL-terminated. |buf| itself will never include quotes;
* |is_quoted| tells us whether this text originally appeared inside quotes. */
static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
@@ -807,7 +856,46 @@ static bool parser_putbool(upb_json_parser *p, bool val) {
return true;
}
+static bool end_bool(upb_json_parser *p, bool val) {
+ if (is_top_level(p)) {
+ if (!is_boolean_wrapper_object(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ } else if (does_boolean_wrapper_start(p)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ }
+
+ if (!parser_putbool(p, val)) {
+ return false;
+ }
+
+ if (does_boolean_wrapper_end(p)) {
+ end_wrapper_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ }
+
+ return true;
+}
+
static bool start_stringval(upb_json_parser *p) {
+ if (is_top_level(p)) {
+ if (!is_string_wrapper_object(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ } else if (does_string_wrapper_start(p)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ }
+
if (p->top->f == NULL) {
multipart_startaccum(p);
return true;
@@ -859,7 +947,7 @@ static bool start_stringval(upb_json_parser *p) {
}
}
-static bool end_stringval(upb_json_parser *p) {
+static bool end_stringval_nontop(upb_json_parser *p) {
bool ok = true;
if (p->top->f == NULL) {
@@ -926,6 +1014,21 @@ static bool end_stringval(upb_json_parser *p) {
return ok;
}
+static bool end_stringval(upb_json_parser *p) {
+ if (!end_stringval_nontop(p)) {
+ return false;
+ }
+
+ if (does_string_wrapper_end(p)) {
+ end_wrapper_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ }
+
+ return true;
+}
+
static void start_member(upb_json_parser *p) {
UPB_ASSERT(!p->top->f);
multipart_startaccum(p);
@@ -1109,6 +1212,10 @@ static void end_member(upb_json_parser *p) {
}
static bool start_subobject(upb_json_parser *p) {
+ if (is_top_level(p)) {
+ return true;
+ }
+
if (p->top->f == NULL) {
upb_jsonparser_frame *inner;
if (!check_stack(p)) return false;
@@ -1172,6 +1279,10 @@ static bool start_subobject(upb_json_parser *p) {
}
static void end_subobject(upb_json_parser *p) {
+ if (is_top_level(p)) {
+ return;
+ }
+
if (p->top->is_map) {
upb_selector_t sel;
p->top--;
@@ -1378,25 +1489,24 @@ static bool is_boolean_wrapper_object(upb_json_parser *p) {
* final state once, when the closing '"' is seen. */
-#line 1557 "upb/json/parser.rl"
+#line 1592 "upb/json/parser.rl"
-#line 1386 "upb/json/parser.c"
+#line 1497 "upb/json/parser.c"
static const char _json_actions[] = {
0, 1, 0, 1, 1, 1, 3, 1,
4, 1, 6, 1, 7, 1, 8, 1,
9, 1, 11, 1, 13, 1, 14, 1,
15, 1, 16, 1, 17, 1, 18, 1,
20, 1, 22, 1, 23, 1, 24, 1,
- 25, 1, 26, 1, 27, 1, 28, 1,
- 29, 1, 30, 2, 4, 9, 2, 5,
- 6, 2, 7, 3, 2, 7, 9, 2,
- 12, 10, 2, 14, 16, 2, 15, 16,
- 2, 19, 2, 2, 20, 30, 2, 21,
- 10, 2, 24, 30, 2, 26, 30, 2,
- 27, 30, 2, 29, 30, 3, 15, 12,
- 10
+ 25, 1, 26, 1, 27, 1, 28, 2,
+ 4, 9, 2, 5, 6, 2, 7, 3,
+ 2, 7, 9, 2, 12, 10, 2, 14,
+ 16, 2, 15, 16, 2, 19, 2, 2,
+ 20, 28, 2, 21, 10, 2, 23, 28,
+ 2, 24, 28, 2, 25, 28, 2, 27,
+ 28, 3, 15, 12, 10
};
static const unsigned char _json_key_offsets[] = {
@@ -1538,21 +1648,21 @@ static const char _json_trans_targs[] = {
};
static const char _json_trans_actions[] = {
- 0, 0, 78, 72, 27, 39, 0, 35,
- 45, 33, 17, 0, 29, 0, 0, 0,
+ 0, 0, 74, 68, 27, 0, 0, 0,
+ 41, 33, 17, 0, 29, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 23, 93, 69, 0, 63, 25, 19,
- 0, 0, 17, 21, 21, 66, 0, 0,
+ 0, 23, 89, 65, 0, 59, 25, 19,
+ 0, 0, 17, 21, 21, 62, 0, 0,
0, 0, 0, 3, 0, 0, 0, 0,
- 0, 5, 15, 0, 0, 51, 7, 13,
- 0, 54, 9, 9, 9, 57, 60, 11,
- 78, 72, 27, 39, 0, 35, 45, 33,
- 49, 75, 17, 0, 29, 0, 0, 0,
- 0, 0, 0, 84, 0, 0, 0, 87,
- 0, 0, 0, 81, 23, 93, 69, 0,
- 63, 25, 19, 0, 0, 17, 21, 21,
- 66, 0, 0, 90, 0, 31, 41, 43,
- 37, 47
+ 0, 5, 15, 0, 0, 47, 7, 13,
+ 0, 50, 9, 9, 9, 53, 56, 11,
+ 74, 68, 27, 0, 0, 0, 41, 33,
+ 45, 71, 17, 0, 29, 0, 0, 0,
+ 0, 0, 0, 80, 0, 0, 0, 83,
+ 0, 0, 0, 77, 23, 89, 65, 0,
+ 59, 25, 19, 0, 0, 17, 21, 21,
+ 62, 0, 0, 86, 0, 31, 37, 39,
+ 35, 43
};
static const char _json_eof_actions[] = {
@@ -1565,7 +1675,7 @@ static const char _json_eof_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 31,
- 41, 43, 37, 47, 0, 0, 0
+ 37, 39, 35, 43, 0, 0, 0
};
static const int json_start = 1;
@@ -1576,7 +1686,7 @@ static const int json_en_value_machine = 41;
static const int json_en_main = 1;
-#line 1560 "upb/json/parser.rl"
+#line 1595 "upb/json/parser.rl"
size_t parse(void *closure, const void *hd, const char *buf, size_t size,
const upb_bufhandle *handle) {
@@ -1599,7 +1709,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size,
capture_resume(parser, buf);
-#line 1603 "upb/json/parser.c"
+#line 1713 "upb/json/parser.c"
{
int _klen;
unsigned int _trans;
@@ -1674,200 +1784,118 @@ _match:
switch ( *_acts++ )
{
case 1:
-#line 1395 "upb/json/parser.rl"
+#line 1506 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
case 2:
-#line 1397 "upb/json/parser.rl"
+#line 1508 "upb/json/parser.rl"
{ p--; {stack[top++] = cs; cs = 24; goto _again;} }
break;
case 3:
-#line 1401 "upb/json/parser.rl"
+#line 1512 "upb/json/parser.rl"
{ start_text(parser, p); }
break;
case 4:
-#line 1402 "upb/json/parser.rl"
+#line 1513 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_text(parser, p)); }
break;
case 5:
-#line 1408 "upb/json/parser.rl"
+#line 1519 "upb/json/parser.rl"
{ start_hex(parser); }
break;
case 6:
-#line 1409 "upb/json/parser.rl"
+#line 1520 "upb/json/parser.rl"
{ hexdigit(parser, p); }
break;
case 7:
-#line 1410 "upb/json/parser.rl"
+#line 1521 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_hex(parser)); }
break;
case 8:
-#line 1416 "upb/json/parser.rl"
+#line 1527 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(escape(parser, p)); }
break;
case 9:
-#line 1422 "upb/json/parser.rl"
+#line 1533 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
case 10:
-#line 1425 "upb/json/parser.rl"
+#line 1536 "upb/json/parser.rl"
{ {stack[top++] = cs; cs = 33; goto _again;} }
break;
case 11:
-#line 1427 "upb/json/parser.rl"
+#line 1538 "upb/json/parser.rl"
{ p--; {stack[top++] = cs; cs = 41; goto _again;} }
break;
case 12:
-#line 1432 "upb/json/parser.rl"
+#line 1543 "upb/json/parser.rl"
{ start_member(parser); }
break;
case 13:
-#line 1433 "upb/json/parser.rl"
+#line 1544 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_membername(parser)); }
break;
case 14:
-#line 1436 "upb/json/parser.rl"
+#line 1547 "upb/json/parser.rl"
{ end_member(parser); }
break;
case 15:
-#line 1442 "upb/json/parser.rl"
+#line 1553 "upb/json/parser.rl"
{ start_object(parser); }
break;
case 16:
-#line 1445 "upb/json/parser.rl"
+#line 1556 "upb/json/parser.rl"
{ end_object(parser); }
break;
case 17:
-#line 1451 "upb/json/parser.rl"
+#line 1562 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_array(parser)); }
break;
case 18:
-#line 1455 "upb/json/parser.rl"
+#line 1566 "upb/json/parser.rl"
{ end_array(parser); }
break;
case 19:
-#line 1460 "upb/json/parser.rl"
- {
- if (is_top_level(parser)) {
- CHECK_RETURN_TOP(is_number_wrapper_object(parser));
- start_wrapper_object(parser);
- } else if (does_number_wrapper_start(parser)) {
- CHECK_RETURN_TOP(start_subobject(parser));
- start_wrapper_object(parser);
- }
- start_number(parser, p);
- }
+#line 1571 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(start_number(parser, p)); }
break;
case 20:
-#line 1470 "upb/json/parser.rl"
- {
- CHECK_RETURN_TOP(end_number(parser, p));
- if (does_number_wrapper_end(parser)) {
- end_wrapper_object(parser);
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
- }
+#line 1572 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_number(parser, p)); }
break;
case 21:
-#line 1480 "upb/json/parser.rl"
- {
- if (is_top_level(parser)) {
- CHECK_RETURN_TOP(is_string_wrapper_object(parser));
- start_wrapper_object(parser);
- } else if (does_string_wrapper_start(parser)) {
- CHECK_RETURN_TOP(start_subobject(parser));
- start_wrapper_object(parser);
- }
- CHECK_RETURN_TOP(start_stringval(parser));
- }
+#line 1574 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(start_stringval(parser)); }
break;
case 22:
-#line 1490 "upb/json/parser.rl"
- {
- CHECK_RETURN_TOP(end_stringval(parser));
- if (does_string_wrapper_end(parser)) {
- end_wrapper_object(parser);
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
- }
+#line 1575 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_stringval(parser)); }
break;
case 23:
-#line 1500 "upb/json/parser.rl"
- {
- if (is_top_level(parser)) {
- CHECK_RETURN_TOP(is_boolean_wrapper_object(parser));
- start_wrapper_object(parser);
- } else if (does_boolean_wrapper_start(parser)) {
- CHECK_RETURN_TOP(start_subobject(parser));
- start_wrapper_object(parser);
- }
- }
+#line 1577 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_bool(parser, true)); }
break;
case 24:
-#line 1509 "upb/json/parser.rl"
- {
- CHECK_RETURN_TOP(parser_putbool(parser, true));
- if (does_boolean_wrapper_end(parser)) {
- end_wrapper_object(parser);
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
- }
+#line 1579 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_bool(parser, false)); }
break;
case 25:
-#line 1519 "upb/json/parser.rl"
- {
- if (is_top_level(parser)) {
- CHECK_RETURN_TOP(is_boolean_wrapper_object(parser));
- start_wrapper_object(parser);
- } else if (does_boolean_wrapper_start(parser)) {
- CHECK_RETURN_TOP(start_subobject(parser));
- start_wrapper_object(parser);
- }
- }
+#line 1581 "upb/json/parser.rl"
+ { /* null value */ }
break;
case 26:
-#line 1528 "upb/json/parser.rl"
- {
- CHECK_RETURN_TOP(parser_putbool(parser, false));
- if (does_boolean_wrapper_end(parser)) {
- end_wrapper_object(parser);
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
- }
+#line 1583 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(start_subobject(parser)); }
break;
case 27:
-#line 1538 "upb/json/parser.rl"
- { /* null value */ }
+#line 1584 "upb/json/parser.rl"
+ { end_subobject(parser); }
break;
case 28:
-#line 1540 "upb/json/parser.rl"
- {
- if (!is_top_level(parser)) {
- CHECK_RETURN_TOP(start_subobject(parser));
- }
- }
- break;
- case 29:
-#line 1545 "upb/json/parser.rl"
- {
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
- break;
- case 30:
-#line 1554 "upb/json/parser.rl"
+#line 1589 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
-#line 1871 "upb/json/parser.c"
+#line 1899 "upb/json/parser.c"
}
}
@@ -1884,7 +1912,7 @@ _again:
while ( __nacts-- > 0 ) {
switch ( *__acts++ ) {
case 0:
-#line 1389 "upb/json/parser.rl"
+#line 1500 "upb/json/parser.rl"
{
if (parser->ready_to_end) {
p--; {cs = stack[--top]; goto _again;}
@@ -1892,52 +1920,24 @@ _again:
}
break;
case 20:
-#line 1470 "upb/json/parser.rl"
- {
- CHECK_RETURN_TOP(end_number(parser, p));
- if (does_number_wrapper_end(parser)) {
- end_wrapper_object(parser);
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
- }
+#line 1572 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_number(parser, p)); }
break;
- case 24:
-#line 1509 "upb/json/parser.rl"
- {
- CHECK_RETURN_TOP(parser_putbool(parser, true));
- if (does_boolean_wrapper_end(parser)) {
- end_wrapper_object(parser);
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
- }
+ case 23:
+#line 1577 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_bool(parser, true)); }
break;
- case 26:
-#line 1528 "upb/json/parser.rl"
- {
- CHECK_RETURN_TOP(parser_putbool(parser, false));
- if (does_boolean_wrapper_end(parser)) {
- end_wrapper_object(parser);
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
- }
+ case 24:
+#line 1579 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_bool(parser, false)); }
break;
- case 27:
-#line 1538 "upb/json/parser.rl"
+ case 25:
+#line 1581 "upb/json/parser.rl"
{ /* null value */ }
break;
- case 29:
-#line 1545 "upb/json/parser.rl"
- {
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
+ case 27:
+#line 1584 "upb/json/parser.rl"
+ { end_subobject(parser); }
break;
#line 1943 "upb/json/parser.c"
}
@@ -1947,7 +1947,7 @@ _again:
_out: {}
}
-#line 1582 "upb/json/parser.rl"
+#line 1617 "upb/json/parser.rl"
if (p != pe) {
upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p);
@@ -1980,7 +1980,7 @@ bool end(void *closure, const void *hd) {
return parser->current_state >=
#line 1982 "upb/json/parser.c"
70
-#line 1611 "upb/json/parser.rl"
+#line 1646 "upb/json/parser.rl"
;
}
@@ -2001,7 +2001,7 @@ static void json_parser_reset(upb_json_parser *p) {
top = 0;
}
-#line 1625 "upb/json/parser.rl"
+#line 1660 "upb/json/parser.rl"
p->current_state = cs;
p->parser_top = top;
accumulate_clear(p);
diff --git a/upb/json/parser.rl b/upb/json/parser.rl
index 368b11d..b1b0b94 100644
--- a/upb/json/parser.rl
+++ b/upb/json/parser.rl
@@ -40,6 +40,27 @@ static const char *kBoolValueFullMessageName = "google.protobuf.BoolValue";
static const char *kStringValueFullMessageName = "google.protobuf.StringValue";
static const char *kBytesValueFullMessageName = "google.protobuf.BytesValue";
+/* Forward declare */
+static bool is_top_level(upb_json_parser *p);
+
+static bool is_number_wrapper_object(upb_json_parser *p);
+static bool does_number_wrapper_start(upb_json_parser *p);
+static bool does_number_wrapper_end(upb_json_parser *p);
+
+static bool is_string_wrapper_object(upb_json_parser *p);
+static bool does_string_wrapper_start(upb_json_parser *p);
+static bool does_string_wrapper_end(upb_json_parser *p);
+
+static bool is_boolean_wrapper_object(upb_json_parser *p);
+static bool does_boolean_wrapper_start(upb_json_parser *p);
+static bool does_boolean_wrapper_end(upb_json_parser *p);
+
+static void start_wrapper_object(upb_json_parser *p);
+static void end_wrapper_object(upb_json_parser *p);
+
+static bool start_subobject(upb_json_parser *p);
+static void end_subobject(upb_json_parser *p);
+
typedef struct {
upb_sink sink;
@@ -618,14 +639,27 @@ static bool end_text(upb_json_parser *p, const char *ptr) {
return capture_end(p, ptr);
}
-static void start_number(upb_json_parser *p, const char *ptr) {
+static bool start_number(upb_json_parser *p, const char *ptr) {
+ if (is_top_level(p)) {
+ if (!is_number_wrapper_object(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ } else if (does_number_wrapper_start(p)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ }
+
multipart_startaccum(p);
capture_begin(p, ptr);
+ return true;
}
static bool parse_number(upb_json_parser *p, bool is_quoted);
-static bool end_number(upb_json_parser *p, const char *ptr) {
+static bool end_number_nontop(upb_json_parser *p, const char *ptr) {
if (!capture_end(p, ptr)) {
return false;
}
@@ -638,6 +672,21 @@ static bool end_number(upb_json_parser *p, const char *ptr) {
return parse_number(p, false);
}
+static bool end_number(upb_json_parser *p, const char *ptr) {
+ if (!end_number_nontop(p, ptr)) {
+ return false;
+ }
+
+ if (does_number_wrapper_end(p)) {
+ end_wrapper_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ }
+
+ return true;
+}
+
/* |buf| is NULL-terminated. |buf| itself will never include quotes;
* |is_quoted| tells us whether this text originally appeared inside quotes. */
static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
@@ -805,7 +854,46 @@ static bool parser_putbool(upb_json_parser *p, bool val) {
return true;
}
+static bool end_bool(upb_json_parser *p, bool val) {
+ if (is_top_level(p)) {
+ if (!is_boolean_wrapper_object(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ } else if (does_boolean_wrapper_start(p)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ }
+
+ if (!parser_putbool(p, val)) {
+ return false;
+ }
+
+ if (does_boolean_wrapper_end(p)) {
+ end_wrapper_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ }
+
+ return true;
+}
+
static bool start_stringval(upb_json_parser *p) {
+ if (is_top_level(p)) {
+ if (!is_string_wrapper_object(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ } else if (does_string_wrapper_start(p)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ }
+
if (p->top->f == NULL) {
multipart_startaccum(p);
return true;
@@ -857,7 +945,7 @@ static bool start_stringval(upb_json_parser *p) {
}
}
-static bool end_stringval(upb_json_parser *p) {
+static bool end_stringval_nontop(upb_json_parser *p) {
bool ok = true;
if (p->top->f == NULL) {
@@ -924,6 +1012,21 @@ static bool end_stringval(upb_json_parser *p) {
return ok;
}
+static bool end_stringval(upb_json_parser *p) {
+ if (!end_stringval_nontop(p)) {
+ return false;
+ }
+
+ if (does_string_wrapper_end(p)) {
+ end_wrapper_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ }
+
+ return true;
+}
+
static void start_member(upb_json_parser *p) {
UPB_ASSERT(!p->top->f);
multipart_startaccum(p);
@@ -1107,6 +1210,10 @@ static void end_member(upb_json_parser *p) {
}
static bool start_subobject(upb_json_parser *p) {
+ if (is_top_level(p)) {
+ return true;
+ }
+
if (p->top->f == NULL) {
upb_jsonparser_frame *inner;
if (!check_stack(p)) return false;
@@ -1170,6 +1277,10 @@ static bool start_subobject(upb_json_parser *p) {
}
static void end_subobject(upb_json_parser *p) {
+ if (is_top_level(p)) {
+ return;
+ }
+
if (p->top->is_map) {
upb_selector_t sel;
p->top--;
@@ -1457,96 +1568,20 @@ static bool is_boolean_wrapper_object(upb_json_parser *p) {
value =
number
- >{
- if (is_top_level(parser)) {
- CHECK_RETURN_TOP(is_number_wrapper_object(parser));
- start_wrapper_object(parser);
- } else if (does_number_wrapper_start(parser)) {
- CHECK_RETURN_TOP(start_subobject(parser));
- start_wrapper_object(parser);
- }
- start_number(parser, p);
- }
- %{
- CHECK_RETURN_TOP(end_number(parser, p));
- if (does_number_wrapper_end(parser)) {
- end_wrapper_object(parser);
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
- }
+ >{ CHECK_RETURN_TOP(start_number(parser, p)); }
+ %{ CHECK_RETURN_TOP(end_number(parser, p)); }
| string
- >{
- if (is_top_level(parser)) {
- CHECK_RETURN_TOP(is_string_wrapper_object(parser));
- start_wrapper_object(parser);
- } else if (does_string_wrapper_start(parser)) {
- CHECK_RETURN_TOP(start_subobject(parser));
- start_wrapper_object(parser);
- }
- CHECK_RETURN_TOP(start_stringval(parser));
- }
- @{
- CHECK_RETURN_TOP(end_stringval(parser));
- if (does_string_wrapper_end(parser)) {
- end_wrapper_object(parser);
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
- }
+ >{ CHECK_RETURN_TOP(start_stringval(parser)); }
+ @{ CHECK_RETURN_TOP(end_stringval(parser)); }
| "true"
- >{
- if (is_top_level(parser)) {
- CHECK_RETURN_TOP(is_boolean_wrapper_object(parser));
- start_wrapper_object(parser);
- } else if (does_boolean_wrapper_start(parser)) {
- CHECK_RETURN_TOP(start_subobject(parser));
- start_wrapper_object(parser);
- }
- }
- %{
- CHECK_RETURN_TOP(parser_putbool(parser, true));
- if (does_boolean_wrapper_end(parser)) {
- end_wrapper_object(parser);
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
- }
+ %{ CHECK_RETURN_TOP(end_bool(parser, true)); }
| "false"
- >{
- if (is_top_level(parser)) {
- CHECK_RETURN_TOP(is_boolean_wrapper_object(parser));
- start_wrapper_object(parser);
- } else if (does_boolean_wrapper_start(parser)) {
- CHECK_RETURN_TOP(start_subobject(parser));
- start_wrapper_object(parser);
- }
- }
- %{
- CHECK_RETURN_TOP(parser_putbool(parser, false));
- if (does_boolean_wrapper_end(parser)) {
- end_wrapper_object(parser);
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
- }
+ %{ CHECK_RETURN_TOP(end_bool(parser, false)); }
| "null"
%{ /* null value */ }
| object
- >{
- if (!is_top_level(parser)) {
- CHECK_RETURN_TOP(start_subobject(parser));
- }
- }
- %{
- if (!is_top_level(parser)) {
- end_subobject(parser);
- }
- }
+ >{ CHECK_RETURN_TOP(start_subobject(parser)); }
+ %{ end_subobject(parser); }
| array;
value_machine :=
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback