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. */
| 1012 | * T_ERROR will leave the json->ptr pointer at the error. |
| 1013 | */ |
| 1014 | static void json_next_token(json_parse_t *json, json_token_t *token) |
| 1015 | { |
| 1016 | const json_token_type_t *ch2token = json->cfg->ch2token; |
| 1017 | int ch; |
| 1018 | |
| 1019 | /* Eat whitespace. */ |
| 1020 | while (1) { |
| 1021 | ch = (unsigned char)*(json->ptr); |
| 1022 | token->type = ch2token[ch]; |
| 1023 | if (token->type != T_WHITESPACE) |
| 1024 | break; |
| 1025 | json->ptr++; |
| 1026 | } |
| 1027 | |
| 1028 | /* Store location of new token. Required when throwing errors |
| 1029 | * for unexpected tokens (syntax errors). */ |
| 1030 | token->index = json->ptr - json->data; |
| 1031 | |
| 1032 | /* Don't advance the pointer for an error or the end */ |
| 1033 | if (token->type == T_ERROR) { |
| 1034 | json_set_token_error(token, json, "invalid token"); |
| 1035 | return; |
| 1036 | } |
| 1037 | |
| 1038 | if (token->type == T_END) { |
| 1039 | return; |
| 1040 | } |
| 1041 | |
| 1042 | /* Found a known single character token, advance index and return */ |
| 1043 | if (token->type != T_UNKNOWN) { |
| 1044 | json->ptr++; |
| 1045 | return; |
| 1046 | } |
| 1047 | |
| 1048 | /* Process characters which triggered T_UNKNOWN |
| 1049 | * |
| 1050 | * Must use strncmp() to match the front of the JSON string. |
| 1051 | * JSON identifier must be lowercase. |
| 1052 | * When strict_numbers if disabled, either case is allowed for |
| 1053 | * Infinity/NaN (since we are no longer following the spec..) */ |
| 1054 | if (ch == '"') { |
| 1055 | json_next_string_token(json, token); |
| 1056 | return; |
| 1057 | } else if (ch == '-' || ('0' <= ch && ch <= '9')) { |
| 1058 | if (!json->cfg->decode_invalid_numbers && json_is_invalid_number(json)) { |
| 1059 | json_set_token_error(token, json, "invalid number"); |
| 1060 | return; |
| 1061 | } |
| 1062 | json_next_number_token(json, token); |
| 1063 | return; |
| 1064 | } else if (!strncmp(json->ptr, "true", 4)) { |
| 1065 | token->type = T_BOOLEAN; |
| 1066 | token->value.boolean = 1; |
| 1067 | json->ptr += 4; |
| 1068 | return; |
| 1069 | } else if (!strncmp(json->ptr, "false", 5)) { |
| 1070 | token->type = T_BOOLEAN; |
| 1071 | token->value.boolean = 0; |
no test coverage detected