ref: c5dfca354a35575443084622a74de02ef3e6ea8e
dir: /rjson.c/
#include <u.h>
#include <libc.h>
#include <json.h>
#include "rjson.h"
int
rjsontostruct(JSON *json, Rjson *rjson, void *target)
{
Rjson *rj;
JSON *j;
char **s;
double *n;
int *b;
char *o;
if (!json) {
werrstr("invalid json");
return 0;
}
if (!target) {
werrstr("invalid target struct");
return 0;
}
if (!rjson) {
werrstr("invalid rjson");
return 0;
}
for (rj = rjson; rj->name; rj++) {
j = jsonbyname(json, rj->name);
if (!j)
continue;
if (j->t != rj->type) {
werrstr("inconsistent type: %s is not %d\n", rj->name, rj->type);
return 0;
}
switch (j->t) {
case JSONNull:
/* skip null */
break;
case JSONBool:
b = (int*)((char*)target + rj->addr);
*b = !!j->n;
break;
case JSONNumber:
n = (double*)((char*)target + rj->addr);
*n = j->n;
break;
case JSONString:
s = (char**)((char*)target + rj->addr);
*s = strdup(j->s);
break;
case JSONArray: // TODO
break;
case JSONObject:
if (!rj->sub) {
werrstr("object %s without valid rjson", rj->name);
return 0;
}
o = (char*)target + rj->addr;
return rjsontostruct(j, rj->sub, o);
break;
}
}
return 1;
}
static void
jappend(JSON *json, char *name, JSON *jn)
{
JSONEl *jel;
if (!json->first) {
jel = json->first = mallocz(sizeof(JSONEl), 1);
} else {
for (jel = json->first; jel->next; jel = jel->next)
;
jel->next = mallocz(sizeof(JSONEl), 1);
jel = jel->next;
}
assert(jel);
jel->name = strdup(name);
jel->val = jn;
}
JSON*
rstructtojson(void *src, Rjson *rjson)
{
JSON *json, *j;
Rjson *rj;
int *i;
double *n;
char **s;
char *o;
if (!src) {
werrstr("invalid src");
return nil;
}
if (!rjson) {
werrstr("invalid rjson");
return nil;
}
json = mallocz(sizeof(JSON), 1);
assert(json);
json->t = JSONObject;
for (rj = rjson; rj->name; rj++) {
if (rj->type == JSONNull)
continue;
if (rj->type == JSONObject) {
o = (char*)src + rj->addr;
j = rstructtojson(o, rj->sub);
jappend(json, rj->name, j);
continue;
}
j = mallocz(sizeof(JSON), 1);
assert(j);
jappend(json, rj->name, j);
j->t = rj->type;
switch (j->t) {
case JSONBool:
i = (int*)((char*)src + rj->addr);
j->n = *i;
break;
case JSONNumber:
n = (double*)((char*)src + rj->addr);
j->n = *n;
break;
case JSONString:
s = (char**)((char*)src + rj->addr);
j->s = strdup(*s);
break;
case JSONArray: // TODO
break;
}
}
return json;
}