diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
commit | 6352e8e3196f78388b6c771073f9e03eaa612673 (patch) | |
tree | e23772f79a7fbc41bc9108951e9e136857484bf4 /source/core/StarJsonBuilder.hpp | |
parent | 6741a057e5639280d85d0f88ba26f000baa58f61 (diff) |
everything everywhere
all at once
Diffstat (limited to 'source/core/StarJsonBuilder.hpp')
-rw-r--r-- | source/core/StarJsonBuilder.hpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/source/core/StarJsonBuilder.hpp b/source/core/StarJsonBuilder.hpp new file mode 100644 index 0000000..cd2d42d --- /dev/null +++ b/source/core/StarJsonBuilder.hpp @@ -0,0 +1,104 @@ +#ifndef STAR_JSON_BUILDER_HPP +#define STAR_JSON_BUILDER_HPP + +#include "StarJsonParser.hpp" +#include "StarJson.hpp" + +namespace Star { + +class JsonBuilderStream : public JsonStream { +public: + virtual void beginObject(); + virtual void objectKey(char32_t const* s, size_t len); + virtual void endObject(); + + virtual void beginArray(); + virtual void endArray(); + + virtual void putString(char32_t const* s, size_t len); + virtual void putDouble(char32_t const* s, size_t len); + virtual void putInteger(char32_t const* s, size_t len); + virtual void putBoolean(bool b); + virtual void putNull(); + + virtual void putWhitespace(char32_t const* s, size_t len); + virtual void putColon(); + virtual void putComma(); + + size_t stackSize(); + Json takeTop(); + +private: + void push(Json v); + Json pop(); + void set(Json v); + void pushSentry(); + bool isSentry(); + + List<Maybe<Json>> m_stack; +}; + +template <typename Jsonlike> +class JsonStreamer { +public: + static void toJsonStream(Jsonlike const& val, JsonStream& stream, bool sort); +}; + +template <> +class JsonStreamer<Json> { +public: + static void toJsonStream(Json const& val, JsonStream& stream, bool sort); +}; + +template <typename InputIterator> +Json inputUtf8Json(InputIterator begin, InputIterator end, bool fragment) { + typedef U8ToU32Iterator<InputIterator> Utf32Input; + typedef JsonParser<Utf32Input> Parser; + + JsonBuilderStream stream; + Parser parser(stream); + Utf32Input wbegin(begin); + Utf32Input wend(end); + Utf32Input pend = parser.parse(wbegin, wend, fragment); + + if (parser.error()) + throw JsonParsingException(strf("Error parsing json: %s at %s:%s", parser.error(), parser.line(), parser.column())); + else if (pend != wend) + throw JsonParsingException(strf("Error extra data at end of input at %s:%s", parser.line(), parser.column())); + + return stream.takeTop(); +} + +template <typename OutputIterator> +void outputUtf8Json(Json const& val, OutputIterator out, int pretty, bool sort) { + typedef Utf8OutputIterator<OutputIterator> Utf8Output; + typedef JsonWriter<Utf8Output> Writer; + Writer writer(Utf8Output(out), pretty); + JsonStreamer<Json>::toJsonStream(val, writer, sort); +} + +template <typename InputIterator, typename Stream = JsonBuilderStream, typename Jsonlike = Json> +Jsonlike inputUtf32Json(InputIterator begin, InputIterator end, bool fragment) { + Stream stream; + JsonParser<InputIterator> parser(stream); + + InputIterator pend = parser.parse(begin, end, fragment); + + if (parser.error()) { + throw JsonParsingException(strf("Error parsing json: %s at %s:%s", parser.error(), parser.line(), parser.column())); + } else if (pend != end) { + throw JsonParsingException(strf("Error extra data at end of input at %s:%s", parser.line(), parser.column())); + } + + return stream.takeTop(); +} + +template <typename OutputIterator, typename Jsonlike = Json> +void outputUtf32Json(Jsonlike const& val, OutputIterator out, int pretty, bool sort) { + JsonWriter<OutputIterator> writer(out, pretty); + JsonStreamer<Jsonlike>::toJsonStream(val, writer, sort); +} + +} + +#endif |