summaryrefslogtreecommitdiff
path: root/jsmn.c
diff options
context:
space:
mode:
authorSerge A. Zaitsev <zaitsev.serge@gmail.com>2014-02-20 22:27:07 +0200
committerSerge A. Zaitsev <zaitsev.serge@gmail.com>2014-02-20 22:27:07 +0200
commit809c7c6db1fd8691db78900b952f94150e7d98c9 (patch)
tree0f5c052fe78d98ddef326b2cd4758e65a8213f35 /jsmn.c
parent86350f2bb1681c573abd44018ee49883989008dd (diff)
added way to estimate number of tokens before parsing
Diffstat (limited to 'jsmn.c')
-rw-r--r--jsmn.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/jsmn.c b/jsmn.c
index 2956230d3..e0644f57d 100644
--- a/jsmn.c
+++ b/jsmn.c
@@ -63,6 +63,10 @@ static jsmnerr_t jsmn_parse_primitive(jsmn_parser *parser, const char *js,
#endif
found:
+ if (tokens == NULL) {
+ parser->pos--;
+ return 0;
+ }
token = jsmn_alloc_token(parser, tokens, num_tokens);
if (token == NULL) {
parser->pos = start;
@@ -73,7 +77,7 @@ found:
token->parent = parser->toksuper;
#endif
parser->pos--;
- return JSMN_SUCCESS;
+ return 0;
}
/**
@@ -93,6 +97,9 @@ static jsmnerr_t jsmn_parse_string(jsmn_parser *parser, const char *js,
/* Quote: end of string */
if (c == '\"') {
+ if (tokens == NULL) {
+ return 0;
+ }
token = jsmn_alloc_token(parser, tokens, num_tokens);
if (token == NULL) {
parser->pos = start;
@@ -102,7 +109,7 @@ static jsmnerr_t jsmn_parse_string(jsmn_parser *parser, const char *js,
#ifdef JSMN_PARENT_LINKS
token->parent = parser->toksuper;
#endif
- return JSMN_SUCCESS;
+ return 0;
}
/* Backslash: Quoted symbol expected */
@@ -148,6 +155,7 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens,
jsmnerr_t r;
int i;
jsmntok_t *token;
+ int count = 0;
for (; js[parser->pos] != '\0'; parser->pos++) {
char c;
@@ -156,6 +164,10 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens,
c = js[parser->pos];
switch (c) {
case '{': case '[':
+ if (tokens == NULL) {
+ count++;
+ break;
+ }
token = jsmn_alloc_token(parser, tokens, num_tokens);
if (token == NULL)
return JSMN_ERROR_NOMEM;
@@ -170,6 +182,8 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens,
parser->toksuper = parser->toknext - 1;
break;
case '}': case ']':
+ if (tokens == NULL)
+ break;
type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
#ifdef JSMN_PARENT_LINKS
if (parser->toknext < 1) {
@@ -216,7 +230,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->toksuper != -1)
+ count++;
+ if (parser->toksuper != -1 && tokens != NULL)
tokens[parser->toksuper].size++;
break;
case '\t' : case '\r' : case '\n' : case ':' : case ',': case ' ':
@@ -232,7 +247,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->toksuper != -1)
+ count++;
+ if (parser->toksuper != -1 && tokens != NULL)
tokens[parser->toksuper].size++;
break;
@@ -241,7 +257,6 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens,
default:
return JSMN_ERROR_INVAL;
#endif
-
}
}
@@ -252,7 +267,7 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens,
}
}
- return JSMN_SUCCESS;
+ return count;
}
/**