shithub: rjson

ref: c5dfca354a35575443084622a74de02ef3e6ea8e
dir: /rjson.c/

View raw version
#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;
}