small weather widget for X11
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 994 lines 27 kB view raw
1/* 2 * Fetched from https://github.com/skeeto/pdjson 67108d883 3 * 4 * This is free and unencumbered software released into the public domain. 5 * 6 * Anyone is free to copy, modify, publish, use, compile, sell, or 7 * distribute this software, either in source code form or as a compiled 8 * binary, for any purpose, commercial or non-commercial, and by any 9 * means. 10 * 11 * In jurisdictions that recognize copyright laws, the author or authors 12 * of this software dedicate any and all copyright interest in the 13 * software to the public domain. We make this dedication for the benefit 14 * of the public at large and to the detriment of our heirs and 15 * successors. We intend this dedication to be an overt act of 16 * relinquishment in perpetuity of all present and future rights to this 17 * software under copyright law. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 * OTHER DEALINGS IN THE SOFTWARE. 26 * 27 * For more information, please refer to <http://unlicense.org/> 28 */ 29 30#ifndef _POSIX_C_SOURCE 31# define _POSIX_C_SOURCE 200112L 32#elif _POSIX_C_SOURCE < 200112L 33# error incompatible _POSIX_C_SOURCE level 34#endif 35 36#include <stdlib.h> 37#include <string.h> 38#include <ctype.h> 39 40#ifndef PDJSON_H 41# include "pdjson.h" 42#endif 43 44#define JSON_FLAG_ERROR (1u << 0) 45#define JSON_FLAG_STREAMING (1u << 1) 46 47#if defined(_MSC_VER) && (_MSC_VER < 1900) 48 49#define json_error(json, format, ...) \ 50 if (!(json->flags & JSON_FLAG_ERROR)) { \ 51 json->flags |= JSON_FLAG_ERROR; \ 52 _snprintf_s(json->errmsg, sizeof(json->errmsg), \ 53 _TRUNCATE, \ 54 format, \ 55 __VA_ARGS__); \ 56 } \ 57 58#else 59 60#define json_error(json, format, ...) \ 61 if (!(json->flags & JSON_FLAG_ERROR)) { \ 62 json->flags |= JSON_FLAG_ERROR; \ 63 snprintf(json->errmsg, sizeof(json->errmsg), \ 64 format, \ 65 __VA_ARGS__); \ 66 } \ 67 68#endif /* _MSC_VER */ 69 70/* See also PDJSON_STACK_MAX below. */ 71#ifndef PDJSON_STACK_INC 72# define PDJSON_STACK_INC 4 73#endif 74 75struct json_stack { 76 enum json_type type; 77 long count; 78}; 79 80static enum json_type 81push(json_stream *json, enum json_type type) 82{ 83 json->stack_top++; 84 85#ifdef PDJSON_STACK_MAX 86 if (json->stack_top > PDJSON_STACK_MAX) { 87 json_error(json, "%s", "maximum depth of nesting reached"); 88 return JSON_ERROR; 89 } 90#endif 91 92 if (json->stack_top >= json->stack_size) { 93 struct json_stack *stack; 94 size_t size = (json->stack_size + PDJSON_STACK_INC) * sizeof(*json->stack); 95 stack = (struct json_stack *)json->alloc.realloc(json->stack, size); 96 if (stack == NULL) { 97 json_error(json, "%s", "out of memory"); 98 return JSON_ERROR; 99 } 100 101 json->stack_size += PDJSON_STACK_INC; 102 json->stack = stack; 103 } 104 105 json->stack[json->stack_top].type = type; 106 json->stack[json->stack_top].count = 0; 107 108 return type; 109} 110 111static enum json_type 112pop(json_stream *json, int c, enum json_type expected) 113{ 114 if (json->stack == NULL || json->stack[json->stack_top].type != expected) { 115 json_error(json, "unexpected byte '%c'", c); 116 return JSON_ERROR; 117 } 118 json->stack_top--; 119 return expected == JSON_ARRAY ? JSON_ARRAY_END : JSON_OBJECT_END; 120} 121 122static int buffer_peek(struct json_source *source) 123{ 124 if (source->position < source->source.buffer.length) 125 return source->source.buffer.buffer[source->position]; 126 else 127 return EOF; 128} 129 130static int buffer_get(struct json_source *source) 131{ 132 int c = source->peek(source); 133 source->position++; 134 return c; 135} 136 137static int stream_get(struct json_source *source) 138{ 139 source->position++; 140 return fgetc(source->source.stream.stream); 141} 142 143static int stream_peek(struct json_source *source) 144{ 145 int c = fgetc(source->source.stream.stream); 146 ungetc(c, source->source.stream.stream); 147 return c; 148} 149 150static void init(json_stream *json) 151{ 152 json->lineno = 1; 153 json->flags = JSON_FLAG_STREAMING; 154 json->errmsg[0] = '\0'; 155 json->ntokens = 0; 156 json->next = (enum json_type)0; 157 158 json->stack = NULL; 159 json->stack_top = -1; 160 json->stack_size = 0; 161 162 json->data.string = NULL; 163 json->data.string_size = 0; 164 json->data.string_fill = 0; 165 json->source.position = 0; 166 167 json->alloc.malloc = malloc; 168 json->alloc.realloc = realloc; 169 json->alloc.free = free; 170} 171 172static enum json_type 173is_match(json_stream *json, const char *pattern, enum json_type type) 174{ 175 int c; 176 for (const char *p = pattern; *p; p++) { 177 if (*p != (c = json->source.get(&json->source))) { 178 json_error(json, "expected '%c' instead of byte '%c'", *p, c); 179 return JSON_ERROR; 180 } 181 } 182 return type; 183} 184 185static int pushchar(json_stream *json, int c) 186{ 187 if (json->data.string_fill == json->data.string_size) { 188 size_t size = json->data.string_size * 2; 189 char *buffer = (char *)json->alloc.realloc(json->data.string, size); 190 if (buffer == NULL) { 191 json_error(json, "%s", "out of memory"); 192 return -1; 193 } else { 194 json->data.string_size = size; 195 json->data.string = buffer; 196 } 197 } 198 json->data.string[json->data.string_fill++] = c; 199 return 0; 200} 201 202static int init_string(json_stream *json) 203{ 204 json->data.string_fill = 0; 205 if (json->data.string == NULL) { 206 json->data.string_size = 1024; 207 json->data.string = (char *)json->alloc.malloc(json->data.string_size); 208 if (json->data.string == NULL) { 209 json_error(json, "%s", "out of memory"); 210 return -1; 211 } 212 } 213 json->data.string[0] = '\0'; 214 return 0; 215} 216 217static int encode_utf8(json_stream *json, unsigned long c) 218{ 219 if (c < 0x80UL) { 220 return pushchar(json, c); 221 } else if (c < 0x0800UL) { 222 return !((pushchar(json, (c >> 6 & 0x1F) | 0xC0) == 0) && 223 (pushchar(json, (c >> 0 & 0x3F) | 0x80) == 0)); 224 } else if (c < 0x010000UL) { 225 if (c >= 0xd800 && c <= 0xdfff) { 226 json_error(json, "invalid codepoint %06lx", c); 227 return -1; 228 } 229 return !((pushchar(json, (c >> 12 & 0x0F) | 0xE0) == 0) && 230 (pushchar(json, (c >> 6 & 0x3F) | 0x80) == 0) && 231 (pushchar(json, (c >> 0 & 0x3F) | 0x80) == 0)); 232 } else if (c < 0x110000UL) { 233 return !((pushchar(json, (c >> 18 & 0x07) | 0xF0) == 0) && 234 (pushchar(json, (c >> 12 & 0x3F) | 0x80) == 0) && 235 (pushchar(json, (c >> 6 & 0x3F) | 0x80) == 0) && 236 (pushchar(json, (c >> 0 & 0x3F) | 0x80) == 0)); 237 } else { 238 json_error(json, "unable to encode %06lx as UTF-8", c); 239 return -1; 240 } 241} 242 243static int hexchar(int c) 244{ 245 switch (c) { 246 case '0': return 0; 247 case '1': return 1; 248 case '2': return 2; 249 case '3': return 3; 250 case '4': return 4; 251 case '5': return 5; 252 case '6': return 6; 253 case '7': return 7; 254 case '8': return 8; 255 case '9': return 9; 256 case 'a': 257 case 'A': return 10; 258 case 'b': 259 case 'B': return 11; 260 case 'c': 261 case 'C': return 12; 262 case 'd': 263 case 'D': return 13; 264 case 'e': 265 case 'E': return 14; 266 case 'f': 267 case 'F': return 15; 268 default: 269 return -1; 270 } 271} 272 273static long 274read_unicode_cp(json_stream *json) 275{ 276 long cp = 0; 277 int shift = 12; 278 279 for (size_t i = 0; i < 4; i++) { 280 int c = json->source.get(&json->source); 281 int hc; 282 283 if (c == EOF) { 284 json_error(json, "%s", "unterminated string literal in Unicode"); 285 return -1; 286 } else if ((hc = hexchar(c)) == -1) { 287 json_error(json, "invalid escape Unicode byte '%c'", c); 288 return -1; 289 } 290 291 cp += hc * (1 << shift); 292 shift -= 4; 293 } 294 295 296 return cp; 297} 298 299static int read_unicode(json_stream *json) 300{ 301 long cp, h, l; 302 303 if ((cp = read_unicode_cp(json)) == -1) { 304 return -1; 305 } 306 307 if (cp >= 0xd800 && cp <= 0xdbff) { 308 /* This is the high portion of a surrogate pair; we need to read the 309 * lower portion to get the codepoint 310 */ 311 h = cp; 312 313 int c = json->source.get(&json->source); 314 if (c == EOF) { 315 json_error(json, "%s", "unterminated string literal in Unicode"); 316 return -1; 317 } else if (c != '\\') { 318 json_error(json, "invalid continuation for surrogate pair '%c', " 319 "expected '\\'", c); 320 return -1; 321 } 322 323 c = json->source.get(&json->source); 324 if (c == EOF) { 325 json_error(json, "%s", "unterminated string literal in Unicode"); 326 return -1; 327 } else if (c != 'u') { 328 json_error(json, "invalid continuation for surrogate pair '%c', " 329 "expected 'u'", c); 330 return -1; 331 } 332 333 if ((l = read_unicode_cp(json)) == -1) { 334 return -1; 335 } 336 337 if (l < 0xdc00 || l > 0xdfff) { 338 json_error(json, "surrogate pair continuation \\u%04lx out " 339 "of range (dc00-dfff)", l); 340 return -1; 341 } 342 343 cp = ((h - 0xd800) * 0x400) + ((l - 0xdc00) + 0x10000); 344 } else if (cp >= 0xdc00 && cp <= 0xdfff) { 345 json_error(json, "dangling surrogate \\u%04lx", cp); 346 return -1; 347 } 348 349 return encode_utf8(json, cp); 350} 351 352static int 353read_escaped(json_stream *json) 354{ 355 int c = json->source.get(&json->source); 356 if (c == EOF) { 357 json_error(json, "%s", "unterminated string literal in escape"); 358 return -1; 359 } else if (c == 'u') { 360 if (read_unicode(json) != 0) 361 return -1; 362 } else { 363 switch (c) { 364 case '\\': 365 case 'b': 366 case 'f': 367 case 'n': 368 case 'r': 369 case 't': 370 case '/': 371 case '"': 372 { 373 const char *codes = "\\bfnrt/\""; 374 const char *p = strchr(codes, c); 375 if (pushchar(json, "\\\b\f\n\r\t/\""[p - codes]) != 0) 376 return -1; 377 } 378 break; 379 default: 380 json_error(json, "invalid escaped byte '%c'", c); 381 return -1; 382 } 383 } 384 return 0; 385} 386 387static int 388char_needs_escaping(int c) 389{ 390 if ((c >= 0) && (c < 0x20 || c == 0x22 || c == 0x5c)) { 391 return 1; 392 } 393 394 return 0; 395} 396 397static int 398utf8_seq_length(char byte) 399{ 400 unsigned char u = (unsigned char) byte; 401 if (u < 0x80) return 1; 402 403 if (0x80 <= u && u <= 0xBF) 404 { 405 // second, third or fourth byte of a multi-byte 406 // sequence, i.e. a "continuation byte" 407 return 0; 408 } 409 else if (u == 0xC0 || u == 0xC1) 410 { 411 // overlong encoding of an ASCII byte 412 return 0; 413 } 414 else if (0xC2 <= u && u <= 0xDF) 415 { 416 // 2-byte sequence 417 return 2; 418 } 419 else if (0xE0 <= u && u <= 0xEF) 420 { 421 // 3-byte sequence 422 return 3; 423 } 424 else if (0xF0 <= u && u <= 0xF4) 425 { 426 // 4-byte sequence 427 return 4; 428 } 429 else 430 { 431 // u >= 0xF5 432 // Restricted (start of 4-, 5- or 6-byte sequence) or invalid UTF-8 433 return 0; 434 } 435} 436 437static int 438is_legal_utf8(const unsigned char *bytes, int length) 439{ 440 if (0 == bytes || 0 == length) return 0; 441 442 unsigned char a; 443 const unsigned char* srcptr = bytes + length; 444 switch (length) 445 { 446 default: 447 return 0; 448 // Everything else falls through when true. 449 case 4: 450 if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; 451 /* FALLTHRU */ 452 case 3: 453 if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; 454 /* FALLTHRU */ 455 case 2: 456 a = (*--srcptr); 457 switch (*bytes) 458 { 459 case 0xE0: 460 if (a < 0xA0 || a > 0xBF) return 0; 461 break; 462 case 0xED: 463 if (a < 0x80 || a > 0x9F) return 0; 464 break; 465 case 0xF0: 466 if (a < 0x90 || a > 0xBF) return 0; 467 break; 468 case 0xF4: 469 if (a < 0x80 || a > 0x8F) return 0; 470 break; 471 default: 472 if (a < 0x80 || a > 0xBF) return 0; 473 break; 474 } 475 /* FALLTHRU */ 476 case 1: 477 if (*bytes >= 0x80 && *bytes < 0xC2) return 0; 478 } 479 return *bytes <= 0xF4; 480} 481 482static int 483read_utf8(json_stream* json, int next_char) 484{ 485 int count = utf8_seq_length(next_char); 486 if (!count) 487 { 488 json_error(json, "%s", "invalid UTF-8 character"); 489 return -1; 490 } 491 492 char buffer[4]; 493 buffer[0] = next_char; 494 int i; 495 for (i = 1; i < count; ++i) 496 { 497 buffer[i] = json->source.get(&json->source);; 498 } 499 500 if (!is_legal_utf8((unsigned char*) buffer, count)) 501 { 502 json_error(json, "%s", "invalid UTF-8 text"); 503 return -1; 504 } 505 506 for (i = 0; i < count; ++i) 507 { 508 if (pushchar(json, buffer[i]) != 0) 509 return -1; 510 } 511 return 0; 512} 513 514static enum json_type 515read_string(json_stream *json) 516{ 517 if (init_string(json) != 0) 518 return JSON_ERROR; 519 while (1) { 520 int c = json->source.get(&json->source); 521 if (c == EOF) { 522 json_error(json, "%s", "unterminated string literal"); 523 return JSON_ERROR; 524 } else if (c == '"') { 525 if (pushchar(json, '\0') == 0) 526 return JSON_STRING; 527 else 528 return JSON_ERROR; 529 } else if (c == '\\') { 530 if (read_escaped(json) != 0) 531 return JSON_ERROR; 532 } else if ((unsigned) c >= 0x80) { 533 if (read_utf8(json, c) != 0) 534 return JSON_ERROR; 535 } else { 536 if (char_needs_escaping(c)) { 537 json_error(json, "%s", "unescaped control character in string"); 538 return JSON_ERROR; 539 } 540 541 if (pushchar(json, c) != 0) 542 return JSON_ERROR; 543 } 544 } 545 return JSON_ERROR; 546} 547 548static int 549is_digit(int c) 550{ 551 return c >= 48 /*0*/ && c <= 57 /*9*/; 552} 553 554static int 555read_digits(json_stream *json) 556{ 557 int c; 558 unsigned nread = 0; 559 while (is_digit(c = json->source.peek(&json->source))) { 560 if (pushchar(json, json->source.get(&json->source)) != 0) 561 return -1; 562 563 nread++; 564 } 565 566 if (nread == 0) { 567 json_error(json, "expected digit instead of byte '%c'", c); 568 return -1; 569 } 570 571 return 0; 572} 573 574static enum json_type 575read_number(json_stream *json, int c) 576{ 577 if (pushchar(json, c) != 0) 578 return JSON_ERROR; 579 if (c == '-') { 580 c = json->source.get(&json->source); 581 if (is_digit(c)) { 582 return read_number(json, c); 583 } else { 584 json_error(json, "unexpected byte '%c' in number", c); 585 return JSON_ERROR; 586 } 587 } else if (strchr("123456789", c) != NULL) { 588 c = json->source.peek(&json->source); 589 if (is_digit(c)) { 590 if (read_digits(json) != 0) 591 return JSON_ERROR; 592 } 593 } 594 /* Up to decimal or exponent has been read. */ 595 c = json->source.peek(&json->source); 596 if (strchr(".eE", c) == NULL) { 597 if (pushchar(json, '\0') != 0) 598 return JSON_ERROR; 599 else 600 return JSON_NUMBER; 601 } 602 if (c == '.') { 603 json->source.get(&json->source); // consume . 604 if (pushchar(json, c) != 0) 605 return JSON_ERROR; 606 if (read_digits(json) != 0) 607 return JSON_ERROR; 608 } 609 /* Check for exponent. */ 610 c = json->source.peek(&json->source); 611 if (c == 'e' || c == 'E') { 612 json->source.get(&json->source); // consume e/E 613 if (pushchar(json, c) != 0) 614 return JSON_ERROR; 615 c = json->source.peek(&json->source); 616 if (c == '+' || c == '-') { 617 json->source.get(&json->source); // consume 618 if (pushchar(json, c) != 0) 619 return JSON_ERROR; 620 if (read_digits(json) != 0) 621 return JSON_ERROR; 622 } else if (is_digit(c)) { 623 if (read_digits(json) != 0) 624 return JSON_ERROR; 625 } else { 626 json_error(json, "unexpected byte '%c' in number", c); 627 return JSON_ERROR; 628 } 629 } 630 if (pushchar(json, '\0') != 0) 631 return JSON_ERROR; 632 else 633 return JSON_NUMBER; 634} 635 636bool 637json_isspace(int c) 638{ 639 switch (c) { 640 case 0x09: 641 case 0x0a: 642 case 0x0d: 643 case 0x20: 644 return true; 645 } 646 647 return false; 648} 649 650/* Returns the next non-whitespace character in the stream. */ 651static int next(json_stream *json) 652{ 653 int c; 654 while (json_isspace(c = json->source.get(&json->source))) 655 if (c == '\n') 656 json->lineno++; 657 return c; 658} 659 660static enum json_type 661read_value(json_stream *json, int c) 662{ 663 json->ntokens++; 664 switch (c) { 665 case EOF: 666 json_error(json, "%s", "unexpected end of text"); 667 return JSON_ERROR; 668 case '{': 669 return push(json, JSON_OBJECT); 670 case '[': 671 return push(json, JSON_ARRAY); 672 case '"': 673 return read_string(json); 674 case 'n': 675 return is_match(json, "ull", JSON_NULL); 676 case 'f': 677 return is_match(json, "alse", JSON_FALSE); 678 case 't': 679 return is_match(json, "rue", JSON_TRUE); 680 case '0': 681 case '1': 682 case '2': 683 case '3': 684 case '4': 685 case '5': 686 case '6': 687 case '7': 688 case '8': 689 case '9': 690 case '-': 691 if (init_string(json) != 0) 692 return JSON_ERROR; 693 return read_number(json, c); 694 default: 695 json_error(json, "unexpected byte '%c' in value", c); 696 return JSON_ERROR; 697 } 698} 699 700enum json_type json_peek(json_stream *json) 701{ 702 enum json_type next; 703 if (json->next) 704 next = json->next; 705 else 706 next = json->next = json_next(json); 707 return next; 708} 709 710enum json_type json_next(json_stream *json) 711{ 712 if (json->flags & JSON_FLAG_ERROR) 713 return JSON_ERROR; 714 if (json->next != 0) { 715 enum json_type next = json->next; 716 json->next = (enum json_type)0; 717 return next; 718 } 719 if (json->ntokens > 0 && json->stack_top == (size_t)-1) { 720 721 /* In the streaming mode leave any trailing whitespaces in the stream. 722 * This allows the user to validate any desired separation between 723 * values (such as newlines) using json_source_get/peek() with any 724 * remaining whitespaces ignored as leading when we parse the next 725 * value. */ 726 if (!(json->flags & JSON_FLAG_STREAMING)) { 727 int c; 728 729 do { 730 c = json->source.peek(&json->source); 731 if (json_isspace(c)) { 732 c = json->source.get(&json->source); 733 } 734 } while (json_isspace(c)); 735 736 if (c != EOF) { 737 json_error(json, "expected end of text instead of byte '%c'", c); 738 return JSON_ERROR; 739 } 740 } 741 742 return JSON_DONE; 743 } 744 int c = next(json); 745 if (json->stack_top == (size_t)-1) { 746 if (c == EOF && (json->flags & JSON_FLAG_STREAMING)) 747 return JSON_DONE; 748 749 return read_value(json, c); 750 } 751 if (json->stack[json->stack_top].type == JSON_ARRAY) { 752 if (json->stack[json->stack_top].count == 0) { 753 if (c == ']') { 754 return pop(json, c, JSON_ARRAY); 755 } 756 json->stack[json->stack_top].count++; 757 return read_value(json, c); 758 } else if (c == ',') { 759 json->stack[json->stack_top].count++; 760 return read_value(json, next(json)); 761 } else if (c == ']') { 762 return pop(json, c, JSON_ARRAY); 763 } else { 764 json_error(json, "unexpected byte '%c'", c); 765 return JSON_ERROR; 766 } 767 } else if (json->stack[json->stack_top].type == JSON_OBJECT) { 768 if (json->stack[json->stack_top].count == 0) { 769 if (c == '}') { 770 return pop(json, c, JSON_OBJECT); 771 } 772 773 /* No member name/value pairs yet. */ 774 enum json_type value = read_value(json, c); 775 if (value != JSON_STRING) { 776 if (value != JSON_ERROR) 777 json_error(json, "%s", "expected member name or '}'"); 778 return JSON_ERROR; 779 } else { 780 json->stack[json->stack_top].count++; 781 return value; 782 } 783 } else if ((json->stack[json->stack_top].count % 2) == 0) { 784 /* Expecting comma followed by member name. */ 785 if (c != ',' && c != '}') { 786 json_error(json, "%s", "expected ',' or '}' after member value"); 787 return JSON_ERROR; 788 } else if (c == '}') { 789 return pop(json, c, JSON_OBJECT); 790 } else { 791 enum json_type value = read_value(json, next(json)); 792 if (value != JSON_STRING) { 793 if (value != JSON_ERROR) 794 json_error(json, "%s", "expected member name"); 795 return JSON_ERROR; 796 } else { 797 json->stack[json->stack_top].count++; 798 return value; 799 } 800 } 801 } else if ((json->stack[json->stack_top].count % 2) == 1) { 802 /* Expecting colon followed by value. */ 803 if (c != ':') { 804 json_error(json, "%s", "expected ':' after member name"); 805 return JSON_ERROR; 806 } else { 807 json->stack[json->stack_top].count++; 808 return read_value(json, next(json)); 809 } 810 } 811 } 812 json_error(json, "%s", "invalid parser state"); 813 return JSON_ERROR; 814} 815 816void json_reset(json_stream *json) 817{ 818 json->stack_top = -1; 819 json->ntokens = 0; 820 json->flags &= ~JSON_FLAG_ERROR; 821 json->errmsg[0] = '\0'; 822} 823 824enum json_type json_skip(json_stream *json) 825{ 826 enum json_type type = json_next(json); 827 size_t cnt_arr = 0; 828 size_t cnt_obj = 0; 829 830 for (enum json_type skip = type; ; skip = json_next(json)) { 831 if (skip == JSON_ERROR || skip == JSON_DONE) 832 return skip; 833 834 if (skip == JSON_ARRAY) { 835 ++cnt_arr; 836 } else if (skip == JSON_ARRAY_END && cnt_arr > 0) { 837 --cnt_arr; 838 } else if (skip == JSON_OBJECT) { 839 ++cnt_obj; 840 } else if (skip == JSON_OBJECT_END && cnt_obj > 0) { 841 --cnt_obj; 842 } 843 844 if (!cnt_arr && !cnt_obj) 845 break; 846 } 847 848 return type; 849} 850 851enum json_type json_skip_until(json_stream *json, enum json_type type) 852{ 853 while (1) { 854 enum json_type skip = json_skip(json); 855 856 if (skip == JSON_ERROR || skip == JSON_DONE) 857 return skip; 858 859 if (skip == type) 860 break; 861 } 862 863 return type; 864} 865 866const char *json_get_string(json_stream *json, size_t *length) 867{ 868 if (length != NULL) 869 *length = json->data.string_fill; 870 if (json->data.string == NULL) 871 return ""; 872 else 873 return json->data.string; 874} 875 876double json_get_number(json_stream *json) 877{ 878 char *p = json->data.string; 879 return p == NULL ? 0 : strtod(p, NULL); 880} 881 882const char *json_get_error(json_stream *json) 883{ 884 return json->flags & JSON_FLAG_ERROR ? json->errmsg : NULL; 885} 886 887size_t json_get_lineno(json_stream *json) 888{ 889 return json->lineno; 890} 891 892size_t json_get_position(json_stream *json) 893{ 894 return json->source.position; 895} 896 897size_t json_get_depth(json_stream *json) 898{ 899 return json->stack_top + 1; 900} 901 902/* Return the current parsing context, that is, JSON_OBJECT if we are inside 903 an object, JSON_ARRAY if we are inside an array, and JSON_DONE if we are 904 not yet/anymore in either. 905 906 Additionally, for the first two cases, also return the number of parsing 907 events that have already been observed at this level with json_next/peek(). 908 In particular, inside an object, an odd number would indicate that the just 909 observed JSON_STRING event is a member name. 910*/ 911enum json_type json_get_context(json_stream *json, size_t *count) 912{ 913 if (json->stack_top == (size_t)-1) 914 return JSON_DONE; 915 916 if (count != NULL) 917 *count = json->stack[json->stack_top].count; 918 919 return json->stack[json->stack_top].type; 920} 921 922int json_source_get(json_stream *json) 923{ 924 int c = json->source.get(&json->source); 925 if (c == '\n') 926 json->lineno++; 927 return c; 928} 929 930int json_source_peek(json_stream *json) 931{ 932 return json->source.peek(&json->source); 933} 934 935void json_open_buffer(json_stream *json, const void *buffer, size_t size) 936{ 937 init(json); 938 json->source.get = buffer_get; 939 json->source.peek = buffer_peek; 940 json->source.source.buffer.buffer = (const char *)buffer; 941 json->source.source.buffer.length = size; 942} 943 944void json_open_string(json_stream *json, const char *string) 945{ 946 json_open_buffer(json, string, strlen(string)); 947} 948 949void json_open_stream(json_stream *json, FILE * stream) 950{ 951 init(json); 952 json->source.get = stream_get; 953 json->source.peek = stream_peek; 954 json->source.source.stream.stream = stream; 955} 956 957static int user_get(struct json_source *json) 958{ 959 return json->source.user.get(json->source.user.ptr); 960} 961 962static int user_peek(struct json_source *json) 963{ 964 return json->source.user.peek(json->source.user.ptr); 965} 966 967void json_open_user(json_stream *json, json_user_io get, json_user_io peek, void *user) 968{ 969 init(json); 970 json->source.get = user_get; 971 json->source.peek = user_peek; 972 json->source.source.user.ptr = user; 973 json->source.source.user.get = get; 974 json->source.source.user.peek = peek; 975} 976 977void json_set_allocator(json_stream *json, json_allocator *a) 978{ 979 json->alloc = *a; 980} 981 982void json_set_streaming(json_stream *json, bool streaming) 983{ 984 if (streaming) 985 json->flags |= JSON_FLAG_STREAMING; 986 else 987 json->flags &= ~JSON_FLAG_STREAMING; 988} 989 990void json_close(json_stream *json) 991{ 992 json->alloc.free(json->stack); 993 json->alloc.free(json->data.string); 994}