xref: /iperf/src/cjson.c (revision ed94082b)
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 #ifdef HAVE_STDINT_H
34 #include <stdint.h>
35 #endif
36 #include <sys/types.h>
37 #include "cjson.h"
38 
39 #ifndef LLONG_MAX
40 #define LLONG_MAX 9223372036854775807LL
41 #endif
42 #ifndef LLONG_MIN
43 #define LLONG_MIN (-LLONG_MAX - 1LL)
44 #endif
45 static const char *global_ep;
46 
47 const char *cJSON_GetErrorPtr(void) {return global_ep;}
48 
49 static int cJSON_strcasecmp(const char *s1,const char *s2)
50 {
51 	if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
52 	for(; tolower(*s1) == tolower(*s2); ++s1, ++s2)	if(*s1 == 0)	return 0;
53 	return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
54 }
55 
56 static void *(*cJSON_malloc)(size_t sz) = malloc;
57 static void (*cJSON_free)(void *ptr) = free;
58 
59 static char* cJSON_strdup(const char* str)
60 {
61       size_t len;
62       char* copy;
63 
64       len = strlen(str) + 1;
65       if (!(copy = (char*)cJSON_malloc(len))) return 0;
66       memcpy(copy,str,len);
67       return copy;
68 }
69 
70 void cJSON_InitHooks(cJSON_Hooks* hooks)
71 {
72     if (!hooks) { /* Reset hooks */
73         cJSON_malloc = malloc;
74         cJSON_free = free;
75         return;
76     }
77 
78 	cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
79 	cJSON_free	 = (hooks->free_fn)?hooks->free_fn:free;
80 }
81 
82 /* Internal constructor. */
83 static cJSON *cJSON_New_Item(void)
84 {
85 	cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
86 	if (node) memset(node,0,sizeof(cJSON));
87 	return node;
88 }
89 
90 /* Delete a cJSON structure. */
91 void cJSON_Delete(cJSON *c)
92 {
93 	cJSON *next;
94 	while (c)
95 	{
96 		next=c->next;
97 		if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
98 		if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
99 		if (!(c->type&cJSON_StringIsConst) && c->string) cJSON_free(c->string);
100 		cJSON_free(c);
101 		c=next;
102 	}
103 }
104 
105 /* Parse the input text to generate a number, and populate the result into item. */
106 static const char *parse_number(cJSON *item,const char *num)
107 {
108 	double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
109 
110 	if (*num=='-') sign=-1,num++;	/* Has sign? */
111 	if (*num=='0') num++;			/* is zero */
112 	if (*num>='1' && *num<='9')	do	n=(n*10.0)+(*num++ -'0');	while (*num>='0' && *num<='9');	/* Number? */
113 	if (*num=='.' && num[1]>='0' && num[1]<='9') {num++;		do	n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');}	/* Fractional part? */
114 	if (*num=='e' || *num=='E')		/* Exponent? */
115 	{	num++;if (*num=='+') num++;	else if (*num=='-') signsubscale=-1,num++;		/* With sign? */
116 		while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0');	/* Number? */
117 	}
118 
119 	n=sign*n*pow(10.0,(scale+subscale*signsubscale));	/* number = +/- number.fraction * 10^+/- exponent */
120 
121 	item->valuedouble=n;
122 	item->valueint=(int64_t)n;
123 	item->type=cJSON_Number;
124 	return num;
125 }
126 
127 static int pow2gt (int x)	{	--x;	x|=x>>1;	x|=x>>2;	x|=x>>4;	x|=x>>8;	x|=x>>16;	return x+1;	}
128 
129 typedef struct {char *buffer; int length; int offset; } printbuffer;
130 
131 static char* ensure(printbuffer *p,int needed)
132 {
133 	char *newbuffer;int newsize;
134 	if (!p || !p->buffer) return 0;
135 	needed+=p->offset;
136 	if (needed<=p->length) return p->buffer+p->offset;
137 
138 	newsize=pow2gt(needed);
139 	newbuffer=(char*)cJSON_malloc(newsize);
140 	if (!newbuffer) {cJSON_free(p->buffer);p->length=0,p->buffer=0;return 0;}
141 	if (newbuffer) memcpy(newbuffer,p->buffer,p->length);
142 	cJSON_free(p->buffer);
143 	p->length=newsize;
144 	p->buffer=newbuffer;
145 	return newbuffer+p->offset;
146 }
147 
148 static int update(printbuffer *p)
149 {
150 	char *str;
151 	if (!p || !p->buffer) return 0;
152 	str=p->buffer+p->offset;
153 	return p->offset+strlen(str);
154 }
155 
156 /* Render the number nicely from the given item into a string. */
157 static char *print_number(cJSON *item,printbuffer *p)
158 {
159 	char *str=0;
160 	double d=item->valuedouble;
161 	if (d==0)
162 	{
163 		if (p)	str=ensure(p,2);
164 		else	str=(char*)cJSON_malloc(2);	/* special case for 0. */
165 		if (str) strcpy(str,"0");
166 	}
167 	else if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=LLONG_MAX && d>=LLONG_MIN)
168 	{
169 		if (p)	str=ensure(p,64);
170 		else	str=(char*)cJSON_malloc(64);
171 		if (str)	sprintf(str,"%lld",(long long) item->valueint);
172 	}
173 	else
174 	{
175 		if (p)	str=ensure(p,64);
176 		else	str=(char*)cJSON_malloc(64);	/* This is a nice tradeoff. */
177 		if (str)
178 		{
179 			if (fpclassify(d) != FP_ZERO && !isnormal(d))				sprintf(str,"null");
180 			else if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)	sprintf(str,"%.0f",d);
181 			else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)					sprintf(str,"%e",d);
182 			else														sprintf(str,"%f",d);
183 		}
184 	}
185 	return str;
186 }
187 
188 static unsigned parse_hex4(const char *str)
189 {
190 	unsigned h=0;
191 	if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
192 	h=h<<4;str++;
193 	if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
194 	h=h<<4;str++;
195 	if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
196 	h=h<<4;str++;
197 	if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
198 	return h;
199 }
200 
201 /* Parse the input text into an unescaped cstring, and populate item. */
202 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
203 static const char *parse_string(cJSON *item,const char *str,const char **ep)
204 {
205 	const char *ptr=str+1,*end_ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
206 	if (*str!='\"') {*ep=str;return 0;}	/* not a string! */
207 
208 	while (*end_ptr!='\"' && *end_ptr && ++len) if (*end_ptr++ == '\\') end_ptr++;	/* Skip escaped quotes. */
209 
210 	out=(char*)cJSON_malloc(len+1);	/* This is how long we need for the string, roughly. */
211 	if (!out) return 0;
212 	item->valuestring=out; /* assign here so out will be deleted during cJSON_Delete() later */
213 	item->type=cJSON_String;
214 
215 	ptr=str+1;ptr2=out;
216 	while (ptr < end_ptr)
217 	{
218 		if (*ptr!='\\') *ptr2++=*ptr++;
219 		else
220 		{
221 			ptr++;
222 			switch (*ptr)
223 			{
224 				case 'b': *ptr2++='\b';	break;
225 				case 'f': *ptr2++='\f';	break;
226 				case 'n': *ptr2++='\n';	break;
227 				case 'r': *ptr2++='\r';	break;
228 				case 't': *ptr2++='\t';	break;
229 				case 'u':	 /* transcode utf16 to utf8. */
230 					uc=parse_hex4(ptr+1);ptr+=4;	/* get the unicode char. */
231 					if (ptr >= end_ptr) {*ep=str;return 0;}	/* invalid */
232 
233 					if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)    {*ep=str;return 0;}	/* check for invalid.   */
234 
235 					if (uc>=0xD800 && uc<=0xDBFF)	/* UTF16 surrogate pairs.	*/
236 					{
237 						if (ptr+6 > end_ptr)    {*ep=str;return 0;}	/* invalid */
238 						if (ptr[1]!='\\' || ptr[2]!='u')    {*ep=str;return 0;}	/* missing second-half of surrogate.    */
239 						uc2=parse_hex4(ptr+3);ptr+=6;
240 						if (uc2<0xDC00 || uc2>0xDFFF)       {*ep=str;return 0;}	/* invalid second-half of surrogate.    */
241 						uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
242 					}
243 
244 					len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
245 
246 					switch (len) {
247 						case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
248 						case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
249 						case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
250 						case 1: *--ptr2 =(uc | firstByteMark[len]);
251 					}
252 					ptr2+=len;
253 					break;
254 				default:  *ptr2++=*ptr; break;
255 			}
256 			ptr++;
257 		}
258 	}
259 	*ptr2=0;
260 	if (*ptr=='\"') ptr++;
261 	return ptr;
262 }
263 
264 /* Render the cstring provided to an escaped version that can be printed. */
265 static char *print_string_ptr(const char *str,printbuffer *p)
266 {
267 	const char *ptr;char *ptr2,*out;int len=0,flag=0;unsigned char token;
268 
269 	if (!str)
270 	{
271 		if (p)	out=ensure(p,3);
272 		else	out=(char*)cJSON_malloc(3);
273 		if (!out) return 0;
274 		strcpy(out,"\"\"");
275 		return out;
276 	}
277 
278 	for (ptr=str;*ptr;ptr++) flag|=((*ptr>0 && *ptr<32)||(*ptr=='\"')||(*ptr=='\\'))?1:0;
279 	if (!flag)
280 	{
281 		len=ptr-str;
282 		if (p) out=ensure(p,len+3);
283 		else		out=(char*)cJSON_malloc(len+3);
284 		if (!out) return 0;
285 		ptr2=out;*ptr2++='\"';
286 		strcpy(ptr2,str);
287 		ptr2[len]='\"';
288 		ptr2[len+1]=0;
289 		return out;
290 	}
291 
292 	ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
293 
294 	if (p)	out=ensure(p,len+3);
295 	else	out=(char*)cJSON_malloc(len+3);
296 	if (!out) return 0;
297 
298 	ptr2=out;ptr=str;
299 	*ptr2++='\"';
300 	while (*ptr)
301 	{
302 		if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
303 		else
304 		{
305 			*ptr2++='\\';
306 			switch (token=*ptr++)
307 			{
308 				case '\\':	*ptr2++='\\';	break;
309 				case '\"':	*ptr2++='\"';	break;
310 				case '\b':	*ptr2++='b';	break;
311 				case '\f':	*ptr2++='f';	break;
312 				case '\n':	*ptr2++='n';	break;
313 				case '\r':	*ptr2++='r';	break;
314 				case '\t':	*ptr2++='t';	break;
315 				default: sprintf(ptr2,"u%04x",token);ptr2+=5;	break;	/* escape and print */
316 			}
317 		}
318 	}
319 	*ptr2++='\"';*ptr2++=0;
320 	return out;
321 }
322 /* Invote print_string_ptr (which is useful) on an item. */
323 static char *print_string(cJSON *item,printbuffer *p)	{return print_string_ptr(item->valuestring,p);}
324 
325 /* Predeclare these prototypes. */
326 static const char *parse_value(cJSON *item,const char *value,const char **ep);
327 static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p);
328 static const char *parse_array(cJSON *item,const char *value,const char **ep);
329 static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p);
330 static const char *parse_object(cJSON *item,const char *value,const char **ep);
331 static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p);
332 
333 /* Utility to jump whitespace and cr/lf */
334 static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
335 
336 /* Parse an object - create a new root, and populate. */
337 cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
338 {
339 	const char *end=0,**ep=return_parse_end?return_parse_end:&global_ep;
340 	cJSON *c=cJSON_New_Item();
341 	*ep=0;
342 	if (!c) return 0;       /* memory fail */
343 
344 	end=parse_value(c,skip(value),ep);
345 	if (!end)	{cJSON_Delete(c);return 0;}	/* parse failure. ep is set. */
346 
347 	/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
348 	if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);*ep=end;return 0;}}
349 	if (return_parse_end) *return_parse_end=end;
350 	return c;
351 }
352 /* Default options for cJSON_Parse */
353 cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
354 
355 /* Render a cJSON item/entity/structure to text. */
356 char *cJSON_Print(cJSON *item)				{return print_value(item,0,1,0);}
357 char *cJSON_PrintUnformatted(cJSON *item)	{return print_value(item,0,0,0);}
358 
359 char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt)
360 {
361 	printbuffer p;
362 	p.buffer=(char*)cJSON_malloc(prebuffer);
363 	p.length=prebuffer;
364 	p.offset=0;
365 	return print_value(item,0,fmt,&p);
366 }
367 
368 
369 /* Parser core - when encountering text, process appropriately. */
370 static const char *parse_value(cJSON *item,const char *value,const char **ep)
371 {
372 	if (!value)						return 0;	/* Fail on null. */
373 	if (!strncmp(value,"null",4))	{ item->type=cJSON_NULL;  return value+4; }
374 	if (!strncmp(value,"false",5))	{ item->type=cJSON_False; return value+5; }
375 	if (!strncmp(value,"true",4))	{ item->type=cJSON_True; item->valueint=1;	return value+4; }
376 	if (*value=='\"')				{ return parse_string(item,value,ep); }
377 	if (*value=='-' || (*value>='0' && *value<='9'))	{ return parse_number(item,value); }
378 	if (*value=='[')				{ return parse_array(item,value,ep); }
379 	if (*value=='{')				{ return parse_object(item,value,ep); }
380 
381 	*ep=value;return 0;	/* failure. */
382 }
383 
384 /* Render a value to text. */
385 static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p)
386 {
387 	char *out=0;
388 	if (!item) return 0;
389 	if (p)
390 	{
391 		switch ((item->type)&255)
392 		{
393 			case cJSON_NULL:	{out=ensure(p,5);	if (out) strcpy(out,"null");	break;}
394 			case cJSON_False:	{out=ensure(p,6);	if (out) strcpy(out,"false");	break;}
395 			case cJSON_True:	{out=ensure(p,5);	if (out) strcpy(out,"true");	break;}
396 			case cJSON_Number:	out=print_number(item,p);break;
397 			case cJSON_String:	out=print_string(item,p);break;
398 			case cJSON_Array:	out=print_array(item,depth,fmt,p);break;
399 			case cJSON_Object:	out=print_object(item,depth,fmt,p);break;
400 		}
401 	}
402 	else
403 	{
404 		switch ((item->type)&255)
405 		{
406 			case cJSON_NULL:	out=cJSON_strdup("null");	break;
407 			case cJSON_False:	out=cJSON_strdup("false");break;
408 			case cJSON_True:	out=cJSON_strdup("true"); break;
409 			case cJSON_Number:	out=print_number(item,0);break;
410 			case cJSON_String:	out=print_string(item,0);break;
411 			case cJSON_Array:	out=print_array(item,depth,fmt,0);break;
412 			case cJSON_Object:	out=print_object(item,depth,fmt,0);break;
413 		}
414 	}
415 	return out;
416 }
417 
418 /* Build an array from input text. */
419 static const char *parse_array(cJSON *item,const char *value,const char **ep)
420 {
421 	cJSON *child;
422 	if (*value!='[')	{*ep=value;return 0;}	/* not an array! */
423 
424 	item->type=cJSON_Array;
425 	value=skip(value+1);
426 	if (*value==']') return value+1;	/* empty array. */
427 
428 	item->child=child=cJSON_New_Item();
429 	if (!item->child) return 0;		 /* memory fail */
430 	value=skip(parse_value(child,skip(value),ep));	/* skip any spacing, get the value. */
431 	if (!value) return 0;
432 
433 	while (*value==',')
434 	{
435 		cJSON *new_item;
436 		if (!(new_item=cJSON_New_Item())) return 0; 	/* memory fail */
437 		child->next=new_item;new_item->prev=child;child=new_item;
438 		value=skip(parse_value(child,skip(value+1),ep));
439 		if (!value) return 0;	/* memory fail */
440 	}
441 
442 	if (*value==']') return value+1;	/* end of array */
443 	*ep=value;return 0;	/* malformed. */
444 }
445 
446 /* Render an array to text */
447 static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p)
448 {
449 	char **entries;
450 	char *out=0,*ptr,*ret;int len=5;
451 	cJSON *child=item->child;
452 	int numentries=0,i=0,fail=0;
453 	size_t tmplen=0;
454 
455 	/* How many entries in the array? */
456 	while (child) numentries++,child=child->next;
457 	/* Explicitly handle numentries==0 */
458 	if (!numentries)
459 	{
460 		if (p)	out=ensure(p,3);
461 		else	out=(char*)cJSON_malloc(3);
462 		if (out) strcpy(out,"[]");
463 		return out;
464 	}
465 
466 	if (p)
467 	{
468 		/* Compose the output array. */
469 		i=p->offset;
470 		ptr=ensure(p,1);if (!ptr) return 0;	*ptr='[';	p->offset++;
471 		child=item->child;
472 		while (child && !fail)
473 		{
474 			print_value(child,depth+1,fmt,p);
475 			p->offset=update(p);
476 			if (child->next) {len=fmt?2:1;ptr=ensure(p,len+1);if (!ptr) return 0;*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;p->offset+=len;}
477 			child=child->next;
478 		}
479 		ptr=ensure(p,2);if (!ptr) return 0;	*ptr++=']';*ptr=0;
480 		out=(p->buffer)+i;
481 	}
482 	else
483 	{
484 		/* Allocate an array to hold the values for each */
485 		entries=(char**)cJSON_malloc(numentries*sizeof(char*));
486 		if (!entries) return 0;
487 		memset(entries,0,numentries*sizeof(char*));
488 		/* Retrieve all the results: */
489 		child=item->child;
490 		while (child && !fail)
491 		{
492 			ret=print_value(child,depth+1,fmt,0);
493 			entries[i++]=ret;
494 			if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
495 			child=child->next;
496 		}
497 
498 		/* If we didn't fail, try to malloc the output string */
499 		if (!fail)	out=(char*)cJSON_malloc(len);
500 		/* If that fails, we fail. */
501 		if (!out) fail=1;
502 
503 		/* Handle failure. */
504 		if (fail)
505 		{
506 			for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
507 			cJSON_free(entries);
508 			return 0;
509 		}
510 
511 		/* Compose the output array. */
512 		*out='[';
513 		ptr=out+1;*ptr=0;
514 		for (i=0;i<numentries;i++)
515 		{
516 			tmplen=strlen(entries[i]);memcpy(ptr,entries[i],tmplen);ptr+=tmplen;
517 			if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
518 			cJSON_free(entries[i]);
519 		}
520 		cJSON_free(entries);
521 		*ptr++=']';*ptr++=0;
522 	}
523 	return out;
524 }
525 
526 /* Build an object from the text. */
527 static const char *parse_object(cJSON *item,const char *value,const char **ep)
528 {
529 	cJSON *child;
530 	if (*value!='{')	{*ep=value;return 0;}	/* not an object! */
531 
532 	item->type=cJSON_Object;
533 	value=skip(value+1);
534 	if (*value=='}') return value+1;	/* empty array. */
535 
536 	item->child=child=cJSON_New_Item();
537 	if (!item->child) return 0;
538 	value=skip(parse_string(child,skip(value),ep));
539 	if (!value) return 0;
540 	child->string=child->valuestring;child->valuestring=0;
541 	if (*value!=':') {*ep=value;return 0;}	/* fail! */
542 	value=skip(parse_value(child,skip(value+1),ep));	/* skip any spacing, get the value. */
543 	if (!value) return 0;
544 
545 	while (*value==',')
546 	{
547 		cJSON *new_item;
548 		if (!(new_item=cJSON_New_Item()))	return 0; /* memory fail */
549 		child->next=new_item;new_item->prev=child;child=new_item;
550 		value=skip(parse_string(child,skip(value+1),ep));
551 		if (!value) return 0;
552 		child->string=child->valuestring;child->valuestring=0;
553 		if (*value!=':') {*ep=value;return 0;}	/* fail! */
554 		value=skip(parse_value(child,skip(value+1),ep));	/* skip any spacing, get the value. */
555 		if (!value) return 0;
556 	}
557 
558 	if (*value=='}') return value+1;	/* end of array */
559 	*ep=value;return 0;	/* malformed. */
560 }
561 
562 /* Render an object to text. */
563 static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p)
564 {
565 	char **entries=0,**names=0;
566 	char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
567 	cJSON *child=item->child;
568 	int numentries=0,fail=0;
569 	size_t tmplen=0;
570 	/* Count the number of entries. */
571 	while (child) numentries++,child=child->next;
572 	/* Explicitly handle empty object case */
573 	if (!numentries)
574 	{
575 		if (p) out=ensure(p,fmt?depth+4:3);
576 		else	out=(char*)cJSON_malloc(fmt?depth+4:3);
577 		if (!out)	return 0;
578 		ptr=out;*ptr++='{';
579 		if (fmt) {*ptr++='\n';for (i=0;i<depth;i++) *ptr++='\t';}
580 		*ptr++='}';*ptr++=0;
581 		return out;
582 	}
583 	if (p)
584 	{
585 		/* Compose the output: */
586 		i=p->offset;
587 		len=fmt?2:1;	ptr=ensure(p,len+1);	if (!ptr) return 0;
588 		*ptr++='{';	if (fmt) *ptr++='\n';	*ptr=0;	p->offset+=len;
589 		child=item->child;depth++;
590 		while (child)
591 		{
592 			if (fmt)
593 			{
594 				ptr=ensure(p,depth);	if (!ptr) return 0;
595 				for (j=0;j<depth;j++) *ptr++='\t';
596 				p->offset+=depth;
597 			}
598 			print_string_ptr(child->string,p);
599 			p->offset=update(p);
600 
601 			len=fmt?2:1;
602 			ptr=ensure(p,len);	if (!ptr) return 0;
603 			*ptr++=':';if (fmt) *ptr++='\t';
604 			p->offset+=len;
605 
606 			print_value(child,depth,fmt,p);
607 			p->offset=update(p);
608 
609 			len=(fmt?1:0)+(child->next?1:0);
610 			ptr=ensure(p,len+1); if (!ptr) return 0;
611 			if (child->next) *ptr++=',';
612 			if (fmt) *ptr++='\n';*ptr=0;
613 			p->offset+=len;
614 			child=child->next;
615 		}
616 		ptr=ensure(p,fmt?(depth+1):2);	 if (!ptr) return 0;
617 		if (fmt)	for (i=0;i<depth-1;i++) *ptr++='\t';
618 		*ptr++='}';*ptr=0;
619 		out=(p->buffer)+i;
620 	}
621 	else
622 	{
623 		/* Allocate space for the names and the objects */
624 		entries=(char**)cJSON_malloc(numentries*sizeof(char*));
625 		if (!entries) return 0;
626 		names=(char**)cJSON_malloc(numentries*sizeof(char*));
627 		if (!names) {cJSON_free(entries);return 0;}
628 		memset(entries,0,sizeof(char*)*numentries);
629 		memset(names,0,sizeof(char*)*numentries);
630 
631 		/* Collect all the results into our arrays: */
632 		child=item->child;depth++;if (fmt) len+=depth;
633 		while (child && !fail)
634 		{
635 			names[i]=str=print_string_ptr(child->string,0);
636 			entries[i++]=ret=print_value(child,depth,fmt,0);
637 			if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
638 			child=child->next;
639 		}
640 
641 		/* Try to allocate the output string */
642 		if (!fail)	out=(char*)cJSON_malloc(len);
643 		if (!out) fail=1;
644 
645 		/* Handle failure */
646 		if (fail)
647 		{
648 			for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
649 			cJSON_free(names);cJSON_free(entries);
650 			return 0;
651 		}
652 
653 		/* Compose the output: */
654 		*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
655 		for (i=0;i<numentries;i++)
656 		{
657 			if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
658 			tmplen=strlen(names[i]);memcpy(ptr,names[i],tmplen);ptr+=tmplen;
659 			*ptr++=':';if (fmt) *ptr++='\t';
660 			strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
661 			if (i!=numentries-1) *ptr++=',';
662 			if (fmt) *ptr++='\n';*ptr=0;
663 			cJSON_free(names[i]);cJSON_free(entries[i]);
664 		}
665 
666 		cJSON_free(names);cJSON_free(entries);
667 		if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
668 		*ptr++='}';*ptr++=0;
669 	}
670 	return out;
671 }
672 
673 /* Get Array size/item / object item. */
674 int    cJSON_GetArraySize(cJSON *array)							{cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
675 cJSON *cJSON_GetArrayItem(cJSON *array,int item)				{cJSON *c=array?array->child:0;while (c && item>0) item--,c=c->next; return c;}
676 cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)	{cJSON *c=object?object->child:0;while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
677 int cJSON_HasObjectItem(cJSON *object,const char *string)		{return cJSON_GetObjectItem(object,string)?1:0;}
678 
679 /* Utility for array list handling. */
680 static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
681 /* Utility for handling references. */
682 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;}
683 
684 /* Add item to array/object. */
685 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);}}
686 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);}
687 void   cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item)	{if (!item) return; if (!(item->type&cJSON_StringIsConst) && item->string) cJSON_free(item->string);item->string=(char*)string;item->type|=cJSON_StringIsConst;cJSON_AddItemToArray(object,item);}
688 void	cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)						{cJSON_AddItemToArray(array,create_reference(item));}
689 void	cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item)	{cJSON_AddItemToObject(object,string,create_reference(item));}
690 
691 cJSON *cJSON_DetachItemFromArray(cJSON *array,int which)			{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
692 	if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
693 void   cJSON_DeleteItemFromArray(cJSON *array,int which)			{cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
694 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;}
695 void   cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
696 
697 /* Replace array/object items with new ones. */
698 void   cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem)		{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) {cJSON_AddItemToArray(array,newitem);return;}
699 	newitem->next=c;newitem->prev=c->prev;c->prev=newitem;if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;}
700 void   cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)		{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
701 	newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
702 	if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
703 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);}}
704 
705 /* Create basic types: */
706 cJSON *cJSON_CreateNull(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
707 cJSON *cJSON_CreateTrue(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
708 cJSON *cJSON_CreateFalse(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
709 cJSON *cJSON_CreateBool(int b)					{cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
710 cJSON *cJSON_CreateNumber(double num)			{cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int64_t)num;}return item;}
711 cJSON *cJSON_CreateString(const char *string)	{cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);if(!item->valuestring){cJSON_Delete(item);return 0;}}return item;}
712 cJSON *cJSON_CreateArray(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
713 cJSON *cJSON_CreateObject(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
714 
715 /* Create Arrays: */
716 cJSON *cJSON_CreateIntArray(const 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(!n){cJSON_Delete(a);return 0;}if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
717 cJSON *cJSON_CreateFloatArray(const 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(!n){cJSON_Delete(a);return 0;}if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
718 cJSON *cJSON_CreateDoubleArray(const 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(!n){cJSON_Delete(a);return 0;}if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
719 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(!n){cJSON_Delete(a);return 0;}if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
720 
721 /* Duplication */
722 cJSON *cJSON_Duplicate(cJSON *item,int recurse)
723 {
724 	cJSON *newitem,*cptr,*nptr=0,*newchild;
725 	/* Bail on bad ptr */
726 	if (!item) return 0;
727 	/* Create new item */
728 	newitem=cJSON_New_Item();
729 	if (!newitem) return 0;
730 	/* Copy over all vars */
731 	newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
732 	if (item->valuestring)	{newitem->valuestring=cJSON_strdup(item->valuestring);	if (!newitem->valuestring)	{cJSON_Delete(newitem);return 0;}}
733 	if (item->string)		{newitem->string=cJSON_strdup(item->string);			if (!newitem->string)		{cJSON_Delete(newitem);return 0;}}
734 	/* If non-recursive, then we're done! */
735 	if (!recurse) return newitem;
736 	/* Walk the ->next chain for the child. */
737 	cptr=item->child;
738 	while (cptr)
739 	{
740 		newchild=cJSON_Duplicate(cptr,1);		/* Duplicate (with recurse) each item in the ->next chain */
741 		if (!newchild) {cJSON_Delete(newitem);return 0;}
742 		if (nptr)	{nptr->next=newchild,newchild->prev=nptr;nptr=newchild;}	/* If newitem->child already set, then crosswire ->prev and ->next and move on */
743 		else		{newitem->child=newchild;nptr=newchild;}					/* Set newitem->child and move to it */
744 		cptr=cptr->next;
745 	}
746 	return newitem;
747 }
748 
749 void cJSON_Minify(char *json)
750 {
751 	char *into=json;
752 	while (*json)
753 	{
754 		if (*json==' ') json++;
755 		else if (*json=='\t') json++;	/* Whitespace characters. */
756 		else if (*json=='\r') json++;
757 		else if (*json=='\n') json++;
758 		else if (*json=='/' && json[1]=='/')  while (*json && *json!='\n') json++;	/* double-slash comments, to end of line. */
759 		else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;}	/* multiline comments. */
760 		else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} /* string literals, which are \" sensitive. */
761 		else *into++=*json++;			/* All other characters. */
762 	}
763 	*into=0;	/* and null-terminate. */
764 }
765