C-based memory friendly JSON parser based on Serge Zaitsev's JSMN (https://bitbucket.org/zserge/jsmn/wiki/Home)
Dependents: _library_jsmn _library_jsmn _library_jsmn
JSMN
jsmn (pronounced like 'jasmine') is a minimalistic JSON parser in C. It can be easily integrated into resource-limited or embedded projects.
You can find more information about JSON format at json.org
Library sources are available at https://bitbucket.org/zserge/jsmn
The web page with some information about jsmn can be found at http://zserge.com/jsmn.html
Diff: jsmn.cpp
- Revision:
- 1:70061827a9c8
- Parent:
- 0:46575249ef23
- Child:
- 2:5167da2fcc4e
--- a/jsmn.cpp Tue May 06 09:33:30 2014 +0000 +++ b/jsmn.cpp Mon Nov 17 15:54:28 2014 +0000 @@ -24,6 +24,7 @@ */ #include <stdlib.h> +#include "mbed.h" #include "jsmn.h" @@ -39,6 +40,7 @@ ) { jsmntok_t *tok; + if (parser->toknext >= num_tokens) { return NULL; @@ -102,6 +104,7 @@ if (js[parser->pos] < 32 || js[parser->pos] >= 127) { parser->pos = start; + printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos); return JSMN_ERR_INVAL; } } @@ -171,8 +174,9 @@ } /* Backslash: Quoted symbol expected */ - if (c == '\\') + if (c == '\\' && parser->pos + 1 < len) { + int i; parser->pos++; switch (js[parser->pos]) { @@ -190,14 +194,16 @@ /* Allows escaped symbol \uXXXX */ case 'u': parser->pos++; - int i = 0; - for (; i < 4 && js[parser->pos] != '\0'; i++) + for (i = 0; + i < 4 && parser->pos < len && js[parser->pos] != '\0'; + i++) { /* If it isn't a hex character we have an ERR */ if (!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */ (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */ (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */ parser->pos = start; + printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos); return JSMN_ERR_INVAL; } parser->pos++; @@ -208,6 +214,7 @@ /* Unexpected symbol */ default: parser->pos = start; + printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos); return JSMN_ERR_INVAL; } } @@ -270,16 +277,20 @@ type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); - if (parser->toknext < 1) + if (parser->toknext < 1) { + printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos); return JSMN_ERR_INVAL; + } token = &tokens[parser->toknext - 1]; for (;;) { if (token->start != -1 && token->end == -1) { - if (token->type != type) + if (token->type != type) { + printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos); return JSMN_ERR_INVAL; + } token->end = parser->pos + 1; parser->toksuper = token->parent; @@ -306,9 +317,20 @@ case '\t': case '\r': case '\n': + case ' ' : + break; + case ':' : + parser->toksuper = parser->toknext - 1; + break; + case ',' : - case ' ' : + if (tokens != NULL && + tokens[parser->toksuper].type != JSMN_ARRAY && + tokens[parser->toksuper].type != JSMN_OBJECT) + { + parser->toksuper = tokens[parser->toksuper].parent; + } break; case '-' : @@ -325,6 +347,17 @@ case 't' : case 'f' : case 'n' : + /* And they must not be keys of the object */ + if (tokens != NULL) + { + jsmntok_t *t = &tokens[parser->toksuper]; + if ( t->type == JSMN_OBJECT || + (t->type == JSMN_STRING && t->size != 0)) + { + printf("%s:%d: js[parser->pos]=%c\r\n", __FILE__, __LINE__, js[parser->pos]); + return JSMN_ERR_INVAL; + } + } r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); if (r < 0) return r; @@ -337,6 +370,7 @@ /* Unexpected char in strict mode */ default: + printf("%s:%d: js[parser->pos]=%c\r\n", __FILE__, __LINE__, js[parser->pos]); return JSMN_ERR_INVAL; } } @@ -365,6 +399,3 @@ parser->toknext = 0; parser->toksuper = -1; } - - -