Jim Flynn
/
aws-iot-device-sdk-mbed-c
Changes to enabled on-line compiler
external_libs/jsmn.c@0:082731ede69f, 2018-05-30 (annotated)
- Committer:
- JMF
- Date:
- Wed May 30 20:59:51 2018 +0000
- Revision:
- 0:082731ede69f
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JMF | 0:082731ede69f | 1 | /* |
JMF | 0:082731ede69f | 2 | * Copyright (c) 2010 Serge A. Zaitsev |
JMF | 0:082731ede69f | 3 | * |
JMF | 0:082731ede69f | 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
JMF | 0:082731ede69f | 5 | * of this software and associated documentation files (the "Software"), to deal |
JMF | 0:082731ede69f | 6 | * in the Software without restriction, including without limitation the rights |
JMF | 0:082731ede69f | 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
JMF | 0:082731ede69f | 8 | * copies of the Software, and to permit persons to whom the Software is |
JMF | 0:082731ede69f | 9 | * furnished to do so, subject to the following conditions: |
JMF | 0:082731ede69f | 10 | * |
JMF | 0:082731ede69f | 11 | * The above copyright notice and this permission notice shall be included in |
JMF | 0:082731ede69f | 12 | * all copies or substantial portions of the Software. |
JMF | 0:082731ede69f | 13 | * |
JMF | 0:082731ede69f | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
JMF | 0:082731ede69f | 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
JMF | 0:082731ede69f | 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
JMF | 0:082731ede69f | 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
JMF | 0:082731ede69f | 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
JMF | 0:082731ede69f | 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
JMF | 0:082731ede69f | 20 | * THE SOFTWARE. |
JMF | 0:082731ede69f | 21 | */ |
JMF | 0:082731ede69f | 22 | |
JMF | 0:082731ede69f | 23 | /** |
JMF | 0:082731ede69f | 24 | * @file jsmn.c |
JMF | 0:082731ede69f | 25 | * @brief Implementation of the JSMN (Jasmine) JSON parser. |
JMF | 0:082731ede69f | 26 | * |
JMF | 0:082731ede69f | 27 | * For more information on JSMN: |
JMF | 0:082731ede69f | 28 | * @see http://zserge.com/jsmn.html |
JMF | 0:082731ede69f | 29 | */ |
JMF | 0:082731ede69f | 30 | |
JMF | 0:082731ede69f | 31 | #include "jsmn.h" |
JMF | 0:082731ede69f | 32 | |
JMF | 0:082731ede69f | 33 | /** |
JMF | 0:082731ede69f | 34 | * Allocates a fresh unused token from the token pull. |
JMF | 0:082731ede69f | 35 | */ |
JMF | 0:082731ede69f | 36 | static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, |
JMF | 0:082731ede69f | 37 | jsmntok_t *tokens, size_t num_tokens) { |
JMF | 0:082731ede69f | 38 | jsmntok_t *tok; |
JMF | 0:082731ede69f | 39 | if (parser->toknext >= num_tokens) { |
JMF | 0:082731ede69f | 40 | return NULL; |
JMF | 0:082731ede69f | 41 | } |
JMF | 0:082731ede69f | 42 | tok = &tokens[parser->toknext++]; |
JMF | 0:082731ede69f | 43 | tok->start = tok->end = -1; |
JMF | 0:082731ede69f | 44 | tok->size = 0; |
JMF | 0:082731ede69f | 45 | #ifdef JSMN_PARENT_LINKS |
JMF | 0:082731ede69f | 46 | tok->parent = -1; |
JMF | 0:082731ede69f | 47 | #endif |
JMF | 0:082731ede69f | 48 | return tok; |
JMF | 0:082731ede69f | 49 | } |
JMF | 0:082731ede69f | 50 | |
JMF | 0:082731ede69f | 51 | /** |
JMF | 0:082731ede69f | 52 | * Fills token type and boundaries. |
JMF | 0:082731ede69f | 53 | */ |
JMF | 0:082731ede69f | 54 | static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type, |
JMF | 0:082731ede69f | 55 | int start, int end) { |
JMF | 0:082731ede69f | 56 | token->type = type; |
JMF | 0:082731ede69f | 57 | token->start = start; |
JMF | 0:082731ede69f | 58 | token->end = end; |
JMF | 0:082731ede69f | 59 | token->size = 0; |
JMF | 0:082731ede69f | 60 | } |
JMF | 0:082731ede69f | 61 | |
JMF | 0:082731ede69f | 62 | /** |
JMF | 0:082731ede69f | 63 | * Fills next available token with JSON primitive. |
JMF | 0:082731ede69f | 64 | */ |
JMF | 0:082731ede69f | 65 | static int jsmn_parse_primitive(jsmn_parser *parser, const char *js, |
JMF | 0:082731ede69f | 66 | size_t len, jsmntok_t *tokens, size_t num_tokens) { |
JMF | 0:082731ede69f | 67 | jsmntok_t *token; |
JMF | 0:082731ede69f | 68 | int start; |
JMF | 0:082731ede69f | 69 | |
JMF | 0:082731ede69f | 70 | start = parser->pos; |
JMF | 0:082731ede69f | 71 | |
JMF | 0:082731ede69f | 72 | for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { |
JMF | 0:082731ede69f | 73 | switch (js[parser->pos]) { |
JMF | 0:082731ede69f | 74 | #ifndef JSMN_STRICT |
JMF | 0:082731ede69f | 75 | /* In strict mode primitive must be followed by "," or "}" or "]" */ |
JMF | 0:082731ede69f | 76 | case ':': |
JMF | 0:082731ede69f | 77 | #endif |
JMF | 0:082731ede69f | 78 | case '\t' : case '\r' : case '\n' : case ' ' : |
JMF | 0:082731ede69f | 79 | case ',' : case ']' : case '}' : |
JMF | 0:082731ede69f | 80 | goto found; |
JMF | 0:082731ede69f | 81 | } |
JMF | 0:082731ede69f | 82 | if (js[parser->pos] < 32 || js[parser->pos] >= 127) { |
JMF | 0:082731ede69f | 83 | parser->pos = start; |
JMF | 0:082731ede69f | 84 | return JSMN_ERROR_INVAL; |
JMF | 0:082731ede69f | 85 | } |
JMF | 0:082731ede69f | 86 | } |
JMF | 0:082731ede69f | 87 | #ifdef JSMN_STRICT |
JMF | 0:082731ede69f | 88 | /* In strict mode primitive must be followed by a comma/object/array */ |
JMF | 0:082731ede69f | 89 | parser->pos = start; |
JMF | 0:082731ede69f | 90 | return JSMN_ERROR_PART; |
JMF | 0:082731ede69f | 91 | #endif |
JMF | 0:082731ede69f | 92 | |
JMF | 0:082731ede69f | 93 | found: |
JMF | 0:082731ede69f | 94 | if (tokens == NULL) { |
JMF | 0:082731ede69f | 95 | parser->pos--; |
JMF | 0:082731ede69f | 96 | return 0; |
JMF | 0:082731ede69f | 97 | } |
JMF | 0:082731ede69f | 98 | token = jsmn_alloc_token(parser, tokens, num_tokens); |
JMF | 0:082731ede69f | 99 | if (token == NULL) { |
JMF | 0:082731ede69f | 100 | parser->pos = start; |
JMF | 0:082731ede69f | 101 | return JSMN_ERROR_NOMEM; |
JMF | 0:082731ede69f | 102 | } |
JMF | 0:082731ede69f | 103 | jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); |
JMF | 0:082731ede69f | 104 | #ifdef JSMN_PARENT_LINKS |
JMF | 0:082731ede69f | 105 | token->parent = parser->toksuper; |
JMF | 0:082731ede69f | 106 | #endif |
JMF | 0:082731ede69f | 107 | parser->pos--; |
JMF | 0:082731ede69f | 108 | return 0; |
JMF | 0:082731ede69f | 109 | } |
JMF | 0:082731ede69f | 110 | |
JMF | 0:082731ede69f | 111 | /** |
JMF | 0:082731ede69f | 112 | * Fills next token with JSON string. |
JMF | 0:082731ede69f | 113 | */ |
JMF | 0:082731ede69f | 114 | static int jsmn_parse_string(jsmn_parser *parser, const char *js, |
JMF | 0:082731ede69f | 115 | size_t len, jsmntok_t *tokens, size_t num_tokens) { |
JMF | 0:082731ede69f | 116 | jsmntok_t *token; |
JMF | 0:082731ede69f | 117 | |
JMF | 0:082731ede69f | 118 | int start = parser->pos; |
JMF | 0:082731ede69f | 119 | |
JMF | 0:082731ede69f | 120 | parser->pos++; |
JMF | 0:082731ede69f | 121 | |
JMF | 0:082731ede69f | 122 | /* Skip starting quote */ |
JMF | 0:082731ede69f | 123 | for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { |
JMF | 0:082731ede69f | 124 | char c = js[parser->pos]; |
JMF | 0:082731ede69f | 125 | |
JMF | 0:082731ede69f | 126 | /* Quote: end of string */ |
JMF | 0:082731ede69f | 127 | if (c == '\"') { |
JMF | 0:082731ede69f | 128 | if (tokens == NULL) { |
JMF | 0:082731ede69f | 129 | return 0; |
JMF | 0:082731ede69f | 130 | } |
JMF | 0:082731ede69f | 131 | token = jsmn_alloc_token(parser, tokens, num_tokens); |
JMF | 0:082731ede69f | 132 | if (token == NULL) { |
JMF | 0:082731ede69f | 133 | parser->pos = start; |
JMF | 0:082731ede69f | 134 | return JSMN_ERROR_NOMEM; |
JMF | 0:082731ede69f | 135 | } |
JMF | 0:082731ede69f | 136 | jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos); |
JMF | 0:082731ede69f | 137 | #ifdef JSMN_PARENT_LINKS |
JMF | 0:082731ede69f | 138 | token->parent = parser->toksuper; |
JMF | 0:082731ede69f | 139 | #endif |
JMF | 0:082731ede69f | 140 | return 0; |
JMF | 0:082731ede69f | 141 | } |
JMF | 0:082731ede69f | 142 | |
JMF | 0:082731ede69f | 143 | /* Backslash: Quoted symbol expected */ |
JMF | 0:082731ede69f | 144 | if (c == '\\' && parser->pos + 1 < len) { |
JMF | 0:082731ede69f | 145 | int i; |
JMF | 0:082731ede69f | 146 | parser->pos++; |
JMF | 0:082731ede69f | 147 | switch (js[parser->pos]) { |
JMF | 0:082731ede69f | 148 | /* Allowed escaped symbols */ |
JMF | 0:082731ede69f | 149 | case '\"': case '/' : case '\\' : case 'b' : |
JMF | 0:082731ede69f | 150 | case 'f' : case 'r' : case 'n' : case 't' : |
JMF | 0:082731ede69f | 151 | break; |
JMF | 0:082731ede69f | 152 | /* Allows escaped symbol \uXXXX */ |
JMF | 0:082731ede69f | 153 | case 'u': |
JMF | 0:082731ede69f | 154 | parser->pos++; |
JMF | 0:082731ede69f | 155 | for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) { |
JMF | 0:082731ede69f | 156 | /* If it isn't a hex character we have an error */ |
JMF | 0:082731ede69f | 157 | if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */ |
JMF | 0:082731ede69f | 158 | (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */ |
JMF | 0:082731ede69f | 159 | (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */ |
JMF | 0:082731ede69f | 160 | parser->pos = start; |
JMF | 0:082731ede69f | 161 | return JSMN_ERROR_INVAL; |
JMF | 0:082731ede69f | 162 | } |
JMF | 0:082731ede69f | 163 | parser->pos++; |
JMF | 0:082731ede69f | 164 | } |
JMF | 0:082731ede69f | 165 | parser->pos--; |
JMF | 0:082731ede69f | 166 | break; |
JMF | 0:082731ede69f | 167 | /* Unexpected symbol */ |
JMF | 0:082731ede69f | 168 | default: |
JMF | 0:082731ede69f | 169 | parser->pos = start; |
JMF | 0:082731ede69f | 170 | return JSMN_ERROR_INVAL; |
JMF | 0:082731ede69f | 171 | } |
JMF | 0:082731ede69f | 172 | } |
JMF | 0:082731ede69f | 173 | } |
JMF | 0:082731ede69f | 174 | parser->pos = start; |
JMF | 0:082731ede69f | 175 | return JSMN_ERROR_PART; |
JMF | 0:082731ede69f | 176 | } |
JMF | 0:082731ede69f | 177 | |
JMF | 0:082731ede69f | 178 | /** |
JMF | 0:082731ede69f | 179 | * Parse JSON string and fill tokens. |
JMF | 0:082731ede69f | 180 | */ |
JMF | 0:082731ede69f | 181 | int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, |
JMF | 0:082731ede69f | 182 | jsmntok_t *tokens, unsigned int num_tokens) { |
JMF | 0:082731ede69f | 183 | int r; |
JMF | 0:082731ede69f | 184 | int i; |
JMF | 0:082731ede69f | 185 | jsmntok_t *token; |
JMF | 0:082731ede69f | 186 | int count = parser->toknext; |
JMF | 0:082731ede69f | 187 | |
JMF | 0:082731ede69f | 188 | for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { |
JMF | 0:082731ede69f | 189 | char c; |
JMF | 0:082731ede69f | 190 | jsmntype_t type; |
JMF | 0:082731ede69f | 191 | |
JMF | 0:082731ede69f | 192 | c = js[parser->pos]; |
JMF | 0:082731ede69f | 193 | switch (c) { |
JMF | 0:082731ede69f | 194 | case '{': case '[': |
JMF | 0:082731ede69f | 195 | count++; |
JMF | 0:082731ede69f | 196 | if (tokens == NULL) { |
JMF | 0:082731ede69f | 197 | break; |
JMF | 0:082731ede69f | 198 | } |
JMF | 0:082731ede69f | 199 | token = jsmn_alloc_token(parser, tokens, num_tokens); |
JMF | 0:082731ede69f | 200 | if (token == NULL) |
JMF | 0:082731ede69f | 201 | return JSMN_ERROR_NOMEM; |
JMF | 0:082731ede69f | 202 | if (parser->toksuper != -1) { |
JMF | 0:082731ede69f | 203 | tokens[parser->toksuper].size++; |
JMF | 0:082731ede69f | 204 | #ifdef JSMN_PARENT_LINKS |
JMF | 0:082731ede69f | 205 | token->parent = parser->toksuper; |
JMF | 0:082731ede69f | 206 | #endif |
JMF | 0:082731ede69f | 207 | } |
JMF | 0:082731ede69f | 208 | token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); |
JMF | 0:082731ede69f | 209 | token->start = parser->pos; |
JMF | 0:082731ede69f | 210 | parser->toksuper = parser->toknext - 1; |
JMF | 0:082731ede69f | 211 | break; |
JMF | 0:082731ede69f | 212 | case '}': case ']': |
JMF | 0:082731ede69f | 213 | if (tokens == NULL) |
JMF | 0:082731ede69f | 214 | break; |
JMF | 0:082731ede69f | 215 | type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); |
JMF | 0:082731ede69f | 216 | #ifdef JSMN_PARENT_LINKS |
JMF | 0:082731ede69f | 217 | if (parser->toknext < 1) { |
JMF | 0:082731ede69f | 218 | return JSMN_ERROR_INVAL; |
JMF | 0:082731ede69f | 219 | } |
JMF | 0:082731ede69f | 220 | token = &tokens[parser->toknext - 1]; |
JMF | 0:082731ede69f | 221 | for (;;) { |
JMF | 0:082731ede69f | 222 | if (token->start != -1 && token->end == -1) { |
JMF | 0:082731ede69f | 223 | if (token->type != type) { |
JMF | 0:082731ede69f | 224 | return JSMN_ERROR_INVAL; |
JMF | 0:082731ede69f | 225 | } |
JMF | 0:082731ede69f | 226 | token->end = parser->pos + 1; |
JMF | 0:082731ede69f | 227 | parser->toksuper = token->parent; |
JMF | 0:082731ede69f | 228 | break; |
JMF | 0:082731ede69f | 229 | } |
JMF | 0:082731ede69f | 230 | if (token->parent == -1) { |
JMF | 0:082731ede69f | 231 | if(token->type != type || parser->toksuper == -1) { |
JMF | 0:082731ede69f | 232 | return JSMN_ERROR_INVAL; |
JMF | 0:082731ede69f | 233 | } |
JMF | 0:082731ede69f | 234 | break; |
JMF | 0:082731ede69f | 235 | } |
JMF | 0:082731ede69f | 236 | token = &tokens[token->parent]; |
JMF | 0:082731ede69f | 237 | } |
JMF | 0:082731ede69f | 238 | #else |
JMF | 0:082731ede69f | 239 | for (i = parser->toknext - 1; i >= 0; i--) { |
JMF | 0:082731ede69f | 240 | token = &tokens[i]; |
JMF | 0:082731ede69f | 241 | if (token->start != -1 && token->end == -1) { |
JMF | 0:082731ede69f | 242 | if (token->type != type) { |
JMF | 0:082731ede69f | 243 | return JSMN_ERROR_INVAL; |
JMF | 0:082731ede69f | 244 | } |
JMF | 0:082731ede69f | 245 | parser->toksuper = -1; |
JMF | 0:082731ede69f | 246 | token->end = parser->pos + 1; |
JMF | 0:082731ede69f | 247 | break; |
JMF | 0:082731ede69f | 248 | } |
JMF | 0:082731ede69f | 249 | } |
JMF | 0:082731ede69f | 250 | /* Error if unmatched closing bracket */ |
JMF | 0:082731ede69f | 251 | if (i == -1) return JSMN_ERROR_INVAL; |
JMF | 0:082731ede69f | 252 | for (; i >= 0; i--) { |
JMF | 0:082731ede69f | 253 | token = &tokens[i]; |
JMF | 0:082731ede69f | 254 | if (token->start != -1 && token->end == -1) { |
JMF | 0:082731ede69f | 255 | parser->toksuper = i; |
JMF | 0:082731ede69f | 256 | break; |
JMF | 0:082731ede69f | 257 | } |
JMF | 0:082731ede69f | 258 | } |
JMF | 0:082731ede69f | 259 | #endif |
JMF | 0:082731ede69f | 260 | break; |
JMF | 0:082731ede69f | 261 | case '\"': |
JMF | 0:082731ede69f | 262 | r = jsmn_parse_string(parser, js, len, tokens, num_tokens); |
JMF | 0:082731ede69f | 263 | if (r < 0) return r; |
JMF | 0:082731ede69f | 264 | count++; |
JMF | 0:082731ede69f | 265 | if (parser->toksuper != -1 && tokens != NULL) |
JMF | 0:082731ede69f | 266 | tokens[parser->toksuper].size++; |
JMF | 0:082731ede69f | 267 | break; |
JMF | 0:082731ede69f | 268 | case '\t' : case '\r' : case '\n' : case ' ': |
JMF | 0:082731ede69f | 269 | break; |
JMF | 0:082731ede69f | 270 | case ':': |
JMF | 0:082731ede69f | 271 | parser->toksuper = parser->toknext - 1; |
JMF | 0:082731ede69f | 272 | break; |
JMF | 0:082731ede69f | 273 | case ',': |
JMF | 0:082731ede69f | 274 | if (tokens != NULL && parser->toksuper != -1 && |
JMF | 0:082731ede69f | 275 | tokens[parser->toksuper].type != JSMN_ARRAY && |
JMF | 0:082731ede69f | 276 | tokens[parser->toksuper].type != JSMN_OBJECT) { |
JMF | 0:082731ede69f | 277 | #ifdef JSMN_PARENT_LINKS |
JMF | 0:082731ede69f | 278 | parser->toksuper = tokens[parser->toksuper].parent; |
JMF | 0:082731ede69f | 279 | #else |
JMF | 0:082731ede69f | 280 | for (i = parser->toknext - 1; i >= 0; i--) { |
JMF | 0:082731ede69f | 281 | if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) { |
JMF | 0:082731ede69f | 282 | if (tokens[i].start != -1 && tokens[i].end == -1) { |
JMF | 0:082731ede69f | 283 | parser->toksuper = i; |
JMF | 0:082731ede69f | 284 | break; |
JMF | 0:082731ede69f | 285 | } |
JMF | 0:082731ede69f | 286 | } |
JMF | 0:082731ede69f | 287 | } |
JMF | 0:082731ede69f | 288 | #endif |
JMF | 0:082731ede69f | 289 | } |
JMF | 0:082731ede69f | 290 | break; |
JMF | 0:082731ede69f | 291 | #ifdef JSMN_STRICT |
JMF | 0:082731ede69f | 292 | /* In strict mode primitives are: numbers and booleans */ |
JMF | 0:082731ede69f | 293 | case '-': case '0': case '1' : case '2': case '3' : case '4': |
JMF | 0:082731ede69f | 294 | case '5': case '6': case '7' : case '8': case '9': |
JMF | 0:082731ede69f | 295 | case 't': case 'f': case 'n' : |
JMF | 0:082731ede69f | 296 | /* And they must not be keys of the object */ |
JMF | 0:082731ede69f | 297 | if (tokens != NULL && parser->toksuper != -1) { |
JMF | 0:082731ede69f | 298 | jsmntok_t *t = &tokens[parser->toksuper]; |
JMF | 0:082731ede69f | 299 | if (t->type == JSMN_OBJECT || |
JMF | 0:082731ede69f | 300 | (t->type == JSMN_STRING && t->size != 0)) { |
JMF | 0:082731ede69f | 301 | return JSMN_ERROR_INVAL; |
JMF | 0:082731ede69f | 302 | } |
JMF | 0:082731ede69f | 303 | } |
JMF | 0:082731ede69f | 304 | #else |
JMF | 0:082731ede69f | 305 | /* In non-strict mode every unquoted value is a primitive */ |
JMF | 0:082731ede69f | 306 | default: |
JMF | 0:082731ede69f | 307 | #endif |
JMF | 0:082731ede69f | 308 | r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); |
JMF | 0:082731ede69f | 309 | if (r < 0) return r; |
JMF | 0:082731ede69f | 310 | count++; |
JMF | 0:082731ede69f | 311 | if (parser->toksuper != -1 && tokens != NULL) |
JMF | 0:082731ede69f | 312 | tokens[parser->toksuper].size++; |
JMF | 0:082731ede69f | 313 | break; |
JMF | 0:082731ede69f | 314 | |
JMF | 0:082731ede69f | 315 | #ifdef JSMN_STRICT |
JMF | 0:082731ede69f | 316 | /* Unexpected char in strict mode */ |
JMF | 0:082731ede69f | 317 | default: |
JMF | 0:082731ede69f | 318 | return JSMN_ERROR_INVAL; |
JMF | 0:082731ede69f | 319 | #endif |
JMF | 0:082731ede69f | 320 | } |
JMF | 0:082731ede69f | 321 | } |
JMF | 0:082731ede69f | 322 | |
JMF | 0:082731ede69f | 323 | if (tokens != NULL) { |
JMF | 0:082731ede69f | 324 | for (i = parser->toknext - 1; i >= 0; i--) { |
JMF | 0:082731ede69f | 325 | /* Unmatched opened object or array */ |
JMF | 0:082731ede69f | 326 | if (tokens[i].start != -1 && tokens[i].end == -1) { |
JMF | 0:082731ede69f | 327 | return JSMN_ERROR_PART; |
JMF | 0:082731ede69f | 328 | } |
JMF | 0:082731ede69f | 329 | } |
JMF | 0:082731ede69f | 330 | } |
JMF | 0:082731ede69f | 331 | |
JMF | 0:082731ede69f | 332 | return count; |
JMF | 0:082731ede69f | 333 | } |
JMF | 0:082731ede69f | 334 | |
JMF | 0:082731ede69f | 335 | /** |
JMF | 0:082731ede69f | 336 | * Creates a new parser based over a given buffer with an array of tokens |
JMF | 0:082731ede69f | 337 | * available. |
JMF | 0:082731ede69f | 338 | */ |
JMF | 0:082731ede69f | 339 | void jsmn_init(jsmn_parser *parser) { |
JMF | 0:082731ede69f | 340 | parser->pos = 0; |
JMF | 0:082731ede69f | 341 | parser->toknext = 0; |
JMF | 0:082731ede69f | 342 | parser->toksuper = -1; |
JMF | 0:082731ede69f | 343 | } |
JMF | 0:082731ede69f | 344 |