src/c/json.c
int iot_json_parse (iot_json_parser *parser, const char * json, size_t len, iot_json_tok_t *tokens, uint32_t num_tokens)
{
  int r;
  iot_json_tok_t *token;
  int32_t count = parser->toknext;

  for (; parser->pos < len && json[parser->pos] != '\0'; parser->pos++)
  {
    char c;
    iot_json_type_t type;

    c = json[parser->pos];
    switch (c)
    {
      case '{':
      case '[':
        count++;
        if (tokens == NULL)
        {
          break;
        }
        token = iot_json_alloc_token (parser, tokens, num_tokens);
        if (token == NULL) return IOT_JSON_ERROR_NOMEM;
        if (parser->toksuper != -1)
        {
          tokens[parser->toksuper].size++;
          token->parent = parser->toksuper;
        }
        token->type = (c == '{' ? IOT_JSON_OBJECT : IOT_JSON_ARRAY);
        token->start = (int32_t) parser->pos;
        parser->toksuper = parser->toknext - 1;
        break;
      case '}': case ']':
        if (tokens == NULL)
        {
          break;
        }
        type = (c == '}' ? IOT_JSON_OBJECT : IOT_JSON_ARRAY);

        if (parser->toknext < 1)
        {
          return IOT_JSON_ERROR_INVAL;
        }
        token = &tokens[parser->toknext - 1];
        for (;;)
        {
          if (token->start != -1 && token->end == -1)
          {
            if (token->type != type)
            {
              return IOT_JSON_ERROR_INVAL;
            }
            token->end = (int32_t) parser->pos + 1;
            parser->toksuper = token->parent;
            break;
          }
          if (token->parent == -1)
          {
            if (token->type != type || parser->toksuper == -1)
            {
              return IOT_JSON_ERROR_INVAL;
            }
            break;
          }
          token = &tokens[token->parent];
        }
        break;
      case '\"':
        r = iot_json_parse_string (parser, json, len, tokens, num_tokens);
        if (r < 0) return r;
        count++;
        if (parser->toksuper != -1 && tokens != NULL)
        {
          tokens[parser->toksuper].size++;
        }
        break;
      case '\t':
      case '\r':
      case '\n':
      case ' ':
        break;
      case ':':
        parser->toksuper = parser->toknext - 1;
        break;
      case ',':
        if (tokens != NULL && parser->toksuper != -1 &&
            tokens[parser->toksuper].type != IOT_JSON_ARRAY &&
            tokens[parser->toksuper].type != IOT_JSON_OBJECT)
        {
          parser->toksuper = tokens[parser->toksuper].parent;
        }
        break;
#ifdef JSON_STRICT
      /* In strict mode primitives are: numbers and booleans */
      case '-': case '0': case '1' : case '2': case '3' : case '4':
      case '5': case '6': case '7' : case '8': case '9':
      case 't': case 'f': case 'n' :
        /* And they must not be keys of the object */
        if (tokens != NULL && parser->toksuper != -1) {
          jsontok_t *t = &tokens[parser->toksuper];
          if (t->type == JSON_OBJECT ||
              ((t->type == JSON_STRING || t->type == JSON_STRING_ESC) && t->size != 0)) {
            return JSON_ERROR_INVAL;
          }
        }
#else
        /* In non-strict mode every unquoted value is a primitive */
      default:
#endif
        r = iot_json_parse_primitive (parser, json, len, tokens, num_tokens);
        if (r < 0) return r;
        count++;
        if (parser->toksuper != -1 && tokens != NULL)
        {
          tokens[parser->toksuper].size++;
        }
        break;

#ifdef JSON_STRICT
      /* Unexpected char in strict mode */
      default:
        return JSON_ERROR_INVAL;
#endif
    }
  }

  if (tokens != NULL)
  {
    for (int i = parser->toknext - 1; i >= 0; i--)
    {
      /* Unmatched opened object or array */
      if (tokens[i].start != -1 && tokens[i].end == -1)
      {
        return IOT_JSON_ERROR_PART;
      }
    }
  }

  return count;
}
/**
 * Parse JSON string and fill tokens.
 */
