Add LICENSE and a copyright note to all sources
[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_nocheck(json_t *json, const char *key, json_t *value)
122 {
123     json_object_t *object;
124
125     if(!json_is_object(json))
126         return -1;
127
128     object = json_to_object(json);
129     return hashtable_set(&object->hashtable, strdup(key), json_incref(value));
130 }
131
132 int json_object_set(json_t *json, const char *key, json_t *value)
133 {
134     if(!utf8_check_string(key, -1))
135         return -1;
136
137     return json_object_set_nocheck(json, key, value);
138 }
139
140 int json_object_del(json_t *json, const char *key)
141 {
142     json_object_t *object;
143
144     if(!json_is_object(json))
145         return -1;
146
147     object = json_to_object(json);
148     return hashtable_del(&object->hashtable, key);
149 }
150
151 void *json_object_iter(json_t *json)
152 {
153     json_object_t *object;
154
155     if(!json_is_object(json))
156         return NULL;
157
158     object = json_to_object(json);
159     return hashtable_iter(&object->hashtable);
160 }
161
162 void *json_object_iter_next(json_t *json, void *iter)
163 {
164     json_object_t *object;
165
166     if(!json_is_object(json) || iter == NULL)
167         return NULL;
168
169     object = json_to_object(json);
170     return hashtable_iter_next(&object->hashtable, iter);
171 }
172
173 const char *json_object_iter_key(void *iter)
174 {
175     if(!iter)
176         return NULL;
177
178     return (const char *)hashtable_iter_key(iter);
179 }
180
181 json_t *json_object_iter_value(void *iter)
182 {
183     if(!iter)
184         return NULL;
185
186     return (json_t *)hashtable_iter_value(iter);
187 }
188
189
190 /*** array ***/
191
192 json_t *json_array(void)
193 {
194     json_array_t *array = malloc(sizeof(json_array_t));
195     if(!array)
196       return NULL;
197     json_init(&array->json, JSON_ARRAY);
198
199     array->entries = 0;
200     array->size = 0;
201     array->table = NULL;
202
203     return &array->json;
204 }
205
206 static void json_delete_array(json_array_t *array)
207 {
208     unsigned int i;
209
210     for(i = 0; i < array->entries; i++)
211         json_decref(array->table[i]);
212
213     free(array->table);
214     free(array);
215 }
216
217 unsigned int json_array_size(const json_t *json)
218 {
219     if(!json_is_array(json))
220         return 0;
221
222     return json_to_array(json)->entries;
223 }
224
225 json_t *json_array_get(const json_t *json, unsigned int index)
226 {
227     json_array_t *array;
228     if(!json_is_array(json))
229         return NULL;
230     array = json_to_array(json);
231
232     if(index >= array->size)
233         return NULL;
234
235     return array->table[index];
236 }
237
238 int json_array_set(json_t *json, unsigned int index, json_t *value)
239 {
240     json_array_t *array;
241     if(!json_is_array(json))
242         return -1;
243     array = json_to_array(json);
244
245     if(index >= array->size)
246         return -1;
247
248     array->table[index] = json_incref(value);
249     return 0;
250 }
251
252 int json_array_append(json_t *json, json_t *value)
253 {
254     json_array_t *array;
255     if(!json_is_array(json))
256         return -1;
257     array = json_to_array(json);
258
259     if(array->entries == array->size) {
260         array->size = max(8, array->size * 2);
261         array->table = realloc(array->table, array->size * sizeof(json_t *));
262         if(!array->table)
263             return -1;
264     }
265
266     array->table[array->entries] = json_incref(value);
267     array->entries++;
268
269     return 0;
270 }
271
272
273 /*** string ***/
274
275 json_t *json_string_nocheck(const char *value)
276 {
277     json_string_t *string = malloc(sizeof(json_string_t));
278     if(!string)
279        return NULL;
280     json_init(&string->json, JSON_STRING);
281
282     string->value = strdup(value);
283     return &string->json;
284 }
285
286 json_t *json_string(const char *value)
287 {
288     if(!utf8_check_string(value, -1))
289         return NULL;
290
291     return json_string_nocheck(value);
292 }
293
294 const char *json_string_value(const json_t *json)
295 {
296     if(!json_is_string(json))
297         return NULL;
298
299     return json_to_string(json)->value;
300 }
301
302 static void json_delete_string(json_string_t *string)
303 {
304     free(string->value);
305     free(string);
306 }
307
308
309 /*** integer ***/
310
311 json_t *json_integer(int value)
312 {
313     json_integer_t *integer = malloc(sizeof(json_integer_t));
314     if(!integer)
315        return NULL;
316     json_init(&integer->json, JSON_INTEGER);
317
318     integer->value = value;
319     return &integer->json;
320 }
321
322 int json_integer_value(const json_t *json)
323 {
324     if(!json_is_integer(json))
325         return 0;
326
327     return json_to_integer(json)->value;
328 }
329
330 static void json_delete_integer(json_integer_t *integer)
331 {
332     free(integer);
333 }
334
335
336 /*** real ***/
337
338 json_t *json_real(double value)
339 {
340     json_real_t *real = malloc(sizeof(json_real_t));
341     if(!real)
342        return NULL;
343     json_init(&real->json, JSON_REAL);
344
345     real->value = value;
346     return &real->json;
347 }
348
349 double json_real_value(const json_t *json)
350 {
351     if(!json_is_real(json))
352         return 0;
353
354     return json_to_real(json)->value;
355 }
356
357 static void json_delete_real (json_real_t *real)
358 {
359     free(real);
360 }
361
362
363 /*** number ***/
364
365 double json_number_value(const json_t *json)
366 {
367     if(json_is_integer(json))
368         return json_integer_value(json);
369     else if(json_is_real(json))
370         return json_real_value(json);
371     else
372         return 0.0;
373 }
374
375
376 /*** simple values ***/
377
378 json_t *json_true(void)
379 {
380     static json_t the_true = {
381         .type = JSON_TRUE,
382         .refcount = 1
383     };
384     return json_incref(&the_true);
385 }
386
387
388 json_t *json_false(void)
389 {
390     static json_t the_false = {
391         .type = JSON_FALSE,
392         .refcount = 1
393     };
394     return json_incref(&the_false);
395 }
396
397
398 json_t *json_null(void)
399 {
400     static json_t the_null = {
401         .type = JSON_NULL,
402         .refcount = 1
403     };
404     return json_incref(&the_null);
405 }
406
407
408 /*** deletion ***/
409
410 void json_delete(json_t *json)
411 {
412     if(json_is_object(json))
413         json_delete_object(json_to_object(json));
414
415     else if(json_is_array(json))
416         json_delete_array(json_to_array(json));
417
418     else if(json_is_string(json))
419         json_delete_string(json_to_string(json));
420
421     else if(json_is_integer(json))
422         json_delete_integer(json_to_integer(json));
423
424     else if(json_is_real(json))
425         json_delete_real(json_to_real(json));
426
427     /* json_delete is not called for true, false or null */
428 }