|
@@ -1665,16 +1665,33 @@ CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array)
|
|
return (int)i;
|
|
return (int)i;
|
|
}
|
|
}
|
|
|
|
|
|
-CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int item)
|
|
|
|
|
|
+static cJSON* get_array_item(const cJSON *array, size_t index)
|
|
{
|
|
{
|
|
- cJSON *c = array ? array->child : NULL;
|
|
|
|
- while (c && item > 0)
|
|
|
|
|
|
+ cJSON *current_child = NULL;
|
|
|
|
+
|
|
|
|
+ if (array == NULL)
|
|
{
|
|
{
|
|
- item--;
|
|
|
|
- c = c->next;
|
|
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ current_child = array->child;
|
|
|
|
+ while ((current_child != NULL) && (index > 0))
|
|
|
|
+ {
|
|
|
|
+ index--;
|
|
|
|
+ current_child = current_child->next;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return current_child;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index)
|
|
|
|
+{
|
|
|
|
+ if (index < 0)
|
|
|
|
+ {
|
|
|
|
+ return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
- return c;
|
|
|
|
|
|
+ return get_array_item(array, (size_t)index);
|
|
}
|
|
}
|
|
|
|
|
|
static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive)
|
|
static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive)
|
|
@@ -1814,37 +1831,36 @@ CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *str
|
|
cJSON_AddItemToObject(object, string, create_reference(item, &global_hooks));
|
|
cJSON_AddItemToObject(object, string, create_reference(item, &global_hooks));
|
|
}
|
|
}
|
|
|
|
|
|
-static cJSON *DetachItemFromArray(cJSON *array, size_t which)
|
|
|
|
|
|
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item)
|
|
{
|
|
{
|
|
- cJSON *c = array->child;
|
|
|
|
- while (c && (which > 0))
|
|
|
|
|
|
+ if ((parent == NULL) || (item == NULL))
|
|
{
|
|
{
|
|
- c = c->next;
|
|
|
|
- which--;
|
|
|
|
- }
|
|
|
|
- if (!c)
|
|
|
|
- {
|
|
|
|
- /* item doesn't exist */
|
|
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
- if (c->prev)
|
|
|
|
|
|
+
|
|
|
|
+ if (item->prev != NULL)
|
|
{
|
|
{
|
|
/* not the first element */
|
|
/* not the first element */
|
|
- c->prev->next = c->next;
|
|
|
|
|
|
+ item->prev->next = item->next;
|
|
}
|
|
}
|
|
- if (c->next)
|
|
|
|
|
|
+ if (item->next != NULL)
|
|
{
|
|
{
|
|
- c->next->prev = c->prev;
|
|
|
|
|
|
+ /* not the last element */
|
|
|
|
+ item->next->prev = item->prev;
|
|
}
|
|
}
|
|
- if (c==array->child)
|
|
|
|
|
|
+
|
|
|
|
+ if (item == parent->child)
|
|
{
|
|
{
|
|
- array->child = c->next;
|
|
|
|
|
|
+ /* first element */
|
|
|
|
+ parent->child = item->next;
|
|
}
|
|
}
|
|
/* make sure the detached item doesn't point anywhere anymore */
|
|
/* make sure the detached item doesn't point anywhere anymore */
|
|
- c->prev = c->next = NULL;
|
|
|
|
|
|
+ item->prev = NULL;
|
|
|
|
+ item->next = NULL;
|
|
|
|
|
|
- return c;
|
|
|
|
|
|
+ return item;
|
|
}
|
|
}
|
|
|
|
+
|
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which)
|
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which)
|
|
{
|
|
{
|
|
if (which < 0)
|
|
if (which < 0)
|
|
@@ -1852,7 +1868,7 @@ CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which)
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
- return DetachItemFromArray(array, (size_t)which);
|
|
|
|
|
|
+ return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which));
|
|
}
|
|
}
|
|
|
|
|
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which)
|
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which)
|
|
@@ -1862,19 +1878,16 @@ CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which)
|
|
|
|
|
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string)
|
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string)
|
|
{
|
|
{
|
|
- size_t i = 0;
|
|
|
|
- cJSON *c = object->child;
|
|
|
|
- while (c && (case_insensitive_strcmp((unsigned char*)c->string, (const unsigned char*)string) != 0))
|
|
|
|
- {
|
|
|
|
- i++;
|
|
|
|
- c = c->next;
|
|
|
|
- }
|
|
|
|
- if (c)
|
|
|
|
- {
|
|
|
|
- return DetachItemFromArray(object, i);
|
|
|
|
- }
|
|
|
|
|
|
+ cJSON *to_detach = cJSON_GetObjectItem(object, string);
|
|
|
|
|
|
- return NULL;
|
|
|
|
|
|
+ return cJSON_DetachItemViaPointer(object, to_detach);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string)
|
|
|
|
+{
|
|
|
|
+ cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string);
|
|
|
|
+
|
|
|
|
+ return cJSON_DetachItemViaPointer(object, to_detach);
|
|
}
|
|
}
|
|
|
|
|
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
|
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
|
|
@@ -1882,24 +1895,32 @@ CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string)
|
|
cJSON_Delete(cJSON_DetachItemFromObject(object, string));
|
|
cJSON_Delete(cJSON_DetachItemFromObject(object, string));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string)
|
|
|
|
+{
|
|
|
|
+ cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string));
|
|
|
|
+}
|
|
|
|
+
|
|
/* Replace array/object items with new ones. */
|
|
/* Replace array/object items with new ones. */
|
|
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
|
|
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem)
|
|
{
|
|
{
|
|
- cJSON *c = array->child;
|
|
|
|
- while (c && (which > 0))
|
|
|
|
|
|
+ cJSON *after_inserted = NULL;
|
|
|
|
+
|
|
|
|
+ if (which < 0)
|
|
{
|
|
{
|
|
- c = c->next;
|
|
|
|
- which--;
|
|
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
- if (!c)
|
|
|
|
|
|
+
|
|
|
|
+ after_inserted = get_array_item(array, (size_t)which);
|
|
|
|
+ if (after_inserted == NULL)
|
|
{
|
|
{
|
|
cJSON_AddItemToArray(array, newitem);
|
|
cJSON_AddItemToArray(array, newitem);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- newitem->next = c;
|
|
|
|
- newitem->prev = c->prev;
|
|
|
|
- c->prev = newitem;
|
|
|
|
- if (c == array->child)
|
|
|
|
|
|
+
|
|
|
|
+ newitem->next = after_inserted;
|
|
|
|
+ newitem->prev = after_inserted->prev;
|
|
|
|
+ after_inserted->prev = newitem;
|
|
|
|
+ if (after_inserted == array->child)
|
|
{
|
|
{
|
|
array->child = newitem;
|
|
array->child = newitem;
|
|
}
|
|
}
|
|
@@ -1909,35 +1930,41 @@ CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newit
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static void ReplaceItemInArray(cJSON *array, size_t which, cJSON *newitem)
|
|
|
|
|
|
+CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
|
|
{
|
|
{
|
|
- cJSON *c = array->child;
|
|
|
|
- while (c && (which > 0))
|
|
|
|
|
|
+ if ((parent == NULL) || (replacement == NULL))
|
|
{
|
|
{
|
|
- c = c->next;
|
|
|
|
- which--;
|
|
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
- if (!c)
|
|
|
|
|
|
+
|
|
|
|
+ if (replacement == item)
|
|
{
|
|
{
|
|
- return;
|
|
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
- newitem->next = c->next;
|
|
|
|
- newitem->prev = c->prev;
|
|
|
|
- if (newitem->next)
|
|
|
|
|
|
+
|
|
|
|
+ replacement->next = item->next;
|
|
|
|
+ replacement->prev = item->prev;
|
|
|
|
+
|
|
|
|
+ if (replacement->next != NULL)
|
|
{
|
|
{
|
|
- newitem->next->prev = newitem;
|
|
|
|
|
|
+ replacement->next->prev = replacement;
|
|
}
|
|
}
|
|
- if (c == array->child)
|
|
|
|
|
|
+ if (replacement->prev != NULL)
|
|
{
|
|
{
|
|
- array->child = newitem;
|
|
|
|
|
|
+ replacement->prev->next = replacement;
|
|
}
|
|
}
|
|
- else
|
|
|
|
|
|
+ if (parent->child == item)
|
|
{
|
|
{
|
|
- newitem->prev->next = newitem;
|
|
|
|
|
|
+ parent->child = replacement;
|
|
}
|
|
}
|
|
- c->next = c->prev = NULL;
|
|
|
|
- cJSON_Delete(c);
|
|
|
|
|
|
+
|
|
|
|
+ item->next = NULL;
|
|
|
|
+ item->prev = NULL;
|
|
|
|
+ cJSON_Delete(item);
|
|
|
|
+
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
+
|
|
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
|
|
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
|
|
{
|
|
{
|
|
if (which < 0)
|
|
if (which < 0)
|
|
@@ -1945,29 +1972,17 @@ CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newi
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- ReplaceItemInArray(array, (size_t)which, newitem);
|
|
|
|
|
|
+ cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem);
|
|
}
|
|
}
|
|
|
|
|
|
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
|
|
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem)
|
|
{
|
|
{
|
|
- size_t i = 0;
|
|
|
|
- cJSON *c = object->child;
|
|
|
|
- while(c && (case_insensitive_strcmp((unsigned char*)c->string, (const unsigned char*)string) != 0))
|
|
|
|
- {
|
|
|
|
- i++;
|
|
|
|
- c = c->next;
|
|
|
|
- }
|
|
|
|
- if(c)
|
|
|
|
- {
|
|
|
|
- /* free the old string if not const */
|
|
|
|
- if (!(newitem->type & cJSON_StringIsConst) && newitem->string)
|
|
|
|
- {
|
|
|
|
- global_hooks.deallocate(newitem->string);
|
|
|
|
- }
|
|
|
|
|
|
+ cJSON_ReplaceItemViaPointer(object, cJSON_GetObjectItem(object, string), newitem);
|
|
|
|
+}
|
|
|
|
|
|
- newitem->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
|
|
|
|
- ReplaceItemInArray(object, i, newitem);
|
|
|
|
- }
|
|
|
|
|
|
+CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem)
|
|
|
|
+{
|
|
|
|
+ cJSON_ReplaceItemViaPointer(object, cJSON_GetObjectItemCaseSensitive(object, string), newitem);
|
|
}
|
|
}
|
|
|
|
|
|
/* Create basic types: */
|
|
/* Create basic types: */
|