Parse JSON string and fill tokens.
Parse JSON string and fill tokens .
int iot_json_parse (iot_json_parser *parser, const char * json, size_t len, iot_json_tok_t *tokens, uint32_t num_tokens)
{
  int r;
  iot_json_tok_t *token;
  int32_t count = parser->toknext;
  for (; parser->pos < len && json[parser->pos] != '\0'; parser->pos++)
  {
    char c;
    iot_json_type_t type;
    c = json[parser->pos];
    switch (c)
    {
      case '{':
      case '[':
        count++;
        if (tokens == NULL)
        {
          break;
        }
        token = iot_json_alloc_token (parser, tokens, num_tokens);
        if (token == NULL) return IOT_JSON_ERROR_NOMEM;
        if (parser->toksuper != -1)
        {
          tokens[parser->toksuper].size++;
          token->parent = parser->toksuper;
        }
        token->type = (c == '{' ? IOT_JSON_OBJECT : IOT_JSON_ARRAY);
        token->start = (int32_t) parser->pos;
        parser->toksuper = parser->toknext - 1;
        break;
      case '}': case ']':
        if (tokens == NULL)
        {
          break;
        }
        type = (c == '}' ? IOT_JSON_OBJECT : IOT_JSON_ARRAY);
        if (parser->toknext < 1)
        {
          return IOT_JSON_ERROR_INVAL;
        }
        token = &tokens[parser->toknext - 1];
        for (;;)
        {
          if (token->start != -1 && token->end == -1)
          {
            if (token->type != type)
            {
              return IOT_JSON_ERROR_INVAL;
            }
            token->end = (int32_t) parser->pos + 1;
            parser->toksuper = token->parent;
            break;
          }
          if (token->parent == -1)
          {
            if (token->type != type || parser->toksuper == -1)
            {
              return IOT_JSON_ERROR_INVAL;
            }
            break;
          }
          token = &tokens[token->parent];
        }
        break;
      case '\"':
        r = iot_json_parse_string (parser, json, len, tokens, num_tokens);
        if (r < 0) return r;
        count++;
        if (parser->toksuper != -1 && tokens != NULL)
        {
          tokens[parser->toksuper].size++;
        }
        break;
      case '\t':
      case '\r':
      case '\n':
      case ' ':
        break;
      case ':':
        parser->toksuper = parser->toknext - 1;
        break;
      case ',':
        if (tokens != NULL && parser->toksuper != -1 &&
            tokens[parser->toksuper].type != IOT_JSON_ARRAY &&
            tokens[parser->toksuper].type != IOT_JSON_OBJECT)
        {
          parser->toksuper = tokens[parser->toksuper].parent;
        }
        break;
#ifdef JSON_STRICT
      case '-': case '0': case '1' : case '2': case '3' : case '4':
      case '5': case '6': case '7' : case '8': case '9':
      case 't': case 'f': case 'n' :
        if (tokens != NULL && parser->toksuper != -1) {
          jsontok_t *t = &tokens[parser->toksuper];
          if (t->type == JSON_OBJECT ||
              ((t->type == JSON_STRING || t->type == JSON_STRING_ESC) && t->size != 0)) {
            return JSON_ERROR_INVAL;
          }
        }
#else
      default:
#endif
        r = iot_json_parse_primitive (parser, json, len, tokens, num_tokens);
        if (r < 0) return r;
        count++;
        if (parser->toksuper != -1 && tokens != NULL)
        {
          tokens[parser->toksuper].size++;
        }
        break;
#ifdef JSON_STRICT
      default:
        return JSON_ERROR_INVAL;
#endif
    }
  }
  if (tokens != NULL)
  {
    for (int i = parser->toknext - 1; i >= 0; i--)
    {
      if (tokens[i].start != -1 && tokens[i].end == -1)
      {
        return IOT_JSON_ERROR_PART;
      }
    }
  }
  return count;
}
int iot_json_parse ( iot_json_parser * parser , const char * json , size_t len , iot_json_tok_t * tokens , uint32_t num_tokens ) { int r ; iot_json_tok_t * token ; int32_t count = parser -> toknext ; for ( ; parser -> pos < len && json [ parser -> pos ] != ' \0 ' ; parser -> pos ++ ) { char c ; iot_json_type_t type ; c = json [ parser -> pos ] ; switch ( c ) { case ' ' : case ' ' : count ++ ; if ( tokens == NULL ) { break ; } token = iot_json_alloc_token ( parser , tokens , num_tokens ) ; if ( token == NULL ) return IOT_JSON_ERROR_NOMEM ; if ( parser -> toksuper != -1 ) { tokens [ parser -> toksuper ] . size ++ ; token -> parent = parser -> toksuper ; } token -> type = ( c == ' ' ? IOT_JSON_OBJECT : IOT_JSON_ARRAY ) ; token -> start = ( int32_t ) parser -> pos ; parser -> toksuper = parser -> toknext - 1 ; break ; case ' ' : case ' ' : if ( tokens == NULL ) { break ; } type = ( c == ' ' ? IOT_JSON_OBJECT : IOT_JSON_ARRAY ) ; if ( parser -> toknext < 1 ) { return IOT_JSON_ERROR_INVAL ; } token = & tokens [ parser -> toknext - 1 ] ; for ( ; ; ) { if ( token -> start != -1 && token -> end == -1 ) { if ( token -> type != type ) { return IOT_JSON_ERROR_INVAL ; } token -> end = ( int32_t ) parser -> pos + 1 ; parser -> toksuper = token -> parent ; break ; } if ( token -> parent == -1 ) { if ( token -> type != type || parser -> toksuper == -1 ) { return IOT_JSON_ERROR_INVAL ; } break ; } token = & tokens [ token -> parent ] ; } break ; case ' \" ' : r = iot_json_parse_string ( parser , json , len , tokens , num_tokens ) ; if ( r < 0 ) return r ; count ++ ; if ( parser -> toksuper != -1 && tokens != NULL ) { tokens [ parser -> toksuper ] . size ++ ; } break ; case ' \t ' : case ' \r ' : case ' \n ' : case ' ' : break ; case ' ' : parser -> toksuper = parser -> toknext - 1 ; break ; case ' ' : if ( tokens != NULL && parser -> toksuper != -1 && tokens [ parser -> toksuper ] . type != IOT_JSON_ARRAY && tokens [ parser -> toksuper ] . type != IOT_JSON_OBJECT ) { parser -> toksuper = tokens [ parser -> toksuper ] . parent ; } break ; #ifdef JSON_STRICT case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : if ( tokens != NULL && parser -> toksuper != -1 ) { jsontok_t * t = & tokens [ parser -> toksuper ] ; if ( t -> type == JSON_OBJECT || ( ( t -> type == JSON_STRING || t -> type == JSON_STRING_ESC ) && t -> size != 0 ) ) { return JSON_ERROR_INVAL ; } } #else default : #endif r = iot_json_parse_primitive ( parser , json , len , tokens , num_tokens ) ; if ( r < 0 ) return r ; count ++ ; if ( parser -> toksuper != -1 && tokens != NULL ) { tokens [ parser -> toksuper ] . size ++ ; } break ; #ifdef JSON_STRICT default : return JSON_ERROR_INVAL ; #endif } } if ( tokens != NULL ) { for ( int i = parser -> toknext - 1 ; i >= 0 ; i -- ) { if ( tokens [ i ] . start != -1 && tokens [ i ] . end == -1 ) { return IOT_JSON_ERROR_PART ; } } } return count ; }
Parse JSON string and fill tokens.
Parse JSON string and fill tokens .
/* In strict mode primitives are: numbers and booleans */ /* And they must not be keys of the object */ /* In non-strict mode every unquoted value is a primitive */ /* Unexpected char in strict mode */ /* Unmatched opened object or array */