static int json_get_key_size(struct json_parse_state_s *state) { if (json_parse_flags_allow_unquoted_keys & state->flags_bitset) { // if we are allowing unquoted keys, first grok for a comma... if ('"' == state->src[state->offset]) { // ... if we got a comma, just parse the key as a string as normal return json_get_string_size(state); } else { while ((state->offset < state->size) && is_valid_unquoted_key_char(state->src[state->offset])) { state->offset++; state->data_size++; } // one more byte for null terminator ending the string! state->data_size++; state->dom_size += sizeof(struct json_string_s); return 0; } } else { // we are only allowed to have quoted keys, so just parse a string! return json_get_string_size(state); } }
static int json_get_value_size(struct json_parse_state_s* state) { if (json_skip_whitespace(state)) { // consumed the whole buffer when we expected a value! return 1; } state->dom_size += sizeof(struct json_value_s); switch (state->src[state->offset]) { case '"': return json_get_string_size(state); case '{': return json_get_object_size(state); case '[': return json_get_array_size(state); case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return json_get_number_size(state); default: if ((state->offset + 4) < state->size && 't' == state->src[state->offset + 0] && 'r' == state->src[state->offset + 1] && 'u' == state->src[state->offset + 2] && 'e' == state->src[state->offset + 3]) { state->offset += 4; return 0; } else if ((state->offset + 5) < state->size && 'f' == state->src[state->offset + 0] && 'a' == state->src[state->offset + 1] && 'l' == state->src[state->offset + 2] && 's' == state->src[state->offset + 3] && 'e' == state->src[state->offset + 4]) { state->offset += 5; return 0; } else if ((state->offset + 4) < state->size && 'n' == state->src[state->offset + 0] && 'u' == state->src[state->offset + 1] && 'l' == state->src[state->offset + 2] && 'l' == state->src[state->offset + 3]) { state->offset += 4; return 0; } // invalid value! return 1; } }
static int json_get_object_size(struct json_parse_state_s* state) { size_t elements = 0; if ('{' != state->src[state->offset]) { // expected object to begin with leading '{' return 1; } // skip leading '{' state->offset++; state->dom_size += sizeof(struct json_object_s); while (state->offset < state->size) { if (json_skip_whitespace(state)) { // reached end of buffer before object was complete! return 1; } if ('}' == state->src[state->offset]) { // skip trailing '}' state->offset++; // finished the object! break; } // if we parsed at least once element previously, grok for a comma if (0 < elements) { if (',' != state->src[state->offset]) { // expected a comma where there was none! return 1; } // skip comma state->offset++; if (json_skip_whitespace(state)) { // reached end of buffer before object was complete! return 1; } } if (json_get_string_size(state)) { // string parsing failed! return 1; } if (json_skip_whitespace(state)) { // reached end of buffer before object was complete! return 1; } if (':' != state->src[state->offset]) { // colon seperating name/value pair was missing! return 1; } // skip colon state->offset++; if (json_skip_whitespace(state)) { // reached end of buffer before object was complete! return 1; } if (json_get_value_size(state)) { // value parsing failed! return 1; } // successfully parsed a name/value pair! elements++; } state->dom_size += sizeof(struct json_string_s) * elements; state->dom_size += sizeof(struct json_value_s) * elements; state->dom_size += sizeof(struct json_object_element_s) * elements; return 0; }
static int json_get_value_size(struct json_parse_state_s *state, int is_global_object) { if (is_global_object) { state->dom_size += sizeof(struct json_value_s); return json_get_object_size(state, /* is_global_object = */ 1); } else { state->dom_size += sizeof(struct json_value_s); if (json_skip_all_skippables(state)) { state->error = json_parse_error_premature_end_of_buffer; return 1; } switch (state->src[state->offset]) { case '"': return json_get_string_size(state); case '{': return json_get_object_size(state, /* is_global_object = */ 0); case '[': return json_get_array_size(state); case '+': case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': return json_get_number_size(state); default: if ((state->offset + 4) <= state->size && 't' == state->src[state->offset + 0] && 'r' == state->src[state->offset + 1] && 'u' == state->src[state->offset + 2] && 'e' == state->src[state->offset + 3]) { state->offset += 4; return 0; } else if ((state->offset + 5) <= state->size && 'f' == state->src[state->offset + 0] && 'a' == state->src[state->offset + 1] && 'l' == state->src[state->offset + 2] && 's' == state->src[state->offset + 3] && 'e' == state->src[state->offset + 4]) { state->offset += 5; return 0; } else if ((state->offset + 4) <= state->size && 'n' == state->src[state->offset + 0] && 'u' == state->src[state->offset + 1] && 'l' == state->src[state->offset + 2] && 'l' == state->src[state->offset + 3]) { state->offset += 4; return 0; } // invalid value! state->error = json_parse_error_invalid_value; return 1; } } }