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