2 * Copyright (c) 2009 Petri Lehtinen <petri@digip.org>
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.
13 #include "hashtable.h"
14 #include "jansson_private.h"
18 #define container_of(ptr_, type_, member_) \
19 ((type_ *)((char *)ptr_ - (size_t)&((type_ *)0)->member_))
23 hashtable_t hashtable;
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)
54 static inline void json_init(json_t *json, json_type type)
63 static unsigned int hash_string(const void *key)
65 const char *str = (const char *)key;
66 unsigned int hash = 5381;
69 while((c = (unsigned int)*str))
71 hash = ((hash << 5) + hash) + c;
78 static int string_equal(const void *key1, const void *key2)
80 return strcmp((const char *)key1, (const char *)key2) == 0;
83 static void value_decref(void *value)
85 json_decref((json_t *)value);
88 json_t *json_object(void)
90 json_object_t *object = malloc(sizeof(json_object_t));
93 json_init(&object->json, JSON_OBJECT);
95 if(hashtable_init(&object->hashtable, hash_string, string_equal,
101 return &object->json;
104 static void json_delete_object(json_object_t *object)
106 hashtable_close(&object->hashtable);
110 json_t *json_object_get(const json_t *json, const char *key)
112 json_object_t *object;
114 if(!json_is_object(json))
117 object = json_to_object(json);
118 return hashtable_get(&object->hashtable, key);
121 int json_object_set_nocheck(json_t *json, const char *key, json_t *value)
123 json_object_t *object;
125 if(!json_is_object(json))
128 object = json_to_object(json);
129 return hashtable_set(&object->hashtable, strdup(key), json_incref(value));
132 int json_object_set(json_t *json, const char *key, json_t *value)
134 if(!utf8_check_string(key, -1))
137 return json_object_set_nocheck(json, key, value);
140 int json_object_del(json_t *json, const char *key)
142 json_object_t *object;
144 if(!json_is_object(json))
147 object = json_to_object(json);
148 return hashtable_del(&object->hashtable, key);
151 void *json_object_iter(json_t *json)
153 json_object_t *object;
155 if(!json_is_object(json))
158 object = json_to_object(json);
159 return hashtable_iter(&object->hashtable);
162 void *json_object_iter_next(json_t *json, void *iter)
164 json_object_t *object;
166 if(!json_is_object(json) || iter == NULL)
169 object = json_to_object(json);
170 return hashtable_iter_next(&object->hashtable, iter);
173 const char *json_object_iter_key(void *iter)
178 return (const char *)hashtable_iter_key(iter);
181 json_t *json_object_iter_value(void *iter)
186 return (json_t *)hashtable_iter_value(iter);
192 json_t *json_array(void)
194 json_array_t *array = malloc(sizeof(json_array_t));
197 json_init(&array->json, JSON_ARRAY);
206 static void json_delete_array(json_array_t *array)
210 for(i = 0; i < array->entries; i++)
211 json_decref(array->table[i]);
217 unsigned int json_array_size(const json_t *json)
219 if(!json_is_array(json))
222 return json_to_array(json)->entries;
225 json_t *json_array_get(const json_t *json, unsigned int index)
228 if(!json_is_array(json))
230 array = json_to_array(json);
232 if(index >= array->size)
235 return array->table[index];
238 int json_array_set(json_t *json, unsigned int index, json_t *value)
241 if(!json_is_array(json))
243 array = json_to_array(json);
245 if(index >= array->size)
248 array->table[index] = json_incref(value);
252 int json_array_append(json_t *json, json_t *value)
255 if(!json_is_array(json))
257 array = json_to_array(json);
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 *));
266 array->table[array->entries] = json_incref(value);
275 json_t *json_string_nocheck(const char *value)
277 json_string_t *string = malloc(sizeof(json_string_t));
280 json_init(&string->json, JSON_STRING);
282 string->value = strdup(value);
283 return &string->json;
286 json_t *json_string(const char *value)
288 if(!utf8_check_string(value, -1))
291 return json_string_nocheck(value);
294 const char *json_string_value(const json_t *json)
296 if(!json_is_string(json))
299 return json_to_string(json)->value;
302 static void json_delete_string(json_string_t *string)
311 json_t *json_integer(int value)
313 json_integer_t *integer = malloc(sizeof(json_integer_t));
316 json_init(&integer->json, JSON_INTEGER);
318 integer->value = value;
319 return &integer->json;
322 int json_integer_value(const json_t *json)
324 if(!json_is_integer(json))
327 return json_to_integer(json)->value;
330 static void json_delete_integer(json_integer_t *integer)
338 json_t *json_real(double value)
340 json_real_t *real = malloc(sizeof(json_real_t));
343 json_init(&real->json, JSON_REAL);
349 double json_real_value(const json_t *json)
351 if(!json_is_real(json))
354 return json_to_real(json)->value;
357 static void json_delete_real (json_real_t *real)
365 double json_number_value(const json_t *json)
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);
376 /*** simple values ***/
378 json_t *json_true(void)
380 static json_t the_true = {
384 return json_incref(&the_true);
388 json_t *json_false(void)
390 static json_t the_false = {
394 return json_incref(&the_false);
398 json_t *json_null(void)
400 static json_t the_null = {
404 return json_incref(&the_null);
410 void json_delete(json_t *json)
412 if(json_is_object(json))
413 json_delete_object(json_to_object(json));
415 else if(json_is_array(json))
416 json_delete_array(json_to_array(json));
418 else if(json_is_string(json))
419 json_delete_string(json_to_string(json));
421 else if(json_is_integer(json))
422 json_delete_integer(json_to_integer(json));
424 else if(json_is_real(json))
425 json_delete_real(json_to_real(json));
427 /* json_delete is not called for true, false or null */