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