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;
}
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;
}
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;
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 ***/
#include <jansson.h>
#include "util.h"
-int main()
+static void test_misc(void)
{
json_t *array, *five, *seven, *value;
int i;
if(!array)
fail("unable to create array");
- if(!five)
- fail("unable to create integer");
- if(!seven)
+ if(!five || !seven)
fail("unable to create integer");
if(json_array_size(array) != 0)
json_decref(five);
json_decref(seven);
json_decref(array);
+}
+
+static void test_insert(void)
+{
+ json_t *array, *five, *seven, *eleven, *value;
+ int i;
+
+ array = json_array();
+ five = json_integer(5);
+ seven = json_integer(7);
+ eleven = json_integer(11);
+
+ if(!array)
+ fail("unable to create array");
+ if(!five || !seven || !eleven)
+ fail("unable to create integer");
+
+
+ if(!json_array_insert(array, 1, five))
+ fail("able to insert value out of bounds");
+
+
+ if(json_array_insert(array, 0, five))
+ fail("unable to insert value in an empty array");
+
+ if(json_array_get(array, 0) != five)
+ fail("json_array_insert works incorrectly");
+
+ if(json_array_size(array) != 1)
+ fail("array size is invalid after insertion");
+
+
+ if(json_array_insert(array, 1, seven))
+ fail("unable to insert value at the end of an array");
+
+ if(json_array_get(array, 0) != five)
+ fail("json_array_insert works incorrectly");
+
+ if(json_array_get(array, 1) != seven)
+ fail("json_array_insert works incorrectly");
+
+ if(json_array_size(array) != 2)
+ fail("array size is invalid after insertion");
+
+
+ if(json_array_insert(array, 1, eleven))
+ fail("unable to insert value in the middle of an array");
+
+ if(json_array_get(array, 0) != five)
+ fail("json_array_insert works incorrectly");
+
+ if(json_array_get(array, 1) != eleven)
+ fail("json_array_insert works incorrectly");
+
+ if(json_array_get(array, 2) != seven)
+ fail("json_array_insert works incorrectly");
+
+ if(json_array_size(array) != 3)
+ fail("array size is invalid after insertion");
+
+
+ if(json_array_insert_new(array, 2, json_integer(123)))
+ fail("unable to insert value in the middle of an array");
+
+ value = json_array_get(array, 2);
+ if(!json_is_integer(value) || json_integer_value(value) != 123)
+ fail("json_array_insert_new works incorrectly");
+
+ if(json_array_size(array) != 4)
+ fail("array size is invalid after insertion");
+
+
+ for(i = 0; i < 20; i++) {
+ if(json_array_insert(array, 0, seven))
+ fail("unable to insert value at the begining of an array");
+ }
+
+ for(i = 0; i < 20; i++) {
+ if(json_array_get(array, i) != seven)
+ fail("json_aray_insert works incorrectly");
+ }
+
+ if(json_array_size(array) != 24)
+ fail("array size is invalid after loop insertion");
+
+ json_decref(five);
+ json_decref(seven);
+ json_decref(eleven);
+ json_decref(array);
+}
+
+static void test_remove(void)
+{
+ json_t *array, *five, *seven;
+
+ array = json_array();
+ five = json_integer(5);
+ seven = json_integer(7);
+
+ if(!array)
+ fail("unable to create array");
+ if(!five)
+ fail("unable to create integer");
+ if(!seven)
+ fail("unable to create integer");
+
+
+ if(!json_array_remove(array, 0))
+ fail("able to remove an unexisting index");
+
+
+ if(json_array_append(array, five))
+ fail("unable to append");
+
+ if(!json_array_remove(array, 1))
+ fail("able to remove an unexisting index");
+
+ if(json_array_remove(array, 0))
+ fail("unable to remove");
+
+ if(json_array_size(array) != 0)
+ fail("array size is invalid after removing");
+
+
+ if(json_array_append(array, five) ||
+ json_array_append(array, seven) ||
+ json_array_append(array, five) ||
+ json_array_append(array, seven))
+ fail("unable to append");
+
+ if(json_array_remove(array, 2))
+ fail("unable to remove");
+
+ if(json_array_size(array) != 3)
+ fail("array size is invalid after removing");
+
+ if(json_array_get(array, 0) != five ||
+ json_array_get(array, 1) != seven ||
+ json_array_get(array, 2) != seven)
+ fail("remove works incorrectly");
+
+ json_decref(five);
+ json_decref(seven);
+ json_decref(array);
+}
+
+static void test_clear(void)
+{
+ json_t *array, *five, *seven;
+ int i;
+
+ array = json_array();
+ five = json_integer(5);
+ seven = json_integer(7);
+
+ if(!array)
+ fail("unable to create array");
+ if(!five || !seven)
+ fail("unable to create integer");
+
+ for(i = 0; i < 10; i++) {
+ if(json_array_append(array, five))
+ fail("unable to append");
+ }
+ for(i = 0; i < 10; i++) {
+ if(json_array_append(array, seven))
+ fail("unable to append");
+ }
+
+ if(json_array_size(array) != 20)
+ fail("array size is invalid after appending");
+
+ if(json_array_clear(array))
+ fail("unable to clear");
+
+ if(json_array_size(array) != 0)
+ fail("array size is invalid after clearing");
+
+ json_decref(five);
+ json_decref(seven);
+ json_decref(array);
+}
+
+static void test_extend(void)
+{
+ json_t *array1, *array2, *five, *seven;
+ int i;
+
+ array1 = json_array();
+ array2 = json_array();
+ five = json_integer(5);
+ seven = json_integer(7);
+
+ if(!array1 || !array2)
+ fail("unable to create array");
+ if(!five || !seven)
+ fail("unable to create integer");
+
+ for(i = 0; i < 10; i++) {
+ if(json_array_append(array1, five))
+ fail("unable to append");
+ }
+ for(i = 0; i < 10; i++) {
+ if(json_array_append(array2, seven))
+ fail("unable to append");
+ }
+
+ if(json_array_size(array1) != 10 || json_array_size(array2) != 10)
+ fail("array size is invalid after appending");
+
+ if(json_array_extend(array1, array2))
+ fail("unable to extend");
+
+ for(i = 0; i < 10; i++) {
+ if(json_array_get(array1, i) != five)
+ fail("invalid array contents after extending");
+ }
+ for(i = 10; i < 20; i++) {
+ if(json_array_get(array1, i) != seven)
+ fail("invalid array contents after extending");
+ }
+
+ json_decref(five);
+ json_decref(seven);
+ json_decref(array1);
+ json_decref(array2);
+}
+
+
+int main()
+{
+ test_misc();
+ test_insert();
+ test_remove();
+ test_clear();
+ test_extend();
return 0;
}