X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=src%2Fvalue.c;h=937aa955fd84903e9940fa5e8d02742df0b9e163;hb=6ecba848171f48d0b3806dbc1aa306be8e69bc82;hp=01e180e1827d6b7783420aa00472e574f7e6d84d;hpb=2ad4634de51bd06c03d1ba5831247ed865c03506;p=jansson.git diff --git a/src/value.c b/src/value.c index 01e180e..937aa95 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) + +size_t jsonp_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) +int jsonp_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) @@ -52,18 +61,20 @@ static void value_decref(void *value) json_t *json_object(void) { - json_object_t *object = malloc(sizeof(json_object_t)); + json_object_t *object = jsonp_malloc(sizeof(json_object_t)); if(!object) return NULL; json_init(&object->json, JSON_OBJECT); - if(hashtable_init(&object->hashtable, hash_string, string_equal, - free, value_decref)) + if(hashtable_init(&object->hashtable, + jsonp_hash_key, jsonp_key_equal, + jsonp_free, value_decref)) { - free(object); + jsonp_free(object); return NULL; } + object->serial = 0; object->visited = 0; return &object->json; @@ -72,15 +83,15 @@ json_t *json_object(void) static void json_delete_object(json_object_t *object) { hashtable_close(&object->hashtable); - free(object); + jsonp_free(object); } -unsigned int json_object_size(const json_t *json) +size_t json_object_size(const json_t *json) { json_object_t *object; if(!json_is_object(json)) - return -1; + return 0; object = json_to_object(json); return object->hashtable.size; @@ -94,12 +105,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 +123,17 @@ 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 = jsonp_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 +161,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 +212,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 +234,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 +258,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; @@ -298,7 +352,7 @@ static json_t *json_object_deep_copy(json_t *object) json_t *json_array(void) { - json_array_t *array = malloc(sizeof(json_array_t)); + json_array_t *array = jsonp_malloc(sizeof(json_array_t)); if(!array) return NULL; json_init(&array->json, JSON_ARRAY); @@ -306,9 +360,9 @@ json_t *json_array(void) array->entries = 0; array->size = 8; - array->table = malloc(array->size * sizeof(json_t *)); + array->table = jsonp_malloc(array->size * sizeof(json_t *)); if(!array->table) { - free(array); + jsonp_free(array); return NULL; } @@ -319,16 +373,16 @@ 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]); - free(array->table); - free(array); + jsonp_free(array->table); + jsonp_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 +390,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 +403,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 +429,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) @@ -401,7 +455,7 @@ static json_t **json_array_grow(json_array_t *array, old_table = array->table; new_size = max(array->size + amount, array->size * 2); - new_table = malloc(new_size * sizeof(json_t *)); + new_table = jsonp_malloc(new_size * sizeof(json_t *)); if(!new_table) return NULL; @@ -410,7 +464,7 @@ static json_t **json_array_grow(json_array_t *array, if(copy) { array_copy(array->table, 0, old_table, 0, array->entries); - free(old_table); + jsonp_free(old_table); return array->table; } @@ -442,7 +496,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; @@ -471,7 +525,7 @@ int json_array_insert_new(json_t *json, unsigned int index, json_t *value) array_copy(array->table, 0, old_table, 0, index); array_copy(array->table, index + 1, old_table, index, array->entries - index); - free(old_table); + jsonp_free(old_table); } else array_move(array, index + 1, index, array->entries - index); @@ -482,7 +536,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 +558,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 +574,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 +595,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 +618,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,7 +633,7 @@ 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) @@ -600,14 +654,14 @@ json_t *json_string_nocheck(const char *value) if(!value) return NULL; - string = malloc(sizeof(json_string_t)); + string = jsonp_malloc(sizeof(json_string_t)); if(!string) return NULL; json_init(&string->json, JSON_STRING); - string->value = strdup(value); + string->value = jsonp_strdup(value); if(!string->value) { - free(string); + jsonp_free(string); return NULL; } @@ -635,12 +689,12 @@ int json_string_set_nocheck(json_t *json, const char *value) char *dup; json_string_t *string; - dup = strdup(value); + dup = jsonp_strdup(value); if(!dup) return -1; string = json_to_string(json); - free(string->value); + jsonp_free(string->value); string->value = dup; return 0; @@ -656,8 +710,8 @@ int json_string_set(json_t *json, const char *value) static void json_delete_string(json_string_t *string) { - free(string->value); - free(string); + jsonp_free(string->value); + jsonp_free(string); } static int json_string_equal(json_t *string1, json_t *string2) @@ -673,9 +727,9 @@ 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)); + json_integer_t *integer = jsonp_malloc(sizeof(json_integer_t)); if(!integer) return NULL; json_init(&integer->json, JSON_INTEGER); @@ -684,7 +738,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 +746,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; @@ -704,7 +758,7 @@ int json_integer_set(json_t *json, int value) static void json_delete_integer(json_integer_t *integer) { - free(integer); + jsonp_free(integer); } static int json_integer_equal(json_t *integer1, json_t *integer2) @@ -722,7 +776,7 @@ static json_t *json_integer_copy(json_t *integer) json_t *json_real(double value) { - json_real_t *real = malloc(sizeof(json_real_t)); + json_real_t *real = jsonp_malloc(sizeof(json_real_t)); if(!real) return NULL; json_init(&real->json, JSON_REAL); @@ -751,7 +805,7 @@ int json_real_set(json_t *json, double value) static void json_delete_real(json_real_t *real) { - free(real); + jsonp_free(real); } static int json_real_equal(json_t *real1, json_t *real2) @@ -782,30 +836,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; }