From 1d055261b4144dbf86b2658437015b15d4dd9bff Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 4 Sep 2022 00:32:56 +0100 Subject: initial --- include/jsoncons/staj2_cursor.hpp | 1178 +++++++++++++++++++++++++++++++++++++ 1 file changed, 1178 insertions(+) create mode 100644 include/jsoncons/staj2_cursor.hpp (limited to 'include/jsoncons/staj2_cursor.hpp') diff --git a/include/jsoncons/staj2_cursor.hpp b/include/jsoncons/staj2_cursor.hpp new file mode 100644 index 0000000..4cbbc2f --- /dev/null +++ b/include/jsoncons/staj2_cursor.hpp @@ -0,0 +1,1178 @@ +// 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_STAJ2_CURSOR_HPP +#define JSONCONS_STAJ2_CURSOR_HPP + +#include // std::allocator +#include +#include +#include +#include +#include // std::enable_if +#include // std::array +#include // std::function +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace jsoncons { + + enum class staj2_event_type + { + begin_array, + end_array, + begin_object, + end_object, + string_value, + byte_string_value, + null_value, + bool_value, + int64_value, + uint64_value, + half_value, + double_value + }; + + template + std::basic_ostream& operator<<(std::basic_ostream& os, staj2_event_type tag) + { + static constexpr const CharT* begin_array_name = JSONCONS_CSTRING_CONSTANT(CharT, "begin_array"); + static constexpr const CharT* end_array_name = JSONCONS_CSTRING_CONSTANT(CharT, "end_array"); + static constexpr const CharT* begin_object_name = JSONCONS_CSTRING_CONSTANT(CharT, "begin_object"); + static constexpr const CharT* end_object_name = JSONCONS_CSTRING_CONSTANT(CharT, "end_object"); + static constexpr const CharT* string_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "string_value"); + static constexpr const CharT* byte_string_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "byte_string_value"); + static constexpr const CharT* null_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "null_value"); + static constexpr const CharT* bool_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "bool_value"); + static constexpr const CharT* uint64_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "uint64_value"); + static constexpr const CharT* int64_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "int64_value"); + static constexpr const CharT* half_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "half_value"); + static constexpr const CharT* double_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "double_value"); + + switch (tag) + { + case staj2_event_type::begin_array: + { + os << begin_array_name; + break; + } + case staj2_event_type::end_array: + { + os << end_array_name; + break; + } + case staj2_event_type::begin_object: + { + os << begin_object_name; + break; + } + case staj2_event_type::end_object: + { + os << end_object_name; + break; + } + case staj2_event_type::string_value: + { + os << string_value_name; + break; + } + case staj2_event_type::byte_string_value: + { + os << byte_string_value_name; + break; + } + case staj2_event_type::null_value: + { + os << null_value_name; + break; + } + case staj2_event_type::bool_value: + { + os << bool_value_name; + break; + } + case staj2_event_type::int64_value: + { + os << int64_value_name; + break; + } + case staj2_event_type::uint64_value: + { + os << uint64_value_name; + break; + } + case staj2_event_type::half_value: + { + os << half_value_name; + break; + } + case staj2_event_type::double_value: + { + os << double_value_name; + break; + } + } + return os; + } + + template + class basic_staj2_event + { + staj2_event_type event_type_; + semantic_tag tag_; + uint64_t ext_tag_; + union + { + bool bool_value_; + int64_t int64_value_; + uint64_t uint64_value_; + uint16_t half_value_; + double double_value_; + const CharT* string_data_; + const uint8_t* byte_string_data_; + } value_; + std::size_t length_; + public: + using string_view_type = jsoncons::basic_string_view; + + basic_staj2_event(staj2_event_type event_type, semantic_tag tag = semantic_tag::none) + : event_type_(event_type), tag_(tag), ext_tag_(0), value_(), length_(0) + { + } + + basic_staj2_event(staj2_event_type event_type, std::size_t length, semantic_tag tag = semantic_tag::none) + : event_type_(event_type), tag_(tag), ext_tag_(0), value_(), length_(length) + { + } + + basic_staj2_event(null_type, semantic_tag tag) + : event_type_(staj2_event_type::null_value), tag_(tag), ext_tag_(0), value_(), length_(0) + { + } + + basic_staj2_event(bool value, semantic_tag tag) + : event_type_(staj2_event_type::bool_value), tag_(tag), ext_tag_(0), length_(0) + { + value_.bool_value_ = value; + } + + basic_staj2_event(int64_t value, semantic_tag tag) + : event_type_(staj2_event_type::int64_value), tag_(tag), ext_tag_(0), length_(0) + { + value_.int64_value_ = value; + } + + basic_staj2_event(uint64_t value, semantic_tag tag) + : event_type_(staj2_event_type::uint64_value), tag_(tag), ext_tag_(0), length_(0) + { + value_.uint64_value_ = value; + } + + basic_staj2_event(half_arg_t, uint16_t value, semantic_tag tag) + : event_type_(staj2_event_type::half_value), tag_(tag), ext_tag_(0), length_(0) + { + value_.half_value_ = value; + } + + basic_staj2_event(double value, semantic_tag tag) + : event_type_(staj2_event_type::double_value), tag_(tag), ext_tag_(0), length_(0) + { + value_.double_value_ = value; + } + + basic_staj2_event(const string_view_type& s, + staj2_event_type event_type, + semantic_tag tag = semantic_tag::none) + : event_type_(event_type), tag_(tag), ext_tag_(0), length_(s.length()) + { + value_.string_data_ = s.data(); + } + + basic_staj2_event(const byte_string_view& s, + staj2_event_type event_type, + semantic_tag tag = semantic_tag::none) + : event_type_(event_type), tag_(tag), ext_tag_(0), length_(s.size()) + { + value_.byte_string_data_ = s.data(); + } + + basic_staj2_event(const byte_string_view& s, + staj2_event_type event_type, + uint64_t ext_tag) + : event_type_(event_type), tag_(semantic_tag::ext), ext_tag_(ext_tag), length_(s.size()) + { + value_.byte_string_data_ = s.data(); + } + + std::size_t size() const + { + return length_; + } + + template + T get() const + { + std::error_code ec; + T val = get(ec); + if (ec) + { + JSONCONS_THROW(ser_error(ec)); + } + return val; + } + + template + typename std::enable_if::value && std::is_same::value, T>::type + get(std::error_code& ec) const + { + converter conv; + switch (event_type_) + { + case staj2_event_type::string_value: + return conv.from(jsoncons::basic_string_view(value_.string_data_, length_), tag(), ec); + case staj2_event_type::byte_string_value: + { + return conv.from(byte_string_view(value_.byte_string_data_,length_), + tag(), + ec); + } + case staj2_event_type::uint64_value: + { + return conv.from(value_.uint64_value_, tag(), ec); + } + case staj2_event_type::int64_value: + { + return conv.from(value_.int64_value_, tag(), ec); + } + case staj2_event_type::half_value: + { + return conv.from(half_arg, value_.half_value_, tag(), ec); + } + case staj2_event_type::double_value: + { + return conv.from(value_.double_value_, tag(), ec); + } + case staj2_event_type::bool_value: + { + return conv.from(value_.bool_value_,tag(),ec); + } + case staj2_event_type::null_value: + { + return conv.from(null_type(),tag(),ec); + } + default: + { + ec = conv_errc::not_string; + return T{}; + } + } + } + + template + typename std::enable_if::value && std::is_same::value, T>::type + get(std::error_code& ec) const + { + T s; + switch (event_type_) + { + case staj2_event_type::string_value: + s = T(value_.string_data_, length_); + break; + default: + ec = conv_errc::not_string_view; + break; + } + return s; + } + + template + typename std::enable_if::value, T>::type + get(std::error_code& ec) const + { + T s; + switch (event_type_) + { + case staj2_event_type::byte_string_value: + s = T(value_.byte_string_data_, length_); + break; + default: + ec = conv_errc::not_byte_string_view; + break; + } + return s; + } + + template + typename std::enable_if::value && + std::is_same::value,T>::type + get(std::error_code& ec) const + { + converter conv; + switch (event_type_) + { + case staj2_event_type::byte_string_value: + return conv.from(byte_string_view(value_.byte_string_data_, length_), tag(), ec); + case staj2_event_type::string_value: + return conv.from(jsoncons::basic_string_view(value_.string_data_, length_), tag(), ec); + default: + ec = conv_errc::not_byte_string; + return T{}; + } + } + + template + typename std::enable_if::value, IntegerType>::type + get(std::error_code& ec) const + { + switch (event_type_) + { + case staj2_event_type::string_value: + { + IntegerType val; + auto result = jsoncons::detail::to_integer(value_.string_data_, length_, val); + if (!result) + { + ec = conv_errc::not_integer; + return IntegerType(); + } + return val; + } + case staj2_event_type::half_value: + return static_cast(value_.half_value_); + case staj2_event_type::double_value: + return static_cast(value_.double_value_); + case staj2_event_type::int64_value: + return static_cast(value_.int64_value_); + case staj2_event_type::uint64_value: + return static_cast(value_.uint64_value_); + case staj2_event_type::bool_value: + return static_cast(value_.bool_value_ ? 1 : 0); + default: + ec = conv_errc::not_integer; + return IntegerType(); + } + } + + template + typename std::enable_if::value, T>::type + get(std::error_code& ec) const + { + return static_cast(as_double(ec)); + } + + template + typename std::enable_if::value, T>::type + get(std::error_code& ec) const + { + return as_bool(ec); + } + + staj2_event_type event_type() const noexcept { return event_type_; } + + semantic_tag tag() const noexcept { return tag_; } + + uint64_t ext_tag() const noexcept { return ext_tag_; } + + private: + + double as_double(std::error_code& ec) const + { + switch (event_type_) + { + case staj2_event_type::string_value: + { + jsoncons::detail::chars_to f; + return f(value_.string_data_, length_); + } + case staj2_event_type::double_value: + return value_.double_value_; + case staj2_event_type::int64_value: + return static_cast(value_.int64_value_); + case staj2_event_type::uint64_value: + return static_cast(value_.uint64_value_); + case staj2_event_type::half_value: + { + double x = binary::decode_half(value_.half_value_); + return static_cast(x); + } + default: + ec = conv_errc::not_double; + return double(); + } + } + + bool as_bool(std::error_code& ec) const + { + switch (event_type_) + { + case staj2_event_type::bool_value: + return value_.bool_value_; + case staj2_event_type::double_value: + return value_.double_value_ != 0.0; + case staj2_event_type::int64_value: + return value_.int64_value_ != 0; + case staj2_event_type::uint64_value: + return value_.uint64_value_ != 0; + default: + ec = conv_errc::not_bool; + return bool(); + } + } + }; + + // basic_staj2_visitor + + enum class staj2_cursor_state + { + typed_array = 1, + multi_dim, + shape + }; + + template + class basic_staj2_visitor : public basic_json_visitor2 + { + using super_type = basic_json_visitor2; + public: + using char_type = CharT; + using typename super_type::string_view_type; + private: + std::function&, const ser_context&)> pred_; + basic_staj2_event event_; + + staj2_cursor_state state_; + typed_array_view data_; + jsoncons::span shape_; + std::size_t index_; + public: + basic_staj2_visitor() + : pred_(accept), event_(staj2_event_type::null_value), + state_(), data_(), shape_(), index_(0) + { + } + + basic_staj2_visitor(std::function&, const ser_context&)> pred) + : pred_(pred), event_(staj2_event_type::null_value), + state_(), data_(), shape_(), index_(0) + { + } + + void reset() + { + event_ = staj2_event_type::null_value; + state_ = {}; + data_ = {}; + shape_ = {}; + index_ = 0; + } + + const basic_staj2_event& event() const + { + return event_; + } + + bool in_available() const + { + return state_ != staj2_cursor_state(); + } + + void send_available(std::error_code& ec) + { + switch (state_) + { + case staj2_cursor_state::typed_array: + advance_typed_array(ec); + break; + case staj2_cursor_state::multi_dim: + case staj2_cursor_state::shape: + advance_multi_dim(ec); + break; + default: + break; + } + } + + bool is_typed_array() const + { + return data_.type() != typed_array_type(); + } + + staj2_cursor_state state() const + { + return state_; + } + + void advance_typed_array(std::error_code& ec) + { + if (is_typed_array()) + { + if (index_ < data_.size()) + { + switch (data_.type()) + { + case typed_array_type::uint8_value: + { + this->uint64_value(data_.data(uint8_array_arg)[index_], semantic_tag::none, ser_context(), ec); + break; + } + case typed_array_type::uint16_value: + { + this->uint64_value(data_.data(uint16_array_arg)[index_], semantic_tag::none, ser_context(), ec); + break; + } + case typed_array_type::uint32_value: + { + this->uint64_value(data_.data(uint32_array_arg)[index_], semantic_tag::none, ser_context(), ec); + break; + } + case typed_array_type::uint64_value: + { + this->uint64_value(data_.data(uint64_array_arg)[index_], semantic_tag::none, ser_context(), ec); + break; + } + case typed_array_type::int8_value: + { + this->int64_value(data_.data(int8_array_arg)[index_], semantic_tag::none, ser_context(), ec); + break; + } + case typed_array_type::int16_value: + { + this->int64_value(data_.data(int16_array_arg)[index_], semantic_tag::none, ser_context(), ec); + break; + } + case typed_array_type::int32_value: + { + this->int64_value(data_.data(int32_array_arg)[index_], semantic_tag::none, ser_context(), ec); + break; + } + case typed_array_type::int64_value: + { + this->int64_value(data_.data(int64_array_arg)[index_], semantic_tag::none, ser_context(), ec); + break; + } + case typed_array_type::half_value: + { + this->half_value(data_.data(half_array_arg)[index_], semantic_tag::none, ser_context(), ec); + break; + } + case typed_array_type::float_value: + { + this->double_value(data_.data(float_array_arg)[index_], semantic_tag::none, ser_context(), ec); + break; + } + case typed_array_type::double_value: + { + this->double_value(data_.data(double_array_arg)[index_], semantic_tag::none, ser_context(), ec); + break; + } + default: + break; + } + ++index_; + } + else + { + this->end_array(); + state_ = staj2_cursor_state(); + data_ = typed_array_view(); + index_ = 0; + } + } + } + + void advance_multi_dim(std::error_code& ec) + { + if (shape_.size() != 0) + { + if (state_ == staj2_cursor_state::multi_dim) + { + this->begin_array(shape_.size(), semantic_tag::none, ser_context(), ec); + state_ = staj2_cursor_state::shape; + } + else if (index_ < shape_.size()) + { + this->uint64_value(shape_[index_], semantic_tag::none, ser_context(), ec); + ++index_; + } + else + { + state_ = staj2_cursor_state(); + this->end_array(ser_context(), ec); + shape_ = jsoncons::span(); + index_ = 0; + } + } + } + + bool dump(basic_json_visitor2& visitor, const ser_context& context, std::error_code& ec) + { + bool more = true; + if (is_typed_array()) + { + if (index_ != 0) + { + more = staj2_to_saj_event(event(), visitor, context, ec); + while (more && is_typed_array()) + { + if (index_ < data_.size()) + { + switch (data_.type()) + { + case typed_array_type::uint8_value: + { + more = visitor.uint64_value(data_.data(uint8_array_arg)[index_]); + break; + } + case typed_array_type::uint16_value: + { + more = visitor.uint64_value(data_.data(uint16_array_arg)[index_]); + break; + } + case typed_array_type::uint32_value: + { + more = visitor.uint64_value(data_.data(uint32_array_arg)[index_]); + break; + } + case typed_array_type::uint64_value: + { + more = visitor.uint64_value(data_.data(uint64_array_arg)[index_]); + break; + } + case typed_array_type::int8_value: + { + more = visitor.int64_value(data_.data(int8_array_arg)[index_]); + break; + } + case typed_array_type::int16_value: + { + more = visitor.int64_value(data_.data(int16_array_arg)[index_]); + break; + } + case typed_array_type::int32_value: + { + more = visitor.int64_value(data_.data(int32_array_arg)[index_]); + break; + } + case typed_array_type::int64_value: + { + more = visitor.int64_value(data_.data(int64_array_arg)[index_]); + break; + } + case typed_array_type::float_value: + { + more = visitor.double_value(data_.data(float_array_arg)[index_]); + break; + } + case typed_array_type::double_value: + { + more = visitor.double_value(data_.data(double_array_arg)[index_]); + break; + } + default: + break; + } + ++index_; + } + else + { + more = visitor.end_array(); + state_ = staj2_cursor_state(); + data_ = typed_array_view(); + index_ = 0; + } + } + } + else + { + switch (data_.type()) + { + case typed_array_type::uint8_value: + { + more = visitor.typed_array(data_.data(uint8_array_arg)); + break; + } + case typed_array_type::uint16_value: + { + more = visitor.typed_array(data_.data(uint16_array_arg)); + break; + } + case typed_array_type::uint32_value: + { + more = visitor.typed_array(data_.data(uint32_array_arg)); + break; + } + case typed_array_type::uint64_value: + { + more = visitor.typed_array(data_.data(uint64_array_arg)); + break; + } + case typed_array_type::int8_value: + { + more = visitor.typed_array(data_.data(int8_array_arg)); + break; + } + case typed_array_type::int16_value: + { + more = visitor.typed_array(data_.data(int16_array_arg)); + break; + } + case typed_array_type::int32_value: + { + more = visitor.typed_array(data_.data(int32_array_arg)); + break; + } + case typed_array_type::int64_value: + { + more = visitor.typed_array(data_.data(int64_array_arg)); + break; + } + case typed_array_type::float_value: + { + more = visitor.typed_array(data_.data(float_array_arg)); + break; + } + case typed_array_type::double_value: + { + more = visitor.typed_array(data_.data(double_array_arg)); + break; + } + default: + break; + } + + state_ = staj2_cursor_state(); + data_ = typed_array_view(); + } + } + else + { + more = staj2_to_saj_event(event(), visitor, context, ec); + } + return more; + } + + private: + static constexpr bool accept(const basic_staj2_event&, const ser_context&) + { + return true; + } + + bool visit_begin_object(semantic_tag tag, const ser_context& context, std::error_code&) override + { + event_ = basic_staj2_event(staj2_event_type::begin_object, tag); + return !pred_(event_, context); + } + + bool visit_begin_object(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code&) override + { + event_ = basic_staj2_event(staj2_event_type::begin_object, length, tag); + return !pred_(event_, context); + } + + bool visit_end_object(const ser_context& context, std::error_code&) override + { + event_ = basic_staj2_event(staj2_event_type::end_object); + return !pred_(event_, context); + } + + bool visit_begin_array(semantic_tag tag, const ser_context& context, std::error_code&) override + { + event_ = basic_staj2_event(staj2_event_type::begin_array, tag); + return !pred_(event_, context); + } + + bool visit_begin_array(std::size_t length, semantic_tag tag, const ser_context& context, std::error_code&) override + { + event_ = basic_staj2_event(staj2_event_type::begin_array, length, tag); + return !pred_(event_, context); + } + + bool visit_end_array(const ser_context& context, std::error_code&) override + { + event_ = basic_staj2_event(staj2_event_type::end_array); + return !pred_(event_, context); + } + + bool visit_null(semantic_tag tag, const ser_context& context, std::error_code&) override + { + event_ = basic_staj2_event(staj2_event_type::null_value, tag); + return !pred_(event_, context); + } + + bool visit_bool(bool value, semantic_tag tag, const ser_context& context, std::error_code&) override + { + event_ = basic_staj2_event(value, tag); + return !pred_(event_, context); + } + + bool visit_string(const string_view_type& s, semantic_tag tag, const ser_context& context, std::error_code&) override + { + event_ = basic_staj2_event(s, staj2_event_type::string_value, tag); + return !pred_(event_, context); + } + + bool visit_byte_string(const byte_string_view& s, + semantic_tag tag, + const ser_context& context, + std::error_code&) override + { + event_ = basic_staj2_event(s, staj2_event_type::byte_string_value, tag); + return !pred_(event_, context); + } + + bool visit_byte_string(const byte_string_view& s, + uint64_t ext_tag, + const ser_context& context, + std::error_code&) override + { + event_ = basic_staj2_event(s, staj2_event_type::byte_string_value, ext_tag); + return !pred_(event_, context); + } + + bool visit_uint64(uint64_t value, + semantic_tag tag, + const ser_context& context, + std::error_code&) override + { + event_ = basic_staj2_event(value, tag); + return !pred_(event_, context); + } + + bool visit_int64(int64_t value, + semantic_tag tag, + const ser_context& context, + std::error_code&) override + { + event_ = basic_staj2_event(value, tag); + return !pred_(event_, context); + } + + bool visit_half(uint16_t value, + semantic_tag tag, + const ser_context& context, + std::error_code&) override + { + event_ = basic_staj2_event(half_arg, value, tag); + return !pred_(event_, context); + } + + bool visit_double(double value, + semantic_tag tag, + const ser_context& context, + std::error_code&) override + { + event_ = basic_staj2_event(value, tag); + return !pred_(event_, context); + } + + bool visit_typed_array(const jsoncons::span& v, + semantic_tag tag, + const ser_context& context, + std::error_code& ec) override + { + state_ = staj2_cursor_state::typed_array; + data_ = typed_array_view(v.data(), v.size()); + index_ = 0; + return this->begin_array(tag, context, ec); + } + + bool visit_typed_array(const jsoncons::span& data, + semantic_tag tag, + const ser_context& context, + std::error_code& ec) override + { + state_ = staj2_cursor_state::typed_array; + data_ = typed_array_view(data.data(), data.size()); + index_ = 0; + return this->begin_array(tag, context, ec); + } + + bool visit_typed_array(const jsoncons::span& data, + semantic_tag tag, + const ser_context& context, + std::error_code& ec) override + { + state_ = staj2_cursor_state::typed_array; + data_ = typed_array_view(data.data(), data.size()); + index_ = 0; + return this->begin_array(tag, context, ec); + } + + bool visit_typed_array(const jsoncons::span& data, + semantic_tag tag, + const ser_context& context, + std::error_code& ec) override + { + state_ = staj2_cursor_state::typed_array; + data_ = typed_array_view(data.data(), data.size()); + index_ = 0; + return this->begin_array(tag, context, ec); + } + + bool visit_typed_array(const jsoncons::span& data, + semantic_tag tag, + const ser_context& context, + std::error_code& ec) override + { + state_ = staj2_cursor_state::typed_array; + data_ = typed_array_view(data.data(), data.size()); + index_ = 0; + return this->begin_array(tag, context, ec); + } + + bool visit_typed_array(const jsoncons::span& data, + semantic_tag tag, + const ser_context& context, + std::error_code& ec) override + { + state_ = staj2_cursor_state::typed_array; + data_ = typed_array_view(data.data(), data.size()); + index_ = 0; + return this->begin_array(tag, context, ec); + } + + bool visit_typed_array(const jsoncons::span& data, + semantic_tag tag, + const ser_context& context, + std::error_code& ec) override + { + state_ = staj2_cursor_state::typed_array; + data_ = typed_array_view(data.data(), data.size()); + index_ = 0; + return this->begin_array(tag, context, ec); + } + + bool visit_typed_array(const jsoncons::span& data, + semantic_tag tag, + const ser_context& context, + std::error_code& ec) override + { + state_ = staj2_cursor_state::typed_array; + data_ = typed_array_view(data.data(), data.size()); + index_ = 0; + return this->begin_array(tag, context, ec); + } + + bool visit_typed_array(half_arg_t, const jsoncons::span& data, + semantic_tag tag, + const ser_context& context, + std::error_code& ec) override + { + state_ = staj2_cursor_state::typed_array; + data_ = typed_array_view(data.data(), data.size()); + index_ = 0; + return this->begin_array(tag, context, ec); + } + + bool visit_typed_array(const jsoncons::span& data, + semantic_tag tag, + const ser_context& context, + std::error_code& ec) override + { + state_ = staj2_cursor_state::typed_array; + data_ = typed_array_view(data.data(), data.size()); + index_ = 0; + return this->begin_array(tag, context, ec); + } + + bool visit_typed_array(const jsoncons::span& data, + semantic_tag tag, + const ser_context& context, + std::error_code& ec) override + { + state_ = staj2_cursor_state::typed_array; + data_ = typed_array_view(data.data(), data.size()); + index_ = 0; + return this->begin_array(tag, context, ec); + } + /* + bool visit_typed_array(const jsoncons::span&, + semantic_tag, + const ser_context&, + std::error_code&) override + { + return true; + } + */ + bool visit_begin_multi_dim(const jsoncons::span& shape, + semantic_tag tag, + const ser_context& context, + std::error_code& ec) override + { + state_ = staj2_cursor_state::multi_dim; + shape_ = shape; + return this->begin_array(2, tag, context, ec); + } + + bool visit_end_multi_dim(const ser_context& context, + std::error_code& ec) override + { + return this->end_array(context, ec); + } + + void visit_flush() override + { + } + }; + + template + bool staj2_to_saj_event(const basic_staj2_event& ev, + basic_json_visitor2& visitor, + const ser_context& context, + std::error_code& ec) + { + switch (ev.event_type()) + { + case staj2_event_type::begin_array: + return visitor.begin_array(ev.tag(), context); + case staj2_event_type::end_array: + return visitor.end_array(context); + case staj2_event_type::begin_object: + return visitor.begin_object(ev.tag(), context, ec); + case staj2_event_type::end_object: + return visitor.end_object(context, ec); + case staj2_event_type::string_value: + return visitor.string_value(ev.template get>(), ev.tag(), context); + case staj2_event_type::byte_string_value: + return visitor.byte_string_value(ev.template get(), ev.tag(), context); + case staj2_event_type::null_value: + return visitor.null_value(ev.tag(), context); + case staj2_event_type::bool_value: + return visitor.bool_value(ev.template get(), ev.tag(), context); + case staj2_event_type::int64_value: + return visitor.int64_value(ev.template get(), ev.tag(), context); + case staj2_event_type::uint64_value: + return visitor.uint64_value(ev.template get(), ev.tag(), context); + case staj2_event_type::half_value: + return visitor.half_value(ev.template get(), ev.tag(), context); + case staj2_event_type::double_value: + return visitor.double_value(ev.template get(), ev.tag(), context); + default: + return false; + } + } + + // basic_staj2_cursor + + template + class basic_staj2_cursor + { + public: + virtual ~basic_staj2_cursor() noexcept = default; + + virtual void array_expected(std::error_code& ec) + { + if (!(current().event_type() == staj2_event_type::begin_array || current().event_type() == staj2_event_type::byte_string_value)) + { + ec = conv_errc::not_vector; + } + } + + virtual bool done() const = 0; + + virtual const basic_staj2_event& current() const = 0; + + virtual void read_to(basic_json_visitor2& visitor) = 0; + + virtual void read_to(basic_json_visitor2& visitor, + std::error_code& ec) = 0; + + virtual void next() = 0; + + virtual void next(std::error_code& ec) = 0; + + virtual const ser_context& context() const = 0; + }; + + template + class basic_staj2_filter_view : basic_staj2_cursor + { + basic_staj2_cursor* cursor_; + std::function&, const ser_context&)> pred_; + public: + basic_staj2_filter_view(basic_staj2_cursor& cursor, + std::function&, const ser_context&)> pred) + : cursor_(std::addressof(cursor)), pred_(pred) + { + while (!done() && !pred_(current(),context())) + { + cursor_->next(); + } + } + + bool done() const override + { + return cursor_->done(); + } + + const basic_staj2_event& current() const override + { + return cursor_->current(); + } + + void read_to(basic_json_visitor2& visitor) override + { + cursor_->read_to(visitor); + } + + void read_to(basic_json_visitor2& visitor, + std::error_code& ec) override + { + cursor_->read_to(visitor, ec); + } + + void next() override + { + cursor_->next(); + while (!done() && !pred_(current(),context())) + { + cursor_->next(); + } + } + + void next(std::error_code& ec) override + { + cursor_->next(ec); + while (!done() && !pred_(current(),context()) && !ec) + { + cursor_->next(ec); + } + } + + const ser_context& context() const override + { + return cursor_->context(); + } + + friend + basic_staj2_filter_view operator|(basic_staj2_filter_view& cursor, + std::function&, const ser_context&)> pred) + { + return basic_staj2_filter_view(cursor, pred); + } + }; + + using staj2_event = basic_staj2_event; + using wstaj2_event = basic_staj2_event; + + using staj2_cursor = basic_staj2_cursor; + using wstaj2_cursor = basic_staj2_cursor; + + using staj2_filter_view = basic_staj2_filter_view; + using wstaj2_filter_view = basic_staj2_filter_view; + +} // namespace jsoncons + +#endif + -- cgit v1.2.3