]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
json_object: introduce json_object_array_insert_idx() API function
authorAlexandru Ardelean <ardeleanalex@gmail.com>
Fri, 16 Apr 2021 13:12:22 +0000 (16:12 +0300)
committerEric Hawicz <erh+git@nimenees.com>
Tue, 1 Aug 2023 02:17:30 +0000 (22:17 -0400)
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>
arraylist.c
arraylist.h
json-c.sym
json_object.c
json_object.h

index d8e12d11cbc77a7a029cc02dad2be0f3469875cd..bfc14251978105009926907afadaf34af0adf0ff 100644 (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)
 {
index f541706936eb8ae944c33514f04283ad93a96d33..a12f27f54fc741925eab879edc08f311a269277e 100644 (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);
index 2867c80332655f01d465ed95f69834e91ea3e7d2..de1fdeb3c97fd96d3dba97589feeddc9926d6f58 100644 (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 {
index 6894a937669229d3087a3994648cd7ab24abddb9..c3974a05ae3f801885a82dba14ee7c42eddadc64 100644 (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);
index 7633e6463e1ee44e3bbd93a5652e6d77a9f71054..97ef84c21b108e337d0a67d14c6823df3d2aaf8f 100644 (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