1 /*
2   Copyright (c) 2009 Dave Gamble
3 
4   Permission is hereby granted, free of charge, to any person obtaining a copy
5   of this software and associated documentation files (the "Software"), to deal
6   in the Software without restriction, including without limitation the rights
7   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8   copies of the Software, and to permit persons to whom the Software is
9   furnished to do so, subject to the following conditions:
10 
11   The above copyright notice and this permission notice shall be included in
12   all copies or substantial portions of the Software.
13 
14   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20   THE SOFTWARE.
21 */
22 
23 // cJSON
24 // JSON parser in C.
25 
26 #include <string.h>
27 #include <stdio.h>
28 #include <math.h>
29 #include <stdlib.h>
30 #include <float.h>
31 #include <limits.h>
32 #include <ctype.h>
33 #include "cJSON.h"
34 
cJSON_strcasecmp(const char * s1,const char * s2)35 static int cJSON_strcasecmp(const char *s1,const char *s2)
36 {
37 	if (!s1) return (s1==s2)?0:1;
38         if (!s2) return 1;
39 	for(; tolower(*s1) == tolower(*s2); ++s1, ++s2)	if(*s1 == 0)	return 0;
40 	return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
41 }
42 
43 static void *(*cJSON_malloc)(size_t sz) = malloc;
44 static void (*cJSON_free)(void *ptr) = free;
45 
cJSON_strdup(const char * str)46 static char* cJSON_strdup(const char* str)
47 {
48       size_t len;
49       char* copy;
50 
51       len = strlen(str) + 1;
52       if (!(copy = (char*)cJSON_malloc(len))) return 0;
53       memcpy(copy,str,len);
54       return copy;
55 }
56 
cJSON_InitHooks(cJSON_Hooks * hooks)57 void cJSON_InitHooks(cJSON_Hooks* hooks)
58 {
59     if (!hooks) { /* Reset hooks */
60         cJSON_malloc = malloc;
61         cJSON_free = free;
62         return;
63     }
64 
65 	cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
66 	cJSON_free	 = (hooks->free_fn)?hooks->free_fn:free;
67 }
68 
69 // Internal constructor.
cJSON_New_Item()70 static cJSON *cJSON_New_Item()
71 {
72 	cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
73 	if (node) memset(node,0,sizeof(cJSON));
74 	return node;
75 }
76 
77 // Delete a cJSON structure.
cJSON_Delete(cJSON * c)78 void cJSON_Delete(cJSON *c)
79 {
80 	cJSON *next;
81 	while (c)
82 	{
83 		next=c->next;
84 		if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
85 		if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
86 		if (c->string) cJSON_free(c->string);
87 		cJSON_free(c);
88 		c=next;
89 	}
90 }
91 
92 // Parse the input text to generate a number, and populate the result into item.
parse_number(cJSON * item,const char * num)93 static const char *parse_number(cJSON *item,const char *num)
94 {
95 	double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
96 
97 	// Could use sscanf for this?
98 	if (*num=='-') sign=-1,num++;	// Has sign?
99 	if (*num=='0') num++;			// is zero
100 	if (*num>='1' && *num<='9')	do	n=(n*10.0)+(*num++ -'0');	while (*num>='0' && *num<='9');	// Number?
101 	if (*num=='.') {num++;		do	n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');}	// Fractional part?
102 	if (*num=='e' || *num=='E')		// Exponent?
103 	{	num++;if (*num=='+') num++;	else if (*num=='-') signsubscale=-1,num++;		// With sign?
104 		while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0');	// Number?
105 	}
106 
107 	n=sign*n*pow(10.0,(scale+subscale*signsubscale));	// number = +/- number.fraction * 10^+/- exponent
108 
109 	item->valuedouble=n;
110 	item->valueint=(int)n;
111 	item->type=cJSON_Number;
112 	return num;
113 }
114 
115 // Render the number nicely from the given item into a string.
print_number(cJSON * item)116 static char *print_number(cJSON *item)
117 {
118 	char *str;
119 	double d=item->valuedouble;
120 	if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
121 	{
122 		str=(char*)cJSON_malloc(21);	// 2^64+1 can be represented in 21 chars.
123 		if (str) sprintf(str,"%d",item->valueint);
124 	}
125 	else
126 	{
127 		str=(char*)cJSON_malloc(64);	// This is a nice tradeoff.
128 		if (str)
129 		{
130 			if (fabs(floor(d)-d)<=DBL_EPSILON)			sprintf(str,"%.0f",d);
131 			else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)	sprintf(str,"%e",d);
132 			else										sprintf(str,"%f",d);
133 		}
134 	}
135 	return str;
136 }
137 
138 // Parse the input text into an unescaped cstring, and populate item.
139 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
parse_string(cJSON * item,const char * str)140 static const char *parse_string(cJSON *item,const char *str)
141 {
142 	const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc;
143 	if (*str!='\"') return 0;	// not a string!
144 
145 	while (*ptr!='\"' && (unsigned char)*ptr>31 && ++len) if (*ptr++ == '\\') ptr++;	// Skip escaped quotes.
146 
147 	out=(char*)cJSON_malloc(len+1);	// This is how long we need for the string, roughly.
148 	if (!out) return 0;
149 
150 	ptr=str+1;ptr2=out;
151 	while (*ptr!='\"' && (unsigned char)*ptr>31)
152 	{
153 		if (*ptr!='\\') *ptr2++=*ptr++;
154 		else
155 		{
156 			ptr++;
157 			switch (*ptr)
158 			{
159 				case 'b': *ptr2++='\b';	break;
160 				case 'f': *ptr2++='\f';	break;
161 				case 'n': *ptr2++='\n';	break;
162 				case 'r': *ptr2++='\r';	break;
163 				case 't': *ptr2++='\t';	break;
164 				case 'u':	 // transcode utf16 to utf8. DOES NOT SUPPORT SURROGATE PAIRS CORRECTLY.
165 					sscanf(ptr+1,"%4x",&uc);	// get the unicode char.
166 					len=3;if (uc<0x80) len=1;else if (uc<0x800) len=2;ptr2+=len;
167 
168 					switch (len) {
169 						case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
170 						case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
171 						case 1: *--ptr2 =(uc | firstByteMark[len]);
172 					}
173 					ptr2+=len;ptr+=4;
174 					break;
175 				default:  *ptr2++=*ptr; break;
176 			}
177 			ptr++;
178 		}
179 	}
180 	*ptr2=0;
181 	if (*ptr=='\"') ptr++;
182 	item->valuestring=out;
183 	item->type=cJSON_String;
184 	return ptr;
185 }
186 
187 // Render the cstring provided to an escaped version that can be printed.
print_string_ptr(const char * str)188 static char *print_string_ptr(const char *str)
189 {
190 	const char *ptr;char *ptr2,*out;int len=0;
191 
192 	if (!str) return cJSON_strdup("");
193 	ptr=str;while (*ptr && ++len) {if ((unsigned char)*ptr<32 || *ptr=='\"' || *ptr=='\\') len++;ptr++;}
194 
195 	out=(char*)cJSON_malloc(len+3);
196 	if (!out) return 0;
197 
198 	ptr2=out;ptr=str;
199 	*ptr2++='\"';
200 	while (*ptr)
201 	{
202 		if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
203 		else
204 		{
205 			*ptr2++='\\';
206 			switch (*ptr++)
207 			{
208 				case '\\':	*ptr2++='\\';	break;
209 				case '\"':	*ptr2++='\"';	break;
210 				case '\b':	*ptr2++='b';	break;
211 				case '\f':	*ptr2++='f';	break;
212 				case '\n':	*ptr2++='n';	break;
213 				case '\r':	*ptr2++='r';	break;
214 				case '\t':	*ptr2++='t';	break;
215 				default: ptr2--;	break;	// eviscerate with prejudice.
216 			}
217 		}
218 	}
219 	*ptr2++='\"';*ptr2++=0;
220 	return out;
221 }
222 // Invote print_string_ptr (which is useful) on an item.
print_string(cJSON * item)223 static char *print_string(cJSON *item)	{return print_string_ptr(item->valuestring);}
224 
225 // Predeclare these prototypes.
226 static const char *parse_value(cJSON *item,const char *value);
227 static char *print_value(cJSON *item,int depth,int fmt);
228 static const char *parse_array(cJSON *item,const char *value);
229 static char *print_array(cJSON *item,int depth,int fmt);
230 static const char *parse_object(cJSON *item,const char *value);
231 static char *print_object(cJSON *item,int depth,int fmt);
232 
233 // Utility to jump whitespace and cr/lf
skip(const char * in)234 static const char *skip(const char *in) {while (in && (unsigned char)*in<=32) in++; return in;}
235 
236 // Parse an object - create a new root, and populate.
cJSON_Parse(const char * value)237 cJSON *cJSON_Parse(const char *value)
238 {
239 	cJSON *c=cJSON_New_Item();
240 	if (!c) return 0;       /* memory fail */
241 
242 	if (!parse_value(c,skip(value))) {cJSON_Delete(c);return 0;}
243 	return c;
244 }
245 
246 // Render a cJSON item/entity/structure to text.
cJSON_Print(cJSON * item)247 char *cJSON_Print(cJSON *item)				{return print_value(item,0,1);}
cJSON_PrintUnformatted(cJSON * item)248 char *cJSON_PrintUnformatted(cJSON *item)	{return print_value(item,0,0);}
249 
250 // Parser core - when encountering text, process appropriately.
parse_value(cJSON * item,const char * value)251 static const char *parse_value(cJSON *item,const char *value)
252 {
253 	if (!value)						return 0;	// Fail on null.
254 	if (!strncmp(value,"null",4))	{ item->type=cJSON_NULL;  return value+4; }
255 	if (!strncmp(value,"false",5))	{ item->type=cJSON_False; return value+5; }
256 	if (!strncmp(value,"true",4))	{ item->type=cJSON_True; item->valueint=1;	return value+4; }
257 	if (*value=='\"')				{ return parse_string(item,value); }
258 	if (*value=='-' || (*value>='0' && *value<='9'))	{ return parse_number(item,value); }
259 	if (*value=='[')				{ return parse_array(item,value); }
260 	if (*value=='{')				{ return parse_object(item,value); }
261 
262 	return 0;	// failure.
263 }
264 
265 // Render a value to text.
print_value(cJSON * item,int depth,int fmt)266 static char *print_value(cJSON *item,int depth,int fmt)
267 {
268 	char *out=0;
269 	if (!item) return 0;
270 	switch ((item->type)&255)
271 	{
272 		case cJSON_NULL:	out=cJSON_strdup("null");	break;
273 		case cJSON_False:	out=cJSON_strdup("false");break;
274 		case cJSON_True:	out=cJSON_strdup("true"); break;
275 		case cJSON_Number:	out=print_number(item);break;
276 		case cJSON_String:	out=print_string(item);break;
277 		case cJSON_Array:	out=print_array(item,depth,fmt);break;
278 		case cJSON_Object:	out=print_object(item,depth,fmt);break;
279 	}
280 	return out;
281 }
282 
283 // Build an array from input text.
parse_array(cJSON * item,const char * value)284 static const char *parse_array(cJSON *item,const char *value)
285 {
286 	cJSON *child;
287 	if (*value!='[')	return 0;	// not an array!
288 
289 	item->type=cJSON_Array;
290 	value=skip(value+1);
291 	if (*value==']') return value+1;	// empty array.
292 
293 	item->child=child=cJSON_New_Item();
294 	if (!item->child) return 0;		 // memory fail
295 	value=skip(parse_value(child,skip(value)));	// skip any spacing, get the value.
296 	if (!value) return 0;
297 
298 	while (*value==',')
299 	{
300 		cJSON *new_item;
301 		if (!(new_item=cJSON_New_Item())) return 0; 	// memory fail
302 		child->next=new_item;new_item->prev=child;child=new_item;
303 		value=skip(parse_value(child,skip(value+1)));
304 		if (!value) return 0;	// memory fail
305 	}
306 
307 	if (*value==']') return value+1;	// end of array
308 	return 0;	// malformed.
309 }
310 
311 // Render an array to text
print_array(cJSON * item,int depth,int fmt)312 static char *print_array(cJSON *item,int depth,int fmt)
313 {
314 	char **entries;
315 	char *out=0,*ptr,*ret;int len=5;
316 	cJSON *child=item->child;
317 	int numentries=0,i=0,fail=0;
318 
319 	// How many entries in the array?
320 	while (child) numentries++,child=child->next;
321 	// Allocate an array to hold the values for each
322 	entries=(char**)cJSON_malloc(numentries*sizeof(char*));
323 	if (!entries) return 0;
324 	memset(entries,0,numentries*sizeof(char*));
325 	// Retrieve all the results:
326 	child=item->child;
327 	while (child && !fail)
328 	{
329 		ret=print_value(child,depth+1,fmt);
330 		entries[i++]=ret;
331 		if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
332 		child=child->next;
333 	}
334 
335 	// If we didn't fail, try to malloc the output string
336 	if (!fail) out=cJSON_malloc(len);
337 	// If that fails, we fail.
338 	if (!out) fail=1;
339 
340 	// Handle failure.
341 	if (fail)
342 	{
343 		for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
344 		cJSON_free(entries);
345 		return 0;
346 	}
347 
348 	// Compose the output array.
349 	*out='[';
350 	ptr=out+1;*ptr=0;
351 	for (i=0;i<numentries;i++)
352 	{
353 		strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
354 		if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
355 		cJSON_free(entries[i]);
356 	}
357 	cJSON_free(entries);
358 	*ptr++=']';*ptr++=0;
359 	return out;
360 }
361 
362 // Build an object from the text.
parse_object(cJSON * item,const char * value)363 static const char *parse_object(cJSON *item,const char *value)
364 {
365 	cJSON *child;
366 	if (*value!='{')	return 0;	// not an object!
367 
368 	item->type=cJSON_Object;
369 	value=skip(value+1);
370 	if (*value=='}') return value+1;	// empty array.
371 
372 	item->child=child=cJSON_New_Item();
373 	if (!item->child) return 0;
374 	value=skip(parse_string(child,skip(value)));
375 	if (!value) return 0;
376 	child->string=child->valuestring;child->valuestring=0;
377 	if (*value!=':') return 0;	// fail!
378 	value=skip(parse_value(child,skip(value+1)));	// skip any spacing, get the value.
379 	if (!value) return 0;
380 
381 	while (*value==',')
382 	{
383 		cJSON *new_item;
384 		if (!(new_item=cJSON_New_Item()))	return 0; // memory fail
385 		child->next=new_item;new_item->prev=child;child=new_item;
386 		value=skip(parse_string(child,skip(value+1)));
387 		if (!value) return 0;
388 		child->string=child->valuestring;child->valuestring=0;
389 		if (*value!=':') return 0;	// fail!
390 		value=skip(parse_value(child,skip(value+1)));	// skip any spacing, get the value.
391 		if (!value) return 0;
392 	}
393 
394 	if (*value=='}') return value+1;	// end of array
395 	return 0;	// malformed.
396 }
397 
398 // Render an object to text.
print_object(cJSON * item,int depth,int fmt)399 static char *print_object(cJSON *item,int depth,int fmt)
400 {
401 	char **entries=0,**names=0;
402 	char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
403 	cJSON *child=item->child;
404 	int numentries=0,fail=0;
405 	// Count the number of entries.
406 	while (child) numentries++,child=child->next;
407 	// Allocate space for the names and the objects
408 	entries=(char**)cJSON_malloc(numentries*sizeof(char*));
409 	if (!entries) return 0;
410 	names=(char**)cJSON_malloc(numentries*sizeof(char*));
411 	if (!names) {cJSON_free(entries);return 0;}
412 	memset(entries,0,sizeof(char*)*numentries);
413 	memset(names,0,sizeof(char*)*numentries);
414 
415 	// Collect all the results into our arrays:
416 	child=item->child;depth++;if (fmt) len+=depth;
417 	while (child)
418 	{
419 		names[i]=str=print_string_ptr(child->string);
420 		entries[i++]=ret=print_value(child,depth,fmt);
421 		if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
422 		child=child->next;
423 	}
424 
425 	// Try to allocate the output string
426 	if (!fail) out=(char*)cJSON_malloc(len);
427 	if (!out) fail=1;
428 
429 	// Handle failure
430 	if (fail)
431 	{
432 		for (i=0;i<numentries;i++) {free(names[i]);free(entries[i]);}
433 		free(names);free(entries);
434 		return 0;
435 	}
436 
437 	// Compose the output:
438 	*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
439 	for (i=0;i<numentries;i++)
440 	{
441 		if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
442 		strcpy(ptr,names[i]);ptr+=strlen(names[i]);
443 		*ptr++=':';if (fmt) *ptr++='\t';
444 		strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
445 		if (i!=numentries-1) *ptr++=',';
446 		if (fmt) *ptr++='\n';
447 		*ptr=0;
448 		cJSON_free(names[i]);cJSON_free(entries[i]);
449 	}
450 
451 	cJSON_free(names);cJSON_free(entries);
452 	if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
453 	*ptr++='}';*ptr++=0;
454 	return out;
455 }
456 
457 // Get Array size/item / object item.
cJSON_GetArraySize(cJSON * array)458 int    cJSON_GetArraySize(cJSON *array)							{cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
cJSON_GetArrayItem(cJSON * array,int item)459 cJSON *cJSON_GetArrayItem(cJSON *array,int item)				{cJSON *c=array->child;  while (c && item>0) item--,c=c->next; return c;}
cJSON_GetObjectItem(cJSON * object,const char * string)460 cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)	{cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
461 
462 // Utility for array list handling.
suffix_object(cJSON * prev,cJSON * item)463 static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
464 // Utility for handling references.
create_reference(cJSON * item)465 static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
466 
467 // Add item to array/object.
cJSON_AddItemToArray(cJSON * array,cJSON * item)468 void   cJSON_AddItemToArray(cJSON *array, cJSON *item)						{cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
cJSON_AddItemToObject(cJSON * object,const char * string,cJSON * item)469 void   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)	{if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
cJSON_AddItemReferenceToArray(cJSON * array,cJSON * item)470 void	cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)						{cJSON_AddItemToArray(array,create_reference(item));}
cJSON_AddItemReferenceToObject(cJSON * object,const char * string,cJSON * item)471 void	cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item)	{cJSON_AddItemToObject(object,string,create_reference(item));}
472 
cJSON_DetachItemFromArray(cJSON * array,int which)473 cJSON *cJSON_DetachItemFromArray(cJSON *array,int which)			{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
474 	if (c->prev) c->prev->next=c->next;
475         if (c->next) c->next->prev=c->prev;
476         if (c==array->child) array->child=c->next;
477         c->prev=c->next=0;
478         return c;}
cJSON_DeleteItemFromArray(cJSON * array,int which)479 void   cJSON_DeleteItemFromArray(cJSON *array,int which)			{cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
cJSON_DetachItemFromObject(cJSON * object,const char * string)480 cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
cJSON_DeleteItemFromObject(cJSON * object,const char * string)481 void   cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
482 
483 // Replace array/object items with new ones.
cJSON_ReplaceItemInArray(cJSON * array,int which,cJSON * newitem)484 void   cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)		{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
485 	newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
486 	if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
cJSON_ReplaceItemInObject(cJSON * object,const char * string,cJSON * newitem)487 void   cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
488 
489 // Create basic types:
cJSON_CreateNull()490 cJSON *cJSON_CreateNull()						{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
cJSON_CreateTrue()491 cJSON *cJSON_CreateTrue()						{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
cJSON_CreateFalse()492 cJSON *cJSON_CreateFalse()						{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
cJSON_CreateBool(int b)493 cJSON *cJSON_CreateBool(int b)					{cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
cJSON_CreateNumber(double num)494 cJSON *cJSON_CreateNumber(double num)			{cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
cJSON_CreateString(const char * string)495 cJSON *cJSON_CreateString(const char *string)	{cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
cJSON_CreateArray()496 cJSON *cJSON_CreateArray()						{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
cJSON_CreateObject()497 cJSON *cJSON_CreateObject()						{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
498 
499 // Create Arrays:
cJSON_CreateIntArray(int * numbers,int count)500 cJSON *cJSON_CreateIntArray(int *numbers,int count)				{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON_CreateFloatArray(float * numbers,int count)501 cJSON *cJSON_CreateFloatArray(float *numbers,int count)			{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON_CreateDoubleArray(double * numbers,int count)502 cJSON *cJSON_CreateDoubleArray(double *numbers,int count)		{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON_CreateStringArray(const char ** strings,int count)503 cJSON *cJSON_CreateStringArray(const char **strings,int count)	{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
504