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