small weather widget for X11
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}