From f3b41ae30c7627f540ee539aed51bcca06d23a82 Mon Sep 17 00:00:00 2001 From: "Serge A. Zaitsev" Date: Thu, 2 Feb 2012 13:26:15 +0200 Subject: [PATCH] fixed: superior node size is now an index, not a pointer (safe to realloc) --- jsmn.c | 22 +++++++++++----------- jsmn.h | 6 +++--- jsmn_test.c | 6 +++++- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/jsmn.c b/jsmn.c index ef53cc0..e38a472 100644 --- a/jsmn.c +++ b/jsmn.c @@ -11,7 +11,6 @@ static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, for (i = parser->toknext; i < num_tokens; i++) { if (tokens[i].start == -1 && tokens[i].end == -1) { parser->toknext = i + 1; - tokens[i].size = 0; return &tokens[i]; } } @@ -26,6 +25,7 @@ static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type, token->type = type; token->start = start; token->end = end; + token->size = 0; } /** @@ -142,11 +142,11 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens, token = jsmn_alloc_token(parser, tokens, num_tokens); if (token == NULL) return JSMN_ERROR_NOMEM; - if (parser->cursize != NULL) - (*parser->cursize)++; + if (parser->toksuper != -1) + tokens[parser->toksuper].size++; token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); token->start = parser->pos; - parser->cursize = &token->size; + parser->toksuper = parser->toknext - 1; break; case '}': case ']': type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); @@ -156,7 +156,7 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens, if (token->type != type) { return JSMN_ERROR_INVAL; } - parser->cursize = NULL; + parser->toksuper = -1; token->end = parser->pos + 1; break; } @@ -164,7 +164,7 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens, for (; i >= 0; i--) { token = &tokens[i]; if (token->start != -1 && token->end == -1) { - parser->cursize = &token->size; + parser->toksuper = i; break; } } @@ -172,8 +172,8 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens, case '\"': r = jsmn_parse_string(parser, js, tokens, num_tokens); if (r < 0) return r; - if (parser->cursize != NULL) - (*parser->cursize)++; + if (parser->toksuper != -1) + tokens[parser->toksuper].size++; break; case '\t' : case '\r' : case '\n' : case ':' : case ',': case ' ': break; @@ -188,8 +188,8 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens, #endif r = jsmn_parse_primitive(parser, js, tokens, num_tokens); if (r < 0) return r; - if (parser->cursize != NULL) - (*parser->cursize)++; + if (parser->toksuper != -1) + tokens[parser->toksuper].size++; break; #ifdef JSMN_STRICT @@ -218,6 +218,6 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens, void jsmn_init(jsmn_parser *parser) { parser->pos = 0; parser->toknext = 0; - parser->cursize = NULL; + parser->toksuper = -1; } diff --git a/jsmn.h b/jsmn.h index 72040bc..91e285d 100644 --- a/jsmn.h +++ b/jsmn.h @@ -44,9 +44,9 @@ typedef struct { * the string being parsed now and current position in that string */ typedef struct { - unsigned int pos; - int toknext; - int *cursize; + unsigned int pos; /* offset in the JSON string */ + int toknext; /* next token to allocate */ + int toksuper; /* suporior token node, e.g parent object or array */ } jsmn_parser; /** diff --git a/jsmn_test.c b/jsmn_test.c index a356a95..0bbd82c 100644 --- a/jsmn_test.c +++ b/jsmn_test.c @@ -254,8 +254,9 @@ int test_array_nomem() { js = " [ 1, true, [123, \"hello\"]]"; for (i = 0; i < 6; i++) { - printf("i = %d\n", i); jsmn_init(&p); + memset(toksmall, 0, sizeof(toksmall)); + memset(toklarge, 0, sizeof(toklarge)); r = jsmn_parse(&p, js, toksmall, i); check(r == JSMN_ERROR_NOMEM); @@ -263,6 +264,9 @@ int test_array_nomem() { r = jsmn_parse(&p, js, toklarge, 10); check(r == JSMN_SUCCESS); + + check(toklarge[0].type == JSMN_ARRAY && toklarge[0].size == 3); + check(toklarge[3].type == JSMN_ARRAY && toklarge[3].size == 2); } return 0; }