X-Git-Url: http://www.project-moonshot.org/gitweb/?p=jansson.git;a=blobdiff_plain;f=src%2Fvalue.c;h=bf5fd5422f62922046ba274385554104266f9944;hp=29f787c5662c2cdb0eb846094fb2b70090ab65e7;hb=cbacac597516b3d7309bf0811ea18cd43870bce4;hpb=b3e1fe2ec5c0fb4d7307ad27fe0ac0ef14c87b37 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 ***/