ref: 0693246c2bcf364b8afedc190f6820ae5f257f5f
parent: c4ef9e2925f8baec22d6737872326736b31bf45f
author: sirjofri <sirjofri@sirjofri.de>
date: Sun Mar 15 13:14:34 EDT 2026
adds jsontostruct for object arrays
--- a/rjson.c
+++ b/rjson.c
@@ -3,15 +3,28 @@
#include <json.h>
#include "rjson.h"
+static int
+rcountarr(JSONEl *jel)
+{+ int i = 0;
+ for (; jel; jel = jel->next)
+ i++;
+ return i;
+}
+
int
rjsontostruct(JSON *json, Rjson *rjson, void *target)
{Rjson *rj;
JSON *j;
+ JSONEl *jel;
+ int count, i, ret;
char **s;
double *n;
int *b;
char *o;
+ char **arr;
+ void *entry;
if (!json) { werrstr("invalid json");@@ -28,6 +41,7 @@
return 0;
}
+ ret = 1;
for (rj = rjson; rj->name; rj++) {j = jsonbyname(json, rj->name);
if (!j)
@@ -52,7 +66,22 @@
s = (char**)((char*)target + rj->addr);
*s = strdup(j->s);
break;
- case JSONArray: // TODO
+ case JSONArray:
+ count = rcountarr(j->first);
+ b = (int*)((char*)target + rj->countaddr);
+ *b = count;
+ arr = (char**)((char*)target + rj->addr);
+ *arr = nil;
+ if (!count)
+ break;
+ *arr = mallocz(count * rj->arrsize, 1);
+ ret = 1;
+ i = 0;
+ for (jel = j->first; jel; jel = jel->next) {+ entry = *arr + i*rj->arrsize;
+ ret &= rjsontostruct(jel->val, rj->sub, entry);
+ i++;
+ }
break;
case JSONObject:
if (!rj->sub) {@@ -60,11 +89,11 @@
return 0;
}
o = (char*)target + rj->addr;
- return rjsontostruct(j, rj->sub, o);
+ ret &= rjsontostruct(j, rj->sub, o);
break;
}
}
- return 1;
+ return ret;
}
static void
--- a/rjson.h
+++ b/rjson.h
@@ -1,9 +1,10 @@
#define RJSON_BEGIN(A) Rjson A[] = { #define RJSON_END() { 0, 0, nil }};-#define RJSON_STRING(A, N) { offsetof(A, N), JSONString, "N", nil },-#define RJSON_NUMBER(A, N) { offsetof(A, N), JSONNumber, "N", nil },-#define RJSON_BOOL(A, N) { offsetof(A, N), JSONBool, "N", nil },-#define RJSON_OBJECT(A, N, S) { offsetof(A, N), JSONObject, "N", S },+#define RJSON_STRING(A, N) { offsetof(A, N), JSONString, "N", nil, 0, 0 },+#define RJSON_NUMBER(A, N) { offsetof(A, N), JSONNumber, "N", nil, 0, 0 },+#define RJSON_BOOL(A, N) { offsetof(A, N), JSONBool, "N", nil, 0, 0 },+#define RJSON_OBJECT(A, N, S) { offsetof(A, N), JSONObject, "N", S, 0, 0 },+#define RJSON_ARRAY_OBJECT(A, N, T, S, I) { offsetof(A, N), JSONArray, "N", S, offsetof(A, I), sizeof(T) },typedef struct Rjson Rjson;
struct Rjson {@@ -11,6 +12,8 @@
int type;
char *name;
Rjson *sub;
+ int countaddr;
+ int arrsize;
};
int rjsontostruct(JSON *json, Rjson*, void*);
--- a/test/t.c
+++ b/test/t.c
@@ -19,6 +19,8 @@
double num;
int bool;
Sub obj;
+ Sub *obarr;
+ int obarrnum;
};
RJSON_BEGIN(Test_rjson)
@@ -27,6 +29,7 @@
RJSON_NUMBER(Test,num)
RJSON_BOOL(Test,bool)
RJSON_OBJECT(Test,obj,Sub_rjson)
+ RJSON_ARRAY_OBJECT(Test,obarr,Sub,Sub_rjson,obarrnum)
RJSON_END()
@@ -38,7 +41,15 @@
" \"bool\": true,\n"
" \"obj\": {\n"" \"xyz\": \"abc\"\n"
-" }\n"
+" },\n"
+" \"obarr\": [\n"
+" {\n"+" \"xyz\": \"one\"\n"
+" },\n"
+" {\n"+" \"xyz\": \"two\"\n"
+" }\n"
+" ]\n"
"}\n";
void
@@ -47,6 +58,7 @@
Test t;
JSON *j;
char *s;
+ int i;
int verbose;
verbose = !!getenv("verbose");@@ -65,6 +77,10 @@
fprint(2, " num: %f\n", t.num);
fprint(2, " bool: %d\n", t.bool);
fprint(2, " obj.xyz: %s\n", t.obj.xyz);
+ fprint(2, "obarrnum: %d\n", t.obarrnum);
+ for (i = 0; i < t.obarrnum; i++) {+ fprint(2, " obarr[%d].xyz: %s\n", i, t.obarr[i].xyz);
+ }
}
} else {fprint(2, "parse failed: %r\n");
--
⑨