6f0094b64cd137bcaba04d8ec04d4cd67e855f43
[jansson.git] / src / value.c
1 #define _GNU_SOURCE
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include <jansson.h>
6 #include "hashtable.h"
7 #include "jansson_private.h"
8 #include "utf.h"
9 #include "util.h"
10
11 #define container_of(ptr_, type_, member_)  \
12     ((type_ *)((char *)ptr_ - (size_t)&((type_ *)0)->member_))
13
14 typedef struct {
15     json_t json;
16     hashtable_t hashtable;
17 } json_object_t;
18
19 typedef struct {
20     json_t json;
21     unsigned int size;
22     unsigned int entries;
23     json_t **table;
24 } json_array_t;
25
26 typedef struct {
27     json_t json;
28     char *value;
29 } json_string_t;
30
31 typedef struct {
32     json_t json;
33     double value;
34 } json_real_t;
35
36 typedef struct {
37     json_t json;
38     int value;
39 } json_integer_t;
40
41 #define json_to_object(json_)  container_of(json_, json_object_t, json)
42 #define json_to_array(json_)   container_of(json_, json_array_t, json)
43 #define json_to_string(json_)  container_of(json_, json_string_t, json)
44 #define json_to_real(json_)   container_of(json_, json_real_t, json)
45 #define json_to_integer(json_) container_of(json_, json_integer_t, json)
46
47 static inline void json_init(json_t *json, json_type type)
48 {
49     json->type = type;
50     json->refcount = 1;
51 }
52
53
54 /*** object ***/
55
56 static unsigned int hash_string(const void *key)
57 {
58     const char *str = (const char *)key;
59     unsigned int hash = 5381;
60     unsigned int c;
61
62     while((c = (unsigned int)*str))
63     {
64         hash = ((hash << 5) + hash) + c;
65         str++;
66     }
67
68     return hash;
69 }
70
71 static int string_equal(const void *key1, const void *key2)
72 {
73     return strcmp((const char *)key1, (const char *)key2) == 0;
74 }
75
76 static void value_decref(void *value)
77 {
78     json_decref((json_t *)value);
79 }
80
81 json_t *json_object(void)
82 {
83     json_object_t *object = malloc(sizeof(json_object_t));
84     if(!object)
85         return NULL;
86     json_init(&object->json, JSON_OBJECT);
87
88     if(hashtable_init(&object->hashtable, hash_string, string_equal,
89                       free, value_decref))
90     {
91         free(object);
92         return NULL;
93     }
94     return &object->json;
95 }
96
97 static void json_delete_object(json_object_t *object)
98 {
99     hashtable_close(&object->hashtable);
100     free(object);
101 }
102
103 json_t *json_object_get(const json_t *json, const char *key)
104 {
105     json_object_t *object;
106
107     if(!json_is_object(json))
108         return NULL;
109
110     object = json_to_object(json);
111     return hashtable_get(&object->hashtable, key);
112 }
113
114 int json_object_set_nocheck(json_t *json, const char *key, json_t *value)
115 {
116     json_object_t *object;
117
118     if(!json_is_object(json))
119         return -1;
120
121     object = json_to_object(json);
122     return hashtable_set(&object->hashtable, strdup(key), json_incref(value));
123 }
124
125 int json_object_set(json_t *json, const char *key, json_t *value)
126 {
127     if(!utf8_check_string(key, -1))
128         return -1;
129
130     return json_object_set_nocheck(json, key, value);
131 }
132
133 int json_object_del(json_t *json, const char *key)
134 {
135     json_object_t *object;
136
137     if(!json_is_object(json))
138         return -1;
139
140     object = json_to_object(json);
141     return hashtable_del(&object->hashtable, key);
142 }
143
144 void *json_object_iter(json_t *json)
145 {
146     json_object_t *object;
147
148     if(!json_is_object(json))
149         return NULL;
150
151     object = json_to_object(json);
152     return hashtable_iter(&object->hashtable);
153 }
154
155 void *json_object_iter_next(json_t *json, void *iter)
156 {
157     json_object_t *object;
158
159     if(!json_is_object(json) || iter == NULL)
160         return NULL;
161
162     object = json_to_object(json);
163     return hashtable_iter_next(&object->hashtable, iter);
164 }
165
166 const char *json_object_iter_key(void *iter)
167 {
168     if(!iter)
169         return NULL;
170
171     return (const char *)hashtable_iter_key(iter);
172 }
173
174 json_t *json_object_iter_value(void *iter)
175 {
176     if(!iter)
177         return NULL;
178
179     return (json_t *)hashtable_iter_value(iter);
180 }
181
182
183 /*** array ***/
184
185 json_t *json_array(void)
186 {
187     json_array_t *array = malloc(sizeof(json_array_t));
188     if(!array)
189       return NULL;
190     json_init(&array->json, JSON_ARRAY);
191
192     array->entries = 0;
193     array->size = 0;
194     array->table = NULL;
195
196     return &array->json;
197 }
198
199 static void json_delete_array(json_array_t *array)
200 {
201     unsigned int i;
202
203     for(i = 0; i < array->entries; i++)
204         json_decref(array->table[i]);
205
206     free(array->table);
207     free(array);
208 }
209
210 unsigned int json_array_size(const json_t *json)
211 {
212     if(!json_is_array(json))
213         return 0;
214
215     return json_to_array(json)->entries;
216 }
217
218 json_t *json_array_get(const json_t *json, unsigned int index)
219 {
220     json_array_t *array;
221     if(!json_is_array(json))
222         return NULL;
223     array = json_to_array(json);
224
225     if(index >= array->size)
226         return NULL;
227
228     return array->table[index];
229 }
230
231 int json_array_set(json_t *json, unsigned int index, json_t *value)
232 {
233     json_array_t *array;
234     if(!json_is_array(json))
235         return -1;
236     array = json_to_array(json);
237
238     if(index >= array->size)
239         return -1;
240
241     array->table[index] = json_incref(value);
242     return 0;
243 }
244
245 int json_array_append(json_t *json, json_t *value)
246 {
247     json_array_t *array;
248     if(!json_is_array(json))
249         return -1;
250     array = json_to_array(json);
251
252     if(array->entries == array->size) {
253         array->size = max(8, array->size * 2);
254         array->table = realloc(array->table, array->size * sizeof(json_t *));
255         if(!array->table)
256             return -1;
257     }
258
259     array->table[array->entries] = json_incref(value);
260     array->entries++;
261
262     return 0;
263 }
264
265
266 /*** string ***/
267
268 json_t *json_string_nocheck(const char *value)
269 {
270     json_string_t *string = malloc(sizeof(json_string_t));
271     if(!string)
272        return NULL;
273     json_init(&string->json, JSON_STRING);
274
275     string->value = strdup(value);
276     return &string->json;
277 }
278
279 json_t *json_string(const char *value)
280 {
281     if(!utf8_check_string(value, -1))
282         return NULL;
283
284     return json_string_nocheck(value);
285 }
286
287 const char *json_string_value(const json_t *json)
288 {
289     if(!json_is_string(json))
290         return NULL;
291
292     return json_to_string(json)->value;
293 }
294
295 static void json_delete_string(json_string_t *string)
296 {
297     free(string->value);
298     free(string);
299 }
300
301
302 /*** integer ***/
303
304 json_t *json_integer(int value)
305 {
306     json_integer_t *integer = malloc(sizeof(json_integer_t));
307     if(!integer)
308        return NULL;
309     json_init(&integer->json, JSON_INTEGER);
310
311     integer->value = value;
312     return &integer->json;
313 }
314
315 int json_integer_value(const json_t *json)
316 {
317     if(!json_is_integer(json))
318         return 0;
319
320     return json_to_integer(json)->value;
321 }
322
323 static void json_delete_integer(json_integer_t *integer)
324 {
325     free(integer);
326 }
327
328
329 /*** real ***/
330
331 json_t *json_real(double value)
332 {
333     json_real_t *real = malloc(sizeof(json_real_t));
334     if(!real)
335        return NULL;
336     json_init(&real->json, JSON_REAL);
337
338     real->value = value;
339     return &real->json;
340 }
341
342 double json_real_value(const json_t *json)
343 {
344     if(!json_is_real(json))
345         return 0;
346
347     return json_to_real(json)->value;
348 }
349
350 static void json_delete_real (json_real_t *real)
351 {
352     free(real);
353 }
354
355
356 /*** number ***/
357
358 double json_number_value(const json_t *json)
359 {
360     if(json_is_integer(json))
361         return json_integer_value(json);
362     else if(json_is_real(json))
363         return json_real_value(json);
364     else
365         return 0.0;
366 }
367
368
369 /*** simple values ***/
370
371 json_t *json_true(void)
372 {
373     static json_t the_true = {
374         .type = JSON_TRUE,
375         .refcount = 1
376     };
377     return json_incref(&the_true);
378 }
379
380
381 json_t *json_false(void)
382 {
383     static json_t the_false = {
384         .type = JSON_FALSE,
385         .refcount = 1
386     };
387     return json_incref(&the_false);
388 }
389
390
391 json_t *json_null(void)
392 {
393     static json_t the_null = {
394         .type = JSON_NULL,
395         .refcount = 1
396     };
397     return json_incref(&the_null);
398 }
399
400
401 /*** deletion ***/
402
403 void json_delete(json_t *json)
404 {
405     if(json_is_object(json))
406         json_delete_object(json_to_object(json));
407
408     else if(json_is_array(json))
409         json_delete_array(json_to_array(json));
410
411     else if(json_is_string(json))
412         json_delete_string(json_to_string(json));
413
414     else if(json_is_integer(json))
415         json_delete_integer(json_to_integer(json));
416
417     else if(json_is_real(json))
418         json_delete_real(json_to_real(json));
419
420     /* json_delete is not called for true, false or null */
421 }