summaryrefslogtreecommitdiffstats
path: root/util/json.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/json.c')
-rw-r--r--util/json.c406
1 files changed, 9 insertions, 397 deletions
diff --git a/util/json.c b/util/json.c
index df0aefb..fd52861 100644
--- a/util/json.c
+++ b/util/json.c
@@ -1,407 +1,19 @@
-#include <stdlib.h>
-#include <string.h>
+// SPDX-License-Identifier: GPL-2.0-or-later
#include <stdio.h>
-#include <errno.h>
-#include <stdarg.h>
-#include "json.h"
-
-static inline void fail_and_notify(void)
-{
- fprintf(stderr, "Allocation of memory for json object failed, aborting.\n");
- abort();
-}
-
-struct json_object *json_create_object(void)
-{
- void *test = calloc(1, sizeof(struct json_object));
- if (!test)
- fail_and_notify();
- return test;
-}
-
-struct json_object *json_create_array(void)
-{
- void *test = calloc(1, sizeof(struct json_object));
- if (!test)
- fail_and_notify();
- return test;
-}
-
-static struct json_pair *json_create_pair(const char *name, struct json_value *value)
-{
- struct json_pair *pair = malloc(sizeof(struct json_pair));
- if (pair) {
- pair->name = strdup(name);
- pair->value = value;
-
- value->parent_type = JSON_PARENT_TYPE_PAIR;
- value->parent_pair = pair;
- } else
- fail_and_notify();
-
- return pair;
-}
-
-static struct json_value *json_create_value_int(long long number)
-{
- struct json_value *value = malloc(sizeof(struct json_value));
-
- if (value) {
- value->type = JSON_TYPE_INTEGER;
- value->integer_number = number;
- } else
- fail_and_notify();
-
- return value;
-}
-
-static struct json_value *json_create_value_uint(unsigned long long number)
-{
- struct json_value *value = malloc(sizeof(struct json_value));
-
- if (value) {
- value->type = JSON_TYPE_UINT;
- value->uint_number = number;
- } else
- fail_and_notify();
-
- return value;
-}
-
-static struct json_value *json_create_value_float(long double number)
-{
- struct json_value *value = malloc(sizeof(struct json_value));
-
- if (value) {
- value->type = JSON_TYPE_FLOAT;
- value->float_number = number;
- } else
- fail_and_notify();
- return value;
-}
+#include "json.h"
-static char *strdup_escape(const char *str)
+struct json_object *util_json_object_new_double(long double d)
{
- const char *input = str;
- char *p, *ret;
- int escapes;
+ struct json_object *obj;
+ char *str;
- if (!strlen(str))
+ if (asprintf(&str, "%Lf", d) < 0)
return NULL;
- escapes = 0;
- while ((input = strpbrk(input, "\\\"")) != NULL) {
- escapes++;
- input++;
- }
-
- p = ret = malloc(strlen(str) + escapes + 1);
- if (!ret)
- fail_and_notify();
-
- while (*str) {
- if (*str == '\\' || *str == '\"')
- *p++ = '\\';
- *p++ = *str++;
- }
- *p = '\0';
-
- return ret;
-}
-
-/*
- * Valid JSON strings must escape '"' and '/' with a preceding '/'
- */
-static struct json_value *json_create_value_string(const char *str)
-{
- struct json_value *value = malloc(sizeof(struct json_value));
-
- if (value) {
- value->type = JSON_TYPE_STRING;
- value->string = strdup_escape(str ? str : "(null)");
- if (!value->string) {
- free(value);
- value = NULL;
- return value;
- }
- }
- if (!value)
- fail_and_notify();
-
- return value;
-}
-
-static struct json_value *json_create_value_object(struct json_object *obj)
-{
- struct json_value *value = malloc(sizeof(struct json_value));
-
- if (value) {
- value->type = JSON_TYPE_OBJECT;
- value->object = obj;
- obj->parent = value;
- } else
- fail_and_notify();
+ obj = json_object_new_string(str);
- return value;
-}
-
-static struct json_value *json_create_value_array(struct json_object *array)
-{
- struct json_value *value = malloc(sizeof(struct json_value));
-
- if (value) {
- value->type = JSON_TYPE_ARRAY;
- value->array = array;
- array->parent = value;
- } else
- fail_and_notify();
-
- return value;
-}
-
-static void json_free_pair(struct json_pair *pair);
-static void json_free_value(struct json_value *value);
+ free(str);
+ return obj;
-void json_free_object(struct json_object *obj)
-{
- int i;
-
- for (i = 0; i < obj->pair_cnt; i++)
- json_free_pair(obj->pairs[i]);
- free(obj->pairs);
- free(obj);
-}
-
-void json_free_array(struct json_object *array)
-{
- int i;
-
- for (i = 0; i < array->value_cnt; i++)
- json_free_value(array->values[i]);
- free(array->values);
- free(array);
-}
-
-static void json_free_pair(struct json_pair *pair)
-{
- json_free_value(pair->value);
- free(pair->name);
- free(pair);
-}
-
-static void json_free_value(struct json_value *value)
-{
- switch (value->type) {
- case JSON_TYPE_STRING:
- free(value->string);
- break;
- case JSON_TYPE_OBJECT:
- json_free_object(value->object);
- break;
- case JSON_TYPE_ARRAY:
- json_free_array(value->array);
- break;
- }
- free(value);
-}
-
-static int json_array_add_value(struct json_object *array, struct json_value *value)
-{
- struct json_value **values = realloc(array->values,
- sizeof(struct json_value *) * (array->value_cnt + 1));
-
- if (!values)
- return ENOMEM;
- values[array->value_cnt] = value;
- array->value_cnt++;
- array->values = values;
-
- value->parent_type = JSON_PARENT_TYPE_ARRAY;
- value->parent_array = array;
- return 0;
-}
-
-static int json_object_add_pair(struct json_object *obj, struct json_pair *pair)
-{
- struct json_pair **pairs = realloc(obj->pairs,
- sizeof(struct json_pair *) * (obj->pair_cnt + 1));
- if (!pairs)
- return ENOMEM;
- pairs[obj->pair_cnt] = pair;
- obj->pair_cnt++;
- obj->pairs = pairs;
-
- pair->parent = obj;
- return 0;
-}
-
-int json_object_add_value_type(struct json_object *obj, const char *name, int type, ...)
-{
- struct json_value *value;
- struct json_pair *pair;
- va_list args;
- int ret;
-
- va_start(args, type);
- if (type == JSON_TYPE_STRING)
- value = json_create_value_string(va_arg(args, char *));
- else if (type == JSON_TYPE_INTEGER)
- value = json_create_value_int(va_arg(args, long long));
- else if (type == JSON_TYPE_UINT)
- value = json_create_value_uint(va_arg(args, unsigned long long));
- else if (type == JSON_TYPE_FLOAT)
- value = json_create_value_float(va_arg(args, long double));
- else if (type == JSON_TYPE_OBJECT)
- value = json_create_value_object(va_arg(args, struct json_object *));
- else
- value = json_create_value_array(va_arg(args, struct json_object *));
- va_end(args);
-
- if (!value)
- return ENOMEM;
-
- pair = json_create_pair(name, value);
- if (!pair) {
- json_free_value(value);
- return ENOMEM;
- }
- ret = json_object_add_pair(obj, pair);
- if (ret) {
- json_free_pair(pair);
- return ENOMEM;
- }
- return 0;
-}
-
-static void json_print_array(struct json_object *array, void *);
-int json_array_add_value_type(struct json_object *array, int type, ...)
-{
- struct json_value *value;
- va_list args;
- int ret;
-
- va_start(args, type);
- if (type == JSON_TYPE_STRING)
- value = json_create_value_string(va_arg(args, char *));
- else if (type == JSON_TYPE_INTEGER)
- value = json_create_value_int(va_arg(args, long long));
- else if (type == JSON_TYPE_UINT)
- value = json_create_value_uint(va_arg(args, unsigned long long));
- else if (type == JSON_TYPE_FLOAT)
- value = json_create_value_float(va_arg(args, double));
- else if (type == JSON_TYPE_OBJECT)
- value = json_create_value_object(va_arg(args, struct json_object *));
- else
- value = json_create_value_array(va_arg(args, struct json_object *));
- va_end(args);
-
- if (!value)
- return ENOMEM;
-
- ret = json_array_add_value(array, value);
- if (ret) {
- json_free_value(value);
- return ENOMEM;
- }
- return 0;
-}
-
-static int json_value_level(struct json_value *value);
-static int json_pair_level(struct json_pair *pair);
-static int json_array_level(struct json_object *array);
-static int json_object_level(struct json_object *object)
-{
- if (object->parent == NULL)
- return 0;
- return json_value_level(object->parent);
-}
-
-static int json_pair_level(struct json_pair *pair)
-{
- return json_object_level(pair->parent) + 1;
-}
-
-static int json_array_level(struct json_object *array)
-{
- return json_value_level(array->parent);
-}
-
-static int json_value_level(struct json_value *value)
-{
- if (value->parent_type == JSON_PARENT_TYPE_PAIR)
- return json_pair_level(value->parent_pair);
- else
- return json_array_level(value->parent_array) + 1;
-}
-
-static void json_print_level(int level, void *out)
-{
- while (level-- > 0)
- printf(" ");
-}
-
-static void json_print_pair(struct json_pair *pair, void *);
-static void json_print_array(struct json_object *array, void *);
-static void json_print_value(struct json_value *value, void *);
-void json_print_object(struct json_object *obj, void *out)
-{
- int i;
-
- printf("{\n");
- for (i = 0; i < obj->pair_cnt; i++) {
- if (i > 0)
- printf(",\n");
- json_print_pair(obj->pairs[i], out);
- }
- printf("\n");
- json_print_level(json_object_level(obj), out);
- printf("}");
-}
-
-static void json_print_pair(struct json_pair *pair, void *out)
-{
- json_print_level(json_pair_level(pair), out);
- printf("\"%s\" : ", pair->name);
- json_print_value(pair->value, out);
-}
-
-static void json_print_array(struct json_object *array, void *out)
-{
- int i;
-
- printf("[\n");
- for (i = 0; i < array->value_cnt; i++) {
- if (i > 0)
- printf(",\n");
- json_print_level(json_value_level(array->values[i]), out);
- json_print_value(array->values[i], out);
- }
- printf("\n");
- json_print_level(json_array_level(array), out);
- printf("]");
-}
-
-static void json_print_value(struct json_value *value, void *out)
-{
- switch (value->type) {
- case JSON_TYPE_STRING:
- printf( "\"%s\"", value->string);
- break;
- case JSON_TYPE_INTEGER:
- printf( "%lld", value->integer_number);
- break;
- case JSON_TYPE_UINT:
- printf( "%llu", value->uint_number);
- break;
- case JSON_TYPE_FLOAT:
- printf( "%.0Lf", value->float_number);
- break;
- case JSON_TYPE_OBJECT:
- json_print_object(value->object, out);
- break;
- case JSON_TYPE_ARRAY:
- json_print_array(value->array, out);
- break;
- }
}