diff options
author | Petri Lehtinen <petri@digip.org> | 2009-09-29 21:19:55 +0300 |
---|---|---|
committer | Petri Lehtinen <petri@digip.org> | 2009-09-29 22:17:58 +0300 |
commit | cbacac597516b3d7309bf0811ea18cd43870bce4 (patch) | |
tree | 7cd4bbd0364d0377a964fe98470d32ea22788bd4 /src | |
parent | b3e1fe2ec5c0fb4d7307ad27fe0ac0ef14c87b37 (diff) | |
download | jansson-cbacac597516b3d7309bf0811ea18cd43870bce4.zip jansson-cbacac597516b3d7309bf0811ea18cd43870bce4.tar.gz jansson-cbacac597516b3d7309bf0811ea18cd43870bce4.tar.bz2 |
Extend array API
Added functions:
json_array_insert
json_array_insert_new
json_array_remove
json_array_clear
json_array_extend
Diffstat (limited to 'src')
-rw-r--r-- | src/jansson.h | 9 | ||||
-rw-r--r-- | src/value.c | 159 |
2 files changed, 158 insertions, 10 deletions
diff --git a/src/jansson.h b/src/jansson.h index b5cdddb..b7a75b6 100644 --- a/src/jansson.h +++ b/src/jansson.h @@ -89,6 +89,10 @@ unsigned int json_array_size(const json_t *array); json_t *json_array_get(const json_t *array, unsigned int index); int json_array_set_new(json_t *array, unsigned int index, json_t *value); int json_array_append_new(json_t *array, json_t *value); +int json_array_insert_new(json_t *array, unsigned int index, json_t *value); +int json_array_remove(json_t *array, unsigned int index); +int json_array_clear(json_t *array); +int json_array_extend(json_t *array, json_t *other); static inline int json_array_set(json_t *array, unsigned int index, json_t *value) @@ -102,6 +106,11 @@ int json_array_append(json_t *array, json_t *value) return json_array_append_new(array, json_incref(value)); } +static inline +int json_array_insert(json_t *array, unsigned int index, json_t *value) +{ + return json_array_insert_new(array, index, json_incref(value)); +} const char *json_string_value(const json_t *json); int json_integer_value(const json_t *json); diff --git a/src/value.c b/src/value.c index 29f787c..bf5fd54 100644 --- a/src/value.c +++ b/src/value.c @@ -217,8 +217,13 @@ json_t *json_array(void) json_init(&array->json, JSON_ARRAY); array->entries = 0; - array->size = 0; - array->table = NULL; + array->size = 8; + + array->table = malloc(array->size * sizeof(json_t *)); + if(!array->table) { + free(array); + return NULL; + } return &array->json; } @@ -281,6 +286,48 @@ 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) +{ + 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) +{ + memcpy(&dest[dpos], &src[spos], count * sizeof(json_t *)); +} + +static json_t **json_array_grow(json_array_t *array, + unsigned int amount, + int copy) +{ + unsigned int new_size; + json_t **old_table, **new_table; + + if(array->entries + amount <= array->size) + return array->table; + + old_table = array->table; + + new_size = max(array->size + amount, array->size * 2); + new_table = malloc(new_size * sizeof(json_t *)); + if(!new_table) + return NULL; + + array->size = new_size; + array->table = new_table; + + if(copy) { + array_copy(array->table, 0, old_table, 0, array->entries); + free(old_table); + return array->table; + } + + return old_table; +} + int json_array_append_new(json_t *json, json_t *value) { json_array_t *array; @@ -295,14 +342,9 @@ int json_array_append_new(json_t *json, json_t *value) } array = json_to_array(json); - if(array->entries == array->size) { - array->size = max(8, array->size * 2); - array->table = realloc(array->table, array->size * sizeof(json_t *)); - if(!array->table) - { - json_decref(value); - return -1; - } + if(!json_array_grow(array, 1, 1)) { + json_decref(value); + return -1; } array->table[array->entries] = value; @@ -311,6 +353,103 @@ 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) +{ + json_array_t *array; + json_t **old_table; + + if(!value) + return -1; + + if(!json_is_array(json)) { + json_decref(value); + return -1; + } + array = json_to_array(json); + + if(index > array->entries) { + json_decref(value); + return -1; + } + + old_table = json_array_grow(array, 1, 0); + if(!old_table) { + json_decref(value); + return -1; + } + + if(old_table != array->table) { + array_copy(array->table, 0, old_table, 0, index); + array_copy(array->table, index + 1, old_table, index, + array->entries - index); + free(old_table); + } + else + array_move(array, index + 1, index, array->entries - index); + + array->table[index] = value; + array->entries++; + + return 0; +} + +int json_array_remove(json_t *json, unsigned int index) +{ + json_array_t *array; + + if(!json_is_array(json)) + return -1; + array = json_to_array(json); + + if(index >= array->entries) + return -1; + + json_decref(array->table[index]); + + array_move(array, index, index + 1, array->entries - index); + array->entries--; + + return 0; +} + +int json_array_clear(json_t *json) +{ + json_array_t *array; + unsigned int i; + + if(!json_is_array(json)) + return -1; + array = json_to_array(json); + + for(i = 0; i < array->entries; i++) + json_decref(array->table[i]); + + array->entries = 0; + return 0; +} + +int json_array_extend(json_t *json, json_t *other_json) +{ + json_array_t *array, *other; + unsigned int i; + + if(!json_is_array(json) || !json_is_array(other_json)) + return -1; + array = json_to_array(json); + other = json_to_array(other_json); + + if(!json_array_grow(array, other->entries, 1)) + return -1; + + for(i = 0; i < other->entries; i++) + json_incref(other->table[i]); + + array_copy(array->table, array->entries, other->table, 0, other->entries); + + array->entries += other->entries; + return 0; +} + /*** string ***/ |