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