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