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