Linija pogona

Dependents:   SERIALPARSER_copy

Committer:
mario_meh
Date:
Wed Nov 22 08:56:09 2017 +0000
Revision:
0:071c54c546de
Linija pogona

Who changed what in which revision?

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