Browse Source

json_object: introduce json_object_array_insert_idx() API function

The behavior of the json_object_array_put_idx() is that, if a user wants to
insert an element inside a JSON array, the element will be replaced.

For some cases, a user would want to insert an element into the JSON array
and shift the elements to the right.

For indexes that are outside the length of the current array this behaves
like json_object_array_put_idx().
If a user wants to enforce that the JSON array is not expanded, then the
json_object_array_length() function can be used to guard against that.

The main driver for this change is JSON patch, where the 'add' operation in
an array means inserting a value at a certain index and shifting everything
by one.

Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
tags/json-c-0.17-20230812
Alexandru Ardelean Eric Hawicz 4 years ago
parent
commit
a86d7a8f5a
5 changed files with 50 additions and 2 deletions
  1. +21
    -0
      arraylist.c
  2. +2
    -0
      arraylist.h
  3. +2
    -2
      json-c.sym
  4. +6
    -0
      json_object.c
  5. +19
    -0
      json_object.h

+ 21
- 0
arraylist.c View File

@@ -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)
{


+ 2
- 0
arraylist.h View File

@@ -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);


+ 2
- 2
json-c.sym View File

@@ -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 {


+ 6
- 0
json_object.c View File

@@ -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);


+ 19
- 0
json_object.h View File

@@ -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


Loading…
Cancel
Save