00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "qcschema_json.h"
00031
00032 #ifdef _MSC_VER
00033 #ifndef _CRT_SECURE_NO_WARNINGS
00034 #define _CRT_SECURE_NO_WARNINGS
00035 #endif
00036 #include <stdint.h>
00037 #endif
00038
00039 const struct _json_value json_value_none;
00040
00041 #include <stdio.h>
00042 #include <string.h>
00043 #include <ctype.h>
00044 #include <math.h>
00045
00046 typedef unsigned int json_uchar;
00047
00048
00049 static const json_int_t JSON_INT_MAX = sizeof(json_int_t) == 1
00050 ? INT8_MAX
00051 : (sizeof(json_int_t) == 2
00052 ? INT16_MAX
00053 : (sizeof(json_int_t) == 4
00054 ? INT32_MAX
00055 : INT64_MAX));
00056
00057 static unsigned char hex_value (json_char c)
00058 {
00059 if (isdigit(c))
00060 return c - '0';
00061
00062 switch (c) {
00063 case 'a': case 'A': return 0x0A;
00064 case 'b': case 'B': return 0x0B;
00065 case 'c': case 'C': return 0x0C;
00066 case 'd': case 'D': return 0x0D;
00067 case 'e': case 'E': return 0x0E;
00068 case 'f': case 'F': return 0x0F;
00069 default: return 0xFF;
00070 }
00071 }
00072
00073 static int would_overflow (json_int_t value, json_char b)
00074 {
00075 return ((JSON_INT_MAX - (b - '0')) / 10 ) < value;
00076 }
00077
00078 typedef struct
00079 {
00080 unsigned long used_memory;
00081
00082 unsigned int uint_max;
00083 unsigned long ulong_max;
00084
00085 json_settings settings;
00086 int first_pass;
00087
00088 const json_char * ptr;
00089 unsigned int cur_line, cur_col;
00090
00091 } json_state;
00092
00093 static void * default_alloc (size_t size, int zero, void * user_data)
00094 {
00095 return zero ? calloc (1, size) : malloc (size);
00096 }
00097
00098 static void default_free (void * ptr, void * user_data)
00099 {
00100 free (ptr);
00101 }
00102
00103 static void * json_alloc (json_state * state, unsigned long size, int zero)
00104 {
00105 if ((state->ulong_max - state->used_memory) < size)
00106 return 0;
00107
00108 if (state->settings.max_memory
00109 && (state->used_memory += size) > state->settings.max_memory)
00110 {
00111 return 0;
00112 }
00113
00114 return state->settings.mem_alloc (size, zero, state->settings.user_data);
00115 }
00116
00117 static int new_value (json_state * state,
00118 json_value ** top, json_value ** root, json_value ** alloc,
00119 json_type type)
00120 {
00121 json_value * value;
00122 int values_size;
00123
00124 if (!state->first_pass)
00125 {
00126 value = *top = *alloc;
00127 *alloc = (*alloc)->_reserved.next_alloc;
00128
00129 if (!*root)
00130 *root = value;
00131
00132 switch (value->type)
00133 {
00134 case json_array:
00135
00136 if (value->u.array.length == 0)
00137 break;
00138
00139 if (! (value->u.array.values = (json_value **) json_alloc
00140 (state, value->u.array.length * sizeof (json_value *), 0)) )
00141 {
00142 return 0;
00143 }
00144
00145 value->u.array.length = 0;
00146 break;
00147
00148 case json_object:
00149
00150 if (value->u.object.length == 0)
00151 break;
00152
00153 values_size = sizeof (*value->u.object.values) * value->u.object.length;
00154
00155 if (! (value->u.object.values = (json_object_entry *) json_alloc
00156 (state, values_size + ((unsigned long) value->u.object.values), 0)) )
00157 {
00158 return 0;
00159 }
00160
00161 value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;
00162
00163 value->u.object.length = 0;
00164 break;
00165
00166 case json_string:
00167
00168 if (! (value->u.string.ptr = (json_char *) json_alloc
00169 (state, (value->u.string.length + 1) * sizeof (json_char), 0)) )
00170 {
00171 return 0;
00172 }
00173
00174 value->u.string.length = 0;
00175 break;
00176
00177 default:
00178 break;
00179 };
00180
00181 return 1;
00182 }
00183
00184 if (! (value = (json_value *) json_alloc
00185 (state, sizeof (json_value) + state->settings.value_extra, 1)))
00186 {
00187 return 0;
00188 }
00189
00190 if (!*root)
00191 *root = value;
00192
00193 value->type = type;
00194 value->parent = *top;
00195
00196 #ifdef JSON_TRACK_SOURCE
00197 value->line = state->cur_line;
00198 value->col = state->cur_col;
00199 #endif
00200
00201 if (*alloc)
00202 (*alloc)->_reserved.next_alloc = value;
00203
00204 *alloc = *top = value;
00205
00206 return 1;
00207 }
00208
00209 #define whitespace \
00210 case '\n': ++ state.cur_line; state.cur_col = 0; \
00211 case ' ': case '\t': case '\r'
00212
00213 #define string_add(b) \
00214 do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0);
00215
00216 #define line_and_col \
00217 state.cur_line, state.cur_col
00218
00219 static const long
00220 flag_next = 1 << 0,
00221 flag_reproc = 1 << 1,
00222 flag_need_comma = 1 << 2,
00223 flag_seek_value = 1 << 3,
00224 flag_escaped = 1 << 4,
00225 flag_string = 1 << 5,
00226 flag_need_colon = 1 << 6,
00227 flag_done = 1 << 7,
00228 flag_num_negative = 1 << 8,
00229 flag_num_zero = 1 << 9,
00230 flag_num_e = 1 << 10,
00231 flag_num_e_got_sign = 1 << 11,
00232 flag_num_e_negative = 1 << 12,
00233 flag_line_comment = 1 << 13,
00234 flag_block_comment = 1 << 14,
00235 flag_num_got_decimal = 1 << 15;
00236
00237 json_value * json_parse_ex (json_settings * settings,
00238 const json_char * json,
00239 size_t length,
00240 char * error_buf)
00241 {
00242 json_char error [json_error_max];
00243 const json_char * end;
00244 json_value * top, * root, * alloc = 0;
00245 json_state state = { 0 };
00246 long flags = 0;
00247 double num_digits = 0, num_e = 0;
00248 double num_fraction = 0;
00249
00250
00251
00252 if (length >= 3 && ((unsigned char) json [0]) == 0xEF
00253 && ((unsigned char) json [1]) == 0xBB
00254 && ((unsigned char) json [2]) == 0xBF)
00255 {
00256 json += 3;
00257 length -= 3;
00258 }
00259
00260 error[0] = '\0';
00261 end = (json + length);
00262
00263 memcpy (&state.settings, settings, sizeof (json_settings));
00264
00265 if (!state.settings.mem_alloc)
00266 state.settings.mem_alloc = default_alloc;
00267
00268 if (!state.settings.mem_free)
00269 state.settings.mem_free = default_free;
00270
00271 memset (&state.uint_max, 0xFF, sizeof (state.uint_max));
00272 memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max));
00273
00274 state.uint_max -= 8;
00275 state.ulong_max -= 8;
00276
00277 for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass)
00278 {
00279 json_uchar uchar;
00280 unsigned char uc_b1, uc_b2, uc_b3, uc_b4;
00281 json_char * string = 0;
00282 unsigned int string_length = 0;
00283
00284 top = root = 0;
00285 flags = flag_seek_value;
00286
00287 state.cur_line = 1;
00288
00289 for (state.ptr = json ;; ++ state.ptr)
00290 {
00291 json_char b = (state.ptr == end ? 0 : *state.ptr);
00292
00293 if (flags & flag_string)
00294 {
00295 if (!b)
00296 { sprintf (error, "Unexpected EOF in string (at %d:%d)", line_and_col);
00297 goto e_failed;
00298 }
00299
00300 if (string_length > state.uint_max)
00301 goto e_overflow;
00302
00303 if (flags & flag_escaped)
00304 {
00305 flags &= ~ flag_escaped;
00306
00307 switch (b)
00308 {
00309 case 'b': string_add ('\b'); break;
00310 case 'f': string_add ('\f'); break;
00311 case 'n': string_add ('\n'); break;
00312 case 'r': string_add ('\r'); break;
00313 case 't': string_add ('\t'); break;
00314 case 'u':
00315
00316 if (end - state.ptr <= 4 ||
00317 (uc_b1 = hex_value (*++ state.ptr)) == 0xFF ||
00318 (uc_b2 = hex_value (*++ state.ptr)) == 0xFF ||
00319 (uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
00320 (uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
00321 {
00322 sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col);
00323 goto e_failed;
00324 }
00325
00326 uc_b1 = (uc_b1 << 4) | uc_b2;
00327 uc_b2 = (uc_b3 << 4) | uc_b4;
00328 uchar = (uc_b1 << 8) | uc_b2;
00329
00330 if ((uchar & 0xF800) == 0xD800) {
00331 json_uchar uchar2;
00332
00333 if (end - state.ptr <= 6 || (*++ state.ptr) != '\\' || (*++ state.ptr) != 'u' ||
00334 (uc_b1 = hex_value (*++ state.ptr)) == 0xFF ||
00335 (uc_b2 = hex_value (*++ state.ptr)) == 0xFF ||
00336 (uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
00337 (uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
00338 {
00339 sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col);
00340 goto e_failed;
00341 }
00342
00343 uc_b1 = (uc_b1 << 4) | uc_b2;
00344 uc_b2 = (uc_b3 << 4) | uc_b4;
00345 uchar2 = (uc_b1 << 8) | uc_b2;
00346
00347 uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF);
00348 }
00349
00350 if (sizeof (json_char) >= sizeof (json_uchar) || (uchar <= 0x7F))
00351 {
00352 string_add ((json_char) uchar);
00353 break;
00354 }
00355
00356 if (uchar <= 0x7FF)
00357 {
00358 if (state.first_pass)
00359 string_length += 2;
00360 else
00361 { string [string_length ++] = 0xC0 | (uchar >> 6);
00362 string [string_length ++] = 0x80 | (uchar & 0x3F);
00363 }
00364
00365 break;
00366 }
00367
00368 if (uchar <= 0xFFFF) {
00369 if (state.first_pass)
00370 string_length += 3;
00371 else
00372 { string [string_length ++] = 0xE0 | (uchar >> 12);
00373 string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
00374 string [string_length ++] = 0x80 | (uchar & 0x3F);
00375 }
00376
00377 break;
00378 }
00379
00380 if (state.first_pass)
00381 string_length += 4;
00382 else
00383 { string [string_length ++] = 0xF0 | (uchar >> 18);
00384 string [string_length ++] = 0x80 | ((uchar >> 12) & 0x3F);
00385 string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
00386 string [string_length ++] = 0x80 | (uchar & 0x3F);
00387 }
00388
00389 break;
00390
00391 default:
00392 string_add (b);
00393 };
00394
00395 continue;
00396 }
00397
00398 if (b == '\\')
00399 {
00400 flags |= flag_escaped;
00401 continue;
00402 }
00403
00404 if (b == '"')
00405 {
00406 if (!state.first_pass)
00407 string [string_length] = 0;
00408
00409 flags &= ~ flag_string;
00410 string = 0;
00411
00412 switch (top->type)
00413 {
00414 case json_string:
00415
00416 top->u.string.length = string_length;
00417 flags |= flag_next;
00418
00419 break;
00420
00421 case json_object:
00422
00423 if (state.first_pass)
00424 (*(json_char **) &top->u.object.values) += string_length + 1;
00425 else
00426 {
00427 top->u.object.values [top->u.object.length].name
00428 = (json_char *) top->_reserved.object_mem;
00429
00430 top->u.object.values [top->u.object.length].name_length
00431 = string_length;
00432
00433 (*(json_char **) &top->_reserved.object_mem) += string_length + 1;
00434 }
00435
00436 flags |= flag_seek_value | flag_need_colon;
00437 continue;
00438
00439 default:
00440 break;
00441 };
00442 }
00443 else
00444 {
00445 string_add (b);
00446 continue;
00447 }
00448 }
00449
00450 if (state.settings.settings & json_enable_comments)
00451 {
00452 if (flags & (flag_line_comment | flag_block_comment))
00453 {
00454 if (flags & flag_line_comment)
00455 {
00456 if (b == '\r' || b == '\n' || !b)
00457 {
00458 flags &= ~ flag_line_comment;
00459 -- state.ptr;
00460 }
00461
00462 continue;
00463 }
00464
00465 if (flags & flag_block_comment)
00466 {
00467 if (!b)
00468 { sprintf (error, "%d:%d: Unexpected EOF in block comment", line_and_col);
00469 goto e_failed;
00470 }
00471
00472 if (b == '*' && state.ptr < (end - 1) && state.ptr [1] == '/')
00473 {
00474 flags &= ~ flag_block_comment;
00475 ++ state.ptr;
00476 }
00477
00478 continue;
00479 }
00480 }
00481 else if (b == '/')
00482 {
00483 if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)
00484 { sprintf (error, "%d:%d: Comment not allowed here", line_and_col);
00485 goto e_failed;
00486 }
00487
00488 if (++ state.ptr == end)
00489 { sprintf (error, "%d:%d: EOF unexpected", line_and_col);
00490 goto e_failed;
00491 }
00492
00493 switch (b = *state.ptr)
00494 {
00495 case '/':
00496 flags |= flag_line_comment;
00497 continue;
00498
00499 case '*':
00500 flags |= flag_block_comment;
00501 continue;
00502
00503 default:
00504 sprintf (error, "%d:%d: Unexpected `%c` in comment opening sequence", line_and_col, b);
00505 goto e_failed;
00506 };
00507 }
00508 }
00509
00510 if (flags & flag_done)
00511 {
00512 if (!b)
00513 break;
00514
00515 switch (b)
00516 {
00517 whitespace:
00518 continue;
00519
00520 default:
00521
00522 sprintf (error, "%d:%d: Trailing garbage: `%c`",
00523 state.cur_line, state.cur_col, b);
00524
00525 goto e_failed;
00526 };
00527 }
00528
00529 if (flags & flag_seek_value)
00530 {
00531 switch (b)
00532 {
00533 whitespace:
00534 continue;
00535
00536 case ']':
00537
00538 if (top && top->type == json_array)
00539 flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
00540 else
00541 { sprintf (error, "%d:%d: Unexpected ]", line_and_col);
00542 goto e_failed;
00543 }
00544
00545 break;
00546
00547 default:
00548
00549 if (flags & flag_need_comma)
00550 {
00551 if (b == ',')
00552 { flags &= ~ flag_need_comma;
00553 continue;
00554 }
00555 else
00556 {
00557 sprintf (error, "%d:%d: Expected , before %c",
00558 state.cur_line, state.cur_col, b);
00559
00560 goto e_failed;
00561 }
00562 }
00563
00564 if (flags & flag_need_colon)
00565 {
00566 if (b == ':')
00567 { flags &= ~ flag_need_colon;
00568 continue;
00569 }
00570 else
00571 {
00572 sprintf (error, "%d:%d: Expected : before %c",
00573 state.cur_line, state.cur_col, b);
00574
00575 goto e_failed;
00576 }
00577 }
00578
00579 flags &= ~ flag_seek_value;
00580
00581 switch (b)
00582 {
00583 case '{':
00584
00585 if (!new_value (&state, &top, &root, &alloc, json_object))
00586 goto e_alloc_failure;
00587
00588 continue;
00589
00590 case '[':
00591
00592 if (!new_value (&state, &top, &root, &alloc, json_array))
00593 goto e_alloc_failure;
00594
00595 flags |= flag_seek_value;
00596 continue;
00597
00598 case '"':
00599
00600 if (!new_value (&state, &top, &root, &alloc, json_string))
00601 goto e_alloc_failure;
00602
00603 flags |= flag_string;
00604
00605 string = top->u.string.ptr;
00606 string_length = 0;
00607
00608 continue;
00609
00610 case 't':
00611
00612 if ((end - state.ptr) < 3 || *(++ state.ptr) != 'r' ||
00613 *(++ state.ptr) != 'u' || *(++ state.ptr) != 'e')
00614 {
00615 goto e_unknown_value;
00616 }
00617
00618 if (!new_value (&state, &top, &root, &alloc, json_boolean))
00619 goto e_alloc_failure;
00620
00621 top->u.boolean = 1;
00622
00623 flags |= flag_next;
00624 break;
00625
00626 case 'f':
00627
00628 if ((end - state.ptr) < 4 || *(++ state.ptr) != 'a' ||
00629 *(++ state.ptr) != 'l' || *(++ state.ptr) != 's' ||
00630 *(++ state.ptr) != 'e')
00631 {
00632 goto e_unknown_value;
00633 }
00634
00635 if (!new_value (&state, &top, &root, &alloc, json_boolean))
00636 goto e_alloc_failure;
00637
00638 flags |= flag_next;
00639 break;
00640
00641 case 'n':
00642
00643 if ((end - state.ptr) < 3 || *(++ state.ptr) != 'u' ||
00644 *(++ state.ptr) != 'l' || *(++ state.ptr) != 'l')
00645 {
00646 goto e_unknown_value;
00647 }
00648
00649 if (!new_value (&state, &top, &root, &alloc, json_null))
00650 goto e_alloc_failure;
00651
00652 flags |= flag_next;
00653 break;
00654
00655 default:
00656
00657 if (isdigit (b) || b == '-')
00658 {
00659 if (!new_value (&state, &top, &root, &alloc, json_integer))
00660 goto e_alloc_failure;
00661
00662 if (!state.first_pass)
00663 {
00664 while (isdigit (b) || b == '+' || b == '-'
00665 || b == 'e' || b == 'E' || b == '.')
00666 {
00667 if ( (++ state.ptr) == end)
00668 {
00669 b = 0;
00670 break;
00671 }
00672
00673 b = *state.ptr;
00674 }
00675
00676 flags |= flag_next | flag_reproc;
00677 break;
00678 }
00679
00680 flags &= ~ (flag_num_negative | flag_num_e |
00681 flag_num_e_got_sign | flag_num_e_negative |
00682 flag_num_zero);
00683
00684 num_digits = 0;
00685 num_fraction = 0;
00686 num_e = 0;
00687
00688 if (b != '-')
00689 {
00690 flags |= flag_reproc;
00691 break;
00692 }
00693
00694 flags |= flag_num_negative;
00695 continue;
00696 }
00697 else
00698 { sprintf (error, "%d:%d: Unexpected %c when seeking value", line_and_col, b);
00699 goto e_failed;
00700 }
00701 };
00702 };
00703 }
00704 else
00705 {
00706 switch (top->type)
00707 {
00708 case json_object:
00709
00710 switch (b)
00711 {
00712 whitespace:
00713 continue;
00714
00715 case '"':
00716
00717 if (flags & flag_need_comma)
00718 { sprintf (error, "%d:%d: Expected , before \"", line_and_col);
00719 goto e_failed;
00720 }
00721
00722 flags |= flag_string;
00723
00724 string = (json_char *) top->_reserved.object_mem;
00725 string_length = 0;
00726
00727 break;
00728
00729 case '}':
00730
00731 flags = (flags & ~ flag_need_comma) | flag_next;
00732 break;
00733
00734 case ',':
00735
00736 if (flags & flag_need_comma)
00737 {
00738 flags &= ~ flag_need_comma;
00739 break;
00740 }
00741
00742 default:
00743 sprintf (error, "%d:%d: Unexpected `%c` in object", line_and_col, b);
00744 goto e_failed;
00745 };
00746
00747 break;
00748
00749 case json_integer:
00750 case json_double:
00751
00752 if (isdigit (b))
00753 {
00754 ++ num_digits;
00755
00756 if (top->type == json_integer || flags & flag_num_e)
00757 {
00758 if (! (flags & flag_num_e))
00759 {
00760 if (flags & flag_num_zero)
00761 { sprintf (error, "%d:%d: Unexpected `0` before `%c`", line_and_col, b);
00762 goto e_failed;
00763 }
00764
00765 if (num_digits == 1 && b == '0')
00766 flags |= flag_num_zero;
00767 }
00768 else
00769 {
00770 flags |= flag_num_e_got_sign;
00771 num_e = (num_e * 10) + (b - '0');
00772 continue;
00773 }
00774
00775 if (would_overflow(top->u.integer, b))
00776 { -- num_digits;
00777 -- state.ptr;
00778 top->type = json_double;
00779 top->u.dbl = (double)top->u.integer;
00780 continue;
00781 }
00782
00783 top->u.integer = (top->u.integer * 10) + (b - '0');
00784 continue;
00785 }
00786
00787 if (flags & flag_num_got_decimal)
00788 num_fraction = (num_fraction * 10) + (b - '0');
00789 else
00790 top->u.dbl = (top->u.dbl * 10) + (b - '0');
00791
00792 continue;
00793 }
00794
00795 if (b == '+' || b == '-')
00796 {
00797 if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign))
00798 {
00799 flags |= flag_num_e_got_sign;
00800
00801 if (b == '-')
00802 flags |= flag_num_e_negative;
00803
00804 continue;
00805 }
00806 }
00807 else if (b == '.' && top->type == json_integer)
00808 {
00809 if (!num_digits)
00810 { sprintf (error, "%d:%d: Expected digit before `.`", line_and_col);
00811 goto e_failed;
00812 }
00813
00814 top->type = json_double;
00815 top->u.dbl = (double) top->u.integer;
00816
00817 flags |= flag_num_got_decimal;
00818 num_digits = 0;
00819 continue;
00820 }
00821
00822 if (! (flags & flag_num_e))
00823 {
00824 if (top->type == json_double)
00825 {
00826 if (!num_digits)
00827 { sprintf (error, "%d:%d: Expected digit after `.`", line_and_col);
00828 goto e_failed;
00829 }
00830
00831 top->u.dbl += num_fraction / pow (10.0, num_digits);
00832 }
00833
00834 if (b == 'e' || b == 'E')
00835 {
00836 flags |= flag_num_e;
00837
00838 if (top->type == json_integer)
00839 {
00840 top->type = json_double;
00841 top->u.dbl = (double) top->u.integer;
00842 }
00843
00844 num_digits = 0;
00845 flags &= ~ flag_num_zero;
00846
00847 continue;
00848 }
00849 }
00850 else
00851 {
00852 if (!num_digits)
00853 { sprintf (error, "%d:%d: Expected digit after `e`", line_and_col);
00854 goto e_failed;
00855 }
00856
00857 top->u.dbl *= pow (10.0, (flags & flag_num_e_negative ? - num_e : num_e));
00858 }
00859
00860 if (flags & flag_num_negative)
00861 {
00862 if (top->type == json_integer)
00863 top->u.integer = - top->u.integer;
00864 else
00865 top->u.dbl = - top->u.dbl;
00866 }
00867
00868 flags |= flag_next | flag_reproc;
00869 break;
00870
00871 default:
00872 break;
00873 };
00874 }
00875
00876 if (flags & flag_reproc)
00877 {
00878 flags &= ~ flag_reproc;
00879 -- state.ptr;
00880 }
00881
00882 if (flags & flag_next)
00883 {
00884 flags = (flags & ~ flag_next) | flag_need_comma;
00885
00886 if (!top->parent)
00887 {
00888
00889
00890 flags |= flag_done;
00891 continue;
00892 }
00893
00894 if (top->parent->type == json_array)
00895 flags |= flag_seek_value;
00896
00897 if (!state.first_pass)
00898 {
00899 json_value * parent = top->parent;
00900
00901 switch (parent->type)
00902 {
00903 case json_object:
00904
00905 parent->u.object.values
00906 [parent->u.object.length].value = top;
00907
00908 break;
00909
00910 case json_array:
00911
00912 parent->u.array.values
00913 [parent->u.array.length] = top;
00914
00915 break;
00916
00917 default:
00918 break;
00919 };
00920 }
00921
00922 if ( (++ top->parent->u.array.length) > state.uint_max)
00923 goto e_overflow;
00924
00925 top = top->parent;
00926
00927 continue;
00928 }
00929 }
00930
00931 alloc = root;
00932 }
00933
00934 return root;
00935
00936 e_unknown_value:
00937
00938 sprintf (error, "%d:%d: Unknown value", line_and_col);
00939 goto e_failed;
00940
00941 e_alloc_failure:
00942
00943 strcpy (error, "Memory allocation failure");
00944 goto e_failed;
00945
00946 e_overflow:
00947
00948 sprintf (error, "%d:%d: Too long (caught overflow)", line_and_col);
00949 goto e_failed;
00950
00951 e_failed:
00952
00953 if (error_buf)
00954 {
00955 if (*error)
00956 strcpy (error_buf, error);
00957 else
00958 strcpy (error_buf, "Unknown error");
00959 }
00960
00961 if (state.first_pass)
00962 alloc = root;
00963
00964 while (alloc)
00965 {
00966 top = alloc->_reserved.next_alloc;
00967 state.settings.mem_free (alloc, state.settings.user_data);
00968 alloc = top;
00969 }
00970
00971 if (!state.first_pass)
00972 json_value_free_ex (&state.settings, root);
00973
00974 return 0;
00975 }
00976
00977 json_value * json_parse (const json_char * json, size_t length)
00978 {
00979 json_settings settings = { 0 };
00980 return json_parse_ex (&settings, json, length, 0);
00981 }
00982
00983 void json_value_free_ex (json_settings * settings, json_value * value)
00984 {
00985 json_value * cur_value;
00986
00987 if (!value)
00988 return;
00989
00990 value->parent = 0;
00991
00992 while (value)
00993 {
00994 switch (value->type)
00995 {
00996 case json_array:
00997
00998 if (!value->u.array.length)
00999 {
01000 settings->mem_free (value->u.array.values, settings->user_data);
01001 break;
01002 }
01003
01004 value = value->u.array.values [-- value->u.array.length];
01005 continue;
01006
01007 case json_object:
01008
01009 if (!value->u.object.length)
01010 {
01011 settings->mem_free (value->u.object.values, settings->user_data);
01012 break;
01013 }
01014
01015 value = value->u.object.values [-- value->u.object.length].value;
01016 continue;
01017
01018 case json_string:
01019
01020 settings->mem_free (value->u.string.ptr, settings->user_data);
01021 break;
01022
01023 default:
01024 break;
01025 };
01026
01027 cur_value = value;
01028 value = value->parent;
01029 settings->mem_free (cur_value, settings->user_data);
01030 }
01031 }
01032
01033 void json_value_free (json_value * value)
01034 {
01035 json_settings settings = { 0 };
01036 settings.mem_free = default_free;
01037 json_value_free_ex (&settings, value);
01038 }
01039