|  | @@ -30,12 +30,47 @@
 | 
	
		
			
				|  |  |  #include <float.h>
 | 
	
		
			
				|  |  |  #include "cJSON.h"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#if defined(WINDOWS) || defined(__WIN32__) || defined(WIN32)
 | 
	
		
			
				|  |  | +#if defined(WINDOWS) || defined(__WIN32__) || defined(WIN32) || defined(_WIN32)
 | 
	
		
			
				|  |  |  #define strcasecmp stricmp
 | 
	
		
			
				|  |  | +#define strdup _strdup
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +static void *(*cJSON_malloc)(size_t sz) = malloc;
 | 
	
		
			
				|  |  | +static void *(*cJSON_realloc)(void *ptr, size_t sz) = realloc;
 | 
	
		
			
				|  |  | +static void (*cJSON_free)(void *ptr) = free;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static char* cJSON_strdup(const char* str)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +      size_t len;
 | 
	
		
			
				|  |  | +      char* copy;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      len = strlen(str) + 1;
 | 
	
		
			
				|  |  | +      if (!(copy = (char*)cJSON_malloc(len))) return 0;
 | 
	
		
			
				|  |  | +      memcpy(copy,str,len);
 | 
	
		
			
				|  |  | +      return copy;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void cJSON_InitHooks(cJSON_Hooks* hooks)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    if (!hooks) { /* Reset hooks */
 | 
	
		
			
				|  |  | +        cJSON_malloc = malloc;
 | 
	
		
			
				|  |  | +        cJSON_realloc = realloc;
 | 
	
		
			
				|  |  | +        cJSON_free = free;
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
 | 
	
		
			
				|  |  | +	cJSON_realloc= (hooks->realloc_fn)?hooks->realloc_fn:realloc;
 | 
	
		
			
				|  |  | +	cJSON_free	 = (hooks->free_fn)?hooks->free_fn:free;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  // Internal constructor.
 | 
	
		
			
				|  |  | -static cJSON *cJSON_New_Item() { return (cJSON*)calloc(sizeof(cJSON),1); }
 | 
	
		
			
				|  |  | +static cJSON *cJSON_New_Item()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
 | 
	
		
			
				|  |  | +	if (node) memset(node,0,sizeof(cJSON));
 | 
	
		
			
				|  |  | +	return node;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // Delete a cJSON structure.
 | 
	
		
			
				|  |  |  void cJSON_Delete(cJSON *c)
 | 
	
	
		
			
				|  | @@ -45,9 +80,9 @@ void cJSON_Delete(cJSON *c)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  |  		next=c->next;
 | 
	
		
			
				|  |  |  		if (c->child) cJSON_Delete(c->child);
 | 
	
		
			
				|  |  | -		if (c->valuestring) free(c->valuestring);
 | 
	
		
			
				|  |  | -		if (c->string) free(c->string);
 | 
	
		
			
				|  |  | -		free(c);
 | 
	
		
			
				|  |  | +		if (c->valuestring) cJSON_free(c->valuestring);
 | 
	
		
			
				|  |  | +		if (c->string) cJSON_free(c->string);
 | 
	
		
			
				|  |  | +		cJSON_free(c);
 | 
	
		
			
				|  |  |  		c=next;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -82,12 +117,12 @@ static char *print_number(cJSON *item)
 | 
	
		
			
				|  |  |  	double d=item->valuedouble;
 | 
	
		
			
				|  |  |  	if (fabs(((double)item->valueint)-d)<=DBL_EPSILON)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  | -		str=(char*)malloc(21);	// 2^64+1 can be represented in 21 chars.
 | 
	
		
			
				|  |  | +		str=(char*)cJSON_malloc(21);	// 2^64+1 can be represented in 21 chars.
 | 
	
		
			
				|  |  |  		sprintf(str,"%d",item->valueint);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	else
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  | -		str=(char*)malloc(64);	// This is a nice tradeoff.
 | 
	
		
			
				|  |  | +		str=(char*)cJSON_malloc(64);	// This is a nice tradeoff.
 | 
	
		
			
				|  |  |  		if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)	sprintf(str,"%e",d);
 | 
	
		
			
				|  |  |  		else									sprintf(str,"%f",d);
 | 
	
		
			
				|  |  |  	}
 | 
	
	
		
			
				|  | @@ -103,7 +138,8 @@ static const char *parse_string(cJSON *item,const char *str)
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  |  	while (*ptr!='\"' && *ptr>31 && ++len) if (*ptr++ == '\\') ptr++;	// Skip escaped quotes.
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  | -	out=(char*)malloc(len+1);	// This is how long we need for the string, roughly.
 | 
	
		
			
				|  |  | +	out=(char*)cJSON_malloc(len+1);	// This is how long we need for the string, roughly.
 | 
	
		
			
				|  |  | +	if (!out) return 0;
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  |  	ptr=str+1;ptr2=out;
 | 
	
		
			
				|  |  |  	while (*ptr!='\"' && *ptr>31)
 | 
	
	
		
			
				|  | @@ -149,7 +185,7 @@ static char *print_string_ptr(const char *str)
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  |  	ptr=str;while (*ptr && ++len) {if (*ptr<32 || *ptr=='\"' || *ptr=='\\') len++;ptr++;}
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  | -	out=(char*)malloc(len+3);
 | 
	
		
			
				|  |  | +	out=(char*)cJSON_malloc(len+3);
 | 
	
		
			
				|  |  |  	ptr2=out;ptr=str;
 | 
	
		
			
				|  |  |  	*ptr2++='\"';
 | 
	
		
			
				|  |  |  	while (*ptr)
 | 
	
	
		
			
				|  | @@ -189,7 +225,15 @@ static char *print_object(cJSON *item,int depth);
 | 
	
		
			
				|  |  |  static const char *skip(const char *in) {while (in && *in<=32) in++; return in;}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // Parse an object - create a new root, and populate.
 | 
	
		
			
				|  |  | -cJSON *cJSON_Parse(const char *value)	{cJSON *c=cJSON_New_Item();parse_value(c,skip(value));return c;}
 | 
	
		
			
				|  |  | +cJSON *cJSON_Parse(const char *value)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	cJSON *c=cJSON_New_Item();
 | 
	
		
			
				|  |  | +	if (!c) return 0;       /* memory fail */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (!parse_value(c,skip(value))) {cJSON_Delete(c);return 0;}
 | 
	
		
			
				|  |  | +	return c;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  // Render a cJSON item/entity/structure to text.
 | 
	
		
			
				|  |  |  char *cJSON_Print(cJSON *item)			{return print_value(item,0);}
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -214,9 +258,9 @@ static char *print_value(cJSON *item,int depth)
 | 
	
		
			
				|  |  |  	char *out=0;
 | 
	
		
			
				|  |  |  	switch (item->type)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  | -		case cJSON_NULL:	out=strdup("null");	break;
 | 
	
		
			
				|  |  | -		case cJSON_False:	out=strdup("false");break;
 | 
	
		
			
				|  |  | -		case cJSON_True:	out=strdup("true"); break;
 | 
	
		
			
				|  |  | +		case cJSON_NULL:	out=cJSON_strdup("null");	break;
 | 
	
		
			
				|  |  | +		case cJSON_False:	out=cJSON_strdup("false");break;
 | 
	
		
			
				|  |  | +		case cJSON_True:	out=cJSON_strdup("true"); break;
 | 
	
		
			
				|  |  |  		case cJSON_Number:	out=print_number(item);break;
 | 
	
		
			
				|  |  |  		case cJSON_String:	out=print_string(item);break;
 | 
	
		
			
				|  |  |  		case cJSON_Array:	out=print_array(item,depth);break;
 | 
	
	
		
			
				|  | @@ -236,14 +280,17 @@ static const char *parse_array(cJSON *item,const char *value)
 | 
	
		
			
				|  |  |  	if (*value==']') return value+1;	// empty array.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	item->child=child=cJSON_New_Item();
 | 
	
		
			
				|  |  | +	if (!item->child) return 0;		 // memory fail
 | 
	
		
			
				|  |  |  	value=skip(parse_value(child,skip(value)));	// skip any spacing, get the value.
 | 
	
		
			
				|  |  | +	if (!value) return 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	while (*value==',')
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  |  		cJSON *new_item;
 | 
	
		
			
				|  |  | -		if (!(new_item=cJSON_New_Item()))	return 0; // memory fail
 | 
	
		
			
				|  |  | +		if (!(new_item=cJSON_New_Item())) return 0; 	// memory fail
 | 
	
		
			
				|  |  |  		child->next=new_item;new_item->prev=child;child=new_item;
 | 
	
		
			
				|  |  |  		value=skip(parse_value(child,skip(value+1)));
 | 
	
		
			
				|  |  | +		if (!value) return 0;	// memory fail
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	if (*value==']') return value+1;	// end of array
 | 
	
	
		
			
				|  | @@ -256,19 +303,19 @@ static char *print_array(cJSON *item,int depth)
 | 
	
		
			
				|  |  |  	char *out,*ptr,*ret;int len=5;
 | 
	
		
			
				|  |  |  	cJSON *child=item->child;
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  | -	out=(char*)malloc(len);*out='[';
 | 
	
		
			
				|  |  | +	out=(char*)cJSON_malloc(len);*out='[';
 | 
	
		
			
				|  |  |  	ptr=out+1;*ptr=0;
 | 
	
		
			
				|  |  |  	while (child)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  |  		ret=print_value(child,depth+1);
 | 
	
		
			
				|  |  | -		if (!ret) {free(out);return 0;}	// Check for failure!
 | 
	
		
			
				|  |  | +		if (!ret) {cJSON_free(out);return 0;}	// Check for failure!
 | 
	
		
			
				|  |  |  		len+=strlen(ret)+3;
 | 
	
		
			
				|  |  | -		out=(char*)realloc(out,len);
 | 
	
		
			
				|  |  | +		out=(char*)cJSON_realloc(out,len);
 | 
	
		
			
				|  |  |  		ptr=out+strlen(out);
 | 
	
		
			
				|  |  |  		ptr+=sprintf(ptr,ret);
 | 
	
		
			
				|  |  |  		if (child->next) {*ptr++=',';*ptr++=' ';*ptr=0;}
 | 
	
		
			
				|  |  |  		child=child->next;
 | 
	
		
			
				|  |  | -		free(ret);
 | 
	
		
			
				|  |  | +		cJSON_free(ret);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	*ptr++=']';*ptr++=0;
 | 
	
		
			
				|  |  |  	return out;	
 | 
	
	
		
			
				|  | @@ -286,9 +333,11 @@ static const char *parse_object(cJSON *item,const char *value)
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  |  	item->child=child=cJSON_New_Item();
 | 
	
		
			
				|  |  |  	value=skip(parse_string(child,skip(value)));
 | 
	
		
			
				|  |  | +	if (!value) return 0;
 | 
	
		
			
				|  |  |  	child->string=child->valuestring;child->valuestring=0;
 | 
	
		
			
				|  |  |  	if (*value!=':') return 0;	// fail!
 | 
	
		
			
				|  |  |  	value=skip(parse_value(child,skip(value+1)));	// skip any spacing, get the value.
 | 
	
		
			
				|  |  | +	if (!value) return 0;
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  |  	while (*value==',')
 | 
	
		
			
				|  |  |  	{
 | 
	
	
		
			
				|  | @@ -296,9 +345,11 @@ static const char *parse_object(cJSON *item,const char *value)
 | 
	
		
			
				|  |  |  		if (!(new_item=cJSON_New_Item()))	return 0; // memory fail
 | 
	
		
			
				|  |  |  		child->next=new_item;new_item->prev=child;child=new_item;
 | 
	
		
			
				|  |  |  		value=skip(parse_string(child,skip(value+1)));
 | 
	
		
			
				|  |  | +		if (!value) return 0;
 | 
	
		
			
				|  |  |  		child->string=child->valuestring;child->valuestring=0;
 | 
	
		
			
				|  |  |  		if (*value!=':') return 0;	// fail!
 | 
	
		
			
				|  |  |  		value=skip(parse_value(child,skip(value+1)));	// skip any spacing, get the value.		
 | 
	
		
			
				|  |  | +		if (!value) return 0;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  |  	if (*value=='}') return value+1;	// end of array
 | 
	
	
		
			
				|  | @@ -311,16 +362,16 @@ static char *print_object(cJSON *item,int depth)
 | 
	
		
			
				|  |  |  	char *out,*ptr,*ret,*str;int len=7,i;
 | 
	
		
			
				|  |  |  	cJSON *child=item->child;
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  | -	depth++;len+=depth;out=(char*)malloc(len);*out='{';
 | 
	
		
			
				|  |  | +	depth++;len+=depth;out=(char*)cJSON_malloc(len);*out='{';
 | 
	
		
			
				|  |  |  	ptr=out+1;*ptr++='\n';*ptr=0;
 | 
	
		
			
				|  |  |  	while (child)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  |  		str=print_string_ptr(child->string);
 | 
	
		
			
				|  |  | -		if (!str) {free(out);return 0;}
 | 
	
		
			
				|  |  | +		if (!str) {cJSON_free(out);return 0;}
 | 
	
		
			
				|  |  |  		ret=print_value(child,depth);
 | 
	
		
			
				|  |  | -		if (!ret) {free(str);free(out);return 0;}	// Check for failure!
 | 
	
		
			
				|  |  | +		if (!ret) {cJSON_free(str);cJSON_free(out);return 0;}	// Check for failure!
 | 
	
		
			
				|  |  |  		len+=strlen(ret)+strlen(str)+4+depth;
 | 
	
		
			
				|  |  | -		out=(char*)realloc(out,len);
 | 
	
		
			
				|  |  | +		out=(char*)cJSON_realloc(out,len);
 | 
	
		
			
				|  |  |  		ptr=out+strlen(out);
 | 
	
		
			
				|  |  |  		for (i=0;i<depth;i++) *ptr++='\t';
 | 
	
		
			
				|  |  |  		ptr+=sprintf(ptr,str);
 | 
	
	
		
			
				|  | @@ -329,7 +380,7 @@ static char *print_object(cJSON *item,int depth)
 | 
	
		
			
				|  |  |  		if (child->next) *ptr++=',';
 | 
	
		
			
				|  |  |  		*ptr++='\n';*ptr=0;
 | 
	
		
			
				|  |  |  		child=child->next;
 | 
	
		
			
				|  |  | -		free(str);free(ret);
 | 
	
		
			
				|  |  | +		cJSON_free(str);cJSON_free(ret);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	for (i=0;i<depth-1;i++) *ptr++='\t';
 | 
	
		
			
				|  |  |  	*ptr++='}';*ptr++=0;
 | 
	
	
		
			
				|  | @@ -346,14 +397,14 @@ static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=p
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // 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) free(item->string);item->string=strdup(string);cJSON_AddItemToArray(object,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);}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // Create basic types:
 | 
	
		
			
				|  |  |  cJSON *cJSON_CreateNull()						{cJSON *item=cJSON_New_Item();item->type=cJSON_NULL;return item;}
 | 
	
		
			
				|  |  |  cJSON *cJSON_CreateTrue()						{cJSON *item=cJSON_New_Item();item->type=cJSON_True;return item;}
 | 
	
		
			
				|  |  |  cJSON *cJSON_CreateFalse()						{cJSON *item=cJSON_New_Item();item->type=cJSON_False;return item;}
 | 
	
		
			
				|  |  |  cJSON *cJSON_CreateNumber(double num)			{cJSON *item=cJSON_New_Item();item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;return item;}
 | 
	
		
			
				|  |  | -cJSON *cJSON_CreateString(const char *string)	{cJSON *item=cJSON_New_Item();item->type=cJSON_String;item->valuestring=strdup(string);return item;}
 | 
	
		
			
				|  |  | +cJSON *cJSON_CreateString(const char *string)	{cJSON *item=cJSON_New_Item();item->type=cJSON_String;item->valuestring=cJSON_strdup(string);return item;}
 | 
	
		
			
				|  |  |  cJSON *cJSON_CreateArray()						{cJSON *item=cJSON_New_Item();item->type=cJSON_Array;return item;}
 | 
	
		
			
				|  |  |  cJSON *cJSON_CreateObject()						{cJSON *item=cJSON_New_Item();item->type=cJSON_Object;return item;}
 | 
	
		
			
				|  |  |  
 |