summaryrefslogtreecommitdiff
path: root/com32/gpllib/zzjson/zzjson_create.c
diff options
context:
space:
mode:
Diffstat (limited to 'com32/gpllib/zzjson/zzjson_create.c')
-rw-r--r--com32/gpllib/zzjson/zzjson_create.c240
1 files changed, 240 insertions, 0 deletions
diff --git a/com32/gpllib/zzjson/zzjson_create.c b/com32/gpllib/zzjson/zzjson_create.c
new file mode 100644
index 00000000..7e6bd5bd
--- /dev/null
+++ b/com32/gpllib/zzjson/zzjson_create.c
@@ -0,0 +1,240 @@
+/* JSON Create ZZJSON structures
+ * ZZJSON - Copyright (C) 2008 by Ivo van Poorten
+ * License: GNU Lesser General Public License version 2.1
+ */
+
+#include "zzjson.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef CONFIG_NO_ERROR_MESSAGES
+#define ERROR(x...)
+#else
+#define ERROR(x...) config->error(config->ehandle, ##x)
+#endif
+#define MEMERROR() ERROR("out of memory")
+
+static ZZJSON *zzjson_create_templ(ZZJSON_CONFIG *config, ZZJSON_TYPE type) {
+ ZZJSON *zzjson = config->calloc(1, sizeof(ZZJSON));
+ if (!zzjson) MEMERROR();
+ else zzjson->type = type;
+ return zzjson;
+}
+
+ZZJSON *zzjson_create_true(ZZJSON_CONFIG *config) {
+ return zzjson_create_templ(config, ZZJSON_TRUE);
+}
+
+ZZJSON *zzjson_create_false(ZZJSON_CONFIG *config) {
+ return zzjson_create_templ(config, ZZJSON_FALSE);
+}
+
+ZZJSON *zzjson_create_null(ZZJSON_CONFIG *config) {
+ return zzjson_create_templ(config, ZZJSON_NULL);
+}
+
+ZZJSON *zzjson_create_number_d(ZZJSON_CONFIG *config, double d) {
+ ZZJSON *zzjson = zzjson_create_templ(config, ZZJSON_NUMBER_DOUBLE);
+ if (zzjson)
+ zzjson->value.number.val.dval = d;
+ return zzjson;
+}
+
+ZZJSON *zzjson_create_number_i(ZZJSON_CONFIG *config, long long i) {
+ ZZJSON *zzjson = zzjson_create_templ(config, ZZJSON_NUMBER_NEGINT);
+ if (zzjson) {
+ zzjson->type = i<0LL ? ZZJSON_NUMBER_NEGINT : ZZJSON_NUMBER_POSINT;
+ zzjson->value.number.val.ival = llabs(i);
+ }
+ return zzjson;
+}
+
+/* sdup mimics strdup, but avoids having another function pointer in config */
+static char *sdup(ZZJSON_CONFIG *config, char *s) {
+ size_t slen = strlen(s)+1;
+ char *scopy = config->malloc(slen);
+
+ if (!scopy) MEMERROR();
+ else memcpy(scopy, s, slen);
+ return scopy;
+}
+
+ZZJSON *zzjson_create_string(ZZJSON_CONFIG *config, char *s) {
+ ZZJSON *zzjson = NULL;
+ char *scopy;
+
+ if (!(scopy = sdup(config,s))) return zzjson;
+
+ if ((zzjson = zzjson_create_templ(config, ZZJSON_STRING)))
+ zzjson->value.string.string = scopy;
+ else
+ config->free(scopy);
+
+ return zzjson;
+}
+
+ZZJSON *zzjson_create_array(ZZJSON_CONFIG *config, ...) {
+ ZZJSON *zzjson, *retval, *val;
+ va_list ap;
+
+ if (!(zzjson = zzjson_create_templ(config, ZZJSON_ARRAY))) return zzjson;
+ retval = zzjson;
+
+ va_start(ap, config);
+ val = va_arg(ap, ZZJSON *);
+ while (val) {
+ zzjson->value.array.val = val;
+ val = va_arg(ap, ZZJSON *);
+
+ if (val) {
+ ZZJSON *next = zzjson_create_templ(config, ZZJSON_ARRAY);
+ if (!next) {
+ while (retval) {
+ next = retval->next;
+ config->free(retval);
+ retval = next;
+ }
+ break;
+ }
+ zzjson->next = next;
+ zzjson = next;
+ }
+ }
+ va_end(ap);
+ return retval;
+}
+
+ZZJSON *zzjson_create_object(ZZJSON_CONFIG *config, ...) {
+ ZZJSON *zzjson, *retval, *val;
+ char *label, *labelcopy;
+ va_list ap;
+
+ if (!(zzjson = zzjson_create_templ(config, ZZJSON_OBJECT))) return zzjson;
+ retval = zzjson;
+
+ va_start(ap, config);
+ label = va_arg(ap, char *);
+ while (label) {
+ val = va_arg(ap, ZZJSON *);
+ labelcopy = sdup(config, label);
+
+ if (!labelcopy) {
+ zzjson_free(config, retval);
+ retval = NULL;
+ break;
+ }
+
+ zzjson->value.object.label = labelcopy;
+ zzjson->value.object.val = val;
+
+ label = va_arg(ap, char *);
+
+ if (label) {
+ ZZJSON *next = zzjson_create_templ(config, ZZJSON_OBJECT);
+ if (!next) {
+ while (retval) {
+ next = retval->next;
+ config->free(retval->value.object.label);
+ config->free(retval);
+ retval = next;
+ }
+ break;
+ }
+ zzjson->next = next;
+ zzjson = next;
+ }
+ }
+ va_end(ap);
+ return retval;
+}
+
+ZZJSON *zzjson_array_prepend(ZZJSON_CONFIG *config, ZZJSON *array,
+ ZZJSON *val) {
+ ZZJSON *zzjson;
+
+ if (!array->value.array.val) { /* empty array */
+ array->value.array.val = val;
+ return array;
+ }
+
+ zzjson = zzjson_create_templ(config, ZZJSON_ARRAY);
+ if (zzjson) {
+ zzjson->value.array.val = val;
+ zzjson->next = array;
+ }
+ return zzjson;
+}
+
+ZZJSON *zzjson_array_append(ZZJSON_CONFIG *config, ZZJSON *array,
+ ZZJSON *val) {
+ ZZJSON *retval = array, *zzjson;
+
+ if (!array->value.array.val) { /* empty array */
+ array->value.array.val = val;
+ return array;
+ }
+
+ zzjson = zzjson_create_templ(config, ZZJSON_ARRAY);
+ if (!zzjson) return NULL;
+
+ while (array->next) array = array->next;
+
+ zzjson->value.array.val = val;
+ array->next = zzjson;
+
+ return retval;
+}
+
+ZZJSON *zzjson_object_prepend(ZZJSON_CONFIG *config, ZZJSON *object,
+ char *label, ZZJSON *val) {
+ ZZJSON *zzjson = NULL;
+ char *labelcopy = sdup(config, label);
+
+ if (!labelcopy) return zzjson;
+
+ if (!object->value.object.label) { /* empty object */
+ object->value.object.label = labelcopy;
+ object->value.object.val = val;
+ return object;
+ }
+
+ zzjson = zzjson_create_templ(config, ZZJSON_OBJECT);
+ if (zzjson) {
+ zzjson->value.object.label = labelcopy;
+ zzjson->value.object.val = val;
+ zzjson->next = object;
+ } else {
+ config->free(labelcopy);
+ }
+ return zzjson;
+}
+
+ZZJSON *zzjson_object_append(ZZJSON_CONFIG *config, ZZJSON *object,
+ char *label, ZZJSON *val) {
+ ZZJSON *retval = object, *zzjson = NULL;
+ char *labelcopy = sdup(config, label);
+
+ if (!labelcopy) return zzjson;
+
+ if (!object->value.object.label) { /* empty object */
+ object->value.object.label = labelcopy;
+ object->value.object.val = val;
+ return object;
+ }
+
+ zzjson = zzjson_create_templ(config, ZZJSON_OBJECT);
+ if (!zzjson) {
+ config->free(labelcopy);
+ return NULL;
+ }
+
+ while (object->next) object = object->next;
+
+ zzjson->value.object.label = labelcopy;
+ zzjson->value.object.val = val;
+ object->next = zzjson;
+
+ return retval;
+}
+