Răsfoiți Sursa

Backport from xs.

grunfink 1 an în urmă
părinte
comite
6fe632ec76
2 a modificat fișierele cu 73 adăugiri și 53 ștergeri
  1. 72 52
      xs_json.h
  2. 1 1
      xs_version.h

+ 72 - 52
xs_json.h

@@ -19,8 +19,8 @@ xs_val *xs_json_loads_full(const xs_str *json, int maxdepth);
 xstype xs_json_load_type(FILE *f);
 int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c);
 int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt, int *c);
-xs_list *xs_json_load_array(FILE *f, int maxdepth);
-xs_dict *xs_json_load_object(FILE *f, int maxdepth);
+int xs_json_load_array(FILE *f, int maxdepth, xs_list **l);
+int xs_json_load_object(FILE *f, int maxdepth, xs_dict **d);
 
 
 #ifdef XS_IMPLEMENTATION
@@ -377,43 +377,51 @@ int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c)
 }
 
 
-xs_list *xs_json_load_array(FILE *f, int maxdepth)
+int xs_json_load_array(FILE *f, int maxdepth, xs_list **l)
 /* loads a full JSON array (after the initial OBRACK) */
+/* l can be NULL for the content to be dropped */
 {
     xstype t;
-    xs_list *l = xs_list_new();
+    int r = 0;
     int c = 0;
 
     for (;;) {
         xs *v = NULL;
-        int r = xs_json_load_array_iter(f, &v, &t, &c);
-
-        if (r == -1)
-            l = xs_free(l);
+        r = xs_json_load_array_iter(f, &v, &t, &c);
 
         if (r == 1) {
             /* partial load? */
             if (v == NULL && maxdepth != 0) {
-                if (t == XSTYPE_LIST)
-                    v = xs_json_load_array(f, maxdepth - 1);
+                if (t == XSTYPE_LIST) {
+                    if (l)
+                        v = xs_list_new();
+
+                    r = xs_json_load_array(f, maxdepth - 1, &v);
+                }
                 else
-                if (t == XSTYPE_DICT)
-                    v = xs_json_load_object(f, maxdepth - 1);
+                if (t == XSTYPE_DICT) {
+                    if (l)
+                        v = xs_dict_new();
+
+                    r = xs_json_load_object(f, maxdepth - 1, &v);
+                }
             }
 
-            /* still null? fail */
-            if (v == NULL) {
-                l = xs_free(l);
+            /* error? */
+            if (r < 0)
                 break;
-            }
 
-            l = xs_list_append(l, v);
+            if (l)
+                *l = xs_list_append(*l, v);
         }
         else
             break;
     }
 
-    return l;
+    if (r < 0 && l)
+        *l = xs_free(*l);
+
+    return r;
 }
 
 
@@ -465,59 +473,52 @@ int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt,
 }
 
 
-xs_dict *xs_json_load_object(FILE *f, int maxdepth)
+int xs_json_load_object(FILE *f, int maxdepth, xs_dict **d)
 /* loads a full JSON object (after the initial OCURLY) */
+/* d can be NULL for the content to be dropped */
 {
     xstype t;
-    xs_dict *d = xs_dict_new();
+    int r = 0;
     int c = 0;
 
     for (;;) {
         xs *k = NULL;
         xs *v = NULL;
-        int r = xs_json_load_object_iter(f, &k, &v, &t, &c);
-
-        if (r == -1)
-            d = xs_free(d);
+        r = xs_json_load_object_iter(f, &k, &v, &t, &c);
 
         if (r == 1) {
             /* partial load? */
             if (v == NULL && maxdepth != 0) {
-                if (t == XSTYPE_LIST)
-                    v = xs_json_load_array(f, maxdepth - 1);
+                if (t == XSTYPE_LIST) {
+                    if (d)
+                        v = xs_list_new();
+
+                    r = xs_json_load_array(f, maxdepth - 1, &v);
+                }
                 else
-                if (t == XSTYPE_DICT)
-                    v = xs_json_load_object(f, maxdepth - 1);
+                if (t == XSTYPE_DICT) {
+                    if (d)
+                        v = xs_dict_new();
+
+                    r = xs_json_load_object(f, maxdepth - 1, &v);
+                }
             }
 
-            /* still null? fail */
-            if (v == NULL) {
-                d = xs_free(d);
+            /* error? */
+            if (r < 0)
                 break;
-            }
 
-            d = xs_dict_append(d, k, v);
+            if (d)
+                *d = xs_dict_append(*d, k, v);
         }
         else
             break;
     }
 
-    return d;
-}
-
-
-xs_val *xs_json_loads_full(const xs_str *json, int maxdepth)
-/* loads a string in JSON format and converts to a multiple data */
-{
-    FILE *f;
-    xs_val *v = NULL;
-
-    if ((f = fmemopen((char *)json, strlen(json), "r")) != NULL) {
-        v = xs_json_load_full(f, maxdepth);
-        fclose(f);
-    }
+    if (r < 0 && d)
+        *d = xs_free(*d);
 
-    return v;
+    return r;
 }
 
 
@@ -545,11 +546,30 @@ xs_val *xs_json_load_full(FILE *f, int maxdepth)
     xs_val *v = NULL;
     xstype t = xs_json_load_type(f);
 
-    if (t == XSTYPE_LIST)
-        v = xs_json_load_array(f, maxdepth);
+    if (t == XSTYPE_LIST) {
+        v = xs_list_new();
+        xs_json_load_array(f, maxdepth, &v);
+    }
     else
-    if (t == XSTYPE_DICT)
-        v = xs_json_load_object(f, maxdepth);
+    if (t == XSTYPE_DICT) {
+        v = xs_dict_new();
+        xs_json_load_object(f, maxdepth, &v);
+    }
+
+    return v;
+}
+
+
+xs_val *xs_json_loads_full(const xs_str *json, int maxdepth)
+/* loads a string in JSON format and converts to a multiple data */
+{
+    FILE *f;
+    xs_val *v = NULL;
+
+    if ((f = fmemopen((char *)json, strlen(json), "r")) != NULL) {
+        v = xs_json_load_full(f, maxdepth);
+        fclose(f);
+    }
 
     return v;
 }

+ 1 - 1
xs_version.h

@@ -1 +1 @@
-/* 963b6129fca4fb5c009533db0ed602ab8ed5424d 2025-06-12T11:33:02+02:00 */
+/* 851c21892c8df1d8f05ae95eaa4a5913e852653b 2025-06-21T17:58:11+02:00 */