From: Stephan Bosch Date: Sun, 13 Aug 2023 15:03:27 +0000 (+0200) Subject: lib-json: Add API for formating JSON text stored in memory X-Git-Tag: 2.4.0~2375 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=22d0bbca8c7ca94e3d9abd8abf161f28570f53f1;p=thirdparty%2Fdovecot%2Fcore.git lib-json: Add API for formating JSON text stored in memory --- diff --git a/src/lib-json/Makefile.am b/src/lib-json/Makefile.am index c18c61ea0a..9e020d8cb6 100644 --- a/src/lib-json/Makefile.am +++ b/src/lib-json/Makefile.am @@ -12,7 +12,8 @@ libjson_la_SOURCES = \ json-parser.new.c \ json-generator.c \ json-istream.c \ - json-ostream.c + json-ostream.c \ + json-text.c libjson_la_LIBADD = -lm headers = \ @@ -23,7 +24,8 @@ headers = \ json-parser.new.h \ json-generator.h \ json-istream.h \ - json-ostream.h + json-ostream.h \ + json-text.h test_programs = \ test-json-parser \ diff --git a/src/lib-json/json-generator.c b/src/lib-json/json-generator.c index 93c8c8480f..c6c1adaf26 100644 --- a/src/lib-json/json-generator.c +++ b/src/lib-json/json-generator.c @@ -432,8 +432,6 @@ int json_generator_flush(struct json_generator *generator) return ret; } - // FIXME: add indent - level = array_idx_get_space(&generator->level_stack, generator->level_stack_written); if (level->object) { diff --git a/src/lib-json/json-text.c b/src/lib-json/json-text.c new file mode 100644 index 0000000000..3b2a392a8e --- /dev/null +++ b/src/lib-json/json-text.c @@ -0,0 +1,81 @@ +/* Copyright (c) 2017-2023 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "buffer.h" +#include "istream.h" +#include "ostream.h" + +#include "json-istream.h" +#include "json-ostream.h" +#include "json-text.h" + +int json_text_format_data(const void *data, size_t size, + enum json_parser_flags parser_flags, + const struct json_limits *limits, + const struct json_format *format, + buffer_t *outbuf, const char **error_r) +{ + struct istream *input; + struct ostream *output; + struct json_istream *jinput; + struct json_ostream *joutput; + struct json_node jnode; + int ret; + + *error_r = NULL; + + parser_flags |= JSON_PARSER_FLAG_NUMBERS_AS_STRING; + + input = i_stream_create_from_data(data, size); + + output = o_stream_create_buffer(outbuf); + o_stream_set_no_error_handling(output, TRUE); + + jinput = json_istream_create(input, JSON_ISTREAM_TYPE_NORMAL, limits, + parser_flags); + joutput = json_ostream_create(output, 0); + if (format != NULL) + json_ostream_set_format(joutput, format); + + i_zero(&jnode); + for (;;) { + ret = json_istream_walk_stream(jinput, 16 * IO_BLOCK_SIZE, + IO_BLOCK_SIZE, NULL, &jnode); + i_assert(ret != 0); + if (ret < 0) + break; + json_ostream_nwrite_node(joutput, &jnode); + } + ret = json_ostream_nfinish(joutput); + if (ret < 0) + *error_r = json_ostream_get_error(joutput); + json_ostream_destroy(&joutput); + + if (ret < 0) + json_istream_destroy(&jinput); + else + ret = json_istream_finish(&jinput, error_r); + + i_stream_destroy(&input); + o_stream_destroy(&output); + return ret; +} + +int json_text_format_buffer(const buffer_t *buf, + enum json_parser_flags parser_flags, + const struct json_limits *limits, + const struct json_format *format, + buffer_t *outbuf, const char **error_r) +{ + return json_text_format_data(buf->data, buf->used, parser_flags, + limits, format, outbuf, error_r); +} + +int json_text_format_cstr(const char *str, enum json_parser_flags parser_flags, + const struct json_limits *limits, + const struct json_format *format, + buffer_t *outbuf, const char **error_r) +{ + return json_text_format_data(str, strlen(str), parser_flags, + limits, format, outbuf, error_r); +} diff --git a/src/lib-json/json-text.h b/src/lib-json/json-text.h new file mode 100644 index 0000000000..754c5957c6 --- /dev/null +++ b/src/lib-json/json-text.h @@ -0,0 +1,22 @@ +#ifndef JSON_TEXT_H +#define JSON_TEXT_H + +#include "json-parser.h" +#include "json-generator.h" + +int json_text_format_data(const void *data, size_t size, + enum json_parser_flags parser_flags, + const struct json_limits *limits, + const struct json_format *format, + buffer_t *outbuf, const char **error_r); +int json_text_format_buffer(const buffer_t *buf, + enum json_parser_flags parser_flags, + const struct json_limits *limits, + const struct json_format *format, + buffer_t *outbuf, const char **error_r); +int json_text_format_cstr(const char *str, enum json_parser_flags parser_flags, + const struct json_limits *limits, + const struct json_format *format, + buffer_t *outbuf, const char **error_r); + +#endif