Add cJSON_ReplaceItemViaPointer

This commit is contained in:
Max Bruckner 2017-05-02 00:49:46 +02:00
parent 2d07bbc9b2
commit 8b953d1202
3 changed files with 77 additions and 39 deletions

67
cJSON.c
View File

@ -1930,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 *replaced = get_array_item(array, which);
if (replaced == NULL)
if ((parent == NULL) || (replacement == NULL))
{
return;
return false;
}
newitem->next = replaced->next;
newitem->prev = replaced->prev;
if (newitem->next)
if (replacement == item)
{
newitem->next->prev = newitem;
}
if (replaced == array->child)
{
array->child = newitem;
}
else
{
newitem->prev->next = newitem;
return true;
}
replaced->next = NULL;
replaced->prev = NULL;
replacement->next = item->next;
replacement->prev = item->prev;
cJSON_Delete(replaced);
if (replacement->next != NULL)
{
replacement->next->prev = replacement;
}
if (replacement->prev != NULL)
{
replacement->prev->next = replacement;
}
if (parent->child == item)
{
parent->child = replacement;
}
item->next = NULL;
item->prev = NULL;
cJSON_Delete(item);
return true;
}
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
{
if (which < 0)
@ -1966,29 +1972,12 @@ CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newi
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)
{
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);
}
newitem->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
ReplaceItemInArray(object, i, newitem);
}
cJSON_ReplaceItemViaPointer(object, cJSON_GetObjectItem(object, string), newitem);
}
/* Create basic types: */

View File

@ -213,6 +213,7 @@ CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const
/* Update array items. */
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);

View File

@ -257,6 +257,53 @@ static void cjson_detach_item_via_pointer_should_detach_items(void)
TEST_ASSERT_NULL_MESSAGE(parent->child, "Child of the parent wasn't set to NULL.");
}
static void cjson_replace_item_via_pointer_should_replace_items(void)
{
cJSON replacements[3];
cJSON *beginning = NULL;
cJSON *middle = NULL;
cJSON *end = NULL;
cJSON *array = NULL;
beginning = cJSON_CreateNull();
TEST_ASSERT_NOT_NULL(beginning);
middle = cJSON_CreateNull();
TEST_ASSERT_NOT_NULL(middle);
end = cJSON_CreateNull();
TEST_ASSERT_NOT_NULL(end);
array = cJSON_CreateArray();
TEST_ASSERT_NOT_NULL(array);
cJSON_AddItemToArray(array, beginning);
cJSON_AddItemToArray(array, middle);
cJSON_AddItemToArray(array, end);
memset(replacements, '\0', sizeof(replacements));
/* replace beginning */
TEST_ASSERT_TRUE(cJSON_ReplaceItemViaPointer(array, beginning, &(replacements[0])));
TEST_ASSERT_NULL(replacements[0].prev);
TEST_ASSERT_TRUE(replacements[0].next == middle);
TEST_ASSERT_TRUE(middle->prev == &(replacements[0]));
TEST_ASSERT_TRUE(array->child == &(replacements[0]));
/* replace middle */
TEST_ASSERT_TRUE(cJSON_ReplaceItemViaPointer(array, middle, &(replacements[1])));
TEST_ASSERT_TRUE(replacements[1].prev == &(replacements[0]));
TEST_ASSERT_TRUE(replacements[1].next == end);
TEST_ASSERT_TRUE(end->prev == &(replacements[1]));
/* replace end */
TEST_ASSERT_TRUE(cJSON_ReplaceItemViaPointer(array, end, &(replacements[2])));
TEST_ASSERT_TRUE(replacements[2].prev == &(replacements[1]));
TEST_ASSERT_NULL(replacements[2].next);
TEST_ASSERT_TRUE(replacements[1].next == &(replacements[2]));
cJSON_free(array);
}
int main(void)
{
UNITY_BEGIN();
@ -269,6 +316,7 @@ int main(void)
RUN_TEST(cjson_should_not_parse_to_deeply_nested_jsons);
RUN_TEST(cjson_set_number_value_should_set_numbers);
RUN_TEST(cjson_detach_item_via_pointer_should_detach_items);
RUN_TEST(cjson_replace_item_via_pointer_should_replace_items);
return UNITY_END();
}