Преглед изворни кода

Add cJSON_ReplaceItemViaPointer

Max Bruckner пре 8 година
родитељ
комит
8b953d1202
3 измењених фајлова са 72 додато и 34 уклоњено
  1. 23 34
      cJSON.c
  2. 1 0
      cJSON.h
  3. 48 0
      tests/misc_tests.c

+ 23 - 34
cJSON.c

@@ -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 ((parent == NULL) || (replacement == NULL))
+    {
+        return false;
+    }
 
-    if (replaced == NULL)
+    if (replacement == item)
     {
-        return;
+        return true;
     }
 
-    newitem->next = replaced->next;
-    newitem->prev = replaced->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 (replaced == 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;
     }
 
-    replaced->next = NULL;
-    replaced->prev = NULL;
+    item->next = NULL;
+    item->prev = NULL;
+    cJSON_Delete(item);
 
-    cJSON_Delete(replaced);
+    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: */

+ 1 - 0
cJSON.h

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

+ 48 - 0
tests/misc_tests.c

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