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

Committer:
yoonghm
Date:
Mon Nov 17 16:09:04 2014 +0000
Revision:
2:5167da2fcc4e
Parent:
1:70061827a9c8
Updated copyright information.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yoonghm 0:46575249ef23 1 /* C-based low-memory footprint JSON parser for mbed
yoonghm 0:46575249ef23 2 * Based on Serge Zaitsev's JSMN https://bitbucket.org/zserge/jsmn/wiki/Home
yoonghm 0:46575249ef23 3 * JSMN is distributed under MIT license.
yoonghm 0:46575249ef23 4 *
yoonghm 2:5167da2fcc4e 5 * Copyright (c) 2010 Serge A. Zaitsev
yoonghm 0:46575249ef23 6 * Copyright (c) 2014 YoongHM
yoonghm 0:46575249ef23 7 *
yoonghm 0:46575249ef23 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
yoonghm 0:46575249ef23 9 * of this software and associated documentation files (the "Software"), to deal
yoonghm 0:46575249ef23 10 * in the Software without restriction, including without limitation the rights
yoonghm 0:46575249ef23 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
yoonghm 0:46575249ef23 12 * copies of the Software, and to permit persons to whom the Software is
yoonghm 0:46575249ef23 13 * furnished to do so, subject to the following conditions:
yoonghm 0:46575249ef23 14 *
yoonghm 0:46575249ef23 15 * The above copyright notice and this permission notice shall be included in
yoonghm 0:46575249ef23 16 * all copies or substantial portions of the Software.
yoonghm 0:46575249ef23 17 *
yoonghm 0:46575249ef23 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
yoonghm 0:46575249ef23 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
yoonghm 0:46575249ef23 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
yoonghm 0:46575249ef23 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
yoonghm 0:46575249ef23 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
yoonghm 0:46575249ef23 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
yoonghm 0:46575249ef23 24 * THE SOFTWARE.
yoonghm 0:46575249ef23 25 */
yoonghm 0:46575249ef23 26
yoonghm 0:46575249ef23 27 #include <stdlib.h>
yoonghm 1:70061827a9c8 28 #include "mbed.h"
yoonghm 0:46575249ef23 29
yoonghm 0:46575249ef23 30 #include "jsmn.h"
yoonghm 0:46575249ef23 31
yoonghm 0:46575249ef23 32
yoonghm 0:46575249ef23 33 /**
yoonghm 0:46575249ef23 34 * Allocates a fresh unused token from the token pull.
yoonghm 0:46575249ef23 35 */
yoonghm 0:46575249ef23 36 static jsmntok_t *
yoonghm 0:46575249ef23 37 jsmn_alloc_token
yoonghm 0:46575249ef23 38 (jsmn_parser *parser
yoonghm 0:46575249ef23 39 ,jsmntok_t *tokens
yoonghm 0:46575249ef23 40 ,size_t num_tokens
yoonghm 0:46575249ef23 41 )
yoonghm 0:46575249ef23 42 {
yoonghm 0:46575249ef23 43 jsmntok_t *tok;
yoonghm 1:70061827a9c8 44
yoonghm 0:46575249ef23 45 if (parser->toknext >= num_tokens)
yoonghm 0:46575249ef23 46 {
yoonghm 0:46575249ef23 47 return NULL;
yoonghm 0:46575249ef23 48 }
yoonghm 0:46575249ef23 49 tok = &tokens[parser->toknext++];
yoonghm 0:46575249ef23 50 tok->start = tok->end = -1;
yoonghm 0:46575249ef23 51 tok->size = 0;
yoonghm 0:46575249ef23 52 tok->parent = -1;
yoonghm 0:46575249ef23 53 return tok;
yoonghm 0:46575249ef23 54 }
yoonghm 0:46575249ef23 55
yoonghm 0:46575249ef23 56
yoonghm 0:46575249ef23 57 /**
yoonghm 0:46575249ef23 58 * Fills token type and boundaries.
yoonghm 0:46575249ef23 59 */
yoonghm 0:46575249ef23 60 static void
yoonghm 0:46575249ef23 61 jsmn_fill_token
yoonghm 0:46575249ef23 62 (jsmntok_t *token
yoonghm 0:46575249ef23 63 ,jsmntype_t type
yoonghm 0:46575249ef23 64 ,int start
yoonghm 0:46575249ef23 65 ,int end
yoonghm 0:46575249ef23 66 )
yoonghm 0:46575249ef23 67 {
yoonghm 0:46575249ef23 68 token->type = type;
yoonghm 0:46575249ef23 69 token->start = start;
yoonghm 0:46575249ef23 70 token->end = end;
yoonghm 0:46575249ef23 71 token->size = 0;
yoonghm 0:46575249ef23 72 }
yoonghm 0:46575249ef23 73
yoonghm 0:46575249ef23 74
yoonghm 0:46575249ef23 75 /**
yoonghm 0:46575249ef23 76 * Fills next available token with JSON primitive.
yoonghm 0:46575249ef23 77 */
yoonghm 0:46575249ef23 78 static int
yoonghm 0:46575249ef23 79 jsmn_parse_primitive
yoonghm 0:46575249ef23 80 (jsmn_parser *parser
yoonghm 0:46575249ef23 81 ,const char *js
yoonghm 0:46575249ef23 82 ,size_t len
yoonghm 0:46575249ef23 83 ,jsmntok_t *tokens
yoonghm 0:46575249ef23 84 ,size_t num_tokens
yoonghm 0:46575249ef23 85 )
yoonghm 0:46575249ef23 86 {
yoonghm 0:46575249ef23 87 jsmntok_t *token;
yoonghm 0:46575249ef23 88 int start;
yoonghm 0:46575249ef23 89
yoonghm 0:46575249ef23 90 start = parser->pos;
yoonghm 0:46575249ef23 91
yoonghm 0:46575249ef23 92 for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++)
yoonghm 0:46575249ef23 93 {
yoonghm 0:46575249ef23 94 switch (js[parser->pos])
yoonghm 0:46575249ef23 95 {
yoonghm 0:46575249ef23 96 case '\t':
yoonghm 0:46575249ef23 97 case '\r':
yoonghm 0:46575249ef23 98 case '\n':
yoonghm 0:46575249ef23 99 case ' ' :
yoonghm 0:46575249ef23 100 case ',' :
yoonghm 0:46575249ef23 101 case ']' :
yoonghm 0:46575249ef23 102 case '}' :
yoonghm 0:46575249ef23 103 goto found;
yoonghm 0:46575249ef23 104 }
yoonghm 0:46575249ef23 105 if (js[parser->pos] < 32 || js[parser->pos] >= 127)
yoonghm 0:46575249ef23 106 {
yoonghm 0:46575249ef23 107 parser->pos = start;
yoonghm 1:70061827a9c8 108 printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos);
yoonghm 0:46575249ef23 109 return JSMN_ERR_INVAL;
yoonghm 0:46575249ef23 110 }
yoonghm 0:46575249ef23 111 }
yoonghm 0:46575249ef23 112 parser->pos = start;
yoonghm 0:46575249ef23 113 return JSMN_ERR_PART;
yoonghm 0:46575249ef23 114
yoonghm 0:46575249ef23 115 found:
yoonghm 0:46575249ef23 116 if (tokens == NULL)
yoonghm 0:46575249ef23 117 {
yoonghm 0:46575249ef23 118 parser->pos--;
yoonghm 0:46575249ef23 119 return 0;
yoonghm 0:46575249ef23 120 }
yoonghm 0:46575249ef23 121
yoonghm 0:46575249ef23 122 token = jsmn_alloc_token(parser, tokens, num_tokens);
yoonghm 0:46575249ef23 123 if (token == NULL)
yoonghm 0:46575249ef23 124 {
yoonghm 0:46575249ef23 125 parser->pos = start;
yoonghm 0:46575249ef23 126 return JSMN_ERR_NOMEM;
yoonghm 0:46575249ef23 127 }
yoonghm 0:46575249ef23 128 jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
yoonghm 0:46575249ef23 129
yoonghm 0:46575249ef23 130 token->parent = parser->toksuper;
yoonghm 0:46575249ef23 131 parser->pos--;
yoonghm 0:46575249ef23 132
yoonghm 0:46575249ef23 133 return 0;
yoonghm 0:46575249ef23 134 }
yoonghm 0:46575249ef23 135
yoonghm 0:46575249ef23 136
yoonghm 0:46575249ef23 137 /**
yoonghm 0:46575249ef23 138 * Fill next token with JSON string.
yoonghm 0:46575249ef23 139 */
yoonghm 0:46575249ef23 140 static int
yoonghm 0:46575249ef23 141 jsmn_parse_string
yoonghm 0:46575249ef23 142 (jsmn_parser *parser
yoonghm 0:46575249ef23 143 ,const char *js
yoonghm 0:46575249ef23 144 ,size_t len
yoonghm 0:46575249ef23 145 ,jsmntok_t *tokens
yoonghm 0:46575249ef23 146 ,size_t num_tokens
yoonghm 0:46575249ef23 147 )
yoonghm 0:46575249ef23 148 {
yoonghm 0:46575249ef23 149 jsmntok_t *token;
yoonghm 0:46575249ef23 150 int start = parser->pos;
yoonghm 0:46575249ef23 151
yoonghm 0:46575249ef23 152 parser->pos++;
yoonghm 0:46575249ef23 153
yoonghm 0:46575249ef23 154 /* Skip starting quote */
yoonghm 0:46575249ef23 155 for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++)
yoonghm 0:46575249ef23 156 {
yoonghm 0:46575249ef23 157 char c = js[parser->pos];
yoonghm 0:46575249ef23 158
yoonghm 0:46575249ef23 159 /* Quote: end of string */
yoonghm 0:46575249ef23 160 if (c == '\"')
yoonghm 0:46575249ef23 161 {
yoonghm 0:46575249ef23 162 if (tokens == NULL)
yoonghm 0:46575249ef23 163 return 0;
yoonghm 0:46575249ef23 164
yoonghm 0:46575249ef23 165 token = jsmn_alloc_token(parser, tokens, num_tokens);
yoonghm 0:46575249ef23 166 if (token == NULL)
yoonghm 0:46575249ef23 167 {
yoonghm 0:46575249ef23 168 parser->pos = start;
yoonghm 0:46575249ef23 169 return JSMN_ERR_NOMEM;
yoonghm 0:46575249ef23 170 }
yoonghm 0:46575249ef23 171
yoonghm 0:46575249ef23 172 jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
yoonghm 0:46575249ef23 173 token->parent = parser->toksuper;
yoonghm 0:46575249ef23 174 return 0;
yoonghm 0:46575249ef23 175 }
yoonghm 0:46575249ef23 176
yoonghm 0:46575249ef23 177 /* Backslash: Quoted symbol expected */
yoonghm 1:70061827a9c8 178 if (c == '\\' && parser->pos + 1 < len)
yoonghm 0:46575249ef23 179 {
yoonghm 1:70061827a9c8 180 int i;
yoonghm 0:46575249ef23 181 parser->pos++;
yoonghm 0:46575249ef23 182 switch (js[parser->pos])
yoonghm 0:46575249ef23 183 {
yoonghm 0:46575249ef23 184 /* Allowed escaped symbols */
yoonghm 0:46575249ef23 185 case '\"':
yoonghm 0:46575249ef23 186 case '/' :
yoonghm 0:46575249ef23 187 case '\\':
yoonghm 0:46575249ef23 188 case 'b' :
yoonghm 0:46575249ef23 189 case 'f' :
yoonghm 0:46575249ef23 190 case 'r' :
yoonghm 0:46575249ef23 191 case 'n' :
yoonghm 0:46575249ef23 192 case 't' :
yoonghm 0:46575249ef23 193 break;
yoonghm 0:46575249ef23 194
yoonghm 0:46575249ef23 195 /* Allows escaped symbol \uXXXX */
yoonghm 0:46575249ef23 196 case 'u':
yoonghm 0:46575249ef23 197 parser->pos++;
yoonghm 1:70061827a9c8 198 for (i = 0;
yoonghm 1:70061827a9c8 199 i < 4 && parser->pos < len && js[parser->pos] != '\0';
yoonghm 1:70061827a9c8 200 i++)
yoonghm 0:46575249ef23 201 {
yoonghm 0:46575249ef23 202 /* If it isn't a hex character we have an ERR */
yoonghm 0:46575249ef23 203 if (!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
yoonghm 0:46575249ef23 204 (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
yoonghm 0:46575249ef23 205 (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
yoonghm 0:46575249ef23 206 parser->pos = start;
yoonghm 1:70061827a9c8 207 printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos);
yoonghm 0:46575249ef23 208 return JSMN_ERR_INVAL;
yoonghm 0:46575249ef23 209 }
yoonghm 0:46575249ef23 210 parser->pos++;
yoonghm 0:46575249ef23 211 }
yoonghm 0:46575249ef23 212 parser->pos--;
yoonghm 0:46575249ef23 213 break;
yoonghm 0:46575249ef23 214
yoonghm 0:46575249ef23 215 /* Unexpected symbol */
yoonghm 0:46575249ef23 216 default:
yoonghm 0:46575249ef23 217 parser->pos = start;
yoonghm 1:70061827a9c8 218 printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos);
yoonghm 0:46575249ef23 219 return JSMN_ERR_INVAL;
yoonghm 0:46575249ef23 220 }
yoonghm 0:46575249ef23 221 }
yoonghm 0:46575249ef23 222 }
yoonghm 0:46575249ef23 223 parser->pos = start;
yoonghm 0:46575249ef23 224 return JSMN_ERR_PART;
yoonghm 0:46575249ef23 225 }
yoonghm 0:46575249ef23 226
yoonghm 0:46575249ef23 227
yoonghm 0:46575249ef23 228 /**
yoonghm 0:46575249ef23 229 * Parse JSON string and fill tokens.
yoonghm 0:46575249ef23 230 */
yoonghm 0:46575249ef23 231 int
yoonghm 0:46575249ef23 232 jsmn_parse
yoonghm 0:46575249ef23 233 (jsmn_parser *parser
yoonghm 0:46575249ef23 234 ,const char *js
yoonghm 0:46575249ef23 235 ,size_t len
yoonghm 0:46575249ef23 236 ,jsmntok_t *tokens
yoonghm 0:46575249ef23 237 ,unsigned int num_tokens
yoonghm 0:46575249ef23 238 )
yoonghm 0:46575249ef23 239 {
yoonghm 0:46575249ef23 240 int r;
yoonghm 0:46575249ef23 241 int i;
yoonghm 0:46575249ef23 242 jsmntok_t *token;
yoonghm 0:46575249ef23 243 int count = 0;
yoonghm 0:46575249ef23 244
yoonghm 0:46575249ef23 245 for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++)
yoonghm 0:46575249ef23 246 {
yoonghm 0:46575249ef23 247 char c;
yoonghm 0:46575249ef23 248 jsmntype_t type = JSMN_INVALID;
yoonghm 0:46575249ef23 249
yoonghm 0:46575249ef23 250 c = js[parser->pos];
yoonghm 0:46575249ef23 251 switch (c)
yoonghm 0:46575249ef23 252 {
yoonghm 0:46575249ef23 253 case '{' :
yoonghm 0:46575249ef23 254 case '[' :
yoonghm 0:46575249ef23 255 count++;
yoonghm 0:46575249ef23 256 if (tokens == NULL)
yoonghm 0:46575249ef23 257 break;
yoonghm 0:46575249ef23 258
yoonghm 0:46575249ef23 259 token = jsmn_alloc_token(parser, tokens, num_tokens);
yoonghm 0:46575249ef23 260
yoonghm 0:46575249ef23 261 if (token == NULL)
yoonghm 0:46575249ef23 262 return JSMN_ERR_NOMEM;
yoonghm 0:46575249ef23 263
yoonghm 0:46575249ef23 264 if (parser->toksuper != -1)
yoonghm 0:46575249ef23 265 {
yoonghm 0:46575249ef23 266 tokens[parser->toksuper].size++;
yoonghm 0:46575249ef23 267 token->parent = parser->toksuper;
yoonghm 0:46575249ef23 268 }
yoonghm 0:46575249ef23 269 token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
yoonghm 0:46575249ef23 270 token->start = parser->pos;
yoonghm 0:46575249ef23 271 parser->toksuper = parser->toknext - 1;
yoonghm 0:46575249ef23 272 break;
yoonghm 0:46575249ef23 273
yoonghm 0:46575249ef23 274 case '}':
yoonghm 0:46575249ef23 275 case ']':
yoonghm 0:46575249ef23 276 if (tokens == NULL)
yoonghm 0:46575249ef23 277 break;
yoonghm 0:46575249ef23 278
yoonghm 0:46575249ef23 279 type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
yoonghm 0:46575249ef23 280
yoonghm 1:70061827a9c8 281 if (parser->toknext < 1) {
yoonghm 1:70061827a9c8 282 printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos);
yoonghm 0:46575249ef23 283 return JSMN_ERR_INVAL;
yoonghm 1:70061827a9c8 284 }
yoonghm 0:46575249ef23 285
yoonghm 0:46575249ef23 286 token = &tokens[parser->toknext - 1];
yoonghm 0:46575249ef23 287 for (;;)
yoonghm 0:46575249ef23 288 {
yoonghm 0:46575249ef23 289 if (token->start != -1 && token->end == -1)
yoonghm 0:46575249ef23 290 {
yoonghm 1:70061827a9c8 291 if (token->type != type) {
yoonghm 1:70061827a9c8 292 printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos);
yoonghm 0:46575249ef23 293 return JSMN_ERR_INVAL;
yoonghm 1:70061827a9c8 294 }
yoonghm 0:46575249ef23 295
yoonghm 0:46575249ef23 296 token->end = parser->pos + 1;
yoonghm 0:46575249ef23 297 parser->toksuper = token->parent;
yoonghm 0:46575249ef23 298 break;
yoonghm 0:46575249ef23 299 }
yoonghm 0:46575249ef23 300
yoonghm 0:46575249ef23 301 if (token->parent == -1)
yoonghm 0:46575249ef23 302 break;
yoonghm 0:46575249ef23 303
yoonghm 0:46575249ef23 304 token = &tokens[token->parent];
yoonghm 0:46575249ef23 305 }
yoonghm 0:46575249ef23 306 break;
yoonghm 0:46575249ef23 307
yoonghm 0:46575249ef23 308 case '\"':
yoonghm 0:46575249ef23 309 r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
yoonghm 0:46575249ef23 310 if (r < 0)
yoonghm 0:46575249ef23 311 return r;
yoonghm 0:46575249ef23 312
yoonghm 0:46575249ef23 313 count++;
yoonghm 0:46575249ef23 314 if (parser->toksuper != -1 && tokens != NULL)
yoonghm 0:46575249ef23 315 tokens[parser->toksuper].size++;
yoonghm 0:46575249ef23 316 break;
yoonghm 0:46575249ef23 317
yoonghm 0:46575249ef23 318 case '\t':
yoonghm 0:46575249ef23 319 case '\r':
yoonghm 0:46575249ef23 320 case '\n':
yoonghm 1:70061827a9c8 321 case ' ' :
yoonghm 1:70061827a9c8 322 break;
yoonghm 1:70061827a9c8 323
yoonghm 0:46575249ef23 324 case ':' :
yoonghm 1:70061827a9c8 325 parser->toksuper = parser->toknext - 1;
yoonghm 1:70061827a9c8 326 break;
yoonghm 1:70061827a9c8 327
yoonghm 0:46575249ef23 328 case ',' :
yoonghm 1:70061827a9c8 329 if (tokens != NULL &&
yoonghm 1:70061827a9c8 330 tokens[parser->toksuper].type != JSMN_ARRAY &&
yoonghm 1:70061827a9c8 331 tokens[parser->toksuper].type != JSMN_OBJECT)
yoonghm 1:70061827a9c8 332 {
yoonghm 1:70061827a9c8 333 parser->toksuper = tokens[parser->toksuper].parent;
yoonghm 1:70061827a9c8 334 }
yoonghm 0:46575249ef23 335 break;
yoonghm 0:46575249ef23 336
yoonghm 0:46575249ef23 337 case '-' :
yoonghm 0:46575249ef23 338 case '0' :
yoonghm 0:46575249ef23 339 case '1' :
yoonghm 0:46575249ef23 340 case '2' :
yoonghm 0:46575249ef23 341 case '3' :
yoonghm 0:46575249ef23 342 case '4' :
yoonghm 0:46575249ef23 343 case '5' :
yoonghm 0:46575249ef23 344 case '6' :
yoonghm 0:46575249ef23 345 case '7' :
yoonghm 0:46575249ef23 346 case '8' :
yoonghm 0:46575249ef23 347 case '9' :
yoonghm 0:46575249ef23 348 case 't' :
yoonghm 0:46575249ef23 349 case 'f' :
yoonghm 0:46575249ef23 350 case 'n' :
yoonghm 1:70061827a9c8 351 /* And they must not be keys of the object */
yoonghm 1:70061827a9c8 352 if (tokens != NULL)
yoonghm 1:70061827a9c8 353 {
yoonghm 1:70061827a9c8 354 jsmntok_t *t = &tokens[parser->toksuper];
yoonghm 1:70061827a9c8 355 if ( t->type == JSMN_OBJECT ||
yoonghm 1:70061827a9c8 356 (t->type == JSMN_STRING && t->size != 0))
yoonghm 1:70061827a9c8 357 {
yoonghm 1:70061827a9c8 358 printf("%s:%d: js[parser->pos]=%c\r\n", __FILE__, __LINE__, js[parser->pos]);
yoonghm 1:70061827a9c8 359 return JSMN_ERR_INVAL;
yoonghm 1:70061827a9c8 360 }
yoonghm 1:70061827a9c8 361 }
yoonghm 0:46575249ef23 362 r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
yoonghm 0:46575249ef23 363 if (r < 0)
yoonghm 0:46575249ef23 364 return r;
yoonghm 0:46575249ef23 365
yoonghm 0:46575249ef23 366 count++;
yoonghm 0:46575249ef23 367
yoonghm 0:46575249ef23 368 if (parser->toksuper != -1 && tokens != NULL)
yoonghm 0:46575249ef23 369 tokens[parser->toksuper].size++;
yoonghm 0:46575249ef23 370 break;
yoonghm 0:46575249ef23 371
yoonghm 0:46575249ef23 372 /* Unexpected char in strict mode */
yoonghm 0:46575249ef23 373 default:
yoonghm 1:70061827a9c8 374 printf("%s:%d: js[parser->pos]=%c\r\n", __FILE__, __LINE__, js[parser->pos]);
yoonghm 0:46575249ef23 375 return JSMN_ERR_INVAL;
yoonghm 0:46575249ef23 376 }
yoonghm 0:46575249ef23 377 }
yoonghm 0:46575249ef23 378
yoonghm 0:46575249ef23 379 for (i = parser->toknext - 1; i >= 0; i--)
yoonghm 0:46575249ef23 380 {
yoonghm 0:46575249ef23 381 /* Unmatched opened object or array */
yoonghm 0:46575249ef23 382 if (tokens[i].start != -1 && tokens[i].end == -1)
yoonghm 0:46575249ef23 383 {
yoonghm 0:46575249ef23 384 return JSMN_ERR_PART;
yoonghm 0:46575249ef23 385 }
yoonghm 0:46575249ef23 386 }
yoonghm 0:46575249ef23 387
yoonghm 0:46575249ef23 388 return count;
yoonghm 0:46575249ef23 389 }
yoonghm 0:46575249ef23 390
yoonghm 0:46575249ef23 391 /**
yoonghm 0:46575249ef23 392 * Creates a new parser based over a given buffer with an array of tokens
yoonghm 0:46575249ef23 393 * available.
yoonghm 0:46575249ef23 394 */
yoonghm 0:46575249ef23 395 void
yoonghm 0:46575249ef23 396 jsmn_init
yoonghm 0:46575249ef23 397 (jsmn_parser *parser)
yoonghm 0:46575249ef23 398 {
yoonghm 0:46575249ef23 399 parser->pos = 0;
yoonghm 0:46575249ef23 400 parser->toknext = 0;
yoonghm 0:46575249ef23 401 parser->toksuper = -1;
yoonghm 0:46575249ef23 402 }