json.c (29212B)
1 /* vim: set et ts=3 sw=3 sts=3 ft=c: 2 * 3 * Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved. 4 * https://github.com/udp/json-parser 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include "json.h" 31 32 #ifdef _MSC_VER 33 #ifndef _CRT_SECURE_NO_WARNINGS 34 #define _CRT_SECURE_NO_WARNINGS 35 #endif 36 #endif 37 38 const struct _json_value json_value_none; 39 40 #include <stdio.h> 41 #include <string.h> 42 #include <ctype.h> 43 #include <math.h> 44 45 typedef unsigned int json_uchar; 46 47 static unsigned char hex_value (json_char c) 48 { 49 if (isdigit(c)) 50 return c - '0'; 51 52 switch (c) { 53 case 'a': case 'A': return 0x0A; 54 case 'b': case 'B': return 0x0B; 55 case 'c': case 'C': return 0x0C; 56 case 'd': case 'D': return 0x0D; 57 case 'e': case 'E': return 0x0E; 58 case 'f': case 'F': return 0x0F; 59 default: return 0xFF; 60 } 61 } 62 63 typedef struct 64 { 65 unsigned long used_memory; 66 67 unsigned int uint_max; 68 unsigned long ulong_max; 69 70 json_settings settings; 71 int first_pass; 72 73 const json_char * ptr; 74 unsigned int cur_line, cur_col; 75 76 } json_state; 77 78 static void * default_alloc (size_t size, int zero, void * user_data) 79 { 80 return zero ? calloc (1, size) : malloc (size); 81 } 82 83 static void default_free (void * ptr, void * user_data) 84 { 85 free (ptr); 86 } 87 88 static void * json_alloc (json_state * state, unsigned long size, int zero) 89 { 90 if ((state->ulong_max - state->used_memory) < size) 91 return 0; 92 93 if (state->settings.max_memory 94 && (state->used_memory += size) > state->settings.max_memory) 95 { 96 return 0; 97 } 98 99 return state->settings.mem_alloc (size, zero, state->settings.user_data); 100 } 101 102 static int new_value (json_state * state, 103 json_value ** top, json_value ** root, json_value ** alloc, 104 json_type type) 105 { 106 json_value * value; 107 int values_size; 108 109 if (!state->first_pass) 110 { 111 value = *top = *alloc; 112 *alloc = (*alloc)->_reserved.next_alloc; 113 114 if (!*root) 115 *root = value; 116 117 switch (value->type) 118 { 119 case json_array: 120 121 if (value->u.array.length == 0) 122 break; 123 124 if (! (value->u.array.values = (json_value **) json_alloc 125 (state, value->u.array.length * sizeof (json_value *), 0)) ) 126 { 127 return 0; 128 } 129 130 value->u.array.length = 0; 131 break; 132 133 case json_object: 134 135 if (value->u.object.length == 0) 136 break; 137 138 values_size = sizeof (*value->u.object.values) * value->u.object.length; 139 140 if (! (value->u.object.values = (json_object_entry *) json_alloc 141 (state, values_size + ((unsigned long) value->u.object.values), 0)) ) 142 { 143 return 0; 144 } 145 146 value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size; 147 148 value->u.object.length = 0; 149 break; 150 151 case json_string: 152 153 if (! (value->u.string.ptr = (json_char *) json_alloc 154 (state, (value->u.string.length + 1) * sizeof (json_char), 0)) ) 155 { 156 return 0; 157 } 158 159 value->u.string.length = 0; 160 break; 161 162 default: 163 break; 164 }; 165 166 return 1; 167 } 168 169 if (! (value = (json_value *) json_alloc 170 (state, sizeof (json_value) + state->settings.value_extra, 1))) 171 { 172 return 0; 173 } 174 175 if (!*root) 176 *root = value; 177 178 value->type = type; 179 value->parent = *top; 180 181 #ifdef JSON_TRACK_SOURCE 182 value->line = state->cur_line; 183 value->col = state->cur_col; 184 #endif 185 186 if (*alloc) 187 (*alloc)->_reserved.next_alloc = value; 188 189 *alloc = *top = value; 190 191 return 1; 192 } 193 194 #define whitespace \ 195 case '\n': ++ state.cur_line; state.cur_col = 0; \ 196 case ' ': case '\t': case '\r' 197 198 #define string_add(b) \ 199 do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0); 200 201 #define line_and_col \ 202 state.cur_line, state.cur_col 203 204 static const long 205 flag_next = 1 << 0, 206 flag_reproc = 1 << 1, 207 flag_need_comma = 1 << 2, 208 flag_seek_value = 1 << 3, 209 flag_escaped = 1 << 4, 210 flag_string = 1 << 5, 211 flag_need_colon = 1 << 6, 212 flag_done = 1 << 7, 213 flag_num_negative = 1 << 8, 214 flag_num_zero = 1 << 9, 215 flag_num_e = 1 << 10, 216 flag_num_e_got_sign = 1 << 11, 217 flag_num_e_negative = 1 << 12, 218 flag_line_comment = 1 << 13, 219 flag_block_comment = 1 << 14; 220 221 json_value * json_parse_ex (json_settings * settings, 222 const json_char * json, 223 size_t length, 224 char * error_buf) 225 { 226 json_char error [json_error_max]; 227 const json_char * end; 228 json_value * top, * root, * alloc = 0; 229 json_state state = { 0 }; 230 long flags; 231 long num_digits = 0, num_e = 0; 232 json_int_t num_fraction = 0; 233 234 /* Skip UTF-8 BOM 235 */ 236 if (length >= 3 && ((unsigned char) json [0]) == 0xEF 237 && ((unsigned char) json [1]) == 0xBB 238 && ((unsigned char) json [2]) == 0xBF) 239 { 240 json += 3; 241 length -= 3; 242 } 243 244 error[0] = '\0'; 245 end = (json + length); 246 247 memcpy (&state.settings, settings, sizeof (json_settings)); 248 249 if (!state.settings.mem_alloc) 250 state.settings.mem_alloc = default_alloc; 251 252 if (!state.settings.mem_free) 253 state.settings.mem_free = default_free; 254 255 memset (&state.uint_max, 0xFF, sizeof (state.uint_max)); 256 memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max)); 257 258 state.uint_max -= 8; /* limit of how much can be added before next check */ 259 state.ulong_max -= 8; 260 261 for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass) 262 { 263 json_uchar uchar; 264 unsigned char uc_b1, uc_b2, uc_b3, uc_b4; 265 json_char * string = 0; 266 unsigned int string_length = 0; 267 268 top = root = 0; 269 flags = flag_seek_value; 270 271 state.cur_line = 1; 272 273 for (state.ptr = json ;; ++ state.ptr) 274 { 275 json_char b = (state.ptr == end ? 0 : *state.ptr); 276 277 if (flags & flag_string) 278 { 279 if (!b) 280 { sprintf (error, "Unexpected EOF in string (at %d:%d)", line_and_col); 281 goto e_failed; 282 } 283 284 if (string_length > state.uint_max) 285 goto e_overflow; 286 287 if (flags & flag_escaped) 288 { 289 flags &= ~ flag_escaped; 290 291 switch (b) 292 { 293 case 'b': string_add ('\b'); break; 294 case 'f': string_add ('\f'); break; 295 case 'n': string_add ('\n'); break; 296 case 'r': string_add ('\r'); break; 297 case 't': string_add ('\t'); break; 298 case 'u': 299 300 if (end - state.ptr < 4 || 301 (uc_b1 = hex_value (*++ state.ptr)) == 0xFF || 302 (uc_b2 = hex_value (*++ state.ptr)) == 0xFF || 303 (uc_b3 = hex_value (*++ state.ptr)) == 0xFF || 304 (uc_b4 = hex_value (*++ state.ptr)) == 0xFF) 305 { 306 sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col); 307 goto e_failed; 308 } 309 310 uc_b1 = (uc_b1 << 4) | uc_b2; 311 uc_b2 = (uc_b3 << 4) | uc_b4; 312 uchar = (uc_b1 << 8) | uc_b2; 313 314 if ((uchar & 0xF800) == 0xD800) { 315 json_uchar uchar2; 316 317 if (end - state.ptr < 6 || (*++ state.ptr) != '\\' || (*++ state.ptr) != 'u' || 318 (uc_b1 = hex_value (*++ state.ptr)) == 0xFF || 319 (uc_b2 = hex_value (*++ state.ptr)) == 0xFF || 320 (uc_b3 = hex_value (*++ state.ptr)) == 0xFF || 321 (uc_b4 = hex_value (*++ state.ptr)) == 0xFF) 322 { 323 sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col); 324 goto e_failed; 325 } 326 327 uc_b1 = (uc_b1 << 4) | uc_b2; 328 uc_b2 = (uc_b3 << 4) | uc_b4; 329 uchar2 = (uc_b1 << 8) | uc_b2; 330 331 uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF); 332 } 333 334 if (sizeof (json_char) >= sizeof (json_uchar) || (uchar <= 0x7F)) 335 { 336 string_add ((json_char) uchar); 337 break; 338 } 339 340 if (uchar <= 0x7FF) 341 { 342 if (state.first_pass) 343 string_length += 2; 344 else 345 { string [string_length ++] = 0xC0 | (uchar >> 6); 346 string [string_length ++] = 0x80 | (uchar & 0x3F); 347 } 348 349 break; 350 } 351 352 if (uchar <= 0xFFFF) { 353 if (state.first_pass) 354 string_length += 3; 355 else 356 { string [string_length ++] = 0xE0 | (uchar >> 12); 357 string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F); 358 string [string_length ++] = 0x80 | (uchar & 0x3F); 359 } 360 361 break; 362 } 363 364 if (state.first_pass) 365 string_length += 4; 366 else 367 { string [string_length ++] = 0xF0 | (uchar >> 18); 368 string [string_length ++] = 0x80 | ((uchar >> 12) & 0x3F); 369 string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F); 370 string [string_length ++] = 0x80 | (uchar & 0x3F); 371 } 372 373 break; 374 375 default: 376 string_add (b); 377 }; 378 379 continue; 380 } 381 382 if (b == '\\') 383 { 384 flags |= flag_escaped; 385 continue; 386 } 387 388 if (b == '"') 389 { 390 if (!state.first_pass) 391 string [string_length] = 0; 392 393 flags &= ~ flag_string; 394 string = 0; 395 396 switch (top->type) 397 { 398 case json_string: 399 400 top->u.string.length = string_length; 401 flags |= flag_next; 402 403 break; 404 405 case json_object: 406 407 if (state.first_pass) 408 (*(json_char **) &top->u.object.values) += string_length + 1; 409 else 410 { 411 top->u.object.values [top->u.object.length].name 412 = (json_char *) top->_reserved.object_mem; 413 414 top->u.object.values [top->u.object.length].name_length 415 = string_length; 416 417 (*(json_char **) &top->_reserved.object_mem) += string_length + 1; 418 } 419 420 flags |= flag_seek_value | flag_need_colon; 421 continue; 422 423 default: 424 break; 425 }; 426 } 427 else 428 { 429 string_add (b); 430 continue; 431 } 432 } 433 434 if (state.settings.settings & json_enable_comments) 435 { 436 if (flags & (flag_line_comment | flag_block_comment)) 437 { 438 if (flags & flag_line_comment) 439 { 440 if (b == '\r' || b == '\n' || !b) 441 { 442 flags &= ~ flag_line_comment; 443 -- state.ptr; /* so null can be reproc'd */ 444 } 445 446 continue; 447 } 448 449 if (flags & flag_block_comment) 450 { 451 if (!b) 452 { sprintf (error, "%d:%d: Unexpected EOF in block comment", line_and_col); 453 goto e_failed; 454 } 455 456 if (b == '*' && state.ptr < (end - 1) && state.ptr [1] == '/') 457 { 458 flags &= ~ flag_block_comment; 459 ++ state.ptr; /* skip closing sequence */ 460 } 461 462 continue; 463 } 464 } 465 else if (b == '/') 466 { 467 if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object) 468 { sprintf (error, "%d:%d: Comment not allowed here", line_and_col); 469 goto e_failed; 470 } 471 472 if (++ state.ptr == end) 473 { sprintf (error, "%d:%d: EOF unexpected", line_and_col); 474 goto e_failed; 475 } 476 477 switch (b = *state.ptr) 478 { 479 case '/': 480 flags |= flag_line_comment; 481 continue; 482 483 case '*': 484 flags |= flag_block_comment; 485 continue; 486 487 default: 488 sprintf (error, "%d:%d: Unexpected `%c` in comment opening sequence", line_and_col, b); 489 goto e_failed; 490 }; 491 } 492 } 493 494 if (flags & flag_done) 495 { 496 if (!b) 497 break; 498 499 switch (b) 500 { 501 whitespace: 502 continue; 503 504 default: 505 506 sprintf (error, "%d:%d: Trailing garbage: `%c`", 507 state.cur_line, state.cur_col, b); 508 509 goto e_failed; 510 }; 511 } 512 513 if (flags & flag_seek_value) 514 { 515 switch (b) 516 { 517 whitespace: 518 continue; 519 520 case ']': 521 522 if (top && top->type == json_array) 523 flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next; 524 else 525 { sprintf (error, "%d:%d: Unexpected ]", line_and_col); 526 goto e_failed; 527 } 528 529 break; 530 531 default: 532 533 if (flags & flag_need_comma) 534 { 535 if (b == ',') 536 { flags &= ~ flag_need_comma; 537 continue; 538 } 539 else 540 { 541 sprintf (error, "%d:%d: Expected , before %c", 542 state.cur_line, state.cur_col, b); 543 544 goto e_failed; 545 } 546 } 547 548 if (flags & flag_need_colon) 549 { 550 if (b == ':') 551 { flags &= ~ flag_need_colon; 552 continue; 553 } 554 else 555 { 556 sprintf (error, "%d:%d: Expected : before %c", 557 state.cur_line, state.cur_col, b); 558 559 goto e_failed; 560 } 561 } 562 563 flags &= ~ flag_seek_value; 564 565 switch (b) 566 { 567 case '{': 568 569 if (!new_value (&state, &top, &root, &alloc, json_object)) 570 goto e_alloc_failure; 571 572 continue; 573 574 case '[': 575 576 if (!new_value (&state, &top, &root, &alloc, json_array)) 577 goto e_alloc_failure; 578 579 flags |= flag_seek_value; 580 continue; 581 582 case '"': 583 584 if (!new_value (&state, &top, &root, &alloc, json_string)) 585 goto e_alloc_failure; 586 587 flags |= flag_string; 588 589 string = top->u.string.ptr; 590 string_length = 0; 591 592 continue; 593 594 case 't': 595 596 if ((end - state.ptr) < 3 || *(++ state.ptr) != 'r' || 597 *(++ state.ptr) != 'u' || *(++ state.ptr) != 'e') 598 { 599 goto e_unknown_value; 600 } 601 602 if (!new_value (&state, &top, &root, &alloc, json_boolean)) 603 goto e_alloc_failure; 604 605 top->u.boolean = 1; 606 607 flags |= flag_next; 608 break; 609 610 case 'f': 611 612 if ((end - state.ptr) < 4 || *(++ state.ptr) != 'a' || 613 *(++ state.ptr) != 'l' || *(++ state.ptr) != 's' || 614 *(++ state.ptr) != 'e') 615 { 616 goto e_unknown_value; 617 } 618 619 if (!new_value (&state, &top, &root, &alloc, json_boolean)) 620 goto e_alloc_failure; 621 622 flags |= flag_next; 623 break; 624 625 case 'n': 626 627 if ((end - state.ptr) < 3 || *(++ state.ptr) != 'u' || 628 *(++ state.ptr) != 'l' || *(++ state.ptr) != 'l') 629 { 630 goto e_unknown_value; 631 } 632 633 if (!new_value (&state, &top, &root, &alloc, json_null)) 634 goto e_alloc_failure; 635 636 flags |= flag_next; 637 break; 638 639 default: 640 641 if (isdigit (b) || b == '-') 642 { 643 if (!new_value (&state, &top, &root, &alloc, json_integer)) 644 goto e_alloc_failure; 645 646 if (!state.first_pass) 647 { 648 while (isdigit (b) || b == '+' || b == '-' 649 || b == 'e' || b == 'E' || b == '.') 650 { 651 if ( (++ state.ptr) == end) 652 { 653 b = 0; 654 break; 655 } 656 657 b = *state.ptr; 658 } 659 660 flags |= flag_next | flag_reproc; 661 break; 662 } 663 664 flags &= ~ (flag_num_negative | flag_num_e | 665 flag_num_e_got_sign | flag_num_e_negative | 666 flag_num_zero); 667 668 num_digits = 0; 669 num_fraction = 0; 670 num_e = 0; 671 672 if (b != '-') 673 { 674 flags |= flag_reproc; 675 break; 676 } 677 678 flags |= flag_num_negative; 679 continue; 680 } 681 else 682 { sprintf (error, "%d:%d: Unexpected %c when seeking value", line_and_col, b); 683 goto e_failed; 684 } 685 }; 686 }; 687 } 688 else 689 { 690 switch (top->type) 691 { 692 case json_object: 693 694 switch (b) 695 { 696 whitespace: 697 continue; 698 699 case '"': 700 701 if (flags & flag_need_comma) 702 { sprintf (error, "%d:%d: Expected , before \"", line_and_col); 703 goto e_failed; 704 } 705 706 flags |= flag_string; 707 708 string = (json_char *) top->_reserved.object_mem; 709 string_length = 0; 710 711 break; 712 713 case '}': 714 715 flags = (flags & ~ flag_need_comma) | flag_next; 716 break; 717 718 case ',': 719 720 if (flags & flag_need_comma) 721 { 722 flags &= ~ flag_need_comma; 723 break; 724 } 725 726 default: 727 sprintf (error, "%d:%d: Unexpected `%c` in object", line_and_col, b); 728 goto e_failed; 729 }; 730 731 break; 732 733 case json_integer: 734 case json_double: 735 736 if (isdigit (b)) 737 { 738 ++ num_digits; 739 740 if (top->type == json_integer || flags & flag_num_e) 741 { 742 if (! (flags & flag_num_e)) 743 { 744 if (flags & flag_num_zero) 745 { sprintf (error, "%d:%d: Unexpected `0` before `%c`", line_and_col, b); 746 goto e_failed; 747 } 748 749 if (num_digits == 1 && b == '0') 750 flags |= flag_num_zero; 751 } 752 else 753 { 754 flags |= flag_num_e_got_sign; 755 num_e = (num_e * 10) + (b - '0'); 756 continue; 757 } 758 759 top->u.integer = (top->u.integer * 10) + (b - '0'); 760 continue; 761 } 762 763 num_fraction = (num_fraction * 10) + (b - '0'); 764 continue; 765 } 766 767 if (b == '+' || b == '-') 768 { 769 if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign)) 770 { 771 flags |= flag_num_e_got_sign; 772 773 if (b == '-') 774 flags |= flag_num_e_negative; 775 776 continue; 777 } 778 } 779 else if (b == '.' && top->type == json_integer) 780 { 781 if (!num_digits) 782 { sprintf (error, "%d:%d: Expected digit before `.`", line_and_col); 783 goto e_failed; 784 } 785 786 top->type = json_double; 787 top->u.dbl = (double) top->u.integer; 788 789 num_digits = 0; 790 continue; 791 } 792 793 if (! (flags & flag_num_e)) 794 { 795 if (top->type == json_double) 796 { 797 if (!num_digits) 798 { sprintf (error, "%d:%d: Expected digit after `.`", line_and_col); 799 goto e_failed; 800 } 801 802 top->u.dbl += ((double) num_fraction) / (pow (10.0, (double) num_digits)); 803 } 804 805 if (b == 'e' || b == 'E') 806 { 807 flags |= flag_num_e; 808 809 if (top->type == json_integer) 810 { 811 top->type = json_double; 812 top->u.dbl = (double) top->u.integer; 813 } 814 815 num_digits = 0; 816 flags &= ~ flag_num_zero; 817 818 continue; 819 } 820 } 821 else 822 { 823 if (!num_digits) 824 { sprintf (error, "%d:%d: Expected digit after `e`", line_and_col); 825 goto e_failed; 826 } 827 828 top->u.dbl *= pow (10.0, (double) 829 (flags & flag_num_e_negative ? - num_e : num_e)); 830 } 831 832 if (flags & flag_num_negative) 833 { 834 if (top->type == json_integer) 835 top->u.integer = - top->u.integer; 836 else 837 top->u.dbl = - top->u.dbl; 838 } 839 840 flags |= flag_next | flag_reproc; 841 break; 842 843 default: 844 break; 845 }; 846 } 847 848 if (flags & flag_reproc) 849 { 850 flags &= ~ flag_reproc; 851 -- state.ptr; 852 } 853 854 if (flags & flag_next) 855 { 856 flags = (flags & ~ flag_next) | flag_need_comma; 857 858 if (!top->parent) 859 { 860 /* root value done */ 861 862 flags |= flag_done; 863 continue; 864 } 865 866 if (top->parent->type == json_array) 867 flags |= flag_seek_value; 868 869 if (!state.first_pass) 870 { 871 json_value * parent = top->parent; 872 873 switch (parent->type) 874 { 875 case json_object: 876 877 parent->u.object.values 878 [parent->u.object.length].value = top; 879 880 break; 881 882 case json_array: 883 884 parent->u.array.values 885 [parent->u.array.length] = top; 886 887 break; 888 889 default: 890 break; 891 }; 892 } 893 894 if ( (++ top->parent->u.array.length) > state.uint_max) 895 goto e_overflow; 896 897 top = top->parent; 898 899 continue; 900 } 901 } 902 903 alloc = root; 904 } 905 906 return root; 907 908 e_unknown_value: 909 910 sprintf (error, "%d:%d: Unknown value", line_and_col); 911 goto e_failed; 912 913 e_alloc_failure: 914 915 strcpy (error, "Memory allocation failure"); 916 goto e_failed; 917 918 e_overflow: 919 920 sprintf (error, "%d:%d: Too long (caught overflow)", line_and_col); 921 goto e_failed; 922 923 e_failed: 924 925 if (error_buf) 926 { 927 if (*error) 928 strcpy (error_buf, error); 929 else 930 strcpy (error_buf, "Unknown error"); 931 } 932 933 if (state.first_pass) 934 alloc = root; 935 936 while (alloc) 937 { 938 top = alloc->_reserved.next_alloc; 939 state.settings.mem_free (alloc, state.settings.user_data); 940 alloc = top; 941 } 942 943 if (!state.first_pass) 944 json_value_free_ex (&state.settings, root); 945 946 return 0; 947 } 948 949 json_value * json_parse (const json_char * json, size_t length) 950 { 951 json_settings settings = { 0 }; 952 return json_parse_ex (&settings, json, length, 0); 953 } 954 955 void json_value_free_ex (json_settings * settings, json_value * value) 956 { 957 json_value * cur_value; 958 959 if (!value) 960 return; 961 962 value->parent = 0; 963 964 while (value) 965 { 966 switch (value->type) 967 { 968 case json_array: 969 970 if (!value->u.array.length) 971 { 972 settings->mem_free (value->u.array.values, settings->user_data); 973 break; 974 } 975 976 value = value->u.array.values [-- value->u.array.length]; 977 continue; 978 979 case json_object: 980 981 if (!value->u.object.length) 982 { 983 settings->mem_free (value->u.object.values, settings->user_data); 984 break; 985 } 986 987 value = value->u.object.values [-- value->u.object.length].value; 988 continue; 989 990 case json_string: 991 992 settings->mem_free (value->u.string.ptr, settings->user_data); 993 break; 994 995 default: 996 break; 997 }; 998 999 cur_value = value; 1000 value = value->parent; 1001 settings->mem_free (cur_value, settings->user_data); 1002 } 1003 } 1004 1005 void json_value_free (json_value * value) 1006 { 1007 json_settings settings = { 0 }; 1008 settings.mem_free = default_free; 1009 json_value_free_ex (&settings, value); 1010 } 1011 1012 1013