SOL_API int sol_json_token_get_uint64(const struct sol_json_token *token, uint64_t *value) { SOL_NULL_CHECK(token, -EINVAL); SOL_NULL_CHECK(value, -EINVAL); *value = 0; if (token->start >= token->end) { SOL_WRN("invalid token: start=%p, end=%p", token->start, token->end); return -EINVAL; } if (sol_json_token_get_type(token) != SOL_JSON_TYPE_NUMBER) { SOL_WRN("expected number, got token type '%c' for token \"%.*s\"", sol_json_token_get_type(token), (int)sol_json_token_get_size(token), token->start); return -EINVAL; } if (*token->start == '-') { SOL_DBG("%.*s: negative number where unsigned is expected", (int)sol_json_token_get_size(token), token->start); return -ERANGE; } return token_get_uint64(token, value); }
SOL_API int sol_json_token_get_int64(const struct sol_json_token *token, int64_t *value) { SOL_NULL_CHECK(token, -EINVAL); SOL_NULL_CHECK(value, -EINVAL); *value = 0; if (token->start >= token->end) { SOL_WRN("invalid token: start=%p, end=%p", token->start, token->end); return -EINVAL; } if (sol_json_token_get_type(token) != SOL_JSON_TYPE_NUMBER) { SOL_WRN("expected number, got token type '%c' for token \"%.*s\"", sol_json_token_get_type(token), sol_json_token_get_size(token), token->start); return -EINVAL; } return token_get_int64(token, value); }
SOL_API bool sol_json_scanner_get_dict_pair(struct sol_json_scanner *scanner, struct sol_json_token *key, struct sol_json_token *value) { const char *start; if (sol_json_mem_get_type(key->start) != SOL_JSON_TYPE_STRING) { SOL_ERR("offset %zu: unexpected token '%c' (want string)", sol_json_scanner_get_mem_offset(scanner, key->start), key->start[0]); errno = EINVAL; return false; } if (!sol_json_scanner_next(scanner, value)) { SOL_ERR("offset %zu: unexpected end of file (want pair separator)", sol_json_scanner_get_mem_offset(scanner, scanner->current)); errno = EINVAL; return false; } if (sol_json_token_get_type(value) != SOL_JSON_TYPE_PAIR_SEP) { SOL_ERR("offset %zu: unexpected token '%c' (want pair separator)", sol_json_scanner_get_mem_offset(scanner, value->start), value->start[0]); errno = EINVAL; return false; } if (!sol_json_scanner_next(scanner, value)) { SOL_ERR("offset %zu: unexpected end of file (want pair value)", sol_json_scanner_get_mem_offset(scanner, scanner->current)); errno = EINVAL; return false; } start = value->start; if (!sol_json_scanner_skip(scanner, value)) { SOL_ERR("offset %zu: unexpected end of file (want pair value to skip over)", sol_json_scanner_get_mem_offset(scanner, scanner->current)); errno = EINVAL; return false; } value->start = start; return true; }
SOL_API bool sol_json_scanner_skip(struct sol_json_scanner *scanner, struct sol_json_token *token) { int level = 0; scanner->current = token->end; do { switch (sol_json_token_get_type(token)) { case SOL_JSON_TYPE_UNKNOWN: errno = EINVAL; return false; case SOL_JSON_TYPE_OBJECT_START: case SOL_JSON_TYPE_ARRAY_START: level++; break; case SOL_JSON_TYPE_OBJECT_END: case SOL_JSON_TYPE_ARRAY_END: level--; if (SOL_UNLIKELY(level < 0)) { errno = EINVAL; return false; } break; case SOL_JSON_TYPE_ELEMENT_SEP: case SOL_JSON_TYPE_PAIR_SEP: case SOL_JSON_TYPE_TRUE: case SOL_JSON_TYPE_FALSE: case SOL_JSON_TYPE_NULL: case SOL_JSON_TYPE_STRING: case SOL_JSON_TYPE_NUMBER: break; } if (level > 0) { if (!sol_json_scanner_next(scanner, token)) { errno = EINVAL; return false; } } } while (level > 0); return true; }