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