aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/json/json_reader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/json/json_reader.c')
-rw-r--r--src/core/json/json_reader.c148
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;