浏览代码

Feature Request: 2903802.
If you need to add an existing cJSON to a new object, but the existing object
must not be affected by this, use cJSON_AddItemReferenceTo<Array|Object>.

This will make a "reference" to the existing object (which is what you really mean to do),
and allow you to use it with a new object without fear of names being corrupted or things
being deleted.

Think of it like a reference, since that's pretty much what it is.
If you modify the resulting object (i.e. you AddItemReference, then retrieve with GetObjectItem,
and then start adding/replacing) you'll modify the object you pass in (in other words, this
doesn't clone everything, since that would probably end up being wasteful of space), however,
if you add it, and treat it as if it were const, everything will be fine!



git-svn-id: http://svn.code.sf.net/p/cjson/code@20 e3330c51-1366-4df0-8b21-3ccf24e3d50e

Dave Gamble 15 年之前
父节点
当前提交
29b085bc5d
共有 2 个文件被更改,包括 15 次插入4 次删除
  1. 8 3
      cJSON.c
  2. 7 1
      cJSON.h

+ 8 - 3
cJSON.c

@@ -77,8 +77,8 @@ void cJSON_Delete(cJSON *c)
 	while (c)
 	{
 		next=c->next;
-		if (c->child) cJSON_Delete(c->child);
-		if (c->valuestring) cJSON_free(c->valuestring);
+		if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
+		if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
 		if (c->string) cJSON_free(c->string);
 		cJSON_free(c);
 		c=next;
@@ -257,7 +257,7 @@ static const char *parse_value(cJSON *item,const char *value)
 static char *print_value(cJSON *item,int depth,int fmt)
 {
 	char *out=0;
-	switch (item->type)
+	switch ((item->type)&255)
 	{
 		case cJSON_NULL:	out=cJSON_strdup("null");	break;
 		case cJSON_False:	out=cJSON_strdup("false");break;
@@ -449,10 +449,15 @@ cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)	{cJSON *c=object->c
 
 // Utility for array list handling.
 static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
+// Utility for handling references.
+static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
 
 // Add item to array/object.
 void   cJSON_AddItemToArray(cJSON *array, cJSON *item)						{cJSON *c=array->child;if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
 void   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)	{if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
+void	cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)						{cJSON_AddItemToArray(array,create_reference(item));}
+void	cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item)	{cJSON_AddItemToObject(object,string,create_reference(item));}
+
 
 // Replace array/object items with new ones.
 void   cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)		{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;

+ 7 - 1
cJSON.h

@@ -36,6 +36,8 @@ extern "C"
 #define cJSON_String 4
 #define cJSON_Array 5
 #define cJSON_Object 6
+	
+#define cJSON_IsReference 256
 
 // The cJSON structure:
 typedef struct cJSON {
@@ -94,7 +96,11 @@ extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
 // Append item to the specified array/object.
 extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
 extern void	cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
-
+// Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON.
+extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
+extern void	cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
+	
+	
 // Update array items.
 extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
 extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);