aboutsummaryrefslogtreecommitdiff
path: root/xs_json.h
diff options
context:
space:
mode:
authorgrunfink <grunfink@comam.es>2025-06-21 19:20:18 +0200
committergrunfink <grunfink@comam.es>2025-06-21 19:20:18 +0200
commit6fe632ec769f6a03825e55840093fada928a0a8a (patch)
tree09792badf298a23bad24dc5b966a491b08c9f4c3 /xs_json.h
parentfa986ad91e15bdea6a9764d04fdb90e404d39e55 (diff)
Backport from xs.
Diffstat (limited to 'xs_json.h')
-rw-r--r--xs_json.h124
1 files changed, 72 insertions, 52 deletions
diff --git a/xs_json.h b/xs_json.h
index 8b449a9..436fa72 100644
--- a/xs_json.h
+++ b/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;
}