--- a/src/json.c Fri Nov 01 18:17:19 2024 +0100 +++ b/src/json.c Fri Nov 01 18:33:16 2024 +0100 @@ -301,40 +301,26 @@ return result; } -static int parse_integer(const char *str, size_t len, int64_t *value) { +static int parse_number(const char *str, size_t len, void *value, bool asint) { char *endptr = NULL; char buf[32]; if (len > 30) { return 1; } + // TODO: if we can guarantee that we are working on a copied string already, we can avoid this memcpy memcpy(buf, str, len); buf[len] = 0; - long long v = strtoll(buf, &endptr, 10); - if (endptr != &buf[len]) { - return 1; + if (asint) { + long long v = strtoll(buf, &endptr, 10); + *((int64_t*)value) = (int64_t) v; + } else { + // TODO: proper JSON spec number parser + double v = strtod(buf, &endptr); + *((double*)value) = v; } - *value = (int64_t) v; - - return 0; -} -static int parse_number(const char *str, size_t len, double *value) { - char *endptr = NULL; - char buf[32]; - if (len > 30) { - return 1; - } - memcpy(buf, str, len); - buf[len] = 0; - - double v = strtod(buf, &endptr); - if (endptr != &buf[len]) { - return 1; - } - *value = v; - - return 0; + return (endptr != &buf[len]); } static int add_state(CxJson *p, int state) { @@ -462,23 +448,17 @@ } case CX_JSON_TOKEN_INTEGER: { p->reader_type = CX_JSON_READER_INTEGER; - int64_t value; - if (parse_integer(token.content, token.length, &value)) { + if (parse_number(token.content, token.length, + &p->value_int, true)) { ret = -1; - } else { - p->value_int = value; - p->value_double = (double) value; } break; } case CX_JSON_TOKEN_NUMBER: { p->reader_type = CX_JSON_READER_NUMBER; - double value; - if (parse_number(token.content, token.length, &value)) { + if (parse_number(token.content, token.length, + &p->value_double, false)) { ret = -1; - } else { - p->value_double = value; - p->value_int = (int64_t) value; } break; }