X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=src%2Fvalue.c;h=0df457022c83df84b5173f22a0a0dad24c2182a8;hb=fa7c2ea070672d05b34b6341142a193e9a7d0a8c;hp=e118af1cdf16627baed555dba7b8aa9cbb605afc;hpb=508873de9bad7019872857c7aa031570f6c1f205;p=jansson.git diff --git a/src/value.c b/src/value.c index e118af1..0df4570 100644 --- a/src/value.c +++ b/src/value.c @@ -1,11 +1,13 @@ /* - * Copyright (c) 2009 Petri Lehtinen + * Copyright (c) 2009-2011 Petri Lehtinen * * Jansson is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. */ #define _GNU_SOURCE + +#include #include #include @@ -13,10 +15,9 @@ #include "hashtable.h" #include "jansson_private.h" #include "utf.h" -#include "util.h" -static inline void json_init(json_t *json, json_type type) +static JSON_INLINE void json_init(json_t *json, json_type type) { json->type = type; json->refcount = 1; @@ -25,13 +26,20 @@ static inline void json_init(json_t *json, json_type type) /*** object ***/ -static unsigned int hash_string(const void *key) +/* This macro just returns a pointer that's a few bytes backwards from + string. This makes it possible to pass a pointer to object_key_t + when only the string inside it is used, without actually creating + an object_key_t instance. */ +#define string_to_key(string) container_of(string, object_key_t, key) + +static size_t hash_key(const void *ptr) { - const char *str = (const char *)key; - unsigned int hash = 5381; - unsigned int c; + const char *str = ((const object_key_t *)ptr)->key; - while((c = (unsigned int)*str)) + size_t hash = 5381; + size_t c; + + while((c = (size_t)*str)) { hash = ((hash << 5) + hash) + c; str++; @@ -40,9 +48,10 @@ static unsigned int hash_string(const void *key) return hash; } -static int string_equal(const void *key1, const void *key2) +static int key_equal(const void *ptr1, const void *ptr2) { - return strcmp((const char *)key1, (const char *)key2) == 0; + return strcmp(((const object_key_t *)ptr1)->key, + ((const object_key_t *)ptr2)->key) == 0; } static void value_decref(void *value) @@ -57,13 +66,14 @@ json_t *json_object(void) return NULL; json_init(&object->json, JSON_OBJECT); - if(hashtable_init(&object->hashtable, hash_string, string_equal, + if(hashtable_init(&object->hashtable, hash_key, key_equal, free, value_decref)) { free(object); return NULL; } + object->serial = 0; object->visited = 0; return &object->json; @@ -75,7 +85,7 @@ static void json_delete_object(json_object_t *object) free(object); } -unsigned int json_object_size(const json_t *json) +size_t json_object_size(const json_t *json) { json_object_t *object; @@ -94,12 +104,13 @@ json_t *json_object_get(const json_t *json, const char *key) return NULL; object = json_to_object(json); - return hashtable_get(&object->hashtable, key); + return hashtable_get(&object->hashtable, string_to_key(key)); } int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value) { json_object_t *object; + object_key_t *k; if(!key || !value) return -1; @@ -111,7 +122,16 @@ int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value) } object = json_to_object(json); - if(hashtable_set(&object->hashtable, strdup(key), value)) + /* offsetof(...) returns the size of object_key_t without the + last, flexible member. This way, the correct amount is + allocated. */ + k = malloc(offsetof(object_key_t, key) + + strlen(key) + 1); if(!k) return -1; + + k->serial = object->serial++; + strcpy(k->key, key); + + if(hashtable_set(&object->hashtable, k, value)) { json_decref(value); return -1; @@ -139,7 +159,7 @@ int json_object_del(json_t *json, const char *key) return -1; object = json_to_object(json); - return hashtable_del(&object->hashtable, key); + return hashtable_del(&object->hashtable, string_to_key(key)); } int json_object_clear(json_t *json) @@ -190,6 +210,17 @@ void *json_object_iter(json_t *json) return hashtable_iter(&object->hashtable); } +void *json_object_iter_at(json_t *json, const char *key) +{ + json_object_t *object; + + if(!key || !json_is_object(json)) + return NULL; + + object = json_to_object(json); + return hashtable_iter_at(&object->hashtable, string_to_key(key)); +} + void *json_object_iter_next(json_t *json, void *iter) { json_object_t *object; @@ -201,12 +232,20 @@ void *json_object_iter_next(json_t *json, void *iter) return hashtable_iter_next(&object->hashtable, iter); } +const object_key_t *jsonp_object_iter_fullkey(void *iter) +{ + if(!iter) + return NULL; + + return hashtable_iter_key(iter); +} + const char *json_object_iter_key(void *iter) { if(!iter) return NULL; - return (const char *)hashtable_iter_key(iter); + return jsonp_object_iter_fullkey(iter)->key; } json_t *json_object_iter_value(void *iter) @@ -217,6 +256,19 @@ json_t *json_object_iter_value(void *iter) return (json_t *)hashtable_iter_value(iter); } +int json_object_iter_set_new(json_t *json, void *iter, json_t *value) +{ + json_object_t *object; + + if(!json_is_object(json) || !iter || !value) + return -1; + + object = json_to_object(json); + hashtable_iter_set(&object->hashtable, iter, value); + + return 0; +} + static int json_object_equal(json_t *object1, json_t *object2) { void *iter; @@ -285,7 +337,7 @@ static json_t *json_object_deep_copy(json_t *object) key = json_object_iter_key(iter); value = json_object_iter_value(iter); - json_object_set_nocheck(result, key, json_deep_copy(value)); + json_object_set_new_nocheck(result, key, json_deep_copy(value)); iter = json_object_iter_next(object, iter); } @@ -319,7 +371,7 @@ json_t *json_array(void) static void json_delete_array(json_array_t *array) { - unsigned int i; + size_t i; for(i = 0; i < array->entries; i++) json_decref(array->table[i]); @@ -328,7 +380,7 @@ static void json_delete_array(json_array_t *array) free(array); } -unsigned int json_array_size(const json_t *json) +size_t json_array_size(const json_t *json) { if(!json_is_array(json)) return 0; @@ -336,7 +388,7 @@ unsigned int json_array_size(const json_t *json) return json_to_array(json)->entries; } -json_t *json_array_get(const json_t *json, unsigned int index) +json_t *json_array_get(const json_t *json, size_t index) { json_array_t *array; if(!json_is_array(json)) @@ -349,7 +401,7 @@ json_t *json_array_get(const json_t *json, unsigned int index) return array->table[index]; } -int json_array_set_new(json_t *json, unsigned int index, json_t *value) +int json_array_set_new(json_t *json, size_t index, json_t *value) { json_array_t *array; @@ -375,24 +427,24 @@ int json_array_set_new(json_t *json, unsigned int index, json_t *value) return 0; } -static void array_move(json_array_t *array, unsigned int dest, - unsigned int src, unsigned int count) +static void array_move(json_array_t *array, size_t dest, + size_t src, size_t count) { memmove(&array->table[dest], &array->table[src], count * sizeof(json_t *)); } -static void array_copy(json_t **dest, unsigned int dpos, - json_t **src, unsigned int spos, - unsigned int count) +static void array_copy(json_t **dest, size_t dpos, + json_t **src, size_t spos, + size_t count) { memcpy(&dest[dpos], &src[spos], count * sizeof(json_t *)); } static json_t **json_array_grow(json_array_t *array, - unsigned int amount, + size_t amount, int copy) { - unsigned int new_size; + size_t new_size; json_t **old_table, **new_table; if(array->entries + amount <= array->size) @@ -442,7 +494,7 @@ int json_array_append_new(json_t *json, json_t *value) return 0; } -int json_array_insert_new(json_t *json, unsigned int index, json_t *value) +int json_array_insert_new(json_t *json, size_t index, json_t *value) { json_array_t *array; json_t **old_table; @@ -482,7 +534,7 @@ int json_array_insert_new(json_t *json, unsigned int index, json_t *value) return 0; } -int json_array_remove(json_t *json, unsigned int index) +int json_array_remove(json_t *json, size_t index) { json_array_t *array; @@ -504,7 +556,7 @@ int json_array_remove(json_t *json, unsigned int index) int json_array_clear(json_t *json) { json_array_t *array; - unsigned int i; + size_t i; if(!json_is_array(json)) return -1; @@ -520,7 +572,7 @@ int json_array_clear(json_t *json) int json_array_extend(json_t *json, json_t *other_json) { json_array_t *array, *other; - unsigned int i; + size_t i; if(!json_is_array(json) || !json_is_array(other_json)) return -1; @@ -541,7 +593,7 @@ int json_array_extend(json_t *json, json_t *other_json) static int json_array_equal(json_t *array1, json_t *array2) { - unsigned int i, size; + size_t i, size; size = json_array_size(array1); if(size != json_array_size(array2)) @@ -564,7 +616,7 @@ static int json_array_equal(json_t *array1, json_t *array2) static json_t *json_array_copy(json_t *array) { json_t *result; - unsigned int i; + size_t i; result = json_array(); if(!result) @@ -579,14 +631,14 @@ static json_t *json_array_copy(json_t *array) static json_t *json_array_deep_copy(json_t *array) { json_t *result; - unsigned int i; + size_t i; result = json_array(); if(!result) return NULL; for(i = 0; i < json_array_size(array); i++) - json_array_append(result, json_deep_copy(json_array_get(array, i))); + json_array_append_new(result, json_deep_copy(json_array_get(array, i))); return result; } @@ -673,7 +725,7 @@ static json_t *json_string_copy(json_t *string) /*** integer ***/ -json_t *json_integer(int value) +json_t *json_integer(json_int_t value) { json_integer_t *integer = malloc(sizeof(json_integer_t)); if(!integer) @@ -684,7 +736,7 @@ json_t *json_integer(int value) return &integer->json; } -int json_integer_value(const json_t *json) +json_int_t json_integer_value(const json_t *json) { if(!json_is_integer(json)) return 0; @@ -692,7 +744,7 @@ int json_integer_value(const json_t *json) return json_to_integer(json)->value; } -int json_integer_set(json_t *json, int value) +int json_integer_set(json_t *json, json_int_t value) { if(!json_is_integer(json)) return -1; @@ -782,30 +834,21 @@ double json_number_value(const json_t *json) json_t *json_true(void) { - static json_t the_true = { - .type = JSON_TRUE, - .refcount = (unsigned int)1 - }; + static json_t the_true = {JSON_TRUE, (size_t)-1}; return &the_true; } json_t *json_false(void) { - static json_t the_false = { - .type = JSON_FALSE, - .refcount = (unsigned int)1 - }; + static json_t the_false = {JSON_FALSE, (size_t)-1}; return &the_false; } json_t *json_null(void) { - static json_t the_null = { - .type = JSON_NULL, - .refcount = (unsigned int)1 - }; + static json_t the_null = {JSON_NULL, (size_t)-1}; return &the_null; }