diff options
Diffstat (limited to 'src/core/json/json_reader.c')
-rw-r--r-- | src/core/json/json_reader.c | 148 |
1 files changed, 77 insertions, 71 deletions
diff --git a/src/core/json/json_reader.c b/src/core/json/json_reader.c index 7f52bf2b6d..304da2a26b 100644 --- a/src/core/json/json_reader.c +++ b/src/core/json/json_reader.c @@ -31,69 +31,72 @@ * */ +#include <string.h> + #include <grpc/support/port_platform.h> + #include "src/core/json/json_reader.h" -static void grpc_json_reader_string_clear(grpc_json_reader* reader) { - reader->string_clear(reader); +static void json_reader_string_clear(grpc_json_reader* reader) { + reader->vtable->string_clear(reader->userdata); } -static void grpc_json_reader_string_add_char(grpc_json_reader* reader, +static void json_reader_string_add_char(grpc_json_reader* reader, gpr_uint32 c) { - reader->string_add_char(reader, c); + reader->vtable->string_add_char(reader->userdata, c); } -static void grpc_json_reader_string_add_utf32(grpc_json_reader* reader, +static void json_reader_string_add_utf32(grpc_json_reader* reader, gpr_uint32 utf32) { - reader->string_add_utf32(reader, utf32); + reader->vtable->string_add_utf32(reader->userdata, utf32); } static gpr_uint32 grpc_json_reader_read_char(grpc_json_reader* reader) { - return reader->read_char(reader); + return reader->vtable->read_char(reader->userdata); } -static void grpc_json_reader_container_begins(grpc_json_reader* reader, +static void json_reader_container_begins(grpc_json_reader* reader, grpc_json_type type) { - reader->container_begins(reader, type); + reader->vtable->container_begins(reader->userdata, type); } static grpc_json_type grpc_json_reader_container_ends(grpc_json_reader* reader) { - return reader->container_ends(reader); + return reader->vtable->container_ends(reader->userdata); } -static void grpc_json_reader_set_key(grpc_json_reader* reader) { - reader->set_key(reader); +static void json_reader_set_key(grpc_json_reader* reader) { + reader->vtable->set_key(reader->userdata); } -static void grpc_json_reader_set_string(grpc_json_reader* reader) { - reader->set_string(reader); +static void json_reader_set_string(grpc_json_reader* reader) { + reader->vtable->set_string(reader->userdata); } -static int grpc_json_reader_set_number(grpc_json_reader* reader) { - return reader->set_number(reader); +static int json_reader_set_number(grpc_json_reader* reader) { + return reader->vtable->set_number(reader->userdata); } -static void grpc_json_reader_set_true(grpc_json_reader* reader) { - reader->set_true(reader); +static void json_reader_set_true(grpc_json_reader* reader) { + reader->vtable->set_true(reader->userdata); } -static void grpc_json_reader_set_false(grpc_json_reader* reader) { - reader->set_false(reader); +static void json_reader_set_false(grpc_json_reader* reader) { + reader->vtable->set_false(reader->userdata); } -static void grpc_json_reader_set_null(grpc_json_reader* reader) { - reader->set_null(reader); +static void json_reader_set_null(grpc_json_reader* reader) { + reader->vtable->set_null(reader->userdata); } /* Call this function to initialize the reader structure. */ -void grpc_json_reader_init(grpc_json_reader* reader) { - reader->depth = 0; - reader->in_object = 0; - reader->in_array = 0; - reader->unicode_high_surrogate = 0; - grpc_json_reader_string_clear(reader); +void grpc_json_reader_init(grpc_json_reader* reader, + grpc_json_reader_vtable* vtable, void* userdata) { + memset(reader, 0, sizeof(grpc_json_reader)); + reader->vtable = vtable; + reader->userdata = userdata; + json_reader_string_clear(reader); reader->state = GRPC_JSON_STATE_VALUE_BEGIN; } @@ -102,7 +105,7 @@ int grpc_json_reader_is_complete(grpc_json_reader* reader) { (reader->state == GRPC_JSON_STATE_VALUE_END))); } -grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { +grpc_json_reader_status grpc_json_reader_run(grpc_json_reader* reader) { gpr_uint32 c, success; /* This state-machine is a strict implementation of ECMA-404 */ @@ -140,17 +143,17 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { case GRPC_JSON_STATE_OBJECT_KEY_STRING: case GRPC_JSON_STATE_VALUE_STRING: if (c != ' ') return GRPC_JSON_PARSE_ERROR; - if (reader->unicode_high_surrogate) return GRPC_JSON_PARSE_ERROR; - grpc_json_reader_string_add_char(reader, c); + if (reader->unicode_high_surrogate != 0) return GRPC_JSON_PARSE_ERROR; + json_reader_string_add_char(reader, c); break; case GRPC_JSON_STATE_VALUE_NUMBER: case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL: case GRPC_JSON_STATE_VALUE_NUMBER_ZERO: case GRPC_JSON_STATE_VALUE_NUMBER_EPM: - success = grpc_json_reader_set_number(reader); + success = json_reader_set_number(reader); if (!success) return GRPC_JSON_PARSE_ERROR; - grpc_json_reader_string_clear(reader); + json_reader_string_clear(reader); reader->state = GRPC_JSON_STATE_VALUE_END; break; @@ -166,17 +169,17 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { switch (reader->state) { case GRPC_JSON_STATE_OBJECT_KEY_STRING: case GRPC_JSON_STATE_VALUE_STRING: - if (reader->unicode_high_surrogate) return GRPC_JSON_PARSE_ERROR; - grpc_json_reader_string_add_char(reader, c); + if (reader->unicode_high_surrogate != 0) return GRPC_JSON_PARSE_ERROR; + json_reader_string_add_char(reader, c); break; case GRPC_JSON_STATE_VALUE_NUMBER: case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL: case GRPC_JSON_STATE_VALUE_NUMBER_ZERO: case GRPC_JSON_STATE_VALUE_NUMBER_EPM: - success = grpc_json_reader_set_number(reader); + success = json_reader_set_number(reader); if (!success) return GRPC_JSON_PARSE_ERROR; - grpc_json_reader_string_clear(reader); + json_reader_string_clear(reader); reader->state = GRPC_JSON_STATE_VALUE_END; /* The missing break here is intentional. */ @@ -250,8 +253,8 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { /* This is the \\ case. */ case GRPC_JSON_STATE_STRING_ESCAPE: - if (reader->unicode_high_surrogate) return GRPC_JSON_PARSE_ERROR; - grpc_json_reader_string_add_char(reader, '\\'); + if (reader->unicode_high_surrogate != 0) return GRPC_JSON_PARSE_ERROR; + json_reader_string_add_char(reader, '\\'); if (reader->escaped_string_was_key) { reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; } else { @@ -273,26 +276,26 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { break; case GRPC_JSON_STATE_OBJECT_KEY_STRING: - if (reader->unicode_high_surrogate) return GRPC_JSON_PARSE_ERROR; + if (reader->unicode_high_surrogate != 0) return GRPC_JSON_PARSE_ERROR; if (c == '"') { reader->state = GRPC_JSON_STATE_OBJECT_KEY_END; - grpc_json_reader_set_key(reader); - grpc_json_reader_string_clear(reader); + json_reader_set_key(reader); + json_reader_string_clear(reader); } else { - if (c < 32) return GRPC_JSON_PARSE_ERROR; - grpc_json_reader_string_add_char(reader, c); + if (c <= 0x001f) return GRPC_JSON_PARSE_ERROR; + json_reader_string_add_char(reader, c); } break; case GRPC_JSON_STATE_VALUE_STRING: - if (reader->unicode_high_surrogate) return GRPC_JSON_PARSE_ERROR; + if (reader->unicode_high_surrogate != 0) return GRPC_JSON_PARSE_ERROR; if (c == '"') { reader->state = GRPC_JSON_STATE_VALUE_END; - grpc_json_reader_set_string(reader); - grpc_json_reader_string_clear(reader); + json_reader_set_string(reader); + json_reader_string_clear(reader); } else { if (c < 32) return GRPC_JSON_PARSE_ERROR; - grpc_json_reader_string_add_char(reader, c); + json_reader_string_add_char(reader, c); } break; @@ -333,13 +336,13 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { case '8': case '9': case '-': - grpc_json_reader_string_add_char(reader, c); + json_reader_string_add_char(reader, c); reader->state = GRPC_JSON_STATE_VALUE_NUMBER; break; case '{': reader->container_just_begun = 1; - grpc_json_reader_container_begins(reader, GRPC_JSON_OBJECT); + json_reader_container_begins(reader, GRPC_JSON_OBJECT); reader->depth++; reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN; reader->in_object = 1; @@ -348,7 +351,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { case '[': reader->container_just_begun = 1; - grpc_json_reader_container_begins(reader, GRPC_JSON_ARRAY); + json_reader_container_begins(reader, GRPC_JSON_ARRAY); reader->depth++; reader->in_object = 0; reader->in_array = 1; @@ -367,22 +370,22 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { switch (c) { case '"': case '/': - grpc_json_reader_string_add_char(reader, c); + json_reader_string_add_char(reader, c); break; case 'b': - grpc_json_reader_string_add_char(reader, '\b'); + json_reader_string_add_char(reader, '\b'); break; case 'f': - grpc_json_reader_string_add_char(reader, '\f'); + json_reader_string_add_char(reader, '\f'); break; case 'n': - grpc_json_reader_string_add_char(reader, '\n'); + json_reader_string_add_char(reader, '\n'); break; case 'r': - grpc_json_reader_string_add_char(reader, '\r'); + json_reader_string_add_char(reader, '\r'); break; case 't': - grpc_json_reader_string_add_char(reader, '\t'); + json_reader_string_add_char(reader, '\t'); break; case 'u': reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U1; @@ -420,26 +423,29 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U4; break; case GRPC_JSON_STATE_STRING_ESCAPE_U4: + /* See grpc_json_writer_escape_string to have a description + * of what's going on here. + */ if ((reader->unicode_char & 0xfc00) == 0xd800) { /* high surrogate utf-16 */ - if (reader->unicode_high_surrogate) + if (reader->unicode_high_surrogate != 0) return GRPC_JSON_PARSE_ERROR; reader->unicode_high_surrogate = reader->unicode_char; } else if ((reader->unicode_char & 0xfc00) == 0xdc00) { /* low surrogate utf-16 */ gpr_uint32 utf32; - if (!reader->unicode_high_surrogate) + if (reader->unicode_high_surrogate == 0) return GRPC_JSON_PARSE_ERROR; utf32 = 0x10000; utf32 += (reader->unicode_high_surrogate - 0xd800) * 0x400; utf32 += reader->unicode_char - 0xdc00; - grpc_json_reader_string_add_utf32(reader, utf32); + json_reader_string_add_utf32(reader, utf32); reader->unicode_high_surrogate = 0; } else { /* anything else */ - if (reader->unicode_high_surrogate) + if (reader->unicode_high_surrogate != 0) return GRPC_JSON_PARSE_ERROR; - grpc_json_reader_string_add_utf32(reader, reader->unicode_char); + json_reader_string_add_utf32(reader, reader->unicode_char); } if (reader->escaped_string_was_key) { reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING; @@ -453,7 +459,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { break; case GRPC_JSON_STATE_VALUE_NUMBER: - grpc_json_reader_string_add_char(reader, c); + json_reader_string_add_char(reader, c); switch (c) { case '0': case '1': @@ -475,7 +481,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { break; case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL: - grpc_json_reader_string_add_char(reader, c); + json_reader_string_add_char(reader, c); switch (c) { case '0': case '1': @@ -499,12 +505,12 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { case GRPC_JSON_STATE_VALUE_NUMBER_ZERO: if (c != '.') return GRPC_JSON_PARSE_ERROR; - grpc_json_reader_string_add_char(reader, c); + json_reader_string_add_char(reader, c); reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT; break; case GRPC_JSON_STATE_VALUE_NUMBER_DOT: - grpc_json_reader_string_add_char(reader, c); + json_reader_string_add_char(reader, c); switch (c) { case '0': case '1': @@ -524,7 +530,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { break; case GRPC_JSON_STATE_VALUE_NUMBER_E: - grpc_json_reader_string_add_char(reader, c); + json_reader_string_add_char(reader, c); switch (c) { case '0': case '1': @@ -545,7 +551,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { } case GRPC_JSON_STATE_VALUE_NUMBER_EPM: - grpc_json_reader_string_add_char(reader, c); + json_reader_string_add_char(reader, c); switch (c) { case '0': case '1': @@ -574,7 +580,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { case GRPC_JSON_STATE_VALUE_TRUE_E: if (c != 'e') return GRPC_JSON_PARSE_ERROR; - grpc_json_reader_set_true(reader); + json_reader_set_true(reader); reader->state = GRPC_JSON_STATE_VALUE_END; break; @@ -595,7 +601,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { case GRPC_JSON_STATE_VALUE_FALSE_E: if (c != 'e') return GRPC_JSON_PARSE_ERROR; - grpc_json_reader_set_false(reader); + json_reader_set_false(reader); reader->state = GRPC_JSON_STATE_VALUE_END; break; @@ -611,7 +617,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) { case GRPC_JSON_STATE_VALUE_NULL_L2: if (c != 'l') return GRPC_JSON_PARSE_ERROR; - grpc_json_reader_set_null(reader); + json_reader_set_null(reader); reader->state = GRPC_JSON_STATE_VALUE_END; break; |