json-parser.c revision 4e8e7a93628b4ed60aaaa47c6f72c1433f21e81d
a4544a5a0e622ef69e38641f87ab1b5685e05911Phill Cunnington/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterjson_try_parse_next(struct json_parser *parser, enum json_type *type_r,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster const char **value_r);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic int json_parser_read_more(struct json_parser *parser)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster uoff_t cur_highwater = parser->input->v_offset +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster i_assert(parser->highwater_offset <= cur_highwater);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (parser->highwater_offset == cur_highwater) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster i_assert(parser->highwater_offset < cur_highwater);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster parser->start = parser->data = i_stream_get_data(parser->input, &size);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic void json_parser_update_input_pos(struct json_parser *parser)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster i_stream_skip(parser->input, parser->data - parser->start);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster parser->start = parser->data = i_stream_get_data(parser->input, &size);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /* we skipped over some data and there's still data left.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster no need to read() the next time. */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster parser->highwater_offset = parser->input->v_offset;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstruct json_parser *json_parser_init(struct istream *input)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterint json_parser_deinit(struct json_parser **_parser, const char **error_r)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /* actual parser error */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *error_r = t_strdup_printf("read(%s) failed: %m",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic bool json_parse_whitespace(struct json_parser *parser)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (; parser->data != parser->end; parser->data++) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic int json_parse_string(struct json_parser *parser, const char **value_r)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (; parser->data != parser->end; parser->data++) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /* wait for more data */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (*parser->data < '0' || *parser->data > '9')
61b4091b1d49fc8b736ee1e150a1b76c14f05c91David Lunastatic int json_parse_int(struct json_parser *parser)
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Leestatic int json_parse_number(struct json_parser *parser, const char **value_r)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (parser->data != parser->end && *parser->data == '.') {
return ret;
const char **value_r)
const char **value_r)
int ret;
case JSON_STATE_ROOT:
case JSON_STATE_OBJECT_VALUE:
if (ret == 0) {
case JSON_STATE_OBJECT_OPEN:
case JSON_STATE_OBJECT_KEY:
case JSON_STATE_OBJECT_COLON:
case JSON_STATE_DONE:
const char **value_r)
int ret;
return ret;