src/json.c

changeset 969
72e5432f6b42
parent 967
a58f602ed2fe
--- 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;
             }

mercurial