Makefile: typo
[fio.git] / json.c
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
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
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
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
38 static struct json_value *json_create_value_int(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
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
60 static struct json_value *json_create_value_string(const char *str)
61 {
62         struct json_value *value = malloc(sizeof(struct json_value));
63
64         if (value) {
65                 value->type = JSON_TYPE_STRING;
66                 value->string = strdup(str);
67                 if (!value->string) {
68                         free(value);
69                         value = NULL;
70                 }
71         }
72         return value;
73 }
74
75 static struct json_value *json_create_value_object(struct json_object *obj)
76 {
77         struct json_value *value = malloc(sizeof(struct json_value));
78
79         if (value) {
80                 value->type = JSON_TYPE_OBJECT;
81                 value->object = obj;
82                 obj->parent = value;
83         }
84         return value;
85 }
86
87 static struct json_value *json_create_value_array(struct json_array *array)
88 {
89         struct json_value *value = malloc(sizeof(struct json_value));
90
91         if (value) {
92                 value->type = JSON_TYPE_ARRAY;
93                 value->array = array;
94                 array->parent = value;
95         }
96         return value;
97 }
98
99 static void json_free_pair(struct json_pair *pair);
100 static void json_free_value(struct json_value *value);
101
102 void json_free_object(struct json_object *obj)
103 {
104         int i;
105
106         for (i = 0; i < obj->pair_cnt; i++)
107                 json_free_pair(obj->pairs[i]);
108         free(obj->pairs);
109         free(obj);
110 }
111
112 static void json_free_array(struct json_array *array)
113 {
114         int i;
115
116         for (i = 0; i < array->value_cnt; i++)
117                 json_free_value(array->values[i]);
118         free(array->values);
119         free(array);
120 }
121
122 static void json_free_pair(struct json_pair *pair)
123 {
124         json_free_value(pair->value);
125         free(pair->name);
126         free(pair);
127 }
128
129 static void json_free_value(struct json_value *value)
130 {
131         switch (value->type) {
132         case JSON_TYPE_STRING:
133                 free(value->string);
134                 break;
135         case JSON_TYPE_OBJECT:
136                 json_free_object(value->object);
137                 break;
138         case JSON_TYPE_ARRAY:
139                 json_free_array(value->array);
140                 break;
141         }
142         free(value);
143 }
144
145 static int json_array_add_value(struct json_array *array, struct json_value *value)
146 {
147         struct json_value **values = realloc(array->values,
148                 sizeof(struct json_value *) * (array->value_cnt + 1));
149
150         if (!values)
151                 return ENOMEM;
152         values[array->value_cnt] = value;
153         array->value_cnt++;
154         array->values = values;
155
156         value->parent_type = JSON_PARENT_TYPE_ARRAY;
157         value->parent_array = array;
158         return 0;
159 }
160
161 static int json_object_add_pair(struct json_object *obj, struct json_pair *pair)
162 {
163         struct json_pair **pairs = realloc(obj->pairs,
164                 sizeof(struct json_pair *) * (obj->pair_cnt + 1));
165         if (!pairs)
166                 return ENOMEM;
167         pairs[obj->pair_cnt] = pair;
168         obj->pair_cnt++;
169         obj->pairs = pairs;
170
171         pair->parent = obj;
172         return 0;
173 }
174
175 int json_object_add_value_type(struct json_object *obj, const char *name, int type, ...)
176 {
177         struct json_value *value;
178         struct json_pair *pair;
179         va_list args;
180         int ret;
181
182         va_start(args, type);
183         if (type == JSON_TYPE_STRING)
184                 value = json_create_value_string(va_arg(args, char *));
185         else if (type == JSON_TYPE_INTEGER)
186                 value = json_create_value_int(va_arg(args, long));
187         else if (type == JSON_TYPE_FLOAT)
188                 value = json_create_value_float(va_arg(args, double));
189         else if (type == JSON_TYPE_OBJECT)
190                 value = json_create_value_object(va_arg(args, struct json_object *));
191         else
192                 value = json_create_value_array(va_arg(args, struct json_array *));
193         va_end(args);
194
195         if (!value)
196                 return ENOMEM;
197
198         pair = json_create_pair(name, value);
199         if (!pair) {
200                 json_free_value(value);
201                 return ENOMEM;
202         }
203         ret = json_object_add_pair(obj, pair);
204         if (ret) {
205                 json_free_pair(pair);
206                 return ENOMEM;
207         }
208         return 0;
209 }
210
211 static void json_print_array(struct json_array *array);
212 int json_array_add_value_type(struct json_array *array, int type, ...)
213 {
214         struct json_value *value;
215         va_list args;
216         int ret;
217
218         va_start(args, type);
219         if (type == JSON_TYPE_STRING)
220                 value = json_create_value_string(va_arg(args, char *));
221         else if (type == JSON_TYPE_INTEGER)
222                 value = json_create_value_int(va_arg(args, long));
223         else if (type == JSON_TYPE_FLOAT)
224                 value = json_create_value_float(va_arg(args, double));
225         else if (type == JSON_TYPE_OBJECT)
226                 value = json_create_value_object(va_arg(args, struct json_object *));
227         else
228                 value = json_create_value_array(va_arg(args, struct json_array *));
229         va_end(args);
230
231         if (!value)
232                 return ENOMEM;
233
234         ret = json_array_add_value(array, value);
235         if (ret) {
236                 json_free_value(value);
237                 return ENOMEM;
238         }
239         return 0;
240 }
241
242 static int json_value_level(struct json_value *value);
243 static int json_pair_level(struct json_pair *pair);
244 static int json_array_level(struct json_array *array);
245 static int json_object_level(struct json_object *object)
246 {
247         if (object->parent == NULL)
248                 return 0;
249         return json_value_level(object->parent);
250 }
251
252 static int json_pair_level(struct json_pair *pair)
253 {
254         return json_object_level(pair->parent) + 1;
255 }
256
257 static int json_array_level(struct json_array *array)
258 {
259         return json_value_level(array->parent);
260 }
261
262 static int json_value_level(struct json_value *value)
263 {
264         if (value->parent_type == JSON_PARENT_TYPE_PAIR)
265                 return json_pair_level(value->parent_pair);
266         else
267                 return json_array_level(value->parent_array) + 1;
268 }
269
270 static void json_print_level(int level)
271 {
272         while (level-- > 0)
273                 log_info("  ");
274 }
275
276 static void json_print_pair(struct json_pair *pair);
277 static void json_print_array(struct json_array *array);
278 static void json_print_value(struct json_value *value);
279 void json_print_object(struct json_object *obj)
280 {
281         int i;
282
283         log_info("{\n");
284         for (i = 0; i < obj->pair_cnt; i++) {
285                 if (i > 0)
286                         log_info(",\n");
287                 json_print_pair(obj->pairs[i]);
288         }
289         log_info("\n");
290         json_print_level(json_object_level(obj));
291         log_info("}");
292 }
293
294 static void json_print_pair(struct json_pair *pair)
295 {
296         json_print_level(json_pair_level(pair));
297         log_info("\"%s\" : ", pair->name);
298         json_print_value(pair->value);
299 }
300
301 static void json_print_array(struct json_array *array)
302 {
303         int i;
304
305         log_info("[\n");
306         for (i = 0; i < array->value_cnt; i++) {
307                 if (i > 0)
308                         log_info(",\n");
309                 json_print_level(json_value_level(array->values[i]));
310                 json_print_value(array->values[i]);
311         }
312         log_info("\n");
313         json_print_level(json_array_level(array));
314         log_info("]");
315 }
316
317 static void json_print_value(struct json_value *value)
318 {
319         switch (value->type) {
320         case JSON_TYPE_STRING:
321                 log_info("\"%s\"", value->string);
322                 break;
323         case JSON_TYPE_INTEGER:
324                 log_info("%ld", value->integer_number);
325                 break;
326         case JSON_TYPE_FLOAT:
327                 log_info("%.2f", value->float_number);
328                 break;
329         case JSON_TYPE_OBJECT:
330                 json_print_object(value->object);
331                 break;
332         case JSON_TYPE_ARRAY:
333                 json_print_array(value->array);
334                 break;
335         }
336 }