diff scid/theme.c @ 43:6854efe15210

scid: push json recursively
author David Demelier <markand@malikania.fr>
date Thu, 11 Aug 2022 11:34:32 +0200
parents 00b9af607524
children 576f4b1ec79f
line wrap: on
line diff
--- a/scid/theme.c	Tue Aug 09 14:54:59 2022 +0200
+++ b/scid/theme.c	Thu Aug 11 11:34:32 2022 +0200
@@ -280,34 +280,98 @@
 
 /* }}} */
 
+static inline void push_object(duk_context *, json_t *);
+static inline void push_array(duk_context *, json_t *);
+
+static inline void
+push_value(duk_context *ctx, json_t *val)
+{
+	switch (json_typeof(val)) {
+	case JSON_STRING:
+		duk_push_string(ctx, json_string_value(val));
+		break;
+	case JSON_INTEGER:
+		duk_push_number(ctx, json_integer_value(val));
+		break;
+	case JSON_REAL:
+		duk_push_number(ctx, json_real_value(val));
+		break;
+	case JSON_TRUE:
+		duk_push_true(ctx);
+		break;
+	case JSON_FALSE:
+		duk_push_false(ctx);
+		break;
+	case JSON_NULL:
+		duk_push_null(ctx);
+		break;
+	case JSON_OBJECT:
+		push_object(ctx, val);
+		break;
+	case JSON_ARRAY:
+		push_array(ctx, val);
+		break;
+	}
+}
+
+static inline void
+push_object(duk_context *ctx, json_t *object)
+{
+	assert(json_is_object(object));
+
+	json_t *val;
+	const char *key;
+
+	duk_push_object(ctx);
+
+	json_object_foreach(object, key, val) {
+		push_value(ctx, val);
+		duk_put_prop_string(ctx, -2, key);
+	}
+}
+
+static inline void
+push_array(duk_context *ctx, json_t *array)
+{
+	assert(json_is_array(array));
+
+	json_t *val;
+	size_t i;
+
+	duk_push_array(ctx);
+
+	json_array_foreach(array, i, val) {
+		push_value(ctx, val);
+		duk_put_prop_index(ctx, -2, i);
+	}
+}
+
 static char *
-call(const json_t *json, const char *function)
+call(json_t *json, const char *function)
 {
-	char *out = NULL, *dump;
+	char *out = NULL;
 	size_t outsz = 0;
 	FILE *fp;
 
 	duk_get_global_string(context, function);
 
 	if (duk_is_callable(context, -1)) {
-		fp   = util_open_memstream(&out, &outsz);
-		dump = util_json_dump(json);
-
+		fp = util_open_memstream(&out, &outsz);
 		duk_push_pointer(context, fp);
-		duk_push_string(context, dump);
-		duk_json_decode(context, -1);
+		push_value(context, json);
 
 		if (duk_pcall(context, 2) != 0)
 			log_warn("theme: %s", duk_safe_to_string(context, -1));
 
 		duk_pop(context);
 		fclose(fp);
-		free(dump);
 	} else
 		duk_pop(context);
 
 	if (!out)
 		out = util_strdup("");
+	if (json)
+		json_decref(json);
 
 	return out;
 }
@@ -352,7 +416,7 @@
 }
 
 char *
-theme_page_index(const json_t *json)
+theme_page_index(json_t *json)
 {
 	assert(json);
 
@@ -360,7 +424,7 @@
 }
 
 char *
-theme_page_jobresults(const json_t *json)
+theme_page_jobresults(json_t *json)
 {
 	assert(json);