From 1d055261b4144dbf86b2658437015b15d4dd9bff Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 4 Sep 2022 00:32:56 +0100 Subject: initial --- include/jsoncons/text_source_adaptor.hpp | 144 +++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 include/jsoncons/text_source_adaptor.hpp (limited to 'include/jsoncons/text_source_adaptor.hpp') diff --git a/include/jsoncons/text_source_adaptor.hpp b/include/jsoncons/text_source_adaptor.hpp new file mode 100644 index 0000000..491e8a6 --- /dev/null +++ b/include/jsoncons/text_source_adaptor.hpp @@ -0,0 +1,144 @@ +// Copyright 2021 Daniel Parker +// Distributed under the Boost license, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See https://github.com/danielaparker/jsoncons for latest version + +#ifndef JSONCONS_TEXT_SOURCE_ADAPTOR_HPP +#define JSONCONS_TEXT_SOURCE_ADAPTOR_HPP + +#include +#include +#include +#include +#include +#include // std::allocator_traits +#include // std::vector +#include +#include // json_errc +#include +#include + +namespace jsoncons { + + // unicode_source_adaptor + + template + class unicode_source_adaptor + { + public: + using value_type = typename Source::value_type; + using source_type = Source; + private: + source_type source_; + bool bof_; + + + public: + template + unicode_source_adaptor(Sourceable&& source) + : source_(std::forward(source)), + bof_(true) + { + } + + bool is_error() const + { + return source_.is_error(); + } + + bool eof() const + { + return source_.eof(); + } + + span read_buffer(std::error_code& ec) + { + if (source_.eof()) + { + return span(); + } + + auto s = source_.read_buffer(); + const value_type* data = s.data(); + std::size_t length = s.size(); + + if (bof_ && length > 0) + { + auto r = unicode_traits::detect_encoding_from_bom(data, length); + if (!(r.encoding == unicode_traits::encoding_kind::utf8 || r.encoding == unicode_traits::encoding_kind::undetected)) + { + ec = json_errc::illegal_unicode_character; + return; + } + length -= (r.ptr - data); + data = r.ptr; + bof_ = false; + } + return span(data, length); + } + }; + + // json_source_adaptor + + template + class json_source_adaptor + { + public: + using value_type = typename Source::value_type; + using value_type = typename Source::value_type; + using source_type = Source; + private: + source_type source_; + bool bof_; + + public: + + template + json_source_adaptor(Sourceable&& source) + : source_(std::forward(source)), + bof_(true) + { + } + + bool is_error() const + { + return source_.is_error(); + } + + bool eof() const + { + return source_.eof(); + } + + span read_buffer(std::error_code& ec) + { + if (source_.eof()) + { + return span(); + } + + auto s = source_.read_buffer(); + const value_type* data = s.data(); + std::size_t length = s.size(); + + if (bof_ && length > 0) + { + auto r = unicode_traits::detect_json_encoding(data, length); + if (!(r.encoding == unicode_traits::encoding_kind::utf8 || r.encoding == unicode_traits::encoding_kind::undetected)) + { + ec = json_errc::illegal_unicode_character; + return span(); + } + length -= (r.ptr - data); + data = r.ptr; + bof_ = false; + } + return span(data, length); + } + }; + +} // namespace jsoncons + +#endif + -- cgit v1.2.3