mirror of
https://github.com/DaveGamble/cJSON.git
synced 2024-12-26 21:04:24 +08:00
update cJSON_SetValuestring and testcase
This commit is contained in:
parent
34e102d0dc
commit
31c7880fab
@ -212,7 +212,7 @@ For every value type there is a `cJSON_Create...` function that can be used to c
|
|||||||
All of these will allocate a `cJSON` struct that can later be deleted with `cJSON_Delete`.
|
All of these will allocate a `cJSON` struct that can later be deleted with `cJSON_Delete`.
|
||||||
Note that you have to delete them at some point, otherwise you will get a memory leak.
|
Note that you have to delete them at some point, otherwise you will get a memory leak.
|
||||||
**Important**: If you have added an item to an array or an object already, you **mustn't** delete it with `cJSON_Delete`. Adding it to an array or object transfers its ownership so that when that array or object is deleted,
|
**Important**: If you have added an item to an array or an object already, you **mustn't** delete it with `cJSON_Delete`. Adding it to an array or object transfers its ownership so that when that array or object is deleted,
|
||||||
it gets deleted as well. You also could use `cJSON_SetValuestringToObject` to change a `cJSON_Object`'s `valuestring`, and you needn't to free the previous `valuestring` manually.
|
it gets deleted as well. You also could use `cJSON_SetValuestring` to change a `cJSON_String`'s `valuestring`, and you needn't to free the previous `valuestring` manually.
|
||||||
|
|
||||||
#### Basic types
|
#### Basic types
|
||||||
|
|
||||||
|
18
cJSON.c
18
cJSON.c
@ -368,23 +368,25 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
|
|||||||
return object->valuedouble = number;
|
return object->valuedouble = number;
|
||||||
}
|
}
|
||||||
|
|
||||||
CJSON_PUBLIC(char*) cJSON_SetValuestringToObject(cJSON *object, const char *valuestring)
|
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
|
||||||
{
|
{
|
||||||
size_t length = 0;
|
|
||||||
char *copy = NULL;
|
char *copy = NULL;
|
||||||
/* if object->valuestring is NULL, it should not set valuestring */
|
/* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
|
||||||
if (object->valuestring == NULL)
|
if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
length = strlen(valuestring) + sizeof("");
|
if (strlen(valuestring) <= strlen(object->valuestring))
|
||||||
copy = (char*) cJSON_malloc(length);
|
{
|
||||||
|
strcpy(object->valuestring, valuestring);
|
||||||
|
return object->valuestring;
|
||||||
|
}
|
||||||
|
copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks);
|
||||||
if (copy == NULL)
|
if (copy == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memcpy(copy, valuestring, length);
|
if (object->valuestring != NULL)
|
||||||
if (!(object->type & cJSON_IsReference) && (object->valuestring != NULL))
|
|
||||||
{
|
{
|
||||||
cJSON_free(object->valuestring);
|
cJSON_free(object->valuestring);
|
||||||
}
|
}
|
||||||
|
4
cJSON.h
4
cJSON.h
@ -278,8 +278,8 @@ CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * c
|
|||||||
/* helper for the cJSON_SetNumberValue macro */
|
/* helper for the cJSON_SetNumberValue macro */
|
||||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||||
/* Only takes effect when type of object is JSON_Object */
|
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
|
||||||
CJSON_PUBLIC(char*) cJSON_SetValuestringToObject(cJSON *object, const char *valuestring);
|
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
|
||||||
|
|
||||||
/* Macro for iterating over an array or object */
|
/* Macro for iterating over an array or object */
|
||||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||||
|
@ -587,24 +587,34 @@ static void cjson_delete_item_from_array_should_not_broken_list_structure(void)
|
|||||||
static void cjson_set_valuestring_to_object_should_not_leak_memory(void)
|
static void cjson_set_valuestring_to_object_should_not_leak_memory(void)
|
||||||
{
|
{
|
||||||
cJSON *root = cJSON_Parse("{}");
|
cJSON *root = cJSON_Parse("{}");
|
||||||
cJSON *item1 = cJSON_CreateString("valuestring could be changed safely");
|
const char *stringvalue = "valuestring could be changed safely";
|
||||||
cJSON *item2 = cJSON_CreateStringReference("reference item should be freed by yourself");
|
const char *reference_valuestring = "reference item should be freed by yourself";
|
||||||
const char *newValuestring = "new valuestring which much longer than previous";
|
const char *short_valuestring = "shorter valuestring";
|
||||||
char *returnValue = NULL;
|
const char *long_valuestring = "new valuestring which much longer than previous should be changed safely";
|
||||||
|
cJSON *item1 = cJSON_CreateString(stringvalue);
|
||||||
|
cJSON *item2 = cJSON_CreateStringReference(reference_valuestring);
|
||||||
|
char *ptr1 = NULL;
|
||||||
|
char *return_value = NULL;
|
||||||
|
|
||||||
cJSON_AddItemToObject(root, "one", item1);
|
cJSON_AddItemToObject(root, "one", item1);
|
||||||
cJSON_AddItemToObject(root, "two", item2);
|
cJSON_AddItemToObject(root, "two", item2);
|
||||||
|
|
||||||
/* we needn't to free the original valuestring manually */
|
ptr1 = item1->valuestring;
|
||||||
returnValue = cJSON_SetValuestringToObject(cJSON_GetObjectItem(root, "one"), newValuestring);
|
return_value = cJSON_SetValuestring(cJSON_GetObjectItem(root, "one"), short_valuestring);
|
||||||
TEST_ASSERT_NOT_NULL(returnValue);
|
TEST_ASSERT_NOT_NULL(return_value);
|
||||||
TEST_ASSERT_EQUAL_STRING(newValuestring, cJSON_GetObjectItem(root, "one")->valuestring);
|
TEST_ASSERT_EQUAL_PTR_MESSAGE(ptr1, return_value, "new valuestring shorter than old should not reallocate memory");
|
||||||
|
TEST_ASSERT_EQUAL_STRING(short_valuestring, cJSON_GetObjectItem(root, "one")->valuestring);
|
||||||
|
|
||||||
returnValue = cJSON_SetValuestringToObject(cJSON_GetObjectItem(root, "two"), newValuestring);
|
/* we needn't to free the original valuestring manually */
|
||||||
TEST_ASSERT_NOT_NULL(returnValue);
|
ptr1 = item1->valuestring;
|
||||||
TEST_ASSERT_EQUAL_STRING(newValuestring, cJSON_GetObjectItem(root, "two")->valuestring);
|
return_value = cJSON_SetValuestring(cJSON_GetObjectItem(root, "one"), long_valuestring);
|
||||||
/* we must free the memory manually when the item's type is cJSON_IsReference */
|
TEST_ASSERT_NOT_NULL(return_value);
|
||||||
cJSON_free(item2->valuestring);
|
TEST_ASSERT_NOT_EQUAL_MESSAGE(ptr1, return_value, "new valuestring longer than old should reallocate memory")
|
||||||
|
TEST_ASSERT_EQUAL_STRING(long_valuestring, cJSON_GetObjectItem(root, "one")->valuestring);
|
||||||
|
|
||||||
|
return_value = cJSON_SetValuestring(cJSON_GetObjectItem(root, "two"), long_valuestring);
|
||||||
|
TEST_ASSERT_NULL_MESSAGE(return_value, "valuestring of reference object should not be changed");
|
||||||
|
TEST_ASSERT_EQUAL_STRING(reference_valuestring, cJSON_GetObjectItem(root, "two")->valuestring);
|
||||||
|
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user