diff --git a/arraylist.c b/arraylist.c index d8e12d1..bfc1425 100644 --- a/arraylist.c +++ b/arraylist.c @@ -125,6 +125,27 @@ int array_list_shrink(struct array_list *arr, size_t empty_slots) return 0; } +int array_list_insert_idx(struct array_list *arr, size_t idx, void *data) +{ + size_t move_amount; + + if (idx >= arr->length) + return array_list_put_idx(arr, idx, data); + + /* we're at full size, what size_t can support */ + if (arr->length == SIZE_T_MAX) + return -1; + + if (array_list_expand_internal(arr, arr->length + 1)) + return -1; + + move_amount = (arr->length - idx) * sizeof(void *); + memmove(arr->array + idx + 1, arr->array + idx, move_amount); + arr->array[idx] = data; + arr->length++; + return 0; +} + //static inline int _array_list_put_idx(struct array_list *arr, size_t idx, void *data) int array_list_put_idx(struct array_list *arr, size_t idx, void *data) { diff --git a/arraylist.h b/arraylist.h index f541706..a12f27f 100644 --- a/arraylist.h +++ b/arraylist.h @@ -62,6 +62,8 @@ extern void array_list_free(struct array_list *al); extern void *array_list_get_idx(struct array_list *al, size_t i); +extern int array_list_insert_idx(struct array_list *al, size_t i, void *data); + extern int array_list_put_idx(struct array_list *al, size_t i, void *data); extern int array_list_add(struct array_list *al, void *data); diff --git a/json-c.sym b/json-c.sym index 2867c80..de1fdeb 100644 --- a/json-c.sym +++ b/json-c.sym @@ -167,8 +167,8 @@ JSONC_0.15 { } JSONC_0.14; JSONC_0.16 { -# global: -# ...new symbols here... + global: + json_object_array_insert_idx; } JSONC_0.15; JSONC_0.17 { diff --git a/json_object.c b/json_object.c index 6894a93..c3974a0 100644 --- a/json_object.c +++ b/json_object.c @@ -1519,6 +1519,12 @@ int json_object_array_add(struct json_object *jso, struct json_object *val) return array_list_add(JC_ARRAY(jso)->c_array, val); } +int json_object_array_insert_idx(struct json_object *jso, size_t idx, struct json_object *val) +{ + assert(json_object_get_type(jso) == json_type_array); + return array_list_insert_idx(JC_ARRAY(jso)->c_array, idx, val); +} + int json_object_array_put_idx(struct json_object *jso, size_t idx, struct json_object *val) { assert(json_object_get_type(jso) == json_type_array); diff --git a/json_object.h b/json_object.h index 7633e64..97ef84c 100644 --- a/json_object.h +++ b/json_object.h @@ -622,6 +622,25 @@ JSON_EXPORT int json_object_array_add(struct json_object *obj, struct json_objec JSON_EXPORT int json_object_array_put_idx(struct json_object *obj, size_t idx, struct json_object *val); +/** Insert an element at a specified index in an array (a json_object of type json_type_array) + * + * The reference count will *not* be incremented. This is to make adding + * fields to objects in code more compact. If you want to retain a reference + * to an added object you must wrap the passed object with json_object_get + * + * The array size will be automatically be expanded to the size of the + * index if the index is larger than the current size. + * If the index is within the existing array limits, then the element will be + * inserted and all elements will be shifted. This is the only difference between + * this function and json_object_array_put_idx(). + * + * @param obj the json_object instance + * @param idx the index to insert the element at + * @param val the json_object to be added + */ +JSON_EXPORT int json_object_array_insert_idx(struct json_object *obj, size_t idx, + struct json_object *val); + /** Get the element at specified index of array `obj` (which must be a json_object of type json_type_array) * * *No* reference counts will be changed, and ownership of the returned