Esempio n. 1
0
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);
  }
}
Esempio n. 2
0
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;
  }
}
Esempio n. 3
0
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;
}
Esempio n. 4
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;
    }
  }
}