commit 6fe632e

grunfink  ·  2025-06-21 17:20:18 +0000 UTC
parent fa986ad
Backport from xs.
2 files changed,  +73, -53
+72, -52
  1@@ -19,8 +19,8 @@ xs_val *xs_json_loads_full(const xs_str *json, int maxdepth);
  2 xstype xs_json_load_type(FILE *f);
  3 int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c);
  4 int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt, int *c);
  5-xs_list *xs_json_load_array(FILE *f, int maxdepth);
  6-xs_dict *xs_json_load_object(FILE *f, int maxdepth);
  7+int xs_json_load_array(FILE *f, int maxdepth, xs_list **l);
  8+int xs_json_load_object(FILE *f, int maxdepth, xs_dict **d);
  9 
 10 
 11 #ifdef XS_IMPLEMENTATION
 12@@ -377,43 +377,51 @@ int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c)
 13 }
 14 
 15 
 16-xs_list *xs_json_load_array(FILE *f, int maxdepth)
 17+int xs_json_load_array(FILE *f, int maxdepth, xs_list **l)
 18 /* loads a full JSON array (after the initial OBRACK) */
 19+/* l can be NULL for the content to be dropped */
 20 {
 21     xstype t;
 22-    xs_list *l = xs_list_new();
 23+    int r = 0;
 24     int c = 0;
 25 
 26     for (;;) {
 27         xs *v = NULL;
 28-        int r = xs_json_load_array_iter(f, &v, &t, &c);
 29-
 30-        if (r == -1)
 31-            l = xs_free(l);
 32+        r = xs_json_load_array_iter(f, &v, &t, &c);
 33 
 34         if (r == 1) {
 35             /* partial load? */
 36             if (v == NULL && maxdepth != 0) {
 37-                if (t == XSTYPE_LIST)
 38-                    v = xs_json_load_array(f, maxdepth - 1);
 39+                if (t == XSTYPE_LIST) {
 40+                    if (l)
 41+                        v = xs_list_new();
 42+
 43+                    r = xs_json_load_array(f, maxdepth - 1, &v);
 44+                }
 45                 else
 46-                if (t == XSTYPE_DICT)
 47-                    v = xs_json_load_object(f, maxdepth - 1);
 48+                if (t == XSTYPE_DICT) {
 49+                    if (l)
 50+                        v = xs_dict_new();
 51+
 52+                    r = xs_json_load_object(f, maxdepth - 1, &v);
 53+                }
 54             }
 55 
 56-            /* still null? fail */
 57-            if (v == NULL) {
 58-                l = xs_free(l);
 59+            /* error? */
 60+            if (r < 0)
 61                 break;
 62-            }
 63 
 64-            l = xs_list_append(l, v);
 65+            if (l)
 66+                *l = xs_list_append(*l, v);
 67         }
 68         else
 69             break;
 70     }
 71 
 72-    return l;
 73+    if (r < 0 && l)
 74+        *l = xs_free(*l);
 75+
 76+    return r;
 77 }
 78 
 79 
 80@@ -465,59 +473,52 @@ int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt,
 81 }
 82 
 83 
 84-xs_dict *xs_json_load_object(FILE *f, int maxdepth)
 85+int xs_json_load_object(FILE *f, int maxdepth, xs_dict **d)
 86 /* loads a full JSON object (after the initial OCURLY) */
 87+/* d can be NULL for the content to be dropped */
 88 {
 89     xstype t;
 90-    xs_dict *d = xs_dict_new();
 91+    int r = 0;
 92     int c = 0;
 93 
 94     for (;;) {
 95         xs *k = NULL;
 96         xs *v = NULL;
 97-        int r = xs_json_load_object_iter(f, &k, &v, &t, &c);
 98-
 99-        if (r == -1)
100-            d = xs_free(d);
101+        r = xs_json_load_object_iter(f, &k, &v, &t, &c);
102 
103         if (r == 1) {
104             /* partial load? */
105             if (v == NULL && maxdepth != 0) {
106-                if (t == XSTYPE_LIST)
107-                    v = xs_json_load_array(f, maxdepth - 1);
108+                if (t == XSTYPE_LIST) {
109+                    if (d)
110+                        v = xs_list_new();
111+
112+                    r = xs_json_load_array(f, maxdepth - 1, &v);
113+                }
114                 else
115-                if (t == XSTYPE_DICT)
116-                    v = xs_json_load_object(f, maxdepth - 1);
117+                if (t == XSTYPE_DICT) {
118+                    if (d)
119+                        v = xs_dict_new();
120+
121+                    r = xs_json_load_object(f, maxdepth - 1, &v);
122+                }
123             }
124 
125-            /* still null? fail */
126-            if (v == NULL) {
127-                d = xs_free(d);
128+            /* error? */
129+            if (r < 0)
130                 break;
131-            }
132 
133-            d = xs_dict_append(d, k, v);
134+            if (d)
135+                *d = xs_dict_append(*d, k, v);
136         }
137         else
138             break;
139     }
140 
141-    return d;
142-}
143-
144-
145-xs_val *xs_json_loads_full(const xs_str *json, int maxdepth)
146-/* loads a string in JSON format and converts to a multiple data */
147-{
148-    FILE *f;
149-    xs_val *v = NULL;
150-
151-    if ((f = fmemopen((char *)json, strlen(json), "r")) != NULL) {
152-        v = xs_json_load_full(f, maxdepth);
153-        fclose(f);
154-    }
155+    if (r < 0 && d)
156+        *d = xs_free(*d);
157 
158-    return v;
159+    return r;
160 }
161 
162 
163@@ -545,11 +546,30 @@ xs_val *xs_json_load_full(FILE *f, int maxdepth)
164     xs_val *v = NULL;
165     xstype t = xs_json_load_type(f);
166 
167-    if (t == XSTYPE_LIST)
168-        v = xs_json_load_array(f, maxdepth);
169+    if (t == XSTYPE_LIST) {
170+        v = xs_list_new();
171+        xs_json_load_array(f, maxdepth, &v);
172+    }
173     else
174-    if (t == XSTYPE_DICT)
175-        v = xs_json_load_object(f, maxdepth);
176+    if (t == XSTYPE_DICT) {
177+        v = xs_dict_new();
178+        xs_json_load_object(f, maxdepth, &v);
179+    }
180+
181+    return v;
182+}
183+
184+
185+xs_val *xs_json_loads_full(const xs_str *json, int maxdepth)
186+/* loads a string in JSON format and converts to a multiple data */
187+{
188+    FILE *f;
189+    xs_val *v = NULL;
190+
191+    if ((f = fmemopen((char *)json, strlen(json), "r")) != NULL) {
192+        v = xs_json_load_full(f, maxdepth);
193+        fclose(f);
194+    }
195 
196     return v;
197 }
+1, -1
1@@ -1 +1 @@
2-/* 963b6129fca4fb5c009533db0ed602ab8ed5424d 2025-06-12T11:33:02+02:00 */
3+/* 851c21892c8df1d8f05ae95eaa4a5913e852653b 2025-06-21T17:58:11+02:00 */