From 1d055261b4144dbf86b2658437015b15d4dd9bff Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 4 Sep 2022 00:32:56 +0100 Subject: initial --- include/jsoncons_ext/cbor/cbor_cursor.hpp | 351 ++++++++++++++++++++++++++++++ 1 file changed, 351 insertions(+) create mode 100644 include/jsoncons_ext/cbor/cbor_cursor.hpp (limited to 'include/jsoncons_ext/cbor/cbor_cursor.hpp') diff --git a/include/jsoncons_ext/cbor/cbor_cursor.hpp b/include/jsoncons_ext/cbor/cbor_cursor.hpp new file mode 100644 index 0000000..af0d1a8 --- /dev/null +++ b/include/jsoncons_ext/cbor/cbor_cursor.hpp @@ -0,0 +1,351 @@ +// Copyright 2018 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_CBOR_CBOR_CURSOR_HPP +#define JSONCONS_CBOR_CBOR_CURSOR_HPP + +#include // std::allocator +#include +#include +#include +#include +#include +#include // std::basic_istream +#include +#include +#include +#include +#include +#include +#include + +namespace jsoncons { +namespace cbor { + +template> +class basic_cbor_cursor : public basic_staj_cursor, private virtual ser_context +{ +public: + using source_type = Source; + using char_type = char; + using allocator_type = Allocator; +private: + basic_cbor_parser parser_; + basic_staj_visitor cursor_visitor_; + basic_json_visitor2_to_visitor_adaptor cursor_handler_adaptor_; + bool eof_; + + // Noncopyable and nonmoveable + basic_cbor_cursor(const basic_cbor_cursor&) = delete; + basic_cbor_cursor& operator=(const basic_cbor_cursor&) = delete; + +public: + using string_view_type = string_view; + + template + basic_cbor_cursor(Sourceable&& source, + const cbor_decode_options& options = cbor_decode_options(), + const Allocator& alloc = Allocator()) + : parser_(std::forward(source), options, alloc), + cursor_visitor_(accept_all), + cursor_handler_adaptor_(cursor_visitor_, alloc), + eof_(false) + { + if (!done()) + { + next(); + } + } + + // Constructors that set parse error codes + + template + basic_cbor_cursor(Sourceable&& source, + std::error_code& ec) + : basic_cbor_cursor(std::allocator_arg, Allocator(), + std::forward(source), + cbor_decode_options(), + ec) + { + } + + template + basic_cbor_cursor(Sourceable&& source, + const cbor_decode_options& options, + std::error_code& ec) + : basic_cbor_cursor(std::allocator_arg, Allocator(), + std::forward(source), + options, + ec) + { + } + + template + basic_cbor_cursor(std::allocator_arg_t, const Allocator& alloc, + Sourceable&& source, + const cbor_decode_options& options, + std::error_code& ec) + : parser_(std::forward(source), options, alloc), + cursor_visitor_(accept_all), + cursor_handler_adaptor_(cursor_visitor_, alloc), + eof_(false) + { + if (!done()) + { + next(ec); + } + } + + void reset() + { + parser_.reset(); + cursor_visitor_.reset(); + cursor_handler_adaptor_.reset(); + eof_ = false; + if (!done()) + { + next(); + } + } + + template + void reset(Sourceable&& source) + { + parser_.reset(std::forward(source)); + cursor_visitor_.reset(); + cursor_handler_adaptor_.reset(); + eof_ = false; + if (!done()) + { + next(); + } + } + + void reset(std::error_code& ec) + { + parser_.reset(); + cursor_visitor_.reset(); + cursor_handler_adaptor_.reset(); + eof_ = false; + if (!done()) + { + next(ec); + } + } + + template + void reset(Sourceable&& source, std::error_code& ec) + { + parser_.reset(std::forward(source)); + cursor_visitor_.reset(); + cursor_handler_adaptor_.reset(); + eof_ = false; + if (!done()) + { + next(ec); + } + } + + bool done() const override + { + return parser_.done(); + } + + bool is_typed_array() const + { + return cursor_visitor_.is_typed_array(); + } + + const staj_event& current() const override + { + return cursor_visitor_.event(); + } + + void read_to(basic_json_visitor& visitor) override + { + std::error_code ec; + read_to(visitor, ec); + if (ec) + { + JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); + } + } + + void read_to(basic_json_visitor& visitor, + std::error_code& ec) override + { + if (cursor_visitor_.dump(visitor, *this, ec)) + { + read_next(visitor, ec); + } + } + + void next() override + { + std::error_code ec; + next(ec); + if (ec) + { + JSONCONS_THROW(ser_error(ec,parser_.line(),parser_.column())); + } + } + + void next(std::error_code& ec) override + { + read_next(ec); + } + + const ser_context& context() const override + { + return *this; + } + + bool eof() const + { + return eof_; + } + + std::size_t line() const override + { + return parser_.line(); + } + + std::size_t column() const override + { + return parser_.column(); + } + + friend + staj_filter_view operator|(basic_cbor_cursor& cursor, + std::function pred) + { + return staj_filter_view(cursor, pred); + } + +#if !defined(JSONCONS_NO_DEPRECATED) + + template + JSONCONS_DEPRECATED_MSG("Instead, use pipe syntax for filter") + basic_cbor_cursor(Sourceable&& source, + std::function filter, + const cbor_decode_options& options = cbor_decode_options(), + const Allocator& alloc = Allocator()) + : parser_(std::forward(source), options, alloc), + cursor_visitor_(filter), + cursor_handler_adaptor_(cursor_visitor_, alloc), + eof_(false) + { + if (!done()) + { + next(); + } + } + + template + JSONCONS_DEPRECATED_MSG("Instead, use pipe syntax for filter") + basic_cbor_cursor(Sourceable&& source, + std::function filter, + std::error_code& ec) + : basic_cbor_cursor(std::allocator_arg, Allocator(), + std::forward(source), filter, ec) + { + } + + template + JSONCONS_DEPRECATED_MSG("Instead, use pipe syntax for filter") + basic_cbor_cursor(std::allocator_arg_t, const Allocator& alloc, + Sourceable&& source, + std::function filter, + std::error_code& ec) + : parser_(std::forward(source), alloc), + cursor_visitor_(filter), + cursor_handler_adaptor_(cursor_visitor_, alloc), + eof_(false) + { + if (!done()) + { + next(ec); + } + } + + JSONCONS_DEPRECATED_MSG("Instead, use read_to(basic_json_visitor&)") + void read(basic_json_visitor& visitor) + { + read_to(visitor); + } + + JSONCONS_DEPRECATED_MSG("Instead, use read_to(basic_json_visitor&, std::error_code&)") + void read(basic_json_visitor& visitor, + std::error_code& ec) + { + read_to(visitor, ec); + } +#endif +private: + static bool accept_all(const staj_event&, const ser_context&) + { + return true; + } + + void read_next(std::error_code& ec) + { + if (cursor_visitor_.in_available()) + { + cursor_visitor_.send_available(ec); + } + else + { + parser_.restart(); + while (!parser_.stopped()) + { + parser_.parse(cursor_handler_adaptor_, ec); + if (ec) return; + } + } + } + + void read_next(basic_json_visitor& visitor, std::error_code& ec) + { + { + struct resource_wrapper + { + basic_json_visitor2_to_visitor_adaptor& adaptor; + basic_json_visitor& original; + + resource_wrapper(basic_json_visitor2_to_visitor_adaptor& adaptor, + basic_json_visitor& visitor) + : adaptor(adaptor), original(adaptor.destination()) + { + adaptor.destination(visitor); + } + + ~resource_wrapper() + { + adaptor.destination(original); + } + } wrapper(cursor_handler_adaptor_, visitor); + + parser_.restart(); + while (!parser_.stopped()) + { + parser_.parse(cursor_handler_adaptor_, ec); + if (ec) + { + return; + } + } + } + } +}; + +using cbor_stream_cursor = basic_cbor_cursor; +using cbor_bytes_cursor = basic_cbor_cursor; + +} // namespace cbor +} // namespace jsoncons + +#endif + -- cgit v1.2.3