Make it compile on platforms where char is unsigned
[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->entries)
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->entries)
246         return -1;
247
248     json_decref(array->table[index]);
249     array->table[index] = json_incref(value);
250
251     return 0;
252 }
253
254 int json_array_append(json_t *json, json_t *value)
255 {
256     json_array_t *array;
257     if(!json_is_array(json))
258         return -1;
259     array = json_to_array(json);
260
261     if(array->entries == array->size) {
262         array->size = max(8, array->size * 2);
263         array->table = realloc(array->table, array->size * sizeof(json_t *));
264         if(!array->table)
265             return -1;
266     }
267
268     array->table[array->entries] = json_incref(value);
269     array->entries++;
270
271     return 0;
272 }
273
274
275 /*** string ***/
276
277 json_t *json_string_nocheck(const char *value)
278 {
279     json_string_t *string = malloc(sizeof(json_string_t));
280     if(!string)
281        return NULL;
282     json_init(&string->json, JSON_STRING);
283
284     string->value = strdup(value);
285     return &string->json;
286 }
287
288 json_t *json_string(const char *value)
289 {
290     if(!utf8_check_string(value, -1))
291         return NULL;
292
293     return json_string_nocheck(value);
294 }
295
296 const char *json_string_value(const json_t *json)
297 {
298     if(!json_is_string(json))
299         return NULL;
300
301     return json_to_string(json)->value;
302 }
303
304 static void json_delete_string(json_string_t *string)
305 {
306     free(string->value);
307     free(string);
308 }
309
310
311 /*** integer ***/
312
313 json_t *json_integer(int value)
314 {
315     json_integer_t *integer = malloc(sizeof(json_integer_t));
316     if(!integer)
317        return NULL;
318     json_init(&integer->json, JSON_INTEGER);
319
320     integer->value = value;
321     return &integer->json;
322 }
323
324 int json_integer_value(const json_t *json)
325 {
326     if(!json_is_integer(json))
327         return 0;
328
329     return json_to_integer(json)->value;
330 }
331
332 static void json_delete_integer(json_integer_t *integer)
333 {
334     free(integer);
335 }
336
337
338 /*** real ***/
339
340 json_t *json_real(double value)
341 {
342     json_real_t *real = malloc(sizeof(json_real_t));
343     if(!real)
344        return NULL;
345     json_init(&real->json, JSON_REAL);
346
347     real->value = value;
348     return &real->json;
349 }
350
351 double json_real_value(const json_t *json)
352 {
353     if(!json_is_real(json))
354         return 0;
355
356     return json_to_real(json)->value;
357 }
358
359 static void json_delete_real (json_real_t *real)
360 {
361     free(real);
362 }
363
364
365 /*** number ***/
366
367 double json_number_value(const json_t *json)
368 {
369     if(json_is_integer(json))
370         return json_integer_value(json);
371     else if(json_is_real(json))
372         return json_real_value(json);
373     else
374         return 0.0;
375 }
376
377
378 /*** simple values ***/
379
380 json_t *json_true(void)
381 {
382     static json_t the_true = {
383         .type = JSON_TRUE,
384         .refcount = 1
385     };
386     return json_incref(&the_true);
387 }
388
389
390 json_t *json_false(void)
391 {
392     static json_t the_false = {
393         .type = JSON_FALSE,
394         .refcount = 1
395     };
396     return json_incref(&the_false);
397 }
398
399
400 json_t *json_null(void)
401 {
402     static json_t the_null = {
403         .type = JSON_NULL,
404         .refcount = 1
405     };
406     return json_incref(&the_null);
407 }
408
409
410 /*** deletion ***/
411
412 void json_delete(json_t *json)
413 {
414     if(json_is_object(json))
415         json_delete_object(json_to_object(json));
416
417     else if(json_is_array(json))
418         json_delete_array(json_to_array(json));
419
420     else if(json_is_string(json))
421         json_delete_string(json_to_string(json));
422
423     else if(json_is_integer(json))
424         json_delete_integer(json_to_integer(json));
425
426     else if(json_is_real(json))
427         json_delete_real(json_to_real(json));
428
429     /* json_delete is not called for true, false or null */
430 }