Initial import
[profile/ivi/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
8 #define max(a, b)  ((a) > (b) ? (a) : (b))
9
10 #define container_of(ptr_, type_, member_)  \
11     ((type_ *)((char *)ptr_ - (size_t)&((type_ *)0)->member_))
12
13 typedef struct {
14     json_t json;
15     hashtable_t *hashtable;
16 } json_object_t;
17
18 typedef struct {
19     json_t json;
20     unsigned int size;
21     unsigned int entries;
22     json_t **table;
23 } json_array_t;
24
25 typedef struct {
26     json_t json;
27     char *value;
28 } json_string_t;
29
30 typedef struct {
31     json_t json;
32     double value;
33 } json_number_t;
34
35 #define json_to_object(json_)  container_of(json_, json_object_t, json)
36 #define json_to_array(json_)   container_of(json_, json_array_t, json)
37 #define json_to_string(json_)  container_of(json_, json_string_t, json)
38 #define json_to_number(json_)  container_of(json_, json_number_t, json)
39
40 static inline void json_init(json_t *json, json_type type)
41 {
42     json->type = type;
43     json->refcount = 1;
44 }
45
46
47 /*** object ***/
48
49 static unsigned int hash_string(const void *key)
50 {
51     const char *str = (const char *)key;
52     unsigned int hash = 5381;
53     unsigned int c;
54
55     while((c = (unsigned int)*str))
56     {
57         hash = ((hash << 5) + hash) + c;
58         str++;
59     }
60
61     return hash;
62 }
63
64 static int string_equal(const void *key1, const void *key2)
65 {
66     return strcmp((const char *)key1, (const char *)key2) == 0;
67 }
68
69 static void value_decref(void *value)
70 {
71     json_decref((json_t *)value);
72 }
73
74 json_t *json_object(void)
75 {
76     json_object_t *object = malloc(sizeof(json_object_t));
77     if(!object)
78         return NULL;
79     json_init(&object->json, JSON_OBJECT);
80
81     object->hashtable =
82       hashtable_new(hash_string, string_equal, free, value_decref);
83     if(!object->hashtable)
84     {
85         free(object);
86         return NULL;
87     }
88     return &object->json;
89 }
90
91 static void json_delete_object(json_object_t *object)
92 {
93     hashtable_free(object->hashtable);
94     free(object);
95 }
96
97 json_t *json_object_get(const json_t *json, const char *key)
98 {
99     json_object_t *object;
100
101     if(!json_is_object(json))
102         return NULL;
103
104     return hashtable_get(object->hashtable, key);
105 }
106
107 int json_object_del(json_t *json, const char *key)
108 {
109     json_object_t *object;
110
111     if(!json_is_object(json))
112         return -1;
113
114     object = json_to_object(json);
115     return hashtable_del(object->hashtable, key);
116 }
117
118 int json_object_set(json_t *json, const char *key, json_t *value)
119 {
120     json_object_t *object;
121
122     if(!json_is_object(json))
123         return -1;
124
125     object = json_to_object(json);
126     return hashtable_set(object->hashtable, strdup(key), json_incref(value));
127 }
128
129
130 /*** array ***/
131
132 json_t *json_array(void)
133 {
134     json_array_t *array = malloc(sizeof(json_array_t));
135     if(!array)
136       return NULL;
137     json_init(&array->json, JSON_ARRAY);
138
139     array->entries = 0;
140     array->size = 0;
141     array->table = NULL;
142
143     return &array->json;
144 }
145
146 static void json_delete_array(json_array_t *array)
147 {
148     unsigned int i;
149
150     for(i = 0; i < array->entries; i++)
151         json_decref(array->table[i]);
152
153     free(array->table);
154     free(array);
155 }
156
157 unsigned int json_array_size(const json_t *json)
158 {
159     if(!json_is_array(json))
160         return 0;
161
162     return json_to_array(json)->entries;
163 }
164
165 json_t *json_array_get(const json_t *json, unsigned int index)
166 {
167     json_array_t *array;
168     if(!json_is_array(json))
169         return NULL;
170     array = json_to_array(json);
171
172     if(index >= array->size)
173         return NULL;
174
175     return array->table[index];
176 }
177
178 int json_array_set(json_t *json, unsigned int index, json_t *value)
179 {
180     json_array_t *array;
181     if(!json_is_array(json))
182         return -1;
183     array = json_to_array(json);
184
185     if(index >= array->size)
186         return -1;
187
188     array->table[index] = json_incref(value);
189     return 0;
190 }
191
192 int json_array_append(json_t *json, json_t *value)
193 {
194     json_array_t *array;
195     if(!json_is_array(json))
196         return -1;
197     array = json_to_array(json);
198
199     if(array->entries == array->size) {
200         array->size = max(8, array->size * 2);
201         array->table = realloc(array->table, array->size * sizeof(json_t *));
202         if(!array->table)
203             return -1;
204     }
205
206     array->table[array->entries] = json_incref(value);
207     array->entries++;
208
209     return 0;
210 }
211
212
213 /*** string ***/
214
215 json_t *json_string(const char *value)
216 {
217     json_string_t *string = malloc(sizeof(json_string_t));
218     if(!string)
219        return NULL;
220     json_init(&string->json, JSON_STRING);
221
222     string->value = strdup(value);
223     return &string->json;
224 }
225
226 const char *json_string_value(const json_t *json)
227 {
228     if(!json_is_string(json))
229         return NULL;
230
231     return json_to_string(json)->value;
232 }
233
234 static void json_delete_string(json_string_t *string)
235 {
236     free(string->value);
237     free(string);
238 }
239
240 json_t *json_number(double value)
241 {
242     json_number_t *number = malloc(sizeof(json_number_t));
243     if(!number)
244        return NULL;
245     json_init(&number->json, JSON_NUMBER);
246
247     number->value = value;
248     return &number->json;
249 }
250
251
252 /*** number ***/
253
254 double json_number_value(const json_t *json)
255 {
256     if(!json_is_number(json))
257         return 0.0;
258
259     return json_to_number(json)->value;
260 }
261
262 static void json_delete_number(json_number_t *number)
263 {
264     free(number);
265 }
266
267
268 /*** simple values ***/
269
270 json_t *json_true(void)
271 {
272     static json_t the_true = {
273         .type = JSON_TRUE,
274         .refcount = 1
275     };
276     return json_incref(&the_true);
277 }
278
279
280 json_t *json_false(void)
281 {
282     static json_t the_false = {
283         .type = JSON_FALSE,
284         .refcount = 1
285     };
286     return json_incref(&the_false);
287 }
288
289
290 json_t *json_null(void)
291 {
292     static json_t the_null = {
293         .type = JSON_NULL,
294         .refcount = 1
295     };
296     return json_incref(&the_null);
297 }
298
299
300 /*** deletion ***/
301
302 void json_delete(json_t *json)
303 {
304     if(json_is_object(json))
305         json_delete_object(json_to_object(json));
306
307     else if(json_is_array(json))
308         json_delete_array(json_to_array(json));
309
310     else if(json_is_string(json))
311         json_delete_string(json_to_string(json));
312
313     else if(json_is_number(json))
314         json_delete_number(json_to_number(json));
315
316     /* json_delete is not called for true, false or null */
317 }