瀏覽代碼

cJSON_DuplicateConfiguration

Max Bruckner 7 年之前
父節點
當前提交
050f982608
共有 3 個文件被更改,包括 54 次插入17 次删除
  1. 13 17
      cJSON.c
  2. 2 0
      cJSON.h
  3. 39 0
      tests/configuration_tests.c

+ 13 - 17
cJSON.c

@@ -206,7 +206,7 @@ static void deallocate(const internal_configuration * const configuration, void
 }
 
 /* this is necessary to assign the default configuration after initialization */
-static const internal_configuration global_default_configuration = default_configuration;
+static internal_configuration global_default_configuration = default_configuration;
 
 static internal_configuration global_configuration = default_configuration;
 
@@ -2887,10 +2887,10 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
     return (item->type & 0xFF) == cJSON_Raw;
 }
 
-CJSON_PUBLIC(cJSON_Configuration) cJSON_CreateConfiguration(const cJSON_Allocators * const allocators, void *allocator_userdata)
+CJSON_PUBLIC(cJSON_Configuration) cJSON_DuplicateConfiguration(const cJSON_Configuration configuration, const cJSON_Allocators * const allocators, void *allocator_userdata)
 {
-    internal_configuration *configuration = NULL;
-    const cJSON_Allocators *local_allocators = &global_configuration.allocators;
+    internal_configuration *duplicate = NULL;
+    const cJSON_Allocators *local_allocators = &global_default_configuration.allocators;
 
     if (allocators != NULL)
     {
@@ -2902,24 +2902,20 @@ CJSON_PUBLIC(cJSON_Configuration) cJSON_CreateConfiguration(const cJSON_Allocato
         local_allocators = allocators;
     }
 
-    configuration = (internal_configuration*)local_allocators->allocate(sizeof(internal_configuration), allocator_userdata);
-    if (configuration == NULL)
+    duplicate = (internal_configuration*)local_allocators->allocate(sizeof(internal_configuration), allocator_userdata);
+    if (duplicate == NULL)
     {
-        goto fail;
+        return NULL;
     }
 
-    /* initialize with the default */
-    *configuration = global_default_configuration;
-
-    return (cJSON_Configuration)configuration;
+    memcpy(duplicate, configuration, sizeof(internal_configuration));
 
-fail:
-    if (configuration != NULL)
-    {
-        local_allocators->deallocate(configuration, allocator_userdata);
-    }
+    return duplicate;
+}
 
-    return NULL;
+CJSON_PUBLIC(cJSON_Configuration) cJSON_CreateConfiguration(const cJSON_Allocators * const allocators, void *allocator_userdata)
+{
+    return cJSON_DuplicateConfiguration((cJSON_Configuration)&global_default_configuration, allocators, allocator_userdata);
 }
 
 CJSON_PUBLIC(cJSON_Configuration) cJSON_ConfigurationChangeAllocators(cJSON_Configuration configuration, const cJSON_Allocators allocators)

+ 2 - 0
cJSON.h

@@ -154,6 +154,8 @@ CJSON_PUBLIC(const char*) cJSON_Version(void);
  * allocator_userdata can be used to pass custom data to your allocator (e.g. for pool allocators).
  * */
 CJSON_PUBLIC(cJSON_Configuration) cJSON_CreateConfiguration(const cJSON_Allocators * const allocators, void *allocator_userdata);
+/* Create a copy of an existing configuration */
+CJSON_PUBLIC(cJSON_Configuration) cJSON_DuplicateConfiguration(const cJSON_Configuration, const cJSON_Allocators * const allocators, void *allocator_userdata);
 /* Change the allocators of a cJSON_Configuration and reset the userdata */
 CJSON_PUBLIC(cJSON_Configuration) cJSON_ConfigurationChangeAllocators(cJSON_Configuration configuration, const cJSON_Allocators allocators);
 /* Change the allocator userdata attached to a cJSON_Configuration */

+ 39 - 0
tests/configuration_tests.c

@@ -83,6 +83,42 @@ static void create_configuration_should_not_take_incomplete_allocators(void)
     TEST_ASSERT_NULL(cJSON_CreateConfiguration(&allocators2, &userdata));
 }
 
+static void duplicate_configuration_should_duplicate_a_configuration(void)
+{
+    internal_configuration *configuration = NULL;
+
+    configuration = (internal_configuration*)cJSON_DuplicateConfiguration(&global_configuration, NULL, NULL);
+    TEST_ASSERT_NOT_NULL(configuration);
+
+    TEST_ASSERT_EQUAL_MEMORY(&global_configuration, configuration, sizeof(internal_configuration));
+
+    free(configuration);
+}
+
+static void duplicate_configuration_should_take_custom_allocators(void)
+{
+    internal_configuration *configuration = NULL;
+    cJSON_Allocators allocators = {custom_allocator, custom_deallocator, NULL};
+    size_t userdata = 0;
+
+    configuration = (internal_configuration*)cJSON_DuplicateConfiguration(&global_configuration, &allocators, &userdata);
+    TEST_ASSERT_NOT_NULL(configuration);
+    TEST_ASSERT_EQUAL_MESSAGE(userdata, sizeof(internal_configuration), "custom allocator wasn't run properly");
+
+    TEST_ASSERT_EQUAL_MEMORY(&global_configuration, configuration, sizeof(internal_configuration));
+    free(configuration);
+}
+
+static void duplicate_configuration_should_not_take_incomplete_allocators(void)
+{
+    cJSON_Allocators allocators1 = {custom_allocator, NULL, NULL};
+    cJSON_Allocators allocators2 = {NULL, custom_deallocator, NULL};
+    size_t userdata = 0;
+
+    TEST_ASSERT_NULL(cJSON_DuplicateConfiguration(&global_configuration, &allocators1, &userdata));
+    TEST_ASSERT_NULL(cJSON_DuplicateConfiguration(&global_configuration, &allocators2, &userdata));
+}
+
 static void configuration_change_allocators_should_change_allocators(void)
 {
     internal_configuration *configuration = NULL;
@@ -211,6 +247,9 @@ int main(void)
     RUN_TEST(create_configuration_should_create_a_configuration);
     RUN_TEST(create_configuration_should_take_custom_allocators);
     RUN_TEST(create_configuration_should_not_take_incomplete_allocators);
+    RUN_TEST(duplicate_configuration_should_duplicate_a_configuration);
+    RUN_TEST(duplicate_configuration_should_take_custom_allocators);
+    RUN_TEST(duplicate_configuration_should_not_take_incomplete_allocators);
     RUN_TEST(configuration_change_allocators_should_change_allocators);
     RUN_TEST(configuration_change_allocators_should_not_change_incomplete_allocators);
     RUN_TEST(configuration_change_userdata_should_change_userdata);