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