Mercurial > dovecot > core-2.2
annotate src/lib/json-parser.c @ 22664:fea53c2725c0
director: Fix director_max_parallel_moves/kicks type
Should be uint, not time.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Thu, 09 Nov 2017 12:24:16 +0200 |
parents | ff8873d5675a |
children | cb108f786fb4 |
rev | line source |
---|---|
21390
2e2563132d5f
Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21322
diff
changeset
|
1 /* Copyright (c) 2013-2017 Dovecot authors, see the included COPYING file */ |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #include "lib.h" |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
4 #include "array.h" |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 #include "str.h" |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
6 #include "istream.h" |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 #include "hex-dec.h" |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 #include "unichar.h" |
15437
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
9 #include "istream-jsonstr.h" |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 #include "json-parser.h" |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 enum json_state { |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 JSON_STATE_ROOT = 0, |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
14 JSON_STATE_OBJECT_OPEN, |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 JSON_STATE_OBJECT_KEY, |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 JSON_STATE_OBJECT_COLON, |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 JSON_STATE_OBJECT_VALUE, |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
18 JSON_STATE_OBJECT_SKIP_STRING, |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
19 JSON_STATE_OBJECT_NEXT, |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
20 JSON_STATE_ARRAY_OPEN, |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
21 JSON_STATE_ARRAY_VALUE, |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
22 JSON_STATE_ARRAY_SKIP_STRING, |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
23 JSON_STATE_ARRAY_NEXT, |
19709
31389e4b4677
lib: Fixed calling json_parse_skip_next() within arrays
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19708
diff
changeset
|
24 JSON_STATE_ARRAY_NEXT_SKIP, |
19689
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
25 JSON_STATE_VALUE, |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 JSON_STATE_DONE |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 }; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
29 struct json_parser { |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
30 struct istream *input; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
31 uoff_t highwater_offset; |
19708
6d45c0bb9b30
lib: If json-parser has JSON_PARSER_NO_ROOT_OBJECT set, return the ending root "]" and "}"
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19689
diff
changeset
|
32 enum json_parser_flags flags; |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
33 |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
34 const unsigned char *start, *end, *data; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
35 const char *error; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 string_t *value; |
15437
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
37 struct istream *strinput; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 enum json_state state; |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
40 ARRAY(enum json_state) nesting; |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
41 unsigned int nested_skip_count; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
42 bool skipping; |
19688
0869e8023eab
lib: Fixed json-parser to correctly parse numbers at EOF.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19687
diff
changeset
|
43 bool seen_eof; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 }; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
46 static int json_parser_read_more(struct json_parser *parser) |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
47 { |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
48 uoff_t cur_highwater = parser->input->v_offset + |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
49 i_stream_get_data_size(parser->input); |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
50 size_t size; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
51 ssize_t ret; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
52 |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
53 i_assert(parser->highwater_offset <= cur_highwater); |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
54 |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
55 if (parser->error != NULL) |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
56 return -1; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
57 |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
58 if (parser->highwater_offset == cur_highwater) { |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
59 ret = i_stream_read(parser->input); |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
60 if (ret == -2) { |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
61 parser->error = "Token too large"; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
62 return -1; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
63 } |
19688
0869e8023eab
lib: Fixed json-parser to correctly parse numbers at EOF.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19687
diff
changeset
|
64 if (ret < 0 && !parser->seen_eof && |
0869e8023eab
lib: Fixed json-parser to correctly parse numbers at EOF.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19687
diff
changeset
|
65 i_stream_get_data_size(parser->input) > 0 && |
0869e8023eab
lib: Fixed json-parser to correctly parse numbers at EOF.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19687
diff
changeset
|
66 parser->input->stream_errno == 0) { |
0869e8023eab
lib: Fixed json-parser to correctly parse numbers at EOF.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19687
diff
changeset
|
67 /* call it once more to finish any pending number */ |
0869e8023eab
lib: Fixed json-parser to correctly parse numbers at EOF.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19687
diff
changeset
|
68 parser->seen_eof = TRUE; |
0869e8023eab
lib: Fixed json-parser to correctly parse numbers at EOF.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19687
diff
changeset
|
69 } else if (ret <= 0) { |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
70 return ret; |
19688
0869e8023eab
lib: Fixed json-parser to correctly parse numbers at EOF.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19687
diff
changeset
|
71 } else { |
0869e8023eab
lib: Fixed json-parser to correctly parse numbers at EOF.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19687
diff
changeset
|
72 cur_highwater = parser->input->v_offset + |
0869e8023eab
lib: Fixed json-parser to correctly parse numbers at EOF.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19687
diff
changeset
|
73 i_stream_get_data_size(parser->input); |
0869e8023eab
lib: Fixed json-parser to correctly parse numbers at EOF.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19687
diff
changeset
|
74 i_assert(parser->highwater_offset < cur_highwater); |
0869e8023eab
lib: Fixed json-parser to correctly parse numbers at EOF.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19687
diff
changeset
|
75 parser->highwater_offset = cur_highwater; |
0869e8023eab
lib: Fixed json-parser to correctly parse numbers at EOF.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19687
diff
changeset
|
76 } |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
77 } |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
78 |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
79 parser->start = parser->data = i_stream_get_data(parser->input, &size); |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
80 parser->end = parser->start + size; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
81 i_assert(size > 0); |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
82 return 1; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
83 } |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
84 |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
85 static void json_parser_update_input_pos(struct json_parser *parser) |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
86 { |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
87 size_t size; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
88 |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
89 if (parser->data == parser->start) |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
90 return; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
91 |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
92 i_stream_skip(parser->input, parser->data - parser->start); |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
93 parser->start = parser->data = i_stream_get_data(parser->input, &size); |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
94 parser->end = parser->start + size; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
95 if (size > 0) { |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
96 /* we skipped over some data and there's still data left. |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
97 no need to read() the next time. */ |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
98 parser->highwater_offset = 0; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
99 } else { |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
100 parser->highwater_offset = parser->input->v_offset; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
101 } |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
102 } |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
103 |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
104 struct json_parser *json_parser_init(struct istream *input) |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 { |
19689
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
106 return json_parser_init_flags(input, 0); |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
107 } |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
108 |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
109 struct json_parser *json_parser_init_flags(struct istream *input, |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
110 enum json_parser_flags flags) |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
111 { |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 struct json_parser *parser; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
114 parser = i_new(struct json_parser, 1); |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
115 parser->input = input; |
19708
6d45c0bb9b30
lib: If json-parser has JSON_PARSER_NO_ROOT_OBJECT set, return the ending root "]" and "}"
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19689
diff
changeset
|
116 parser->flags = flags; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
117 parser->value = str_new(default_pool, 128); |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
118 i_array_init(&parser->nesting, 8); |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
119 i_stream_ref(input); |
19689
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
120 |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
121 if ((flags & JSON_PARSER_NO_ROOT_OBJECT) != 0) |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
122 parser->state = JSON_STATE_VALUE; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
123 return parser; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
124 } |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
125 |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
126 int json_parser_deinit(struct json_parser **_parser, const char **error_r) |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
127 { |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
128 struct json_parser *parser = *_parser; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
129 |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
130 *_parser = NULL; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
131 |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
132 if (parser->error != NULL) { |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
133 /* actual parser error */ |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
134 *error_r = parser->error; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
135 } else if (parser->input->stream_errno != 0) { |
20264
0fd0fb05e2b3
global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19784
diff
changeset
|
136 *error_r = t_strdup_printf("read(%s) failed: %s", |
0fd0fb05e2b3
global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19784
diff
changeset
|
137 i_stream_get_name(parser->input), |
0fd0fb05e2b3
global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19784
diff
changeset
|
138 i_stream_get_error(parser->input)); |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
139 } else if (parser->data == parser->end && |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
140 !i_stream_have_bytes_left(parser->input) && |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
141 parser->state != JSON_STATE_DONE) { |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
142 *error_r = "Missing '}'"; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
143 } else { |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
144 *error_r = NULL; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
145 } |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
146 |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
147 i_stream_unref(&parser->input); |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
148 array_free(&parser->nesting); |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
149 str_free(&parser->value); |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
150 i_free(parser); |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
151 return *error_r != NULL ? -1 : 0; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
152 } |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
153 |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
154 static bool json_parse_whitespace(struct json_parser *parser) |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
155 { |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
156 for (; parser->data != parser->end; parser->data++) { |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
157 switch (*parser->data) { |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
158 case ' ': |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
159 case '\t': |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
160 case '\r': |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
161 case '\n': |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
162 break; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
163 default: |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
164 json_parser_update_input_pos(parser); |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
165 return TRUE; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
166 } |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
167 } |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
168 json_parser_update_input_pos(parser); |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
169 return FALSE; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
170 } |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
171 |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
172 static int json_skip_string(struct json_parser *parser) |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
173 { |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
174 for (; parser->data != parser->end; parser->data++) { |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
175 if (*parser->data == '"') { |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
176 parser->data++; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
177 json_parser_update_input_pos(parser); |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
178 return 1; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
179 } |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
180 if (*parser->data == '\\') { |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
181 switch (*++parser->data) { |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
182 case '"': |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
183 case '\\': |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
184 case '/': |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
185 case 'b': |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
186 case 'f': |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
187 case 'n': |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
188 case 'r': |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
189 case 't': |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
190 break; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
191 case 'u': |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
192 if (parser->end - parser->data < 4) |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
193 return -1; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
194 parser->data += 3; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
195 break; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
196 default: |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
197 return -1; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
198 } |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
199 } |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
200 } |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
201 json_parser_update_input_pos(parser); |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
202 return 0; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
203 } |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
204 |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
205 static int json_parse_string(struct json_parser *parser, bool allow_skip, |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
206 const char **value_r) |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
207 { |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
208 if (*parser->data != '"') |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
209 return -1; |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
210 parser->data++; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
211 |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
212 if (parser->skipping && allow_skip) { |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
213 *value_r = NULL; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
214 return json_skip_string(parser); |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
215 } |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
216 |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
217 str_truncate(parser->value, 0); |
15436 | 218 for (; parser->data != parser->end; parser->data++) { |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
219 if (*parser->data == '"') { |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
220 parser->data++; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
221 *value_r = str_c(parser->value); |
15436 | 222 return 1; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
223 } |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
224 if (*parser->data != '\\') |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
225 str_append_c(parser->value, *parser->data); |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
226 else { |
17505
07456a200816
lib: Fixed potential read buffer overflow in JSON parser.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
227 if (++parser->data == parser->end) |
07456a200816
lib: Fixed potential read buffer overflow in JSON parser.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
228 return 0; |
07456a200816
lib: Fixed potential read buffer overflow in JSON parser.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
229 switch (*parser->data) { |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
230 case '"': |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
231 case '\\': |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
232 case '/': |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
233 str_append_c(parser->value, *parser->data); |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
234 break; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
235 case 'b': |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
236 str_append_c(parser->value, '\b'); |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
237 break; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
238 case 'f': |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
239 str_append_c(parser->value, '\f'); |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
240 break; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
241 case 'n': |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
242 str_append_c(parser->value, '\n'); |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
243 break; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
244 case 'r': |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
245 str_append_c(parser->value, '\r'); |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
246 break; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
247 case 't': |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
248 str_append_c(parser->value, '\t'); |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
249 break; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
250 case 'u': |
15436 | 251 parser->data++; |
252 if (parser->end - parser->data < 4) { | |
253 /* wait for more data */ | |
254 parser->data = parser->end; | |
255 return 0; | |
256 } | |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
257 uni_ucs4_to_utf8_c(hex2dec(parser->data, 4), |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
258 parser->value); |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
259 parser->data += 3; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
260 break; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
261 default: |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
262 return -1; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
263 } |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
264 } |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
265 } |
15436 | 266 return 0; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
267 } |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
268 |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
269 static int |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
270 json_parse_digits(struct json_parser *parser) |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
271 { |
15436 | 272 if (parser->data == parser->end) |
273 return 0; | |
274 if (*parser->data < '0' || *parser->data > '9') | |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
275 return -1; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
276 |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
277 while (parser->data != parser->end && |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
278 *parser->data >= '0' && *parser->data <= '9') |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
279 str_append_c(parser->value, *parser->data++); |
15436 | 280 return 1; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
281 } |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
282 |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
283 static int json_parse_int(struct json_parser *parser) |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
284 { |
15436 | 285 int ret; |
286 | |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
287 if (*parser->data == '-') { |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
288 str_append_c(parser->value, *parser->data++); |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
289 if (parser->data == parser->end) |
15436 | 290 return 0; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
291 } |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
292 if (*parser->data == '0') |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
293 str_append_c(parser->value, *parser->data++); |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
294 else { |
15436 | 295 if ((ret = json_parse_digits(parser)) <= 0) |
296 return ret; | |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
297 } |
15436 | 298 return 1; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
299 } |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
300 |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
301 static int json_parse_number(struct json_parser *parser, const char **value_r) |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
302 { |
15436 | 303 int ret; |
304 | |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
305 str_truncate(parser->value, 0); |
15436 | 306 if ((ret = json_parse_int(parser)) <= 0) |
307 return ret; | |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
308 if (parser->data != parser->end && *parser->data == '.') { |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
309 /* frac */ |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
310 str_append_c(parser->value, *parser->data++); |
15436 | 311 if ((ret = json_parse_digits(parser)) <= 0) |
312 return ret; | |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
313 } |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
314 if (parser->data != parser->end && |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
315 (*parser->data == 'e' || *parser->data == 'E')) { |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
316 /* exp */ |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
317 str_append_c(parser->value, *parser->data++); |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
318 if (parser->data == parser->end) |
15436 | 319 return 0; |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
320 if (*parser->data == '+' || *parser->data == '-') |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
321 str_append_c(parser->value, *parser->data++); |
15436 | 322 if ((ret = json_parse_digits(parser)) <= 0) |
323 return ret; | |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
324 } |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
325 if (parser->data == parser->end && !parser->input->eof) |
15436 | 326 return 0; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
327 *value_r = str_c(parser->value); |
15436 | 328 return 1; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
329 } |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
330 |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
331 static int json_parse_atom(struct json_parser *parser, const char *atom) |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
332 { |
21322
5ab8dc1a4a6f
global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20264
diff
changeset
|
333 size_t avail, len = strlen(atom); |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
334 |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
335 avail = parser->end - parser->data; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
336 if (avail < len) { |
15436 | 337 if (memcmp(parser->data, atom, avail) != 0) |
338 return -1; | |
339 | |
340 /* everything matches so far, but we need more data */ | |
341 parser->data += avail; | |
342 return 0; | |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
343 } |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
344 if (memcmp(parser->data, atom, len) != 0) |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
345 return -1; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
346 parser->data += len; |
15436 | 347 return 1; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
348 } |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
349 |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
350 static int json_parse_denest(struct json_parser *parser) |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
351 { |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
352 const enum json_state *nested_states; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
353 unsigned count; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
354 |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
355 parser->data++; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
356 json_parser_update_input_pos(parser); |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
357 |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
358 nested_states = array_get(&parser->nesting, &count); |
19687
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
359 i_assert(count > 0); |
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
360 if (count == 1) { |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
361 /* closing root */ |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
362 parser->state = JSON_STATE_DONE; |
19708
6d45c0bb9b30
lib: If json-parser has JSON_PARSER_NO_ROOT_OBJECT set, return the ending root "]" and "}"
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19689
diff
changeset
|
363 if ((parser->flags & JSON_PARSER_NO_ROOT_OBJECT) == 0) |
6d45c0bb9b30
lib: If json-parser has JSON_PARSER_NO_ROOT_OBJECT set, return the ending root "]" and "}"
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19689
diff
changeset
|
364 return 0; |
6d45c0bb9b30
lib: If json-parser has JSON_PARSER_NO_ROOT_OBJECT set, return the ending root "]" and "}"
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19689
diff
changeset
|
365 /* we want to return the ending "]" or "}" to caller */ |
6d45c0bb9b30
lib: If json-parser has JSON_PARSER_NO_ROOT_OBJECT set, return the ending root "]" and "}"
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19689
diff
changeset
|
366 return 1; |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
367 } |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
368 |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
369 /* closing a nested object */ |
19687
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
370 parser->state = nested_states[count-2] == JSON_STATE_OBJECT_OPEN ? |
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
371 JSON_STATE_OBJECT_NEXT : JSON_STATE_ARRAY_NEXT; |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
372 array_delete(&parser->nesting, count-1, 1); |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
373 |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
374 if (parser->nested_skip_count > 0) { |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
375 parser->nested_skip_count--; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
376 return 0; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
377 } |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
378 return 1; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
379 } |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
380 |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
381 static int |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
382 json_parse_close_object(struct json_parser *parser, enum json_type *type_r) |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
383 { |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
384 if (json_parse_denest(parser) == 0) |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
385 return 0; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
386 *type_r = JSON_TYPE_OBJECT_END; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
387 return 1; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
388 } |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
389 |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
390 static int |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
391 json_parse_close_array(struct json_parser *parser, enum json_type *type_r) |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
392 { |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
393 if (json_parse_denest(parser) == 0) |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
394 return 0; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
395 *type_r = JSON_TYPE_ARRAY_END; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
396 return 1; |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
397 } |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
398 |
19687
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
399 static void json_parser_object_open(struct json_parser *parser) |
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
400 { |
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
401 parser->data++; |
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
402 parser->state = JSON_STATE_OBJECT_OPEN; |
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
403 array_append(&parser->nesting, &parser->state, 1); |
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
404 json_parser_update_input_pos(parser); |
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
405 } |
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
406 |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
407 static int |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
408 json_try_parse_next(struct json_parser *parser, enum json_type *type_r, |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
409 const char **value_r) |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
410 { |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
411 bool skipping = parser->skipping; |
15436 | 412 int ret; |
413 | |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
414 if (!json_parse_whitespace(parser)) |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
415 return -1; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
416 |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
417 switch (parser->state) { |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
418 case JSON_STATE_ROOT: |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
419 if (*parser->data != '{') { |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
420 parser->error = "Object doesn't begin with '{'"; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
421 return -1; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
422 } |
19687
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
423 json_parser_object_open(parser); |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
424 return 0; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
425 case JSON_STATE_OBJECT_VALUE: |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
426 case JSON_STATE_ARRAY_VALUE: |
19689
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
427 case JSON_STATE_VALUE: |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
428 if (*parser->data == '{') { |
19687
2166e0f25e43
lib: Code cleanup to json-parser - assume less that the root is an object
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19657
diff
changeset
|
429 json_parser_object_open(parser); |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
430 |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
431 if (parser->skipping) { |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
432 parser->nested_skip_count++; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
433 return 0; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
434 } |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
435 *type_r = JSON_TYPE_OBJECT; |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
436 return 1; |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
437 } else if (*parser->data == '[') { |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
438 parser->data++; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
439 parser->state = JSON_STATE_ARRAY_OPEN; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
440 array_append(&parser->nesting, &parser->state, 1); |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
441 json_parser_update_input_pos(parser); |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
442 |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
443 if (parser->skipping) { |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
444 parser->nested_skip_count++; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
445 return 0; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
446 } |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
447 *type_r = JSON_TYPE_ARRAY; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
448 return 1; |
15436 | 449 } |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
450 |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
451 if ((ret = json_parse_string(parser, TRUE, value_r)) >= 0) { |
15436 | 452 *type_r = JSON_TYPE_STRING; |
453 } else if ((ret = json_parse_number(parser, value_r)) >= 0) { | |
454 *type_r = JSON_TYPE_NUMBER; | |
455 } else if ((ret = json_parse_atom(parser, "true")) >= 0) { | |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
456 *type_r = JSON_TYPE_TRUE; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
457 *value_r = "true"; |
15436 | 458 } else if ((ret = json_parse_atom(parser, "false")) >= 0) { |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
459 *type_r = JSON_TYPE_FALSE; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
460 *value_r = "false"; |
15436 | 461 } else if ((ret = json_parse_atom(parser, "null")) >= 0) { |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
462 *type_r = JSON_TYPE_NULL; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
463 *value_r = NULL; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
464 } else { |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
465 parser->error = "Invalid data as value"; |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
466 return -1; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
467 } |
15436 | 468 if (ret == 0) { |
469 i_assert(parser->data == parser->end); | |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
470 if (parser->skipping && *type_r == JSON_TYPE_STRING) { |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
471 /* a large string that we want to skip over. */ |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
472 json_parser_update_input_pos(parser); |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
473 parser->state = parser->state == JSON_STATE_OBJECT_VALUE ? |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
474 JSON_STATE_OBJECT_SKIP_STRING : |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
475 JSON_STATE_ARRAY_SKIP_STRING; |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
476 return 0; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
477 } |
15436 | 478 return -1; |
479 } | |
19689
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
480 switch (parser->state) { |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
481 case JSON_STATE_OBJECT_VALUE: |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
482 parser->state = JSON_STATE_OBJECT_NEXT; |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
483 break; |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
484 case JSON_STATE_ARRAY_VALUE: |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
485 parser->state = JSON_STATE_ARRAY_NEXT; |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
486 break; |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
487 case JSON_STATE_VALUE: |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
488 parser->state = JSON_STATE_DONE; |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
489 break; |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
490 default: |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
491 i_unreached(); |
8bcb62e748b9
lib: JSON parser can now optionally parse input that isn't an object.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19688
diff
changeset
|
492 } |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
493 break; |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
494 case JSON_STATE_OBJECT_OPEN: |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
495 if (*parser->data == '}') |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
496 return json_parse_close_object(parser, type_r); |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
497 parser->state = JSON_STATE_OBJECT_KEY; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
498 /* fall through */ |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
499 case JSON_STATE_OBJECT_KEY: |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
500 if (json_parse_string(parser, FALSE, value_r) <= 0) { |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
501 parser->error = "Expected string as object key"; |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
502 return -1; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
503 } |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
504 *type_r = JSON_TYPE_OBJECT_KEY; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
505 parser->state = JSON_STATE_OBJECT_COLON; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
506 break; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
507 case JSON_STATE_OBJECT_COLON: |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
508 if (*parser->data != ':') { |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
509 parser->error = "Expected ':' after key"; |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
510 return -1; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
511 } |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
512 parser->data++; |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
513 parser->state = JSON_STATE_OBJECT_VALUE; |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
514 json_parser_update_input_pos(parser); |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
515 return 0; |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
516 case JSON_STATE_OBJECT_NEXT: |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
517 if (parser->skipping && parser->nested_skip_count == 0) { |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
518 /* we skipped over the previous value */ |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
519 parser->skipping = FALSE; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
520 } |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
521 if (*parser->data == '}') |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
522 return json_parse_close_object(parser, type_r); |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
523 if (*parser->data != ',') { |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
524 parser->error = "Expected ',' or '}' after object value"; |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
525 return -1; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
526 } |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
527 parser->state = JSON_STATE_OBJECT_KEY; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
528 parser->data++; |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
529 json_parser_update_input_pos(parser); |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
530 return 0; |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
531 case JSON_STATE_ARRAY_OPEN: |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
532 if (*parser->data == ']') |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
533 return json_parse_close_array(parser, type_r); |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
534 parser->state = JSON_STATE_ARRAY_VALUE; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
535 return 0; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
536 case JSON_STATE_ARRAY_NEXT: |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
537 if (parser->skipping && parser->nested_skip_count == 0) { |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
538 /* we skipped over the previous value */ |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
539 parser->skipping = FALSE; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
540 } |
22465
ff8873d5675a
global: Add/change switch case "fall through" comments
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21390
diff
changeset
|
541 /* fall through */ |
19709
31389e4b4677
lib: Fixed calling json_parse_skip_next() within arrays
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19708
diff
changeset
|
542 case JSON_STATE_ARRAY_NEXT_SKIP: |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
543 if (*parser->data == ']') |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
544 return json_parse_close_array(parser, type_r); |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
545 if (*parser->data != ',') { |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
546 parser->error = "Expected ',' or '}' after array value"; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
547 return -1; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
548 } |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
549 parser->state = JSON_STATE_ARRAY_VALUE; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
550 parser->data++; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
551 json_parser_update_input_pos(parser); |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
552 return 0; |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
553 case JSON_STATE_OBJECT_SKIP_STRING: |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
554 case JSON_STATE_ARRAY_SKIP_STRING: |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
555 if (json_skip_string(parser) <= 0) |
15437
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
556 return -1; |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
557 parser->state = parser->state == JSON_STATE_OBJECT_SKIP_STRING ? |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
558 JSON_STATE_OBJECT_NEXT : JSON_STATE_ARRAY_NEXT; |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
559 return 0; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
560 case JSON_STATE_DONE: |
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
561 parser->error = "Unexpected data at the end"; |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
562 return -1; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
563 } |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
564 json_parser_update_input_pos(parser); |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
565 return skipping ? 0 : 1; |
14783
01cdca5817f2
Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
566 } |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
567 |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
568 int json_parse_next(struct json_parser *parser, enum json_type *type_r, |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
569 const char **value_r) |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
570 { |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
571 int ret; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
572 |
15437
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
573 i_assert(parser->strinput == NULL); |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
574 |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
575 *value_r = NULL; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
576 |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
577 while ((ret = json_parser_read_more(parser)) > 0) { |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
578 while ((ret = json_try_parse_next(parser, type_r, value_r)) == 0) |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
579 ; |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
580 if (ret > 0) |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
581 break; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
582 if (parser->data != parser->end) |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
583 return -1; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
584 /* parsing probably failed because there wasn't enough input. |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
585 reset the error and try reading more. */ |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
586 parser->error = NULL; |
15491
a1b814081f0c
json-parser: Fixed infinite looping in some situations.
Timo Sirainen <tss@iki.fi>
parents:
15441
diff
changeset
|
587 parser->highwater_offset = parser->input->v_offset + |
a1b814081f0c
json-parser: Fixed infinite looping in some situations.
Timo Sirainen <tss@iki.fi>
parents:
15441
diff
changeset
|
588 i_stream_get_data_size(parser->input); |
15435
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
589 } |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
590 return ret; |
86572582647e
JSON parser supports now nested objects and parsing from non-blocking input stream.
Timo Sirainen <tss@iki.fi>
parents:
15080
diff
changeset
|
591 } |
15437
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
592 |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
593 void json_parse_skip_next(struct json_parser *parser) |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
594 { |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
595 i_assert(!parser->skipping); |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
596 i_assert(parser->strinput == NULL); |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
597 i_assert(parser->state == JSON_STATE_OBJECT_COLON || |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
598 parser->state == JSON_STATE_OBJECT_VALUE || |
19709
31389e4b4677
lib: Fixed calling json_parse_skip_next() within arrays
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19708
diff
changeset
|
599 parser->state == JSON_STATE_ARRAY_VALUE || |
31389e4b4677
lib: Fixed calling json_parse_skip_next() within arrays
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19708
diff
changeset
|
600 parser->state == JSON_STATE_ARRAY_NEXT); |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
601 |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
602 parser->skipping = TRUE; |
19709
31389e4b4677
lib: Fixed calling json_parse_skip_next() within arrays
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19708
diff
changeset
|
603 if (parser->state == JSON_STATE_ARRAY_NEXT) |
31389e4b4677
lib: Fixed calling json_parse_skip_next() within arrays
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19708
diff
changeset
|
604 parser->state = JSON_STATE_ARRAY_NEXT_SKIP; |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
605 } |
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
606 |
15437
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
607 static void json_strinput_destroyed(struct json_parser *parser) |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
608 { |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
609 i_assert(parser->strinput != NULL); |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
610 |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
611 parser->strinput = NULL; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
612 } |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
613 |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
614 static int |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
615 json_try_parse_stream_start(struct json_parser *parser, |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
616 struct istream **input_r) |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
617 { |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
618 if (!json_parse_whitespace(parser)) |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
619 return -1; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
620 |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
621 if (parser->state == JSON_STATE_OBJECT_COLON) { |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
622 if (*parser->data != ':') { |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
623 parser->error = "Expected ':' after key"; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
624 return -1; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
625 } |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
626 parser->data++; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
627 parser->state = JSON_STATE_OBJECT_VALUE; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
628 if (!json_parse_whitespace(parser)) |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
629 return -1; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
630 } |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
631 |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
632 if (*parser->data != '"') |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
633 return -1; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
634 parser->data++; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
635 json_parser_update_input_pos(parser); |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
636 |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
637 parser->state = parser->state == JSON_STATE_OBJECT_VALUE ? |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
638 JSON_STATE_OBJECT_SKIP_STRING : JSON_STATE_ARRAY_SKIP_STRING; |
15437
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
639 parser->strinput = i_stream_create_jsonstr(parser->input); |
16236
81d87e43e167
istream API change: Added support for multiple destroy callbacks.
Timo Sirainen <tss@iki.fi>
parents:
15715
diff
changeset
|
640 i_stream_add_destroy_callback(parser->strinput, |
15437
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
641 json_strinput_destroyed, parser); |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
642 |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
643 *input_r = parser->strinput; |
19784
7fbc18735f8d
lib: json_parse_next_stream() wrongly returned -1 even when a stream was returned.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19735
diff
changeset
|
644 return 0; |
15437
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
645 } |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
646 |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
647 int json_parse_next_stream(struct json_parser *parser, |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
648 struct istream **input_r) |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
649 { |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
650 int ret; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
651 |
15438
4f7e0be9cc35
JSON parser: Added json_parse_skip_next() to skip over unwanted values.
Timo Sirainen <tss@iki.fi>
parents:
15437
diff
changeset
|
652 i_assert(!parser->skipping); |
15437
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
653 i_assert(parser->strinput == NULL); |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
654 i_assert(parser->state == JSON_STATE_OBJECT_COLON || |
15439
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
655 parser->state == JSON_STATE_OBJECT_VALUE || |
f456fffeec5c
JSON parser: Added support for arrays.
Timo Sirainen <tss@iki.fi>
parents:
15438
diff
changeset
|
656 parser->state == JSON_STATE_ARRAY_VALUE); |
15437
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
657 |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
658 *input_r = NULL; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
659 |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
660 while ((ret = json_parser_read_more(parser)) > 0) { |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
661 if (json_try_parse_stream_start(parser, input_r) == 0) |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
662 break; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
663 if (parser->data != parser->end) |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
664 return -1; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
665 /* parsing probably failed because there wasn't enough input. |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
666 reset the error and try reading more. */ |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
667 parser->error = NULL; |
15491
a1b814081f0c
json-parser: Fixed infinite looping in some situations.
Timo Sirainen <tss@iki.fi>
parents:
15441
diff
changeset
|
668 parser->highwater_offset = parser->input->v_offset + |
a1b814081f0c
json-parser: Fixed infinite looping in some situations.
Timo Sirainen <tss@iki.fi>
parents:
15441
diff
changeset
|
669 i_stream_get_data_size(parser->input); |
15437
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
670 } |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
671 return ret; |
014be18f7130
JSON parser: Added support for reading string value as istream.
Timo Sirainen <tss@iki.fi>
parents:
15436
diff
changeset
|
672 } |
15441 | 673 |
19657
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
674 static void json_append_escaped_char(string_t *dest, unsigned char src) |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
675 { |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
676 switch (src) { |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
677 case '\b': |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
678 str_append(dest, "\\b"); |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
679 break; |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
680 case '\f': |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
681 str_append(dest, "\\f"); |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
682 break; |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
683 case '\n': |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
684 str_append(dest, "\\n"); |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
685 break; |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
686 case '\r': |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
687 str_append(dest, "\\r"); |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
688 break; |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
689 case '\t': |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
690 str_append(dest, "\\t"); |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
691 break; |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
692 case '"': |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
693 str_append(dest, "\\\""); |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
694 break; |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
695 case '\\': |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
696 str_append(dest, "\\\\"); |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
697 break; |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
698 default: |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
699 if (src < 32) |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
700 str_printfa(dest, "\\u%04x", src); |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
701 else |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
702 str_append_c(dest, src); |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
703 break; |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
704 } |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
705 } |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
706 |
19735
a3872143befd
lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
19709
diff
changeset
|
707 void ostream_escaped_json_format(string_t *dest, unsigned char src) |
a3872143befd
lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
19709
diff
changeset
|
708 { |
a3872143befd
lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
19709
diff
changeset
|
709 json_append_escaped_char(dest, src); |
a3872143befd
lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
19709
diff
changeset
|
710 } |
a3872143befd
lib: Add ostream-escaped filter
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
19709
diff
changeset
|
711 |
15441 | 712 void json_append_escaped(string_t *dest, const char *src) |
713 { | |
19657
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
714 for (; *src != '\0'; src++) |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
715 json_append_escaped_char(dest, *src); |
15441 | 716 } |
19657
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
717 |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
718 void json_append_escaped_data(string_t *dest, const unsigned char *src, size_t size) |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
719 { |
21322
5ab8dc1a4a6f
global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
20264
diff
changeset
|
720 size_t i; |
19657
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
721 |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
722 for (i = 0; i < size; i++) |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
723 json_append_escaped_char(dest, src[i]); |
ea87c511c6c8
lib: Added json_append_escaped_data() to escape non-NUL terminated input.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19656
diff
changeset
|
724 } |