Fills in the token struct. * T_STRING will return a pointer to the json_parse_t temporary string * T_ERROR will leave the json->ptr pointer at the error. */
| 1293 | * T_ERROR will leave the json->ptr pointer at the error. |
| 1294 | */ |
| 1295 | static void json_next_token(json_parse_t *json, json_token_t *token) |
| 1296 | { |
| 1297 | const json_token_type_t *ch2token = json->cfg->ch2token; |
| 1298 | int ch; |
| 1299 | |
| 1300 | // DEFOLD |
| 1301 | if (json->ptr >= json->data_end) { |
| 1302 | token->type = T_END; |
| 1303 | return; |
| 1304 | } |
| 1305 | // END DEFOLD |
| 1306 | |
| 1307 | /* Eat whitespace. */ |
| 1308 | while (1) { |
| 1309 | ch = (unsigned char)*(json->ptr); |
| 1310 | token->type = ch2token[ch]; |
| 1311 | if (token->type != T_WHITESPACE) |
| 1312 | break; |
| 1313 | json->ptr++; |
| 1314 | } |
| 1315 | |
| 1316 | /* Store location of new token. Required when throwing errors |
| 1317 | * for unexpected tokens (syntax errors). */ |
| 1318 | token->index = json->ptr - json->data; |
| 1319 | |
| 1320 | /* Don't advance the pointer for an error or the end */ |
| 1321 | if (token->type == T_ERROR) { |
| 1322 | json_set_token_error(token, json, "invalid token"); |
| 1323 | return; |
| 1324 | } |
| 1325 | |
| 1326 | if (token->type == T_END) { |
| 1327 | return; |
| 1328 | } |
| 1329 | |
| 1330 | /* Found a known single character token, advance index and return */ |
| 1331 | if (token->type != T_UNKNOWN) { |
| 1332 | json->ptr++; |
| 1333 | return; |
| 1334 | } |
| 1335 | |
| 1336 | /* Process characters which triggered T_UNKNOWN |
| 1337 | * |
| 1338 | * Must use strncmp() to match the front of the JSON string. |
| 1339 | * JSON identifier must be lowercase. |
| 1340 | * When strict_numbers if disabled, either case is allowed for |
| 1341 | * Infinity/NaN (since we are no longer following the spec..) */ |
| 1342 | if (ch == '"') { |
| 1343 | json_next_string_token(json, token); |
| 1344 | return; |
| 1345 | } else if (ch == '-' || ('0' <= ch && ch <= '9')) { |
| 1346 | if (!json->cfg->decode_invalid_numbers && json_is_invalid_number(json)) { |
| 1347 | json_set_token_error(token, json, "invalid number"); |
| 1348 | return; |
| 1349 | } |
| 1350 | json_next_number_token(json, token); |
| 1351 | return; |
| 1352 | } else if (!strncmp(json->ptr, "true", 4)) { |
no test coverage detected