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