From 6fe632ec769f6a03825e55840093fada928a0a8a Mon Sep 17 00:00:00 2001 From: grunfink Date: Sat, 21 Jun 2025 19:20:18 +0200 Subject: Backport from xs. --- xs_json.h | 124 ++++++++++++++++++++++++++++++++++------------------------- xs_version.h | 2 +- 2 files changed, 73 insertions(+), 53 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; } diff --git a/xs_version.h b/xs_version.h index c9418a7..74f453f 100644 --- a/xs_version.h +++ b/xs_version.h @@ -1 +1 @@ -/* 963b6129fca4fb5c009533db0ed602ab8ed5424d 2025-06-12T11:33:02+02:00 */ +/* 851c21892c8df1d8f05ae95eaa4a5913e852653b 2025-06-21T17:58:11+02:00 */ -- cgit v1.2.3