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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
251 parser->data++;
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
252 if (parser->end - parser->data < 4) {
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
253 /* wait for more data */
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
254 parser->data = parser->end;
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
255 return 0;
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
272 if (parser->data == parser->end)
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
273 return 0;
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
285 int ret;
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
295 if ((ret = json_parse_digits(parser)) <= 0)
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
296 return ret;
14783
01cdca5817f2 Added a simple JSON parser for parsing an object.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
297 }
15436
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
303 int ret;
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
306 if ((ret = json_parse_int(parser)) <= 0)
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
311 if ((ret = json_parse_digits(parser)) <= 0)
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
322 if ((ret = json_parse_digits(parser)) <= 0)
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
337 if (memcmp(parser->data, atom, avail) != 0)
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
338 return -1;
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
339
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
340 /* everything matches so far, but we need more data */
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
341 parser->data += avail;
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
412 int ret;
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
452 *type_r = JSON_TYPE_STRING;
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
453 } else if ((ret = json_parse_number(parser, value_r)) >= 0) {
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
454 *type_r = JSON_TYPE_NUMBER;
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
468 if (ret == 0) {
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
478 return -1;
9a31c44c1184 JSON parser fixes
Timo Sirainen <tss@iki.fi>
parents: 15435
diff changeset
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
009287402687 Added json_append_escaped()
Timo Sirainen <tss@iki.fi>
parents: 15439
diff changeset
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
009287402687 Added json_append_escaped()
Timo Sirainen <tss@iki.fi>
parents: 15439
diff changeset
712 void json_append_escaped(string_t *dest, const char *src)
009287402687 Added json_append_escaped()
Timo Sirainen <tss@iki.fi>
parents: 15439
diff changeset
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
009287402687 Added json_append_escaped()
Timo Sirainen <tss@iki.fi>
parents: 15439
diff changeset
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 }