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