xref: /iperf/src/cjson.c (revision 23481e79)
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 
35 
36 static const char *ep;
37 
38 const char *cJSON_GetErrorPtr( void )
39 {
40 	return ep;
41 }
42 
43 
44 static int cJSON_strcasecmp( const char *s1, const char *s2 )
45 {
46 	if ( ! s1 )
47 		return ( s1 == s2 ) ? 0 : 1;
48 	if ( ! s2 )
49 		return 1;
50 	for ( ; tolower(*s1) == tolower(*s2); ++s1, ++s2)
51 		if( *s1 == 0 )
52 			return 0;
53 	return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
54 }
55 
56 
57 static void *(*cJSON_malloc)( size_t ) = malloc;
58 static void (*cJSON_free)( void * ) = free;
59 
60 void cJSON_InitHooks(cJSON_Hooks* hooks)
61 {
62 	if ( ! hooks ) {
63 		/* Reset hooks. */
64 		cJSON_malloc = malloc;
65 		cJSON_free = free;
66 		return;
67 	}
68 	cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : malloc;
69 	cJSON_free = (hooks->free_fn) ? hooks->free_fn : free;
70 }
71 
72 
73 static char* cJSON_strdup( const char* str )
74 {
75 	size_t len;
76 	char* copy;
77 
78 	len = strlen( str ) + 1;
79 	if ( ! ( copy = (char*) cJSON_malloc( len ) ) )
80 		return 0;
81 	memcpy( copy, str, len );
82 	return copy;
83 }
84 
85 
86 /* Internal constructor. */
87 static cJSON *cJSON_New_Item( void )
88 {
89 	cJSON* node = (cJSON*) cJSON_malloc( sizeof(cJSON) );
90 	if ( node )
91 		memset( node, 0, sizeof(cJSON) );
92 	return node;
93 }
94 
95 
96 /* Delete a cJSON structure. */
97 void cJSON_Delete( cJSON *c )
98 {
99 	cJSON *next;
100 
101 	while ( c ) {
102 		next = c->next;
103 		if ( ! ( c->type & cJSON_IsReference ) && c->child )
104 			cJSON_Delete( c->child );
105 		if ( ! ( c->type & cJSON_IsReference ) && c->valuestring )
106 			cJSON_free( c->valuestring );
107 		if ( c->string )
108 			cJSON_free( c->string );
109 		cJSON_free( c );
110 		c = next;
111 	}
112 }
113 
114 
115 /* Parse the input text to generate a number, and populate the result into item. */
116 static const char *parse_number( cJSON *item, const char *num )
117 {
118 	double n = 0, sign = 1, scale = 0;
119 	int subscale = 0, signsubscale = 1;
120 
121 	/* Could use sscanf for this? */
122 	if ( *num == '-' ) {
123 		/* Has sign. */
124 		sign=-1;
125 		num++;
126 	}
127 	if ( *num == '0' )
128 		/* Is zero. */
129 		num++;
130 	if ( *num >= '1' && *num<='9' ) {
131 		/* Number. */
132 		do {
133 			n = ( n * 10.0 ) + ( *num++ - '0' );
134 		} while ( *num >= '0' && *num <= '9' );
135 	}
136 	if ( *num == '.' && num[1] >= '0' && num[1] <= '9' ) {
137 		/* Fractional part. */
138 		num++;
139 		do {
140 			n = ( n * 10.0 ) + ( *num++ - '0' );
141 			scale--;
142 		} while ( *num >= '0' && *num <= '9' );
143 	}
144 	if ( *num == 'e' || *num == 'E' ) {
145 		/* Exponent. */
146 		num++;
147 		if ( *num == '+' )
148 			num++;
149 		else if ( *num == '-' ) {
150 			/* With sign. */
151 			signsubscale = -1;
152 			num++;
153 		}
154 		while ( *num >= '0' && *num <= '9' )
155 			subscale = ( subscale * 10 ) + ( *num++ - '0' );
156 	}
157 
158 	/* Put it together: number = +/- number.fraction * 10^+/- exponent */
159 	n = sign * n * pow( 10.0, ( scale + subscale * signsubscale ) );
160 
161 	item->valuefloat = n;
162 	item->valueint = n;
163 	item->type = cJSON_Number;
164 	return num;
165 }
166 
167 
168 /* Render the number nicely from the given item into a string. */
169 static char *print_number( cJSON *item )
170 {
171 	char *str;
172 	double d = item->valuefloat;
173 	if ( fabs( ( (double) item->valueint ) - d ) <= DBL_EPSILON && d <= INT_MAX && d >= INT_MIN ) {
174 		str = (char*) cJSON_malloc( 21 );	/* 2^64+1 can be represented in 21 chars. */
175 		if ( str )
176 			sprintf( str, "%d", item->valueint );
177 	} else {
178 		str = (char*) cJSON_malloc( 64 );	/* This is a nice tradeoff. */
179 		if ( str ) {
180 			if ( fabs( floor( d ) - d ) <= DBL_EPSILON )
181 				sprintf( str, "%.0f", d );
182 			else if ( fabs( d ) < 1.0e-6 || fabs( d ) > 1.0e9 )
183 				sprintf( str, "%e", d );
184 			else
185 				sprintf( str, "%f", d );
186 		}
187 	}
188 	return str;
189 }
190 
191 
192 /* Parse the input text into an unescaped cstring, and populate item. */
193 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
194 
195 static const char *parse_string( cJSON *item, const char *str )
196 {
197 	const char *ptr = str + 1;
198 	char *ptr2;
199 	char *out;
200 	int len = 0;
201 	unsigned uc, uc2;
202 
203 	if ( *str != '\"' ) {
204 		/* Not a string! */
205 		ep = str;
206 		return 0;
207 	}
208 
209 	/* Skip escaped quotes. */
210 	while ( *ptr != '\"' && *ptr && ++len )
211 		if ( *ptr++ == '\\' )
212 			ptr++;
213 
214 	if ( ! ( out = (char*) cJSON_malloc( len + 1 ) ) )
215 		return 0;
216 
217 	ptr = str + 1;
218 	ptr2 = out;
219 	while ( *ptr != '\"' && *ptr ) {
220 		if ( *ptr != '\\' )
221 			*ptr2++ = *ptr++;
222 		else {
223 			ptr++;
224 			switch ( *ptr ) {
225 				case 'b': *ptr2++ ='\b'; break;
226 				case 'f': *ptr2++ ='\f'; break;
227 				case 'n': *ptr2++ ='\n'; break;
228 				case 'r': *ptr2++ ='\r'; break;
229 				case 't': *ptr2++ ='\t'; break;
230 				case 'u':
231 					/* Transcode utf16 to utf8. */
232 					/* Get the unicode char. */
233 					sscanf( ptr + 1,"%4x", &uc );
234 					ptr += 4;
235 					/* Check for invalid. */
236 					if ( ( uc >= 0xDC00 && uc <= 0xDFFF ) || uc == 0 )
237 						break;
238 
239 					/* UTF16 surrogate pairs. */
240 					if ( uc >= 0xD800 && uc <= 0xDBFF ) {
241 						if ( ptr[1] != '\\' || ptr[2] != 'u' )
242 							/* Missing second-half of surrogate. */
243 							break;
244 						sscanf( ptr + 3, "%4x", &uc2 );
245 						ptr += 6;
246 						if ( uc2 < 0xDC00 || uc2 > 0xDFFF )
247 							/* Invalid second-half of surrogate. */
248 							break;
249 						uc = 0x10000 | ( ( uc & 0x3FF ) << 10 ) | ( uc2 & 0x3FF );
250 					}
251 
252 					len = 4;
253 					if ( uc < 0x80 )
254 						len = 1;
255 					else if ( uc < 0x800 )
256 						len = 2;
257 					else if ( uc < 0x10000 )
258 						len = 3;
259 					ptr2 += len;
260 
261 					switch ( len ) {
262 						case 4: *--ptr2 = ( ( uc | 0x80) & 0xBF ); uc >>= 6;
263 						case 3: *--ptr2 = ( ( uc | 0x80) & 0xBF ); uc >>= 6;
264 						case 2: *--ptr2 = ( ( uc | 0x80) & 0xBF ); uc >>= 6;
265 						case 1: *--ptr2 = ( uc | firstByteMark[len] );
266 					}
267 					ptr2 += len;
268 					break;
269 				default:  *ptr2++ = *ptr; break;
270 			}
271 			++ptr;
272 		}
273 	}
274 	*ptr2 = 0;
275 	if ( *ptr == '\"' )
276 		++ptr;
277 	item->valuestring = out;
278 	item->type = cJSON_String;
279 	return ptr;
280 }
281 
282 
283 /* Render the cstring provided to an escaped version that can be printed. */
284 static char *print_string_ptr( const char *str )
285 {
286 	const char *ptr;
287 	char *ptr2, *out;
288 	int len = 0;
289 	unsigned char token;
290 
291 	if ( ! str )
292 		return cJSON_strdup( "" );
293 	ptr = str;
294 	while ( ( token = *ptr ) && ++len ) {
295 		if ( strchr( "\"\\\b\f\n\r\t", token ) )
296 			++len;
297 		else if ( token < 32 )
298 			len += 5;
299 		++ptr;
300 	}
301 
302 	if ( ! ( out = (char*) cJSON_malloc( len + 3 ) ) )
303 		return 0;
304 
305 	ptr2 = out;
306 	ptr = str;
307 	*ptr2++ = '\"';
308 	while ( *ptr ) {
309 		if ( (unsigned char) *ptr > 31 && *ptr != '\"' && *ptr != '\\' )
310 			*ptr2++ = *ptr++;
311 		else {
312 			*ptr2++ = '\\';
313 			switch ( token = *ptr++ ) {
314 				case '\\': *ptr2++ = '\\'; break;
315 				case '\"': *ptr2++ = '\"'; break;
316 				case '\b': *ptr2++ = 'b'; break;
317 				case '\f': *ptr2++ = 'f'; break;
318 				case '\n': *ptr2++ = 'n'; break;
319 				case '\r': *ptr2++ = 'r'; break;
320 				case '\t': *ptr2++ = 't'; break;
321 				default:
322 				/* Escape and print. */
323 				sprintf( ptr2, "u%04x", token );
324 				ptr2 += 5;
325 				break;
326 			}
327 		}
328 	}
329 	*ptr2++ = '\"';
330 	*ptr2++ = 0;
331 	return out;
332 }
333 
334 
335 /* Invote print_string_ptr (which is useful) on an item. */
336 static char *print_string( cJSON *item )
337 {
338 	return print_string_ptr( item->valuestring );
339 }
340 
341 
342 /* Predeclare these prototypes. */
343 static const char *parse_value( cJSON *item, const char *value );
344 static char *print_value( cJSON *item, int depth, int fmt );
345 static const char *parse_array( cJSON *item, const char *value );
346 static char *print_array( cJSON *item, int depth, int fmt );
347 static const char *parse_object( cJSON *item, const char *value );
348 static char *print_object( cJSON *item, int depth, int fmt );
349 
350 /* Utility to jump whitespace and cr/lf. */
351 static const char *skip( const char *in )
352 {
353 	while ( in && *in && (unsigned char) *in <= 32 )
354 		in++;
355 	return in;
356 }
357 
358 
359 /* Parse an object - create a new root, and populate. */
360 cJSON *cJSON_Parse( const char *value )
361 {
362 	cJSON *c;
363 	ep = 0;
364 	if ( ! ( c = cJSON_New_Item() ) )
365 		return 0;       /* memory fail */
366 
367 	if ( ! parse_value( c, skip( value ) ) ) {
368 		cJSON_Delete( c );
369 		return 0;
370 	}
371 	return c;
372 }
373 
374 
375 /* Render a cJSON item/entity/structure to text. */
376 char *cJSON_Print( cJSON *item )
377 {
378 	return print_value( item, 0, 1 );
379 }
380 char *cJSON_PrintUnformatted( cJSON *item )
381 {
382 	return print_value( item, 0, 0 );
383 }
384 
385 
386 /* Parser core - when encountering text, process appropriately. */
387 static const char *parse_value( cJSON *item, const char *value )
388 {
389 	if ( ! value )
390 		return 0;	/* Fail on null. */
391 	if ( ! strncmp( value, "null", 4 ) ) {
392 		item->type = cJSON_NULL;
393 		return value + 4;
394 	}
395 	if ( ! strncmp( value, "false", 5 ) ) {
396 		item->type = cJSON_False;
397 		return value + 5;
398 	}
399 	if ( ! strncmp( value, "true", 4 ) ) {
400 		item->type = cJSON_True;
401 		item->valueint = 1;
402 		return value + 4;
403 	}
404 	if ( *value == '\"' )
405 		return parse_string( item, value );
406 	if ( *value == '-' || ( *value >= '0' && *value <= '9' ) )
407 		return parse_number( item, value );
408 	if ( *value == '[' )
409 		return parse_array( item, value );
410 	if ( *value == '{' )
411 		return parse_object( item, value );
412 
413 	/* Fail. */
414 	ep = value;
415 	return 0;
416 }
417 
418 
419 /* Render a value to text. */
420 static char *print_value( cJSON *item, int depth, int fmt )
421 {
422 	char *out = 0;
423 
424 	if ( ! item )
425 		return 0;
426 	switch ( ( item->type ) & 255 ) {
427 		case cJSON_NULL:   out = cJSON_strdup( "null" ); break;
428 		case cJSON_False:  out = cJSON_strdup( "false" ); break;
429 		case cJSON_True:   out = cJSON_strdup( "true" ); break;
430 		case cJSON_Number: out = print_number( item ); break;
431 		case cJSON_String: out = print_string( item ); break;
432 		case cJSON_Array:  out = print_array( item, depth, fmt ); break;
433 		case cJSON_Object: out = print_object( item, depth, fmt ); break;
434 	}
435 	return out;
436 }
437 
438 
439 /* Build an array from input text. */
440 static const char *parse_array( cJSON *item, const char *value )
441 {
442 	cJSON *child;
443 
444 	if ( *value != '[' ) {
445 		/* Not an array! */
446 		ep = value;
447 		return 0;
448 	}
449 
450 	item->type = cJSON_Array;
451 	value = skip( value + 1 );
452 	if ( *value == ']' )
453 		return value + 1;	/* empty array. */
454 
455 	if ( ! ( item->child = child = cJSON_New_Item() ) )
456 		return 0;		 /* memory fail */
457 	if ( ! ( value = skip( parse_value( child, skip( value ) ) ) ) )
458 		return 0;
459 
460 	while ( *value == ',' ) {
461 		cJSON *new_item;
462 		if ( ! ( new_item = cJSON_New_Item() ) )
463 			return 0;	/* memory fail */
464 		child->next = new_item;
465 		new_item->prev = child;
466 		child = new_item;
467 		if ( ! ( value = skip( parse_value( child, skip( value+1 ) ) ) ) )
468 			return 0;	/* memory fail */
469 	}
470 
471 	if ( *value == ']' )
472 		return value + 1;	/* end of array */
473 	/* Malformed. */
474 	ep = value;
475 	return 0;
476 }
477 
478 
479 /* Render an array to text */
480 static char *print_array( cJSON *item, int depth, int fmt )
481 {
482 	char **entries;
483 	char *out = 0, *ptr, *ret;
484 	int len = 5;
485 	cJSON *child = item->child;
486 	int numentries = 0, i = 0, fail = 0;
487 
488 	/* How many entries in the array? */
489 	while ( child ) {
490 		++numentries;
491 		child = child->next;
492 	}
493 	/* Allocate an array to hold the values for each. */
494 	if ( ! ( entries = (char**) cJSON_malloc( numentries * sizeof(char*) ) ) )
495 		return 0;
496 	memset( entries, 0, numentries * sizeof(char*) );
497 	/* Retrieve all the results. */
498 	child = item->child;
499 	while ( child && ! fail ) {
500 		ret = print_value( child, depth + 1, fmt );
501 		entries[i++] = ret;
502 		if ( ret )
503 			len += strlen( ret ) + 2 + ( fmt ? 1 : 0 );
504 		else
505 			fail = 1;
506 		child = child -> next;
507 	}
508 
509 	/* If we didn't fail, try to malloc the output string. */
510 	if ( ! fail ) {
511 		out = (char*) cJSON_malloc( len );
512 		if ( ! out )
513 			fail = 1;
514 	}
515 
516 	/* Handle failure. */
517 	if ( fail ) {
518 		for ( i = 0; i < numentries; ++i )
519 			if ( entries[i] )
520 				cJSON_free( entries[i] );
521 		cJSON_free( entries );
522 		return 0;
523 	}
524 
525 	/* Compose the output array. */
526 	*out = '[';
527 	ptr = out + 1;
528 	*ptr = 0;
529 	for ( i = 0; i < numentries; ++i ) {
530 		strcpy( ptr, entries[i] );
531 		ptr += strlen( entries[i] );
532 		if ( i != numentries - 1 ) {
533 			*ptr++ = ',';
534 			if ( fmt )
535 				*ptr++ = ' ';
536 			*ptr = 0;
537 		}
538 		cJSON_free( entries[i] );
539 	}
540 	cJSON_free( entries );
541 	*ptr++ = ']';
542 	*ptr++ = 0;
543 	return out;
544 }
545 
546 
547 /* Build an object from the text. */
548 static const char *parse_object( cJSON *item, const char *value )
549 {
550 	cJSON *child;
551 
552 	if ( *value != '{' ) {
553 		/* Not an object! */
554 		ep = value;
555 		return 0;
556 	}
557 
558 	item->type = cJSON_Object;
559 	value =skip( value + 1 );
560 	if ( *value == '}' )
561 		return value + 1;	/* empty array. */
562 
563 	if ( ! ( item->child = child = cJSON_New_Item() ) )
564 		return 0;
565 	if ( ! ( value = skip( parse_string( child, skip( value ) ) ) ) )
566 		return 0;
567 	child->string = child->valuestring;
568 	child->valuestring = 0;
569 	if ( *value != ':' ) {
570 		/* Fail! */
571 		ep = value;
572 		return 0;
573 	}
574 	if ( ! ( value = skip( parse_value( child, skip( value + 1 ) ) ) ) )
575 		return 0;
576 
577 	while ( *value == ',' ) {
578 		cJSON *new_item;
579 		if ( ! ( new_item = cJSON_New_Item() ) )
580 			return 0;	/* memory fail */
581 		child->next = new_item;
582 		new_item->prev = child;
583 		child = new_item;
584 		if ( ! ( value = skip( parse_string( child, skip( value + 1 ) ) ) ) )
585 			return 0;
586 		child->string = child->valuestring;
587 		child->valuestring = 0;
588 		if ( *value != ':' ) {
589 			/* Fail! */
590 			ep = value;
591 			return 0;
592 		}
593 		if ( ! ( value = skip( parse_value( child, skip( value + 1 ) ) ) ) )
594 			return 0;
595 	}
596 
597 	if ( *value == '}' )
598 		return value + 1;	/* end of array */
599 	/* Malformed. */
600 	ep = value;
601 	return 0;
602 }
603 
604 
605 /* Render an object to text. */
606 static char *print_object( cJSON *item, int depth, int fmt )
607 {
608 	char **entries = 0, **names = 0;
609 	char *out = 0, *ptr, *ret, *str;
610 	int len = 7, i = 0, j;
611 	cJSON *child = item->child;
612 	int numentries = 0, fail = 0;
613 
614 	/* Count the number of entries. */
615 	while ( child ) {
616 		++numentries;
617 		child = child->next;
618 	}
619 	/* Allocate space for the names and the objects. */
620 	if ( ! ( entries = (char**) cJSON_malloc( numentries * sizeof(char*) ) ) )
621 		return 0;
622 	if ( ! ( names = (char**) cJSON_malloc( numentries * sizeof(char*) ) ) ) {
623 		cJSON_free( entries );
624 		return 0;
625 	}
626 	memset( entries, 0, sizeof(char*) * numentries );
627 	memset( names, 0, sizeof(char*) * numentries );
628 
629 	/* Collect all the results into our arrays. */
630 	child = item->child;
631 	++depth;
632 	if ( fmt )
633 		len += depth;
634 	while ( child ) {
635 		names[i] = str = print_string_ptr( child->string );
636 		entries[i++] = ret = print_value( child, depth, fmt );
637 		if ( str && ret )
638 			len += strlen( ret ) + strlen( str ) + 2 + ( fmt ? 2 + depth : 0 );
639 		else
640 			fail = 1;
641 		child = child->next;
642 	}
643 
644 	/* Try to allocate the output string. */
645 	if ( ! fail ) {
646 		out = (char*) cJSON_malloc( len );
647 		if ( ! out )
648 			fail = 1;
649 	}
650 
651 	/* Handle failure. */
652 	if ( fail ) {
653 		for ( i = 0; i < numentries; ++i ) {
654 			if ( names[i] )
655 				cJSON_free( names[i] );
656 			if ( entries[i] )
657 				cJSON_free( entries[i] );
658 		}
659 		cJSON_free( names );
660 		cJSON_free( entries );
661 		return 0;
662 	}
663 
664 	/* Compose the output. */
665 	*out = '{';
666 	ptr = out + 1;
667 	if ( fmt )
668 		*ptr++ = '\n';
669 	*ptr = 0;
670 	for ( i = 0; i < numentries; ++i ) {
671 		if ( fmt )
672 			for ( j = 0; j < depth; ++j )
673 				*ptr++ = '\t';
674 		strcpy( ptr, names[i] );
675 		ptr += strlen( names[i] );
676 		*ptr++ = ':';
677 		if ( fmt )
678 			*ptr++ = '\t';
679 		strcpy( ptr, entries[i] );
680 		ptr += strlen( entries[i] );
681 		if ( i != numentries - 1 )
682 			*ptr++ = ',';
683 		if ( fmt )
684 			*ptr++ = '\n';
685 		*ptr = 0;
686 		cJSON_free( names[i] );
687 		cJSON_free( entries[i] );
688 	}
689 
690 	cJSON_free( names );
691 	cJSON_free( entries );
692 	if ( fmt )
693 		for ( i = 0; i < depth - 1; ++i )
694 			*ptr++ = '\t';
695 	*ptr++ = '}';
696 	*ptr++ = 0;
697 	return out;
698 }
699 
700 
701 int cJSON_GetArraySize( cJSON *array )
702 {
703 	cJSON *c = array->child;
704 	int i = 0;
705 	while ( c ) {
706 		++i;
707 		c = c->next;
708 	}
709 	return i;
710 }
711 
712 
713 cJSON *cJSON_GetArrayItem( cJSON *array, int item )
714 {
715 	cJSON *c = array->child;
716 	while ( c && item > 0 ) {
717 		--item;
718 		c = c->next;
719 	}
720 	return c;
721 }
722 
723 
724 cJSON *cJSON_GetObjectItem( cJSON *object, const char *string )
725 {
726 	cJSON *c = object->child;
727 	while ( c && cJSON_strcasecmp( c->string, string ) )
728 		c = c->next;
729 	return c;
730 }
731 
732 
733 /* Utility for array list handling. */
734 static void suffix_object( cJSON *prev, cJSON *item )
735 {
736 	prev->next = item;
737 	item->prev = prev;
738 }
739 
740 
741 /* Utility for handling references. */
742 static cJSON *create_reference( cJSON *item )
743 {
744 	cJSON *ref;
745 	if ( ! ( ref = cJSON_New_Item() ) )
746 		return 0;
747 	memcpy( ref, item, sizeof(cJSON) );
748 	ref->string = 0;
749 	ref->type |= cJSON_IsReference;
750 	ref->next = ref->prev = 0;
751 	return ref;
752 }
753 
754 
755 /* Add item to array/object. */
756 void cJSON_AddItemToArray( cJSON *array, cJSON *item )
757 {
758 	cJSON *c = array->child;
759 	if ( ! item )
760 		return;
761 	if ( ! c ) {
762 		array->child = item;
763 	} else {
764 		while ( c && c->next )
765 			c = c->next;
766 		suffix_object( c, item );
767 	}
768 }
769 
770 void cJSON_AddItemToObject( cJSON *object, const char *string, cJSON *item )
771 {
772 	if ( ! item )
773 		return;
774 	if ( item->string )
775 		cJSON_free( item->string );
776 	item->string = cJSON_strdup( string );
777 	cJSON_AddItemToArray( object, item );
778 }
779 
780 void cJSON_AddItemReferenceToArray( cJSON *array, cJSON *item )
781 {
782 	cJSON_AddItemToArray( array, create_reference( item ) );
783 }
784 
785 void cJSON_AddItemReferenceToObject( cJSON *object, const char *string, cJSON *item )
786 {
787 	cJSON_AddItemToObject( object, string, create_reference( item ) );
788 }
789 
790 cJSON *cJSON_DetachItemFromArray( cJSON *array, int which )
791 {
792 	cJSON *c = array->child;
793 	while ( c && which > 0 ) {
794 		c = c->next;
795 		--which;
796 	}
797 	if ( ! c )
798 		return 0;
799 	if ( c->prev )
800 		c->prev->next = c->next;
801 	if ( c->next ) c->next->prev = c->prev;
802 	if ( c == array->child )
803 		array->child = c->next;
804 	c->prev = c->next = 0;
805 	return c;
806 }
807 
808 void cJSON_DeleteItemFromArray( cJSON *array, int which )
809 {
810 	cJSON_Delete( cJSON_DetachItemFromArray( array, which ) );
811 }
812 
813 cJSON *cJSON_DetachItemFromObject( cJSON *object, const char *string )
814 {
815 	int i = 0;
816 	cJSON *c = object->child;
817 	while ( c && cJSON_strcasecmp( c->string, string ) ) {
818 		++i;
819 		c = c->next;
820 	}
821 	if ( c )
822 		return cJSON_DetachItemFromArray( object, i );
823 	return 0;
824 }
825 
826 void cJSON_DeleteItemFromObject( cJSON *object, const char *string )
827 {
828 	cJSON_Delete( cJSON_DetachItemFromObject( object, string ) );
829 }
830 
831 /* Replace array/object items with new ones. */
832 void cJSON_ReplaceItemInArray( cJSON *array, int which, cJSON *newitem )
833 {
834 	cJSON *c = array->child;
835 	while ( c && which > 0 ) {
836 		c = c->next;
837 		--which;
838 	}
839 	if ( ! c )
840 		return;
841 	newitem->next = c->next;
842 	newitem->prev = c->prev;
843 	if ( newitem->next )
844 		newitem->next->prev = newitem;
845 	if ( c == array->child )
846 		array->child = newitem;
847 	else
848 		newitem->prev->next = newitem;
849 	c->next = c->prev = 0;
850 	cJSON_Delete( c );
851 }
852 
853 void cJSON_ReplaceItemInObject( cJSON *object, const char *string, cJSON *newitem )
854 {
855 	int i = 0;
856 	cJSON *c = object->child;
857 	while ( c && cJSON_strcasecmp( c->string, string ) ) {
858 		++i;
859 		c = c->next;
860 	}
861 	if ( c ) {
862 		newitem->string = cJSON_strdup( string );
863 		cJSON_ReplaceItemInArray( object, i, newitem );
864 	}
865 }
866 
867 
868 /* Create basic types: */
869 
870 cJSON *cJSON_CreateNull( void )
871 {
872 	cJSON *item = cJSON_New_Item();
873 	if ( item )
874 		item->type = cJSON_NULL;
875 	return item;
876 }
877 
878 cJSON *cJSON_CreateTrue( void )
879 {
880 	cJSON *item = cJSON_New_Item();
881 	if ( item )
882 		item->type = cJSON_True;
883 	return item;
884 }
885 
886 cJSON *cJSON_CreateFalse( void )
887 {
888 	cJSON *item = cJSON_New_Item();
889 	if ( item )
890 		item->type = cJSON_False;
891 	return item;
892 }
893 
894 cJSON *cJSON_CreateBool( int b )
895 {
896 	cJSON *item = cJSON_New_Item();
897 	if ( item )
898 		item->type = b ? cJSON_True : cJSON_False;
899 	return item;
900 }
901 
902 cJSON *cJSON_CreateInt( long long num )
903 {
904 	cJSON *item = cJSON_New_Item();
905 	if ( item ) {
906 		item->type = cJSON_Number;
907 		item->valuefloat = num;
908 		item->valueint = num;
909 	}
910 	return item;
911 }
912 
913 cJSON *cJSON_CreateFloat( double num )
914 {
915 	cJSON *item = cJSON_New_Item();
916 	if ( item ) {
917 		item->type = cJSON_Number;
918 		item->valuefloat = num;
919 		item->valueint = num;
920 	}
921 	return item;
922 }
923 
924 cJSON *cJSON_CreateString( const char *string )
925 {
926 	cJSON *item = cJSON_New_Item();
927 	if ( item ) {
928 		item->type = cJSON_String;
929 		item->valuestring = cJSON_strdup( string );
930 	}
931 	return item;
932 }
933 
934 cJSON *cJSON_CreateArray( void )
935 {
936 	cJSON *item = cJSON_New_Item();
937 	if ( item )
938 		item->type = cJSON_Array;
939 	return item;
940 }
941 
942 cJSON *cJSON_CreateObject( void )
943 {
944 	cJSON *item = cJSON_New_Item();
945 	if ( item )
946 		item->type = cJSON_Object;
947 	return item;
948 }
949 
950 
951 /* Create Arrays. */
952 
953 cJSON *cJSON_CreateIntArray( long long *numbers, int count )
954 {
955 	int i;
956 	cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
957 	for ( i = 0; a && i < count; ++i ) {
958 		n = cJSON_CreateInt( numbers[i] );
959 		if ( ! i )
960 			a->child = n;
961 		else
962 			suffix_object( p, n );
963 		p = n;
964 	}
965 	return a;
966 }
967 
968 cJSON *cJSON_CreateFloatArray( double *numbers, int count )
969 {
970 	int i;
971 	cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
972 	for ( i = 0; a && i < count; ++i ) {
973 		n = cJSON_CreateFloat( numbers[i] );
974 		if ( ! i )
975 			a->child = n;
976 		else
977 			suffix_object( p, n );
978 		p = n;
979 	}
980 	return a;
981 }
982 
983 cJSON *cJSON_CreateStringArray( const char **strings, int count )
984 {
985 	int i;
986 	cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
987 	for ( i = 0; a && i < count; ++i ) {
988 		n = cJSON_CreateString( strings[i] );
989 		if ( ! i )
990 			a->child = n;
991 		else
992 			suffix_object( p, n );
993 		p = n;
994 	}
995 	return a;
996 }
997