127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#include <stdlib.h>
227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#include "jsmn.h"
427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong/**
627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong * Allocates a fresh unused token from the token pull.
727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong */
827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wongstatic jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    jsmntok_t *tokens, size_t num_tokens) {
1027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  jsmntok_t *tok;
1127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  if (parser->toknext >= num_tokens) {
1227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    return NULL;
1327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  }
1427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  tok = &tokens[parser->toknext++];
1527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  tok->start = tok->end = -1;
1627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  tok->size = 0;
1727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#ifdef JSMN_PARENT_LINKS
1827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  tok->parent = -1;
1927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#endif
2027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  return tok;
2127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong}
2227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
2327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong/**
2427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong * Fills token type and boundaries.
2527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong */
2627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wongstatic void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
2727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong                            int start, int end) {
2827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  token->type = type;
2927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  token->start = start;
3027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  token->end = end;
3127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  token->size = 0;
3227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong}
3327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
3427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong/**
3527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong * Fills next available token with JSON primitive.
3627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong */
3727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wongstatic jsmnerr_t jsmn_parse_primitive(jsmn_parser *parser, const char *js,
3827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    size_t len, jsmntok_t *tokens, size_t num_tokens) {
3927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  jsmntok_t *token;
4027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  int start;
4127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
4227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  start = parser->pos;
4327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
4427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
4527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    switch (js[parser->pos]) {
4627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#ifndef JSMN_STRICT
4727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      /* In strict mode primitive must be followed by "," or "}" or "]" */
4827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      case ':':
4927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#endif
5027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      case '\t' : case '\r' : case '\n' : case ' ' :
5127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      case ','  : case ']'  : case '}' :
5227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        goto found;
5327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    }
5427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
5527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      parser->pos = start;
5627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      return JSMN_ERROR_INVAL;
5727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    }
5827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  }
5927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#ifdef JSMN_STRICT
6027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  /* In strict mode primitive must be followed by a comma/object/array */
6127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  parser->pos = start;
6227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  return JSMN_ERROR_PART;
6327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#endif
6427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
6527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wongfound:
6627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  if (tokens == NULL) {
6727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    parser->pos--;
6827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    return 0;
6927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  }
7027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  token = jsmn_alloc_token(parser, tokens, num_tokens);
7127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  if (token == NULL) {
7227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    parser->pos = start;
7327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    return JSMN_ERROR_NOMEM;
7427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  }
7527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
7627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#ifdef JSMN_PARENT_LINKS
7727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  token->parent = parser->toksuper;
7827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#endif
7927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  parser->pos--;
8027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  return 0;
8127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong}
8227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
8327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong/**
8427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong * Filsl next token with JSON string.
8527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong */
8627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wongstatic jsmnerr_t jsmn_parse_string(jsmn_parser *parser, const char *js,
8727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    size_t len, jsmntok_t *tokens, size_t num_tokens) {
8827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  jsmntok_t *token;
8927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
9027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  int start = parser->pos;
9127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
9227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  parser->pos++;
9327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
9427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  /* Skip starting quote */
9527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
9627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    char c = js[parser->pos];
9727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
9827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    /* Quote: end of string */
9927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    if (c == '\"') {
10027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      if (tokens == NULL) {
10127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        return 0;
10227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      }
10327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      token = jsmn_alloc_token(parser, tokens, num_tokens);
10427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      if (token == NULL) {
10527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        parser->pos = start;
10627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        return JSMN_ERROR_NOMEM;
10727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      }
10827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
10927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#ifdef JSMN_PARENT_LINKS
11027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      token->parent = parser->toksuper;
11127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#endif
11227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      return 0;
11327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    }
11427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
11527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    /* Backslash: Quoted symbol expected */
11627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    if (c == '\\') {
11727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      parser->pos++;
11827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      switch (js[parser->pos]) {
11927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        /* Allowed escaped symbols */
12027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        case '\"': case '/' : case '\\' : case 'b' :
12127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        case 'f' : case 'r' : case 'n'  : case 't' :
12227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          break;
12327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        /* Allows escaped symbol \uXXXX */
12427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        case 'u':
12527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          parser->pos++;
12627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          int i = 0;
12727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          for(; i < 4 && js[parser->pos] != '\0'; i++) {
12827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            /* If it isn't a hex character we have an error */
12927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
13027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong                  (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
13127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong                  (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
13227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong              parser->pos = start;
13327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong              return JSMN_ERROR_INVAL;
13427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            }
13527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            parser->pos++;
13627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          }
13727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          parser->pos--;
13827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          break;
13927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        /* Unexpected symbol */
14027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        default:
14127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          parser->pos = start;
14227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          return JSMN_ERROR_INVAL;
14327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      }
14427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    }
14527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  }
14627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  parser->pos = start;
14727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  return JSMN_ERROR_PART;
14827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong}
14927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
15027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong/**
15127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong * Parse JSON string and fill tokens.
15227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong */
15327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wongjsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
15427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    jsmntok_t *tokens, unsigned int num_tokens) {
15527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  jsmnerr_t r;
15627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  int i;
15727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  jsmntok_t *token;
15827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  int count = 0;
15927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
16027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
16127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    char c;
16227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    jsmntype_t type;
16327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
16427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    c = js[parser->pos];
16527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    switch (c) {
16627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      case '{': case '[':
16727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        count++;
16827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        if (tokens == NULL) {
16927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          break;
17027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        }
17127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        token = jsmn_alloc_token(parser, tokens, num_tokens);
17227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        if (token == NULL)
17327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          return JSMN_ERROR_NOMEM;
17427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        if (parser->toksuper != -1) {
17527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          tokens[parser->toksuper].size++;
17627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#ifdef JSMN_PARENT_LINKS
17727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          token->parent = parser->toksuper;
17827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#endif
17927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        }
18027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
18127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        token->start = parser->pos;
18227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        parser->toksuper = parser->toknext - 1;
18327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        break;
18427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      case '}': case ']':
18527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        if (tokens == NULL)
18627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          break;
18727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
18827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#ifdef JSMN_PARENT_LINKS
18927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        if (parser->toknext < 1) {
19027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          return JSMN_ERROR_INVAL;
19127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        }
19227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        token = &tokens[parser->toknext - 1];
19327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        for (;;) {
19427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          if (token->start != -1 && token->end == -1) {
19527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            if (token->type != type) {
19627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong              return JSMN_ERROR_INVAL;
19727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            }
19827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            token->end = parser->pos + 1;
19927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            parser->toksuper = token->parent;
20027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            break;
20127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          }
20227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          if (token->parent == -1) {
20327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            break;
20427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          }
20527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          token = &tokens[token->parent];
20627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        }
20727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#else
20827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        for (i = parser->toknext - 1; i >= 0; i--) {
20927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          token = &tokens[i];
21027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          if (token->start != -1 && token->end == -1) {
21127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            if (token->type != type) {
21227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong              return JSMN_ERROR_INVAL;
21327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            }
21427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            parser->toksuper = -1;
21527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            token->end = parser->pos + 1;
21627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            break;
21727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          }
21827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        }
21927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        /* Error if unmatched closing bracket */
22027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        if (i == -1) return JSMN_ERROR_INVAL;
22127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        for (; i >= 0; i--) {
22227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          token = &tokens[i];
22327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          if (token->start != -1 && token->end == -1) {
22427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            parser->toksuper = i;
22527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong            break;
22627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          }
22727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        }
22827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#endif
22927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        break;
23027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      case '\"':
23127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
23227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        if (r < 0) return r;
23327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        count++;
23427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        if (parser->toksuper != -1 && tokens != NULL)
23527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          tokens[parser->toksuper].size++;
23627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        break;
23727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      case '\t' : case '\r' : case '\n' : case ':' : case ',': case ' ':
23827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        break;
23927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#ifdef JSMN_STRICT
24027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      /* In strict mode primitives are: numbers and booleans */
24127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      case '-': case '0': case '1' : case '2': case '3' : case '4':
24227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      case '5': case '6': case '7' : case '8': case '9':
24327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      case 't': case 'f': case 'n' :
24427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#else
24527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      /* In non-strict mode every unquoted value is a primitive */
24627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      default:
24727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#endif
24827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
24927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        if (r < 0) return r;
25027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        count++;
25127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        if (parser->toksuper != -1 && tokens != NULL)
25227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong          tokens[parser->toksuper].size++;
25327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        break;
25427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
25527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#ifdef JSMN_STRICT
25627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      /* Unexpected char in strict mode */
25727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      default:
25827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong        return JSMN_ERROR_INVAL;
25927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong#endif
26027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    }
26127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  }
26227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
26327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  for (i = parser->toknext - 1; i >= 0; i--) {
26427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    /* Unmatched opened object or array */
26527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    if (tokens[i].start != -1 && tokens[i].end == -1) {
26627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong      return JSMN_ERROR_PART;
26727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong    }
26827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  }
26927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
27027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  return count;
27127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong}
27227b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong
27327b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong/**
27427b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong * Creates a new parser based over a given  buffer with an array of tokens
27527b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong * available.
27627b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong */
27727b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wongvoid jsmn_init(jsmn_parser *parser) {
27827b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  parser->pos = 0;
27927b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  parser->toknext = 0;
28027b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong  parser->toksuper = -1;
28127b5a35db0630b86791fa037a12da7b37c2aab49Edwin Wong}
282