shithub: rjson

Download patch

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");
--