diff options
Diffstat (limited to 'com32/gpllib/zzjson/zzjson_create.c')
-rw-r--r-- | com32/gpllib/zzjson/zzjson_create.c | 240 |
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; +} + |