1cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li#include <stdlib.h>
2cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li#include <string.h>
3cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li#include <stdio.h>
4cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li#include <errno.h>
5cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li#include <stdarg.h>
6cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li#include "json.h"
7cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li#include "log.h"
8cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
9cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listruct json_object *json_create_object(void)
10cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
116a27ed94ab5c2a07f6b98f2bcdce06c56f16e8cdJens Axboe	return calloc(1, sizeof(struct json_object));
12cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
13cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
14cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listruct json_array *json_create_array(void)
15cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
166a27ed94ab5c2a07f6b98f2bcdce06c56f16e8cdJens Axboe	return calloc(1, sizeof(struct json_array));
17cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
18cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
19cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic struct json_pair *json_create_pair(const char *name, struct json_value *value)
20cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
21cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	struct json_pair *pair = malloc(sizeof(struct json_pair));
22cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (pair) {
23cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		pair->name = strdup(name);
24cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		pair->value = value;
25cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
26cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value->parent_type = JSON_PARENT_TYPE_PAIR;
27cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value->parent_pair = pair;
28cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	}
29cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	return pair;
30cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
31cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
32ee2e5717d1df0c37279eb94876777ee43d403e58Bruce Cranstatic struct json_value *json_create_value_int(long long number)
33cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
34cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	struct json_value *value = malloc(sizeof(struct json_value));
35cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
36cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (value) {
37cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value->type = JSON_TYPE_INTEGER;
38cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value->integer_number = number;
39cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	}
40cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	return value;
41cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
42cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
43cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic struct json_value *json_create_value_float(float number)
44cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
45cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	struct json_value *value = malloc(sizeof(struct json_value));
46cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
47cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (value) {
48cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value->type = JSON_TYPE_FLOAT;
49cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value->float_number = number;
50cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	}
51cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	return value;
52cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
53cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
54d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboestatic char *strdup_escape(const char *str)
55d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe{
56d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe	const char *input = str;
57d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe	char *p, *ret;
58d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe	int escapes;
59d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe
60a57251532f088ef372f317f89695678691e3e095Jens Axboe	if (!strlen(str))
61a57251532f088ef372f317f89695678691e3e095Jens Axboe		return NULL;
62a57251532f088ef372f317f89695678691e3e095Jens Axboe
63d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe	escapes = 0;
64d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe	while ((input = strpbrk(input, "\\\"")) != NULL) {
65d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe		escapes++;
66d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe		input++;
67d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe	}
68d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe
69a57251532f088ef372f317f89695678691e3e095Jens Axboe	p = ret = malloc(strlen(str) + escapes + 1);
70d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe	while (*str) {
71d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe		if (*str == '\\' || *str == '\"')
72d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe			*p++ = '\\';
73d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe		*p++ = *str++;
74d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe	}
75a57251532f088ef372f317f89695678691e3e095Jens Axboe	*p = '\0';
76d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe
77d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe	return ret;
78d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe}
79d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe
80d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe/*
81de8f6de97438d5664cd8765e60102b9109a273e2Anatol Pomozov * Valid JSON strings must escape '"' and '/' with a preceding '/'
82d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe */
83cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic struct json_value *json_create_value_string(const char *str)
84cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
85cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	struct json_value *value = malloc(sizeof(struct json_value));
86cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
87cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (value) {
88cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value->type = JSON_TYPE_STRING;
89d366a95e3c140e628efbac6448605455d8bd2dfcJens Axboe		value->string = strdup_escape(str);
90cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		if (!value->string) {
91cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li			free(value);
92cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li			value = NULL;
93cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		}
94cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	}
95cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	return value;
96cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
97cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
98cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic struct json_value *json_create_value_object(struct json_object *obj)
99cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
100cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	struct json_value *value = malloc(sizeof(struct json_value));
101cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
102cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (value) {
103cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value->type = JSON_TYPE_OBJECT;
104cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value->object = obj;
105cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		obj->parent = value;
106cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	}
107cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	return value;
108cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
109cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
110cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic struct json_value *json_create_value_array(struct json_array *array)
111cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
112cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	struct json_value *value = malloc(sizeof(struct json_value));
113cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
114cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (value) {
115cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value->type = JSON_TYPE_ARRAY;
116cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value->array = array;
117cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		array->parent = value;
118cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	}
119cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	return value;
120cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
121cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
122cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic void json_free_pair(struct json_pair *pair);
123cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic void json_free_value(struct json_value *value);
124f3afa57e36550288340f1b6c694f354ae72654b9Jens Axboe
125cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Livoid json_free_object(struct json_object *obj)
126cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
127cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	int i;
128cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
129cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	for (i = 0; i < obj->pair_cnt; i++)
130cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		json_free_pair(obj->pairs[i]);
131cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	free(obj->pairs);
132cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	free(obj);
133cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
134cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
135cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic void json_free_array(struct json_array *array)
136cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
137cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	int i;
138cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
139cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	for (i = 0; i < array->value_cnt; i++)
140cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		json_free_value(array->values[i]);
141cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	free(array->values);
142cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	free(array);
143cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
144cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
145cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic void json_free_pair(struct json_pair *pair)
146cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
147cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	json_free_value(pair->value);
148cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	free(pair->name);
149cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	free(pair);
150cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
151cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
152cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic void json_free_value(struct json_value *value)
153cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
154cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	switch (value->type) {
155cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	case JSON_TYPE_STRING:
156cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		free(value->string);
157cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		break;
158cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	case JSON_TYPE_OBJECT:
159cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		json_free_object(value->object);
160cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		break;
161cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	case JSON_TYPE_ARRAY:
162cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		json_free_array(value->array);
163cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		break;
164cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	}
165cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	free(value);
166cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
167cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
168cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic int json_array_add_value(struct json_array *array, struct json_value *value)
169cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
170cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	struct json_value **values = realloc(array->values,
171cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		sizeof(struct json_value *) * (array->value_cnt + 1));
172cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
173cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (!values)
174cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		return ENOMEM;
175cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	values[array->value_cnt] = value;
176cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	array->value_cnt++;
177cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	array->values = values;
178cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
179cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	value->parent_type = JSON_PARENT_TYPE_ARRAY;
180cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	value->parent_array = array;
181cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	return 0;
182cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
183cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
184cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic int json_object_add_pair(struct json_object *obj, struct json_pair *pair)
185cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
186cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	struct json_pair **pairs = realloc(obj->pairs,
187cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		sizeof(struct json_pair *) * (obj->pair_cnt + 1));
188cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (!pairs)
189cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		return ENOMEM;
190cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	pairs[obj->pair_cnt] = pair;
191cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	obj->pair_cnt++;
192cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	obj->pairs = pairs;
193cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
194cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	pair->parent = obj;
195cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	return 0;
196cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
197cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
198cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Liint json_object_add_value_type(struct json_object *obj, const char *name, int type, ...)
199cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
200cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	struct json_value *value;
201cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	struct json_pair *pair;
202cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	va_list args;
203cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	int ret;
204cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
205cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	va_start(args, type);
206cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (type == JSON_TYPE_STRING)
207cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value = json_create_value_string(va_arg(args, char *));
208cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	else if (type == JSON_TYPE_INTEGER)
209ee2e5717d1df0c37279eb94876777ee43d403e58Bruce Cran		value = json_create_value_int(va_arg(args, long long));
210cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	else if (type == JSON_TYPE_FLOAT)
211cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value = json_create_value_float(va_arg(args, double));
212cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	else if (type == JSON_TYPE_OBJECT)
213cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value = json_create_value_object(va_arg(args, struct json_object *));
214cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	else
215cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value = json_create_value_array(va_arg(args, struct json_array *));
216cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	va_end(args);
217cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
218cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (!value)
219cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		return ENOMEM;
220cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
221cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	pair = json_create_pair(name, value);
222cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (!pair) {
223cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		json_free_value(value);
224cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		return ENOMEM;
225cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	}
226cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	ret = json_object_add_pair(obj, pair);
227cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (ret) {
228cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		json_free_pair(pair);
229cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		return ENOMEM;
230cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	}
231cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	return 0;
232cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
233cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
234cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic void json_print_array(struct json_array *array);
235cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Liint json_array_add_value_type(struct json_array *array, int type, ...)
236cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
237cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	struct json_value *value;
238cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	va_list args;
239cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	int ret;
240cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
241cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	va_start(args, type);
242cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (type == JSON_TYPE_STRING)
243cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value = json_create_value_string(va_arg(args, char *));
244cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	else if (type == JSON_TYPE_INTEGER)
245ee2e5717d1df0c37279eb94876777ee43d403e58Bruce Cran		value = json_create_value_int(va_arg(args, long long));
246cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	else if (type == JSON_TYPE_FLOAT)
247cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value = json_create_value_float(va_arg(args, double));
248cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	else if (type == JSON_TYPE_OBJECT)
249cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value = json_create_value_object(va_arg(args, struct json_object *));
250cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	else
251cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		value = json_create_value_array(va_arg(args, struct json_array *));
252cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	va_end(args);
253cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
254cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (!value)
255cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		return ENOMEM;
256cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
257cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	ret = json_array_add_value(array, value);
258cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (ret) {
259cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		json_free_value(value);
260cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		return ENOMEM;
261cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	}
262cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	return 0;
263cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
264cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
265cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic int json_value_level(struct json_value *value);
266cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic int json_pair_level(struct json_pair *pair);
267cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic int json_array_level(struct json_array *array);
268cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic int json_object_level(struct json_object *object)
269cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
270cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (object->parent == NULL)
271cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		return 0;
272cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	return json_value_level(object->parent);
273cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
274cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
275cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic int json_pair_level(struct json_pair *pair)
276cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
277cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	return json_object_level(pair->parent) + 1;
278cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
279cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
280cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic int json_array_level(struct json_array *array)
281cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
282cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	return json_value_level(array->parent);
283cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
284cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
285cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic int json_value_level(struct json_value *value)
286cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
287cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	if (value->parent_type == JSON_PARENT_TYPE_PAIR)
288cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		return json_pair_level(value->parent_pair);
289cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	else
290cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		return json_array_level(value->parent_array) + 1;
291cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
292cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
293cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic void json_print_level(int level)
294cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
295cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	while (level-- > 0)
296cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		log_info("  ");
297cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
298cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
299cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic void json_print_pair(struct json_pair *pair);
300cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic void json_print_array(struct json_array *array);
301cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic void json_print_value(struct json_value *value);
302cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Livoid json_print_object(struct json_object *obj)
303cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
304cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	int i;
305cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
306cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	log_info("{\n");
307cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	for (i = 0; i < obj->pair_cnt; i++) {
308cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		if (i > 0)
309cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li			log_info(",\n");
310cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		json_print_pair(obj->pairs[i]);
311cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	}
312cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	log_info("\n");
313cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	json_print_level(json_object_level(obj));
314cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	log_info("}");
315cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
316cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
317cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic void json_print_pair(struct json_pair *pair)
318cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
319cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	json_print_level(json_pair_level(pair));
320cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	log_info("\"%s\" : ", pair->name);
321cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	json_print_value(pair->value);
322cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
323cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
324cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic void json_print_array(struct json_array *array)
325cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
326cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	int i;
327cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
328cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	log_info("[\n");
329cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	for (i = 0; i < array->value_cnt; i++) {
330cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		if (i > 0)
331cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li			log_info(",\n");
332cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		json_print_level(json_value_level(array->values[i]));
333cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		json_print_value(array->values[i]);
334cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	}
335cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	log_info("\n");
336cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	json_print_level(json_array_level(array));
337cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	log_info("]");
338cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
339cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li
340cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Listatic void json_print_value(struct json_value *value)
341cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{
342cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	switch (value->type) {
343cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	case JSON_TYPE_STRING:
344cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		log_info("\"%s\"", value->string);
345cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		break;
346cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	case JSON_TYPE_INTEGER:
347ee2e5717d1df0c37279eb94876777ee43d403e58Bruce Cran		log_info("%lld", value->integer_number);
348cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		break;
349cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	case JSON_TYPE_FLOAT:
350cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		log_info("%.2f", value->float_number);
351cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		break;
352cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	case JSON_TYPE_OBJECT:
353cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		json_print_object(value->object);
354cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		break;
355cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	case JSON_TYPE_ARRAY:
356cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		json_print_array(value->array);
357cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li		break;
358cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li	}
359cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li}
360