cJSON_DuplicateConfiguration

This commit is contained in:
Max Bruckner 2018-02-03 05:02:05 +01:00
parent d2d19127d3
commit 050f982608
3 changed files with 54 additions and 17 deletions

30
cJSON.c
View File

@ -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;
memcpy(duplicate, configuration, sizeof(internal_configuration));
return (cJSON_Configuration)configuration;
return duplicate;
}
fail:
if (configuration != NULL)
{
local_allocators->deallocate(configuration, allocator_userdata);
}
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)

View File

@ -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 */

View File

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