diff --git a/invehicle-apps/3rd-party-libs/jsoncons/LICENSE b/invehicle-apps/3rd-party-libs/jsoncons/LICENSE deleted file mode 100644 index d508ab0..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright Daniel Parker 2013 - 2017. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/invehicle-apps/3rd-party-libs/jsoncons/basic_json.hpp b/invehicle-apps/3rd-party-libs/jsoncons/basic_json.hpp new file mode 100644 index 0000000..79340c7 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/basic_json.hpp @@ -0,0 +1,5236 @@ +// Copyright 2013 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_BASIC_JSON_HPP +#define JSONCONS_BASIC_JSON_HPP + +#include // std::numeric_limits +#include +#include +#include +#include +#include +#include // std::allocator +#include +#include // std::memcpy +#include // std::swap +#include // std::initializer_list +#include // std::move +#include // std::enable_if +#include // std::basic_istream +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace jsoncons { + +struct sorted_policy +{ + static constexpr bool preserve_order = false; + + template + using sequence_container_type = std::vector; + + template + using key_storage = std::basic_string; + + template + using string_storage = std::basic_string; + + typedef default_json_parsing parse_error_handler_type; +}; + +struct preserve_order_policy : public sorted_policy +{ + static constexpr bool preserve_order = true; +}; + +template +class range +{ + IteratorT first_; + IteratorT last_; +public: + range(const IteratorT& first, const IteratorT& last) + : first_(first), last_(last) + { + } + +public: + IteratorT begin() + { + return first_; + } + IteratorT end() + { + return last_; + } +}; + +enum class storage_type : uint8_t +{ + null_val = 0x00, + bool_val = 0x01, + int64_val = 0x02, + uint64_val = 0x03, + double_val = 0x04, + short_string_val = 0x05, + long_string_val = 0x06, + byte_string_val = 0x07, + array_val = 0x08, + empty_object_val = 0x09, + object_val = 0x0a, + tag_val = 0x0b +}; + +template +class basic_json +{ +public: + + typedef Allocator allocator_type; + + typedef ImplementationPolicy implementation_policy; + + typedef typename ImplementationPolicy::parse_error_handler_type parse_error_handler_type; + + typedef CharT char_type; + typedef std::char_traits char_traits_type; + typedef basic_string_view string_view_type; + + typedef typename std::allocator_traits:: template rebind_alloc char_allocator_type; + + typedef std::basic_string key_type; + + + typedef basic_json& reference; + typedef const basic_json& const_reference; + typedef basic_json* pointer; + typedef const basic_json* const_pointer; + + typedef key_value key_value_type; + +#if !defined(JSONCONS_NO_DEPRECATED) + JSONCONS_DEPRECATED("instead, use basic_json") typedef basic_json value_type; + JSONCONS_DEPRECATED("instead, use basic_json") typedef basic_json json_type; + JSONCONS_DEPRECATED("instead, use basic_string") typedef std::basic_string string_type; + JSONCONS_DEPRECATED("instead, use key_value_type") typedef key_value_type kvp_type; + JSONCONS_DEPRECATED("instead, use key_value_type") typedef key_value_type member_type; +#endif + + typedef typename std::allocator_traits:: template rebind_alloc byte_allocator_type; + using byte_string_storage_type = typename implementation_policy::template sequence_container_type; + + typedef json_array array; + + typedef typename std::allocator_traits:: template rebind_alloc key_value_allocator_type; + + typedef json_object object; + + typedef typename std::allocator_traits:: template rebind_alloc array_allocator; + typedef typename std::allocator_traits:: template rebind_alloc object_allocator; + + typedef typename object::iterator object_iterator; + typedef typename object::const_iterator const_object_iterator; + typedef typename array::iterator array_iterator; + typedef typename array::const_iterator const_array_iterator; + + struct variant + { + class data_base + { + static const uint8_t major_type_shift = 0x04; + static const uint8_t additional_information_mask = (1U << 4) - 1; + + uint8_t ext_type_; + public: + data_base(uint8_t type) + : ext_type_(type) + {} + + data_base(storage_type data_type, semantic_tag semantic_type) + : ext_type_((static_cast(data_type) << major_type_shift) | static_cast(semantic_type)) + {} + + uint8_t ext_type() const + { + return ext_type_; + } + + storage_type type() const + { + + uint8_t value = ext_type_ >> major_type_shift; + return static_cast(value); + } + + semantic_tag tag() const + { + uint8_t value = ext_type_ & additional_information_mask; + return static_cast(value); + } + }; + + class null_data final : public data_base + { + public: + null_data() + : data_base(storage_type::null_val, semantic_tag::none) + { + } + null_data(semantic_tag tag) + : data_base(storage_type::null_val, tag) + { + } + }; + + class empty_object_data final : public data_base + { + public: + empty_object_data(semantic_tag tag) + : data_base(storage_type::empty_object_val, tag) + { + } + }; + + class bool_data final : public data_base + { + bool val_; + public: + bool_data(bool val, semantic_tag tag) + : data_base(storage_type::bool_val, tag),val_(val) + { + } + + bool_data(const bool_data& val) + : data_base(val.ext_type()),val_(val.val_) + { + } + + bool value() const + { + return val_; + } + + }; + + class int64_data final : public data_base + { + int64_t val_; + public: + int64_data(int64_t val, + semantic_tag tag = semantic_tag::none) + : data_base(storage_type::int64_val, tag),val_(val) + { + } + + int64_data(const int64_data& val) + : data_base(val.ext_type()),val_(val.val_) + { + } + + int64_t value() const + { + return val_; + } + }; + + class uint64_data final : public data_base + { + uint64_t val_; + public: + uint64_data(uint64_t val, + semantic_tag tag = semantic_tag::none) + : data_base(storage_type::uint64_val, tag),val_(val) + { + } + + uint64_data(const uint64_data& val) + : data_base(val.ext_type()),val_(val.val_) + { + } + + uint64_t value() const + { + return val_; + } + }; + + class double_data final : public data_base + { + double val_; + public: + double_data(double val, + semantic_tag tag = semantic_tag::none) + : data_base(storage_type::double_val, tag), + val_(val) + { + } + + double_data(const double_data& val) + : data_base(val.ext_type()), + val_(val.val_) + { + } + + double value() const + { + return val_; + } + }; + + class short_string_data final : public data_base + { + static const size_t capacity = 14/sizeof(char_type); + uint8_t length_; + char_type data_[capacity]; + public: + static const size_t max_length = (14 / sizeof(char_type)) - 1; + + short_string_data(semantic_tag tag, const char_type* p, uint8_t length) + : data_base(storage_type::short_string_val, tag), length_(length) + { + JSONCONS_ASSERT(length <= max_length); + std::memcpy(data_,p,length*sizeof(char_type)); + data_[length] = 0; + } + + short_string_data(const short_string_data& val) + : data_base(val.ext_type()), length_(val.length_) + { + std::memcpy(data_,val.data_,val.length_*sizeof(char_type)); + data_[length_] = 0; + } + + uint8_t length() const + { + return length_; + } + + const char_type* data() const + { + return data_; + } + + const char_type* c_str() const + { + return data_; + } + }; + + // long_string_data + class long_string_data final : public data_base + { + typedef typename jsoncons::detail::heap_only_string_factory::string_pointer pointer; + + pointer ptr_; + public: + + long_string_data(semantic_tag tag, const char_type* data, size_t length, const Allocator& a) + : data_base(storage_type::long_string_val, tag) + { + ptr_ = jsoncons::detail::heap_only_string_factory::create(data,length,a); + } + + long_string_data(const long_string_data& val) + : data_base(val.ext_type()) + { + ptr_ = jsoncons::detail::heap_only_string_factory::create(val.data(),val.length(),val.get_allocator()); + } + + long_string_data(long_string_data&& val) + : data_base(val.ext_type()), ptr_(nullptr) + { + std::swap(val.ptr_,ptr_); + } + + long_string_data(const long_string_data& val, const Allocator& a) + : data_base(val.ext_type()) + { + ptr_ = jsoncons::detail::heap_only_string_factory::create(val.data(),val.length(),a); + } + + ~long_string_data() + { + if (ptr_ != nullptr) + { + jsoncons::detail::heap_only_string_factory::destroy(ptr_); + } + } + + void swap(long_string_data& val) + { + std::swap(val.ptr_,ptr_); + } + + const char_type* data() const + { + return ptr_->data(); + } + + const char_type* c_str() const + { + return ptr_->c_str(); + } + + size_t length() const + { + return ptr_->length(); + } + + allocator_type get_allocator() const + { + return ptr_->get_allocator(); + } + }; + + // byte_string_data + class byte_string_data final : public data_base + { + typedef typename std::allocator_traits:: template rebind_alloc string_holder_allocator_type; + typedef typename std::allocator_traits::pointer pointer; + + pointer ptr_; + + template + void create(string_holder_allocator_type allocator, Args&& ... args) + { + typename std::allocator_traits:: template rebind_alloc alloc(allocator); + ptr_ = alloc.allocate(1); + try + { + std::allocator_traits:: template rebind_traits::construct(alloc, jsoncons::detail::to_plain_pointer(ptr_), std::forward(args)...); + } + catch (...) + { + alloc.deallocate(ptr_,1); + throw; + } + } + public: + + byte_string_data(semantic_tag semantic_type, + const uint8_t* data, size_t length, + const Allocator& a) + : data_base(storage_type::byte_string_val, semantic_type) + { + create(string_holder_allocator_type(a), data, data+length, a); + } + + byte_string_data(const byte_string_data& val) + : data_base(val.ext_type()) + { + create(val.ptr_->get_allocator(), *(val.ptr_)); + } + + byte_string_data(byte_string_data&& val) + : data_base(val.ext_type()), ptr_(nullptr) + { + std::swap(val.ptr_,ptr_); + } + + byte_string_data(const byte_string_data& val, const Allocator& a) + : data_base(val.ext_type()) + { + create(string_holder_allocator_type(a), *(val.ptr_), a); + } + + ~byte_string_data() + { + if (ptr_ != nullptr) + { + typename std::allocator_traits:: template rebind_alloc alloc(ptr_->get_allocator()); + std::allocator_traits:: template rebind_traits::destroy(alloc, jsoncons::detail::to_plain_pointer(ptr_)); + alloc.deallocate(ptr_,1); + } + } + + void swap(byte_string_data& val) + { + std::swap(val.ptr_,ptr_); + } + + const uint8_t* data() const + { + return ptr_->data(); + } + + size_t length() const + { + return ptr_->size(); + } + + const uint8_t* begin() const + { + return ptr_->data(); + } + + const uint8_t* end() const + { + return ptr_->data() + ptr_->size(); + } + + allocator_type get_allocator() const + { + return ptr_->get_allocator(); + } + }; + + // array_data + class array_data final : public data_base + { + typedef typename std::allocator_traits::pointer pointer; + pointer ptr_; + + template + void create(array_allocator allocator, Args&& ... args) + { + typename std::allocator_traits:: template rebind_alloc alloc(allocator); + ptr_ = alloc.allocate(1); + try + { + std::allocator_traits:: template rebind_traits::construct(alloc, jsoncons::detail::to_plain_pointer(ptr_), std::forward(args)...); + } + catch (...) + { + alloc.deallocate(ptr_,1); + throw; + } + } + public: + array_data(const array& val, semantic_tag tag) + : data_base(storage_type::array_val, tag) + { + create(val.get_allocator(), val); + } + + array_data(const array& val, semantic_tag tag, const Allocator& a) + : data_base(storage_type::array_val, tag) + { + create(array_allocator(a), val, a); + } + + array_data(const array_data& val) + : data_base(val.ext_type()) + { + create(val.ptr_->get_allocator(), *(val.ptr_)); + } + + array_data(array_data&& val) + : data_base(val.ext_type()), ptr_(nullptr) + { + std::swap(val.ptr_, ptr_); + } + + array_data(const array_data& val, const Allocator& a) + : data_base(val.ext_type()) + { + create(array_allocator(a), *(val.ptr_), a); + } + ~array_data() + { + if (ptr_ != nullptr) + { + typename std::allocator_traits:: template rebind_alloc alloc(ptr_->get_allocator()); + std::allocator_traits:: template rebind_traits::destroy(alloc, jsoncons::detail::to_plain_pointer(ptr_)); + alloc.deallocate(ptr_,1); + } + } + + allocator_type get_allocator() const + { + return ptr_->get_allocator(); + } + + void swap(array_data& val) + { + std::swap(val.ptr_,ptr_); + } + + array& value() + { + return *ptr_; + } + + const array& value() const + { + return *ptr_; + } + }; + + // object_data + class object_data final : public data_base + { + typedef typename std::allocator_traits::pointer pointer; + pointer ptr_; + + template + void create(Allocator allocator, Args&& ... args) + { + typename std::allocator_traits:: template rebind_alloc alloc(allocator); + ptr_ = alloc.allocate(1); + try + { + std::allocator_traits:: template rebind_traits::construct(alloc, jsoncons::detail::to_plain_pointer(ptr_), std::forward(args)...); + } + catch (...) + { + alloc.deallocate(ptr_,1); + throw; + } + } + public: + explicit object_data(const object& val, semantic_tag tag) + : data_base(storage_type::object_val, tag) + { + create(val.get_allocator(), val); + } + + explicit object_data(const object& val, semantic_tag tag, const Allocator& a) + : data_base(storage_type::object_val, tag) + { + create(object_allocator(a), val, a); + } + + explicit object_data(const object_data& val) + : data_base(val.ext_type()) + { + create(val.ptr_->get_allocator(), *(val.ptr_)); + } + + explicit object_data(object_data&& val) + : data_base(val.ext_type()), ptr_(nullptr) + { + std::swap(val.ptr_,ptr_); + } + + explicit object_data(const object_data& val, const Allocator& a) + : data_base(val.ext_type()) + { + create(object_allocator(a), *(val.ptr_), a); + } + + ~object_data() + { + if (ptr_ != nullptr) + { + typename std::allocator_traits:: template rebind_alloc alloc(ptr_->get_allocator()); + std::allocator_traits:: template rebind_traits::destroy(alloc, jsoncons::detail::to_plain_pointer(ptr_)); + alloc.deallocate(ptr_,1); + } + } + + void swap(object_data& val) + { + std::swap(val.ptr_,ptr_); + } + + object& value() + { + return *ptr_; + } + + const object& value() const + { + return *ptr_; + } + + allocator_type get_allocator() const + { + return ptr_->get_allocator(); + } + }; + + private: + static const size_t data_size = static_max::value; + static const size_t data_align = static_max::value; + + typedef typename std::aligned_storage::type data_t; + + data_t data_; + public: + variant(semantic_tag tag) + { + new(reinterpret_cast(&data_))empty_object_data(tag); + } + + explicit variant(null_type, semantic_tag tag) + { + new(reinterpret_cast(&data_))null_data(tag); + } + + explicit variant(bool val, semantic_tag tag) + { + new(reinterpret_cast(&data_))bool_data(val,tag); + } + explicit variant(int64_t val, semantic_tag tag) + { + new(reinterpret_cast(&data_))int64_data(val, tag); + } + explicit variant(uint64_t val, semantic_tag tag) + { + new(reinterpret_cast(&data_))uint64_data(val, tag); + } + + variant(double val, semantic_tag tag) + { + new(reinterpret_cast(&data_))double_data(val, tag); + } + + variant(const char_type* s, size_t length, semantic_tag tag) + { + if (length <= short_string_data::max_length) + { + new(reinterpret_cast(&data_))short_string_data(tag, s, static_cast(length)); + } + else + { + new(reinterpret_cast(&data_))long_string_data(tag, s, length, char_allocator_type()); + } + } + + variant(const char_type* s, size_t length, semantic_tag tag, const Allocator& alloc) + { + if (length <= short_string_data::max_length) + { + new(reinterpret_cast(&data_))short_string_data(tag, s, static_cast(length)); + } + else + { + new(reinterpret_cast(&data_))long_string_data(tag, s, length, char_allocator_type(alloc)); + } + } + + variant(const byte_string_view& bs, semantic_tag tag) + { + new(reinterpret_cast(&data_))byte_string_data(tag, bs.data(), bs.length(), byte_allocator_type()); + } + + variant(const byte_string_view& bs, semantic_tag tag, const Allocator& allocator) + { + new(reinterpret_cast(&data_))byte_string_data(tag, bs.data(), bs.length(), allocator); + } + + variant(const basic_bignum& n) + { + std::basic_string s; + n.dump(s); + + if (s.length() <= short_string_data::max_length) + { + new(reinterpret_cast(&data_))short_string_data(semantic_tag::bigint, s.data(), static_cast(s.length())); + } + else + { + new(reinterpret_cast(&data_))long_string_data(semantic_tag::bigint, s.data(), s.length(), char_allocator_type()); + } + } + + variant(const basic_bignum& n, const Allocator& allocator) + { + std::basic_string s; + n.dump(s); + + if (s.length() <= short_string_data::max_length) + { + new(reinterpret_cast(&data_))short_string_data(semantic_tag::bigint, s.data(), static_cast(s.length())); + } + else + { + new(reinterpret_cast(&data_))long_string_data(semantic_tag::bigint, s.data(), s.length(), char_allocator_type(allocator)); + } + } + variant(const object& val, semantic_tag tag) + { + new(reinterpret_cast(&data_))object_data(val, tag); + } + variant(const object& val, semantic_tag tag, const Allocator& alloc) + { + new(reinterpret_cast(&data_))object_data(val, tag, alloc); + } + variant(const array& val, semantic_tag tag) + { + new(reinterpret_cast(&data_))array_data(val, tag); + } + variant(const array& val, semantic_tag tag, const Allocator& alloc) + { + new(reinterpret_cast(&data_))array_data(val, tag, alloc); + } + + variant(const variant& val) + { + Init_(val); + } + + variant(const variant& val, const Allocator& allocator) + { + Init_(val,allocator); + } + + variant(variant&& val) noexcept + { + Init_rv_(std::forward(val)); + } + + variant(variant&& val, const Allocator& allocator) noexcept + { + Init_rv_(std::forward(val), allocator, + typename std::allocator_traits::propagate_on_container_move_assignment()); + } + + ~variant() + { + Destroy_(); + } + + void Destroy_() + { + switch (type()) + { + case storage_type::long_string_val: + reinterpret_cast(&data_)->~long_string_data(); + break; + case storage_type::byte_string_val: + reinterpret_cast(&data_)->~byte_string_data(); + break; + case storage_type::array_val: + reinterpret_cast(&data_)->~array_data(); + break; + case storage_type::object_val: + reinterpret_cast(&data_)->~object_data(); + break; + default: + break; + } + } + + variant& operator=(const variant& val) + { + if (this !=&val) + { + Destroy_(); + switch (val.type()) + { + case storage_type::null_val: + new(reinterpret_cast(&data_))null_data(*(val.null_data_cast())); + break; + case storage_type::empty_object_val: + new(reinterpret_cast(&data_))empty_object_data(*(val.empty_object_data_cast())); + break; + case storage_type::bool_val: + new(reinterpret_cast(&data_))bool_data(*(val.bool_data_cast())); + break; + case storage_type::int64_val: + new(reinterpret_cast(&data_))int64_data(*(val.int64_data_cast())); + break; + case storage_type::uint64_val: + new(reinterpret_cast(&data_))uint64_data(*(val.uint64_data_cast())); + break; + case storage_type::double_val: + new(reinterpret_cast(&data_))double_data(*(val.double_data_cast())); + break; + case storage_type::short_string_val: + new(reinterpret_cast(&data_))short_string_data(*(val.short_string_data_cast())); + break; + case storage_type::long_string_val: + new(reinterpret_cast(&data_))long_string_data(*(val.string_data_cast())); + break; + case storage_type::byte_string_val: + new(reinterpret_cast(&data_))byte_string_data(*(val.byte_string_data_cast())); + break; + case storage_type::array_val: + new(reinterpret_cast(&data_))array_data(*(val.array_data_cast())); + break; + case storage_type::object_val: + new(reinterpret_cast(&data_))object_data(*(val.object_data_cast())); + break; + default: + JSONCONS_UNREACHABLE(); + break; + } + } + return *this; + } + + variant& operator=(variant&& val) noexcept + { + if (this !=&val) + { + swap(val); + } + return *this; + } + + storage_type type() const + { + return reinterpret_cast(&data_)->type(); + } + + semantic_tag tag() const + { + return reinterpret_cast(&data_)->tag(); + } + + const null_data* null_data_cast() const + { + return reinterpret_cast(&data_); + } + + const empty_object_data* empty_object_data_cast() const + { + return reinterpret_cast(&data_); + } + + const bool_data* bool_data_cast() const + { + return reinterpret_cast(&data_); + } + + const int64_data* int64_data_cast() const + { + return reinterpret_cast(&data_); + } + + const uint64_data* uint64_data_cast() const + { + return reinterpret_cast(&data_); + } + + const double_data* double_data_cast() const + { + return reinterpret_cast(&data_); + } + + const short_string_data* short_string_data_cast() const + { + return reinterpret_cast(&data_); + } + + long_string_data* string_data_cast() + { + return reinterpret_cast(&data_); + } + + const long_string_data* string_data_cast() const + { + return reinterpret_cast(&data_); + } + + byte_string_data* byte_string_data_cast() + { + return reinterpret_cast(&data_); + } + + const byte_string_data* byte_string_data_cast() const + { + return reinterpret_cast(&data_); + } + + object_data* object_data_cast() + { + return reinterpret_cast(&data_); + } + + const object_data* object_data_cast() const + { + return reinterpret_cast(&data_); + } + + array_data* array_data_cast() + { + return reinterpret_cast(&data_); + } + + const array_data* array_data_cast() const + { + return reinterpret_cast(&data_); + } + + size_t size() const + { + switch (type()) + { + case storage_type::array_val: + return array_data_cast()->value().size(); + case storage_type::object_val: + return object_data_cast()->value().size(); + default: + return 0; + } + } + + string_view_type as_string_view() const + { + switch (type()) + { + case storage_type::short_string_val: + return string_view_type(short_string_data_cast()->data(),short_string_data_cast()->length()); + case storage_type::long_string_val: + return string_view_type(string_data_cast()->data(),string_data_cast()->length()); + default: + JSONCONS_THROW(json_runtime_error("Not a string")); + } + } + + template > + basic_byte_string as_byte_string() const + { + switch (type()) + { + case storage_type::short_string_val: + case storage_type::long_string_val: + { + switch (tag()) + { + case semantic_tag::base16: + { + basic_byte_string bs; + auto s = as_string_view(); + decode_base16(s.begin(), s.end(), bs); + return bs; + } + case semantic_tag::base64: + { + basic_byte_string bs; + auto s = as_string_view(); + decode_base64(s.begin(), s.end(), bs); + return bs; + } + case semantic_tag::base64url: + { + basic_byte_string bs; + auto s = as_string_view(); + decode_base64url(s.begin(), s.end(), bs); + return bs; + } + default: + JSONCONS_THROW(json_runtime_error("Not a byte string")); + } + break; + } + case storage_type::byte_string_val: + return basic_byte_string(byte_string_data_cast()->data(),byte_string_data_cast()->length()); + default: + JSONCONS_THROW(json_runtime_error("Not a byte string")); + } + } + + byte_string_view as_byte_string_view() const + { + switch (type()) + { + case storage_type::byte_string_val: + return byte_string_view(byte_string_data_cast()->data(),byte_string_data_cast()->length()); + default: + JSONCONS_THROW(json_runtime_error("Not a byte string")); + } + } + + template > + basic_bignum as_bignum() const + { + switch (type()) + { + case storage_type::short_string_val: + case storage_type::long_string_val: + if (!jsoncons::detail::is_integer(as_string_view().data(), as_string_view().length())) + { + JSONCONS_THROW(json_runtime_error("Not an integer")); + } + return basic_bignum(as_string_view().data(), as_string_view().length()); + case storage_type::double_val: + return basic_bignum(double_data_cast()->value()); + case storage_type::int64_val: + return basic_bignum(int64_data_cast()->value()); + case storage_type::uint64_val: + return basic_bignum(uint64_data_cast()->value()); + case storage_type::bool_val: + return basic_bignum(bool_data_cast()->value() ? 1 : 0); + default: + JSONCONS_THROW(json_runtime_error("Not a bignum")); + } + } + + bool operator==(const variant& rhs) const + { + if (this ==&rhs) + { + return true; + } + switch (type()) + { + case storage_type::null_val: + switch (rhs.type()) + { + case storage_type::null_val: + return true; + default: + return false; + } + break; + case storage_type::empty_object_val: + switch (rhs.type()) + { + case storage_type::empty_object_val: + return true; + case storage_type::object_val: + return rhs.size() == 0; + default: + return false; + } + break; + case storage_type::bool_val: + switch (rhs.type()) + { + case storage_type::bool_val: + return bool_data_cast()->value() == rhs.bool_data_cast()->value(); + default: + return false; + } + break; + case storage_type::int64_val: + switch (rhs.type()) + { + case storage_type::int64_val: + return int64_data_cast()->value() == rhs.int64_data_cast()->value(); + case storage_type::uint64_val: + return int64_data_cast()->value() >= 0 ? static_cast(int64_data_cast()->value()) == rhs.uint64_data_cast()->value() : false; + case storage_type::double_val: + return static_cast(int64_data_cast()->value()) == rhs.double_data_cast()->value(); + default: + return false; + } + break; + case storage_type::uint64_val: + switch (rhs.type()) + { + case storage_type::int64_val: + return rhs.int64_data_cast()->value() >= 0 ? uint64_data_cast()->value() == static_cast(rhs.int64_data_cast()->value()) : false; + case storage_type::uint64_val: + return uint64_data_cast()->value() == rhs.uint64_data_cast()->value(); + case storage_type::double_val: + return static_cast(uint64_data_cast()->value()) == rhs.double_data_cast()->value(); + default: + return false; + } + break; + case storage_type::double_val: + switch (rhs.type()) + { + case storage_type::int64_val: + return double_data_cast()->value() == static_cast(rhs.int64_data_cast()->value()); + case storage_type::uint64_val: + return double_data_cast()->value() == static_cast(rhs.uint64_data_cast()->value()); + case storage_type::double_val: + return double_data_cast()->value() == rhs.double_data_cast()->value(); + default: + return false; + } + break; + case storage_type::short_string_val: + switch (rhs.type()) + { + case storage_type::short_string_val: + return as_string_view() == rhs.as_string_view(); + case storage_type::long_string_val: + return as_string_view() == rhs.as_string_view(); + default: + return false; + } + break; + case storage_type::long_string_val: + switch (rhs.type()) + { + case storage_type::short_string_val: + return as_string_view() == rhs.as_string_view(); + case storage_type::long_string_val: + return as_string_view() == rhs.as_string_view(); + default: + return false; + } + break; + case storage_type::byte_string_val: + switch (rhs.type()) + { + case storage_type::byte_string_val: + { + return as_byte_string_view() == rhs.as_byte_string_view(); + } + default: + return false; + } + break; + case storage_type::array_val: + switch (rhs.type()) + { + case storage_type::array_val: + return array_data_cast()->value() == rhs.array_data_cast()->value(); + default: + return false; + } + break; + case storage_type::object_val: + switch (rhs.type()) + { + case storage_type::empty_object_val: + return size() == 0; + case storage_type::object_val: + return object_data_cast()->value() == rhs.object_data_cast()->value(); + default: + return false; + } + break; + default: + JSONCONS_UNREACHABLE(); + break; + } + } + + bool operator!=(const variant& rhs) const + { + return !(*this == rhs); + } + + bool operator<(const variant& rhs) const + { + if (this == &rhs) + { + return false; + } + switch (type()) + { + case storage_type::null_val: + return (int)type() < (int)rhs.type(); + case storage_type::empty_object_val: + switch (rhs.type()) + { + case storage_type::empty_object_val: + return false; + case storage_type::object_val: + return rhs.size() != 0; + default: + return (int)type() < (int)rhs.type(); + } + break; + case storage_type::bool_val: + switch (rhs.type()) + { + case storage_type::bool_val: + return bool_data_cast()->value() < rhs.bool_data_cast()->value(); + default: + return (int)type() < (int)rhs.type(); + } + break; + case storage_type::int64_val: + switch (rhs.type()) + { + case storage_type::int64_val: + return int64_data_cast()->value() < rhs.int64_data_cast()->value(); + case storage_type::uint64_val: + return int64_data_cast()->value() >= 0 ? static_cast(int64_data_cast()->value()) < rhs.uint64_data_cast()->value() : true; + case storage_type::double_val: + return static_cast(int64_data_cast()->value()) < rhs.double_data_cast()->value(); + default: + return (int)type() < (int)rhs.type(); + } + break; + case storage_type::uint64_val: + switch (rhs.type()) + { + case storage_type::int64_val: + return rhs.int64_data_cast()->value() >= 0 ? uint64_data_cast()->value() < static_cast(rhs.int64_data_cast()->value()) : true; + case storage_type::uint64_val: + return uint64_data_cast()->value() < rhs.uint64_data_cast()->value(); + case storage_type::double_val: + return static_cast(uint64_data_cast()->value()) < rhs.double_data_cast()->value(); + default: + return (int)type() < (int)rhs.type(); + } + break; + case storage_type::double_val: + switch (rhs.type()) + { + case storage_type::int64_val: + return double_data_cast()->value() < static_cast(rhs.int64_data_cast()->value()); + case storage_type::uint64_val: + return double_data_cast()->value() < static_cast(rhs.uint64_data_cast()->value()); + case storage_type::double_val: + return double_data_cast()->value() < rhs.double_data_cast()->value(); + default: + return (int)type() < (int)rhs.type(); + } + break; + case storage_type::short_string_val: + switch (rhs.type()) + { + case storage_type::short_string_val: + return as_string_view() < rhs.as_string_view(); + case storage_type::long_string_val: + return as_string_view() < rhs.as_string_view(); + default: + return (int)type() < (int)rhs.type(); + } + break; + case storage_type::long_string_val: + switch (rhs.type()) + { + case storage_type::short_string_val: + return as_string_view() < rhs.as_string_view(); + case storage_type::long_string_val: + return as_string_view() < rhs.as_string_view(); + default: + return (int)type() < (int)rhs.type(); + } + break; + case storage_type::byte_string_val: + switch (rhs.type()) + { + case storage_type::byte_string_val: + { + return as_byte_string_view() < rhs.as_byte_string_view(); + } + default: + return (int)type() < (int)rhs.type(); + } + break; + case storage_type::array_val: + switch (rhs.type()) + { + case storage_type::array_val: + return array_data_cast()->value() < rhs.array_data_cast()->value(); + default: + return (int)type() < (int)rhs.type(); + } + break; + case storage_type::object_val: + switch (rhs.type()) + { + case storage_type::empty_object_val: + return false; + case storage_type::object_val: + return object_data_cast()->value() < rhs.object_data_cast()->value(); + default: + return (int)type() < (int)rhs.type(); + } + break; + default: + JSONCONS_UNREACHABLE(); + break; + } + } + + template + typename std::enable_if::pointer>::value,void>::type + swap(variant& other) noexcept + { + if (this ==&other) + { + return; + } + + std::swap(data_,other.data_); + } + + template + typename std::enable_if::pointer>::value, void>::type + swap(variant& other) noexcept + { + if (this ==&other) + { + return; + } + + variant temp(other); + switch (type()) + { + case storage_type::null_val: + new(reinterpret_cast(&(other.data_)))null_data(*null_data_cast()); + break; + case storage_type::empty_object_val: + new(reinterpret_cast(&(other.data_)))empty_object_data(*empty_object_data_cast()); + break; + case storage_type::bool_val: + new(reinterpret_cast(&(other.data_)))bool_data(*bool_data_cast()); + break; + case storage_type::int64_val: + new(reinterpret_cast(&(other.data_)))int64_data(*int64_data_cast()); + break; + case storage_type::uint64_val: + new(reinterpret_cast(&(other.data_)))uint64_data(*uint64_data_cast()); + break; + case storage_type::double_val: + new(reinterpret_cast(&(other.data_)))double_data(*double_data_cast()); + break; + case storage_type::short_string_val: + new(reinterpret_cast(&(other.data_)))short_string_data(*short_string_data_cast()); + break; + case storage_type::long_string_val: + new(reinterpret_cast(&other.data_))long_string_data(std::move(*string_data_cast())); + break; + case storage_type::byte_string_val: + new(reinterpret_cast(&other.data_))byte_string_data(std::move(*byte_string_data_cast())); + break; + case storage_type::array_val: + new(reinterpret_cast(&(other.data_)))array_data(std::move(*array_data_cast())); + break; + case storage_type::object_val: + new(reinterpret_cast(&(other.data_)))object_data(std::move(*object_data_cast())); + break; + default: + JSONCONS_UNREACHABLE(); + break; + } + switch (temp.type()) + { + case storage_type::long_string_val: + new(reinterpret_cast(&data_))long_string_data(std::move(*temp.string_data_cast())); + break; + case storage_type::byte_string_val: + new(reinterpret_cast(&data_))byte_string_data(std::move(*temp.byte_string_data_cast())); + break; + case storage_type::array_val: + new(reinterpret_cast(&(data_)))array_data(std::move(*temp.array_data_cast())); + break; + case storage_type::object_val: + new(reinterpret_cast(&(data_)))object_data(std::move(*temp.object_data_cast())); + break; + default: + std::swap(data_,temp.data_); + break; + } + } + private: + + void Init_(const variant& val) + { + switch (val.type()) + { + case storage_type::null_val: + new(reinterpret_cast(&data_))null_data(*(val.null_data_cast())); + break; + case storage_type::empty_object_val: + new(reinterpret_cast(&data_))empty_object_data(*(val.empty_object_data_cast())); + break; + case storage_type::bool_val: + new(reinterpret_cast(&data_))bool_data(*(val.bool_data_cast())); + break; + case storage_type::int64_val: + new(reinterpret_cast(&data_))int64_data(*(val.int64_data_cast())); + break; + case storage_type::uint64_val: + new(reinterpret_cast(&data_))uint64_data(*(val.uint64_data_cast())); + break; + case storage_type::double_val: + new(reinterpret_cast(&data_))double_data(*(val.double_data_cast())); + break; + case storage_type::short_string_val: + new(reinterpret_cast(&data_))short_string_data(*(val.short_string_data_cast())); + break; + case storage_type::long_string_val: + new(reinterpret_cast(&data_))long_string_data(*(val.string_data_cast())); + break; + case storage_type::byte_string_val: + new(reinterpret_cast(&data_))byte_string_data(*(val.byte_string_data_cast())); + break; + case storage_type::object_val: + new(reinterpret_cast(&data_))object_data(*(val.object_data_cast())); + break; + case storage_type::array_val: + new(reinterpret_cast(&data_))array_data(*(val.array_data_cast())); + break; + default: + break; + } + } + + void Init_(const variant& val, const Allocator& a) + { + switch (val.type()) + { + case storage_type::null_val: + case storage_type::empty_object_val: + case storage_type::bool_val: + case storage_type::int64_val: + case storage_type::uint64_val: + case storage_type::double_val: + case storage_type::short_string_val: + Init_(val); + break; + case storage_type::long_string_val: + new(reinterpret_cast(&data_))long_string_data(*(val.string_data_cast()),a); + break; + case storage_type::byte_string_val: + new(reinterpret_cast(&data_))byte_string_data(*(val.byte_string_data_cast()),a); + break; + case storage_type::array_val: + new(reinterpret_cast(&data_))array_data(*(val.array_data_cast()),a); + break; + case storage_type::object_val: + new(reinterpret_cast(&data_))object_data(*(val.object_data_cast()),a); + break; + default: + break; + } + } + + void Init_rv_(variant&& val) noexcept + { + switch (val.type()) + { + case storage_type::null_val: + case storage_type::empty_object_val: + case storage_type::double_val: + case storage_type::int64_val: + case storage_type::uint64_val: + case storage_type::bool_val: + case storage_type::short_string_val: + Init_(val); + break; + case storage_type::long_string_val: + { + new(reinterpret_cast(&data_))long_string_data(std::move(*val.string_data_cast())); + new(reinterpret_cast(&val.data_))null_data(); + } + break; + case storage_type::byte_string_val: + { + new(reinterpret_cast(&data_))byte_string_data(std::move(*val.byte_string_data_cast())); + new(reinterpret_cast(&val.data_))null_data(); + } + break; + case storage_type::array_val: + { + new(reinterpret_cast(&data_))array_data(std::move(*val.array_data_cast())); + new(reinterpret_cast(&val.data_))null_data(); + } + break; + case storage_type::object_val: + { + new(reinterpret_cast(&data_))object_data(std::move(*val.object_data_cast())); + new(reinterpret_cast(&val.data_))null_data(); + } + break; + default: + JSONCONS_UNREACHABLE(); + break; + } + } + + void Init_rv_(variant&& val, const Allocator&, std::true_type) noexcept + { + Init_rv_(std::forward(val)); + } + + void Init_rv_(variant&& val, const Allocator& a, std::false_type) noexcept + { + switch (val.type()) + { + case storage_type::null_val: + case storage_type::empty_object_val: + case storage_type::double_val: + case storage_type::int64_val: + case storage_type::uint64_val: + case storage_type::bool_val: + case storage_type::short_string_val: + Init_(std::forward(val)); + break; + case storage_type::long_string_val: + { + if (a == val.string_data_cast()->get_allocator()) + { + Init_rv_(std::forward(val), a, std::true_type()); + } + else + { + Init_(val,a); + } + } + break; + case storage_type::byte_string_val: + { + if (a == val.byte_string_data_cast()->get_allocator()) + { + Init_rv_(std::forward(val), a, std::true_type()); + } + else + { + Init_(val,a); + } + } + break; + case storage_type::object_val: + { + if (a == val.object_data_cast()->get_allocator()) + { + Init_rv_(std::forward(val), a, std::true_type()); + } + else + { + Init_(val,a); + } + } + break; + case storage_type::array_val: + { + if (a == val.array_data_cast()->get_allocator()) + { + Init_rv_(std::forward(val), a, std::true_type()); + } + else + { + Init_(val,a); + } + } + break; + default: + break; + } + } + }; + + template + class proxy + { + private: + friend class basic_json; + + ParentT& parent_; + string_view_type key_; + + proxy() = delete; + + proxy(const proxy& other) = default; + proxy(proxy&& other) = default; + proxy& operator = (const proxy& other) = delete; + proxy& operator = (proxy&& other) = delete; + + proxy(ParentT& parent, const string_view_type& key) + : parent_(parent), key_(key) + { + } + + basic_json& evaluate() + { + return parent_.evaluate(key_); + } + + const basic_json& evaluate() const + { + return parent_.evaluate(key_); + } + + basic_json& evaluate_with_default() + { + basic_json& val = parent_.evaluate_with_default(); + auto it = val.find(key_); + if (it == val.object_range().end()) + { + it = val.insert_or_assign(val.object_range().begin(),key_,object(val.object_value().get_allocator())); + } + return it->value(); + } + + basic_json& evaluate(size_t index) + { + return evaluate().at(index); + } + + const basic_json& evaluate(size_t index) const + { + return evaluate().at(index); + } + + basic_json& evaluate(const string_view_type& index) + { + return evaluate().at(index); + } + + const basic_json& evaluate(const string_view_type& index) const + { + return evaluate().at(index); + } + public: + + typedef proxy proxy_type; + + range object_range() + { + return evaluate().object_range(); + } + + range object_range() const + { + return evaluate().object_range(); + } + + range array_range() + { + return evaluate().array_range(); + } + + range array_range() const + { + return evaluate().array_range(); + } + + size_t size() const noexcept + { + try + { + return evaluate().size(); + } + catch (...) + { + return 0; + } + } + + storage_type type() const + { + return evaluate().type(); + } + + semantic_tag tag() const + { + return evaluate().tag(); + } + + size_t count(const string_view_type& name) const + { + return evaluate().count(name); + } + + allocator_type get_allocator() const + { + return evaluate().get_allocator(); + } + + bool contains(const string_view_type& key) const + { + return evaluate().contains(key); + } + + bool is_null() const noexcept + { + try + { + return evaluate().is_null(); + } + catch (...) + { + return false; + } + } + + bool empty() const noexcept + { + try + { + return evaluate().empty(); + } + catch (...) + { + return true; + } + } + + size_t capacity() const + { + return evaluate().capacity(); + } + + void reserve(size_t n) + { + evaluate().reserve(n); + } + + void resize(size_t n) + { + evaluate().resize(n); + } + + template + void resize(size_t n, T val) + { + evaluate().resize(n,val); + } + + template + bool is(Args&&... args) const noexcept + { + try + { + return evaluate().template is(std::forward(args)...); + } + catch (...) + { + return false; + } + } + + bool is_string() const noexcept + { + try + { + return evaluate().is_string(); + } + catch (...) + { + return false; + } + } + + bool is_string_view() const noexcept + { + try + { + return evaluate().is_string_view(); + } + catch (...) + { + return false; + } + } + + bool is_byte_string() const noexcept + { + try + { + return evaluate().is_byte_string(); + } + catch (...) + { + return false; + } + } + + bool is_byte_string_view() const noexcept + { + try + { + return evaluate().is_byte_string_view(); + } + catch (...) + { + return false; + } + } + + bool is_bignum() const noexcept + { + try + { + return evaluate().is_bignum(); + } + catch (...) + { + return false; + } + } + + bool is_number() const noexcept + { + try + { + return evaluate().is_number(); + } + catch (...) + { + return false; + } + } + bool is_bool() const noexcept + { + try + { + return evaluate().is_bool(); + } + catch (...) + { + return false; + } + } + + bool is_object() const noexcept + { + try + { + return evaluate().is_object(); + } + catch (...) + { + return false; + } + } + + bool is_array() const noexcept + { + try + { + return evaluate().is_array(); + } + catch (...) + { + return false; + } + } + + bool is_int64() const noexcept + { + try + { + return evaluate().is_int64(); + } + catch (...) + { + return false; + } + } + + bool is_uint64() const noexcept + { + try + { + return evaluate().is_uint64(); + } + catch (...) + { + return false; + } + } + + bool is_double() const noexcept + { + try + { + return evaluate().is_double(); + } + catch (...) + { + return false; + } + } + + string_view_type as_string_view() const + { + return evaluate().as_string_view(); + } + + byte_string_view as_byte_string_view() const + { + return evaluate().as_byte_string_view(); + } + + basic_bignum as_bignum() const + { + return evaluate().as_bignum(); + } + + template > + std::basic_string as_string() const + { + return evaluate().as_string(); + } + + template > + std::basic_string as_string(const SAllocator& allocator) const + { + return evaluate().as_string(allocator); + } + + template > + basic_byte_string as_byte_string() const + { + return evaluate().template as_byte_string(); + } + + template > + std::basic_string as_string(const basic_json_options& options) const + { + return evaluate().as_string(options); + } + + template > + std::basic_string as_string(const basic_json_options& options, + const SAllocator& allocator) const + { + return evaluate().as_string(options,allocator); + } + + template + T as(Args&&... args) const + { + return evaluate().template as(std::forward(args)...); + } + bool as_bool() const + { + return evaluate().as_bool(); + } + + double as_double() const + { + return evaluate().as_double(); + } + + template + T as_integer() const + { + return evaluate().template as_integer(); + } + + template + proxy& operator=(T&& val) + { + parent_.evaluate_with_default().insert_or_assign(key_, std::forward(val)); + return *this; + } + + bool operator==(const basic_json& rhs) const + { + return evaluate() == rhs; + } + + bool operator!=(const basic_json& rhs) const + { + return evaluate() != rhs; + } + + bool operator<(const basic_json& rhs) const + { + return evaluate() < rhs; + } + + bool operator<=(const basic_json& rhs) const + { + return !(rhs < evaluate()); + } + + bool operator>(const basic_json& rhs) const + { + return !(evaluate() <= rhs); + } + + bool operator>=(const basic_json& rhs) const + { + return !(evaluate() < rhs); + } + + basic_json& operator[](size_t i) + { + return evaluate_with_default().at(i); + } + + const basic_json& operator[](size_t i) const + { + return evaluate().at(i); + } + + proxy_type operator[](const string_view_type& key) + { + return proxy_type(*this,key); + } + + const basic_json& operator[](const string_view_type& name) const + { + return at(name); + } + + basic_json& at(const string_view_type& name) + { + return evaluate().at(name); + } + + const basic_json& at(const string_view_type& name) const + { + return evaluate().at(name); + } + + const basic_json& at(size_t index) + { + return evaluate().at(index); + } + + const basic_json& at(size_t index) const + { + return evaluate().at(index); + } + + object_iterator find(const string_view_type& name) + { + return evaluate().find(name); + } + + const_object_iterator find(const string_view_type& name) const + { + return evaluate().find(name); + } + + template + T get_with_default(const string_view_type& name, const T& default_val) const + { + return evaluate().template get_with_default(name,default_val); + } + + template > + T get_with_default(const string_view_type& name, const char_type* default_val) const + { + return evaluate().template get_with_default(name,default_val); + } + + void shrink_to_fit() + { + evaluate_with_default().shrink_to_fit(); + } + + void clear() + { + evaluate().clear(); + } + // Remove all elements from an array or object + + void erase(const_object_iterator pos) + { + evaluate().erase(pos); + } + // Remove a range of elements from an object + + void erase(const_object_iterator first, const_object_iterator last) + { + evaluate().erase(first, last); + } + // Remove a range of elements from an object + + void erase(const string_view_type& name) + { + evaluate().erase(name); + } + + void erase(const_array_iterator pos) + { + evaluate().erase(pos); + } + // Removes the element at pos + + void erase(const_array_iterator first, const_array_iterator last) + { + evaluate().erase(first, last); + } + // Remove a range of elements from an array + + // merge + + void merge(const basic_json& source) + { + return evaluate().merge(source); + } + + void merge(basic_json&& source) + { + return evaluate().merge(std::forward(source)); + } + + void merge(object_iterator hint, const basic_json& source) + { + return evaluate().merge(hint, source); + } + + void merge(object_iterator hint, basic_json&& source) + { + return evaluate().merge(hint, std::forward(source)); + } + + // merge_or_update + + void merge_or_update(const basic_json& source) + { + return evaluate().merge_or_update(source); + } + + void merge_or_update(basic_json&& source) + { + return evaluate().merge_or_update(std::forward(source)); + } + + void merge_or_update(object_iterator hint, const basic_json& source) + { + return evaluate().merge_or_update(hint, source); + } + + void merge_or_update(object_iterator hint, basic_json&& source) + { + return evaluate().merge_or_update(hint, std::forward(source)); + } + + template + std::pair insert_or_assign(const string_view_type& name, T&& val) + { + return evaluate().insert_or_assign(name,std::forward(val)); + } + + // emplace + + template + std::pair try_emplace(const string_view_type& name, Args&&... args) + { + return evaluate().try_emplace(name,std::forward(args)...); + } + + template + object_iterator insert_or_assign(object_iterator hint, const string_view_type& name, T&& val) + { + return evaluate().insert_or_assign(hint, name, std::forward(val)); + } + + template + object_iterator try_emplace(object_iterator hint, const string_view_type& name, Args&&... args) + { + return evaluate().try_emplace(hint, name, std::forward(args)...); + } + + template + array_iterator emplace(const_array_iterator pos, Args&&... args) + { + evaluate_with_default().emplace(pos, std::forward(args)...); + } + + template + basic_json& emplace_back(Args&&... args) + { + return evaluate_with_default().emplace_back(std::forward(args)...); + } + + template + void push_back(T&& val) + { + evaluate_with_default().push_back(std::forward(val)); + } + + template + array_iterator insert(const_array_iterator pos, T&& val) + { + return evaluate_with_default().insert(pos, std::forward(val)); + } + + template + array_iterator insert(const_array_iterator pos, InputIt first, InputIt last) + { + return evaluate_with_default().insert(pos, first, last); + } + + template + void insert(InputIt first, InputIt last) + { + evaluate_with_default().insert(first, last); + } + + template + void insert(sorted_unique_range_tag tag, InputIt first, InputIt last) + { + evaluate_with_default().insert(tag, first, last); + } + + template > + void dump(std::basic_string& s) const + { + evaluate().dump(s); + } + + template > + void dump(std::basic_string& s, + indenting line_indent) const + { + evaluate().dump(s, line_indent); + } + + template > + void dump(std::basic_string& s, + const basic_json_options& options) const + { + evaluate().dump(s,options); + } + + template > + void dump(std::basic_string& s, + const basic_json_options& options, + indenting line_indent) const + { + evaluate().dump(s,options,line_indent); + } + + void dump(basic_json_content_handler& handler) const + { + evaluate().dump(handler); + } + + void dump(std::basic_ostream& os) const + { + evaluate().dump(os); + } + + void dump(std::basic_ostream& os, indenting line_indent) const + { + evaluate().dump(os, line_indent); + } + + void dump(std::basic_ostream& os, const basic_json_options& options) const + { + evaluate().dump(os,options); + } + + void dump(std::basic_ostream& os, const basic_json_options& options, indenting line_indent) const + { + evaluate().dump(os,options,line_indent); + } + void swap(basic_json& val) + { + evaluate_with_default().swap(val); + } + + friend std::basic_ostream& operator<<(std::basic_ostream& os, const proxy& o) + { + o.dump(os); + return os; + } +#if !defined(JSONCONS_NO_DEPRECATED) + + JSONCONS_DEPRECATED("Instead, use tag()") + semantic_tag get_semantic_tag() const + { + return evaluate().tag(); + } + + JSONCONS_DEPRECATED("Instead, use tag() == semantic_tag::datetime") + bool is_datetime() const noexcept + { + try + { + return evaluate().is_datetime(); + } + catch (...) + { + return false; + } + } + + JSONCONS_DEPRECATED("Instead, use tag() == semantic_tag::timestamp") + bool is_epoch_time() const noexcept + { + try + { + return evaluate().is_epoch_time(); + } + catch (...) + { + return false; + } + } + + template + JSONCONS_DEPRECATED("Instead, use push_back(T&&)") + void add(T&& val) + { + evaluate_with_default().add(std::forward(val)); + } + + template + JSONCONS_DEPRECATED("Instead, use insert(const_array_iterator, T&&)") + array_iterator add(const_array_iterator pos, T&& val) + { + return evaluate_with_default().add(pos, std::forward(val)); + } + + template + JSONCONS_DEPRECATED("Instead, use insert_or_assign(const string_view_type&, T&&)") + std::pair set(const string_view_type& name, T&& val) + { + return evaluate().set(name,std::forward(val)); + } + + template + JSONCONS_DEPRECATED("Instead, use insert_or_assign(object_iterator, const string_view_type&, T&&)") + object_iterator set(object_iterator hint, const string_view_type& name, T&& val) + { + return evaluate().set(hint, name, std::forward(val)); + } + + JSONCONS_DEPRECATED("Instead, use contains(const string_view_type&)") + bool has_key(const string_view_type& name) const + { + return evaluate().contains(name); + } + + JSONCONS_DEPRECATED("Instead, use is_int64()") + bool is_integer() const noexcept + { + try + { + return evaluate().is_int64(); + } + catch (...) + { + return false; + } + } + + JSONCONS_DEPRECATED("Instead, use is_uint64()") + bool is_uinteger() const noexcept + { + try + { + return evaluate().is_uint64(); + } + catch (...) + { + return false; + } + } + + JSONCONS_DEPRECATED("Instead, use is()") + bool is_ulonglong() const noexcept + { + try + { + return evaluate().is_ulonglong(); + } + catch (...) + { + return false; + } + } + + JSONCONS_DEPRECATED("Instead, use is()") + bool is_longlong() const noexcept + { + try + { + return evaluate().is_longlong(); + } + catch (...) + { + return false; + } + } + + JSONCONS_DEPRECATED("Instead, use as()") + int as_int() const + { + return evaluate().as_int(); + } + + JSONCONS_DEPRECATED("Instead, use as()") + unsigned int as_uint() const + { + return evaluate().as_uint(); + } + + JSONCONS_DEPRECATED("Instead, use as()") + long as_long() const + { + return evaluate().as_long(); + } + + JSONCONS_DEPRECATED("Instead, use as()") + unsigned long as_ulong() const + { + return evaluate().as_ulong(); + } + + JSONCONS_DEPRECATED("Instead, use as()") + long long as_longlong() const + { + return evaluate().as_longlong(); + } + + JSONCONS_DEPRECATED("Instead, use is()") + unsigned long long as_ulonglong() const + { + return evaluate().as_ulonglong(); + } + + JSONCONS_DEPRECATED("Instead, use as()") + uint64_t as_uinteger() const + { + return evaluate().as_uinteger(); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&, const basic_json_options&, indenting)") + void dump(std::basic_ostream& os, const basic_json_options& options, bool pprint) const + { + evaluate().dump(os,options,pprint); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&, indenting)") + void dump(std::basic_ostream& os, bool pprint) const + { + evaluate().dump(os, pprint); + } + + template > + JSONCONS_DEPRECATED("Instead, use dump(std::basic_string&)") + std::basic_string to_string(const SAllocator& allocator = SAllocator()) const + { + return evaluate().to_string(allocator); + } + JSONCONS_DEPRECATED("Instead, use dump(basic_json_content_handler&)") + void write(basic_json_content_handler& handler) const + { + evaluate().write(handler); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&)") + void write(std::basic_ostream& os) const + { + evaluate().write(os); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&, const basic_json_options&)") + void write(std::basic_ostream& os, const basic_json_options& options) const + { + evaluate().write(os,options); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&, const basic_json_options&, indenting)") + void write(std::basic_ostream& os, const basic_json_options& options, bool pprint) const + { + evaluate().write(os,options,pprint); + } + + template > + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&, const basic_json_options&)") + std::basic_string to_string(const basic_json_options& options, char_allocator_type& allocator = char_allocator_type()) const + { + return evaluate().to_string(options,allocator); + } + + JSONCONS_DEPRECATED("Instead, use object_range()") + range members() + { + return evaluate().members(); + } + + JSONCONS_DEPRECATED("Instead, use object_range()") + range members() const + { + return evaluate().members(); + } + + JSONCONS_DEPRECATED("Instead, use array_range()") + range elements() + { + return evaluate().elements(); + } + + JSONCONS_DEPRECATED("Instead, use array_range()") + range elements() const + { + return evaluate().elements(); + } + JSONCONS_DEPRECATED("Instead, use dump(basic_json_content_handler&)") + void to_stream(basic_json_content_handler& handler) const + { + evaluate().to_stream(handler); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&)") + void to_stream(std::basic_ostream& os) const + { + evaluate().to_stream(os); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&, const basic_json_options&)") + void to_stream(std::basic_ostream& os, const basic_json_options& options) const + { + evaluate().to_stream(os,options); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&, const basic_json_options&, indenting)") + void to_stream(std::basic_ostream& os, const basic_json_options& options, bool pprint) const + { + evaluate().to_stream(os,options,pprint); + } + + JSONCONS_DEPRECATED("Instead, use resize(size_t)") + void resize_array(size_t n) + { + evaluate().resize_array(n); + } + + template + JSONCONS_DEPRECATED("Instead, use resize(size_t, T)") + void resize_array(size_t n, T val) + { + evaluate().resize_array(n,val); + } + + JSONCONS_DEPRECATED("Instead, use object_range().begin()") + object_iterator begin_members() + { + return evaluate().begin_members(); + } + + JSONCONS_DEPRECATED("Instead, use object_range().begin()") + const_object_iterator begin_members() const + { + return evaluate().begin_members(); + } + + JSONCONS_DEPRECATED("Instead, use object_range().end()") + object_iterator end_members() + { + return evaluate().end_members(); + } + + JSONCONS_DEPRECATED("Instead, use object_range().end()") + const_object_iterator end_members() const + { + return evaluate().end_members(); + } + + JSONCONS_DEPRECATED("Instead, use array_range().begin()") + array_iterator begin_elements() + { + return evaluate().begin_elements(); + } + + JSONCONS_DEPRECATED("Instead, use array_range().begin()") + const_array_iterator begin_elements() const + { + return evaluate().begin_elements(); + } + + JSONCONS_DEPRECATED("Instead, use array_range().end()") + array_iterator end_elements() + { + return evaluate().end_elements(); + } + + JSONCONS_DEPRECATED("Instead, use array_range().end()") + const_array_iterator end_elements() const + { + return evaluate().end_elements(); + } + + template + JSONCONS_DEPRECATED("Instead, use get_with_default(const string_view_type&, T&&)") + basic_json get(const string_view_type& name, T&& default_val) const + { + return evaluate().get(name,std::forward(default_val)); + } + + JSONCONS_DEPRECATED("Instead, use at(const string_view_type&)") + const basic_json& get(const string_view_type& name) const + { + return evaluate().get(name); + } + + JSONCONS_DEPRECATED("Instead, use contains(const string_view_type&)") + bool has_member(const string_view_type& name) const + { + return evaluate().has_member(name); + } + + JSONCONS_DEPRECATED("Instead, use erase(const_object_iterator, const_object_iterator)") + void remove_range(size_t from_index, size_t to_index) + { + evaluate().remove_range(from_index, to_index); + } + JSONCONS_DEPRECATED("Instead, use erase(const string_view_type& name)") + void remove(const string_view_type& name) + { + evaluate().remove(name); + } + JSONCONS_DEPRECATED("Instead, use erase(const string_view_type& name)") + void remove_member(const string_view_type& name) + { + evaluate().remove(name); + } + JSONCONS_DEPRECATED("Instead, use empty()") + bool is_empty() const noexcept + { + return empty(); + } + JSONCONS_DEPRECATED("Instead, use is_number()") + bool is_numeric() const noexcept + { + try + { + return is_number(); + } + catch (...) + { + return false; + } + } +#endif + }; + + typedef proxy proxy_type; + + static basic_json parse(std::basic_istream& is) + { + parse_error_handler_type err_handler; + return parse(is,err_handler); + } + + static basic_json parse(std::basic_istream& is, std::function err_handler) + { + json_decoder handler; + basic_json_reader> reader(is, handler, err_handler); + reader.read_next(); + reader.check_done(); + if (!handler.is_valid()) + { + JSONCONS_THROW(json_runtime_error("Failed to parse json stream")); + } + return handler.get_result(); + } + + static basic_json parse(const string_view_type& s) + { + parse_error_handler_type err_handler; + return parse(s,err_handler); + } + + static basic_json parse(const string_view_type& s, std::function err_handler) + { + json_decoder decoder; + basic_json_parser parser(err_handler); + + auto result = unicons::skip_bom(s.begin(), s.end()); + if (result.ec != unicons::encoding_errc()) + { + throw ser_error(result.ec); + } + size_t offset = result.it - s.begin(); + parser.update(s.data()+offset,s.size()-offset); + parser.parse_some(decoder); + parser.finish_parse(decoder); + parser.check_done(); + if (!decoder.is_valid()) + { + JSONCONS_THROW(json_runtime_error("Failed to parse json string")); + } + return decoder.get_result(); + } + + static basic_json parse(std::basic_istream& is, const basic_json_options& options) + { + parse_error_handler_type err_handler; + return parse(is,options,err_handler); + } + + static basic_json parse(std::basic_istream& is, const basic_json_options& options, std::function err_handler) + { + json_decoder handler; + basic_json_reader> reader(is, handler, options, err_handler); + reader.read_next(); + reader.check_done(); + if (!handler.is_valid()) + { + JSONCONS_THROW(json_runtime_error("Failed to parse json stream")); + } + return handler.get_result(); + } + + static basic_json parse(const string_view_type& s, const basic_json_options& options) + { + parse_error_handler_type err_handler; + return parse(s,options,err_handler); + } + + static basic_json parse(const string_view_type& s, const basic_json_options& options, std::function err_handler) + { + json_decoder decoder; + basic_json_parser parser(options,err_handler); + + auto result = unicons::skip_bom(s.begin(), s.end()); + if (result.ec != unicons::encoding_errc()) + { + throw ser_error(result.ec); + } + size_t offset = result.it - s.begin(); + parser.update(s.data()+offset,s.size()-offset); + parser.parse_some(decoder); + parser.finish_parse(decoder); + parser.check_done(); + if (!decoder.is_valid()) + { + JSONCONS_THROW(json_runtime_error("Failed to parse json string")); + } + return decoder.get_result(); + } + + static basic_json make_array() + { + return basic_json(array()); + } + + static basic_json make_array(const array& a) + { + return basic_json(a); + } + + static basic_json make_array(const array& a, allocator_type allocator) + { + return basic_json(variant(a, semantic_tag::none, allocator)); + } + + static basic_json make_array(std::initializer_list init, const Allocator& allocator = Allocator()) + { + return array(std::move(init),allocator); + } + + static basic_json make_array(size_t n, const Allocator& allocator = Allocator()) + { + return array(n,allocator); + } + + template + static basic_json make_array(size_t n, const T& val, const Allocator& allocator = Allocator()) + { + return basic_json::array(n, val,allocator); + } + + template + static typename std::enable_if::type make_array(size_t n) + { + return array(n); + } + + template + static typename std::enable_if::type make_array(size_t n, const T& val, const Allocator& allocator = Allocator()) + { + return array(n,val,allocator); + } + + template + static typename std::enable_if<(dim>1),basic_json>::type make_array(size_t n, Args... args) + { + const size_t dim1 = dim - 1; + + basic_json val = make_array(std::forward(args)...); + val.resize(n); + for (size_t i = 0; i < n; ++i) + { + val[i] = make_array(std::forward(args)...); + } + return val; + } + + static const basic_json& null() + { + static basic_json a_null = basic_json(null_type(), semantic_tag::none); + return a_null; + } + + variant var_; + + basic_json(semantic_tag tag = semantic_tag::none) + : var_(tag) + { + } + + explicit basic_json(const Allocator& allocator, semantic_tag tag = semantic_tag::none) + : var_(object(allocator),tag) + { + } + + basic_json(const basic_json& val) + : var_(val.var_) + { + } + + basic_json(const basic_json& val, const Allocator& allocator) + : var_(val.var_,allocator) + { + } + + basic_json(basic_json&& other) noexcept + : var_(std::move(other.var_)) + { + } + + basic_json(basic_json&& other, const Allocator&) noexcept + : var_(std::move(other.var_) /*,allocator*/ ) + { + } + + basic_json(const variant& val) + : var_(val) + { + } + + basic_json(variant&& other) + : var_(std::forward(other)) + { + } + + basic_json(const array& val, semantic_tag tag = semantic_tag::none) + : var_(val, tag) + { + } + + basic_json(array&& other, semantic_tag tag = semantic_tag::none) + : var_(std::forward(other), tag) + { + } + + basic_json(const object& other, semantic_tag tag = semantic_tag::none) + : var_(other, tag) + { + } + + basic_json(object&& other, semantic_tag tag = semantic_tag::none) + : var_(std::forward(other), tag) + { + } + + template + basic_json(const proxy& other) + : var_(other.evaluate().var_) + { + } + + template + basic_json(const proxy& other, const Allocator& allocator) + : var_(other.evaluate().var_,allocator) + { + } + + template + basic_json(const T& val) + : var_(json_type_traits::to_json(val).var_) + { + } + + template + basic_json(const T& val, const Allocator& allocator) + : var_(json_type_traits::to_json(val,allocator).var_) + { + } + + basic_json(const char_type* s, semantic_tag tag = semantic_tag::none) + : var_(s, char_traits_type::length(s), tag) + { + } + + basic_json(const char_type* s, const Allocator& allocator) + : var_(s, char_traits_type::length(s), semantic_tag::none, allocator) + { + } + + basic_json(double val, semantic_tag tag) + : var_(val, tag) + { + } + + template + basic_json(T val, semantic_tag tag, typename std::enable_if::value && std::is_signed::value>::type* = 0) + : var_(static_cast(val), tag) + { + } + + template + basic_json(T val, semantic_tag tag, typename std::enable_if::value && !std::is_signed::value>::type* = 0) + : var_(static_cast(val), tag) + { + } + + basic_json(const char_type *s, size_t length, semantic_tag tag = semantic_tag::none) + : var_(s, length, tag) + { + } + + basic_json(const string_view_type& sv, semantic_tag tag) + : var_(sv.data(), sv.length(), tag) + { + } + + basic_json(null_type val, semantic_tag tag) + : var_(val, tag) + { + } + + basic_json(bool val, semantic_tag tag) + : var_(val, tag) + { + } + + basic_json(const string_view_type& sv, semantic_tag tag, const Allocator& allocator) + : var_(sv.data(), sv.length(), tag, allocator) + { + } + + basic_json(const char_type *s, size_t length, + semantic_tag tag, const Allocator& allocator) + : var_(s, length, tag, allocator) + { + } + + explicit basic_json(const byte_string_view& bs, + semantic_tag tag = semantic_tag::none) + : var_(bs, tag) + { + } + + basic_json(const byte_string_view& bs, + semantic_tag tag, + const Allocator& allocator) + : var_(bs, tag, allocator) + { + } + + explicit basic_json(const basic_bignum& bs) + : var_(bs) + { + } + + explicit basic_json(const basic_bignum& bs, const Allocator& allocator) + : var_(bs, byte_allocator_type(allocator)) + { + } + + ~basic_json() + { + } + + basic_json& operator=(const basic_json& rhs) + { + if (this != &rhs) + { + var_ = rhs.var_; + } + return *this; + } + + basic_json& operator=(basic_json&& rhs) noexcept + { + if (this !=&rhs) + { + var_ = std::move(rhs.var_); + } + return *this; + } + + template + basic_json& operator=(const T& val) + { + var_ = json_type_traits::to_json(val).var_; + return *this; + } + + basic_json& operator=(const char_type* s) + { + var_ = variant(s, char_traits_type::length(s), semantic_tag::none); + return *this; + } + + friend bool operator==(const basic_json& lhs, const basic_json& rhs) + { + return lhs.var_ == rhs.var_; + } + + friend bool operator!=(const basic_json& lhs, const basic_json& rhs) + { + return !(lhs == rhs); + } + + friend bool operator<(const basic_json& lhs, const basic_json& rhs) + { + return lhs.var_ < rhs.var_; + } + + friend bool operator<=(const basic_json& lhs, const basic_json& rhs) + { + return !(rhs < lhs); + } + + friend bool operator>(const basic_json& lhs, const basic_json& rhs) + { + return !(lhs <= rhs); + } + + friend bool operator>=(const basic_json& lhs, const basic_json& rhs) + { + return !(lhs < rhs); + } + + size_t size() const noexcept + { + switch (var_.type()) + { + case storage_type::empty_object_val: + return 0; + case storage_type::object_val: + return object_value().size(); + case storage_type::array_val: + return array_value().size(); + default: + return 0; + } + } + + basic_json& operator[](size_t i) + { + return at(i); + } + + const basic_json& operator[](size_t i) const + { + return at(i); + } + + proxy_type operator[](const string_view_type& name) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return proxy_type(*this, name); + break; + default: + JSONCONS_THROW(not_an_object(name.data(),name.length())); + break; + } + } + + const basic_json& operator[](const string_view_type& name) const + { + return at(name); + } + + template > + void dump(std::basic_string& s) const + { + typedef std::basic_string string_type; + basic_json_compressed_encoder> encoder(s); + dump(encoder); + } + + template > + void dump(std::basic_string& s, indenting line_indent) const + { + typedef std::basic_string string_type; + if (line_indent == indenting::indent) + { + basic_json_encoder> encoder(s); + dump(encoder); + } + else + { + basic_json_compressed_encoder> encoder(s); + dump(encoder); + } + } + + template > + void dump(std::basic_string& s, + const basic_json_options& options) const + { + typedef std::basic_string string_type; + basic_json_compressed_encoder> encoder(s, options); + dump(encoder); + } + + template > + void dump(std::basic_string& s, + const basic_json_options& options, + indenting line_indent) const + { + typedef std::basic_string string_type; + if (line_indent == indenting::indent) + { + basic_json_encoder> encoder(s, options); + dump(encoder); + } + else + { + basic_json_compressed_encoder> encoder(s, options); + dump(encoder); + } + } + + void dump(basic_json_content_handler& handler) const + { + dump_noflush(handler); + handler.flush(); + } + + void dump(std::basic_ostream& os) const + { + basic_json_compressed_encoder encoder(os); + dump(encoder); + } + + void dump(std::basic_ostream& os, indenting line_indent) const + { + if (line_indent == indenting::indent) + { + basic_json_encoder encoder(os); + dump(encoder); + } + else + { + basic_json_compressed_encoder encoder(os); + dump(encoder); + } + } + + void dump(std::basic_ostream& os, const basic_json_options& options) const + { + basic_json_compressed_encoder encoder(os, options); + dump(encoder); + } + + void dump(std::basic_ostream& os, const basic_json_options& options, indenting line_indent) const + { + if (line_indent == indenting::indent) + { + basic_json_encoder encoder(os, options); + dump(encoder); + } + else + { + basic_json_compressed_encoder encoder(os, options); + dump(encoder); + } + } + + template > + std::basic_string to_string(const char_allocator_type& allocator=SAllocator()) const noexcept + { + typedef std::basic_string string_type; + string_type s(allocator); + basic_json_compressed_encoder> encoder(s); + dump(encoder); + return s; + } + + template > + std::basic_string to_string(const basic_json_options& options, + const SAllocator& allocator=SAllocator()) const + { + typedef std::basic_string string_type; + string_type s(allocator); + basic_json_compressed_encoder> encoder(s,options); + dump(encoder); + return s; + } + + bool is_null() const noexcept + { + return var_.type() == storage_type::null_val; + } + + allocator_type get_allocator() const + { + switch (var_.type()) + { + case storage_type::long_string_val: + { + return var_.string_data_cast()->get_allocator(); + } + case storage_type::byte_string_val: + { + return var_.byte_string_data_cast()->get_allocator(); + } + case storage_type::array_val: + { + return var_.array_data_cast()->get_allocator(); + } + case storage_type::object_val: + { + return var_.object_data_cast()->get_allocator(); + } + default: + return allocator_type(); + } + } + + bool contains(const string_view_type& key) const + { + switch (var_.type()) + { + case storage_type::object_val: + { + const_object_iterator it = object_value().find(key); + return it != object_range().end(); + } + break; + default: + return false; + } + } + + size_t count(const string_view_type& name) const + { + switch (var_.type()) + { + case storage_type::object_val: + { + auto it = object_value().find(name); + if (it == object_range().end()) + { + return 0; + } + size_t count = 0; + while (it != object_range().end()&& it->key() == name) + { + ++count; + ++it; + } + return count; + } + break; + default: + return 0; + } + } + + template + bool is(Args&&... args) const noexcept + { + return json_type_traits::is(*this,std::forward(args)...); + } + + bool is_string() const noexcept + { + return (var_.type() == storage_type::long_string_val) || (var_.type() == storage_type::short_string_val); + } + + bool is_string_view() const noexcept + { + return is_string(); + } + + bool is_byte_string() const noexcept + { + return var_.type() == storage_type::byte_string_val; + } + + bool is_byte_string_view() const noexcept + { + return is_byte_string(); + } + + bool is_bignum() const + { + switch (type()) + { + case storage_type::short_string_val: + case storage_type::long_string_val: + return jsoncons::detail::is_integer(as_string_view().data(), as_string_view().length()); + case storage_type::int64_val: + case storage_type::uint64_val: + return true; + default: + return false; + } + } + + bool is_bool() const noexcept + { + return var_.type() == storage_type::bool_val; + } + + bool is_object() const noexcept + { + return var_.type() == storage_type::object_val || var_.type() == storage_type::empty_object_val; + } + + bool is_array() const noexcept + { + return var_.type() == storage_type::array_val; + } + + bool is_int64() const noexcept + { + return var_.type() == storage_type::int64_val || (var_.type() == storage_type::uint64_val&& (as_integer() <= static_cast((std::numeric_limits::max)()))); + } + + bool is_uint64() const noexcept + { + return var_.type() == storage_type::uint64_val || (var_.type() == storage_type::int64_val&& as_integer() >= 0); + } + + bool is_double() const noexcept + { + return var_.type() == storage_type::double_val; + } + + bool is_number() const noexcept + { + switch (var_.type()) + { + case storage_type::int64_val: + case storage_type::uint64_val: + case storage_type::double_val: + return true; + case storage_type::short_string_val: + case storage_type::long_string_val: + return var_.tag() == semantic_tag::bigint || + var_.tag() == semantic_tag::bigdec || + var_.tag() == semantic_tag::bigfloat; +#if !defined(JSONCONS_NO_DEPRECATED) + case storage_type::array_val: + return var_.tag() == semantic_tag::bigfloat; +#endif + default: + return false; + } + } + + bool empty() const noexcept + { + switch (var_.type()) + { + case storage_type::byte_string_val: + return var_.byte_string_data_cast()->length() == 0; + break; + case storage_type::short_string_val: + return var_.short_string_data_cast()->length() == 0; + case storage_type::long_string_val: + return var_.string_data_cast()->length() == 0; + case storage_type::array_val: + return array_value().size() == 0; + case storage_type::empty_object_val: + return true; + case storage_type::object_val: + return object_value().size() == 0; + default: + return false; + } + } + + size_t capacity() const + { + switch (var_.type()) + { + case storage_type::array_val: + return array_value().capacity(); + case storage_type::object_val: + return object_value().capacity(); + default: + return 0; + } + } + + template + void create_object_implicitly() + { + static_assert(is_stateless::value, "Cannot create object implicitly - allocator is stateful."); + var_ = variant(object(Allocator()), semantic_tag::none); + } + + void reserve(size_t n) + { + switch (var_.type()) + { + case storage_type::array_val: + array_value().reserve(n); + break; + case storage_type::empty_object_val: + { + create_object_implicitly(); + object_value().reserve(n); + } + break; + case storage_type::object_val: + { + object_value().reserve(n); + } + break; + default: + break; + } + } + + void resize(size_t n) + { + switch (var_.type()) + { + case storage_type::array_val: + array_value().resize(n); + break; + default: + break; + } + } + + template + void resize(size_t n, T val) + { + switch (var_.type()) + { + case storage_type::array_val: + array_value().resize(n, val); + break; + default: + break; + } + } + + template + T as(Args&&... args) const + { + return json_type_traits::as(*this,std::forward(args)...); + } + + bool as_bool() const + { + switch (var_.type()) + { + case storage_type::short_string_val: + case storage_type::long_string_val: + if (var_.tag() == semantic_tag::bigint) + { + return static_cast(var_.as_bignum()); + } + + try + { + basic_json j = basic_json::parse(as_string_view()); + return j.as_bool(); + } + catch (...) + { + JSONCONS_THROW(json_runtime_error("Not a bool")); + } + break; + case storage_type::bool_val: + return var_.bool_data_cast()->value(); + case storage_type::double_val: + return var_.double_data_cast()->value() != 0.0; + case storage_type::int64_val: + return var_.int64_data_cast()->value() != 0; + case storage_type::uint64_val: + return var_.uint64_data_cast()->value() != 0; + default: + JSONCONS_THROW(json_runtime_error("Not a bool")); + } + } + + template + T as_integer() const + { + switch (var_.type()) + { + case storage_type::short_string_val: + case storage_type::long_string_val: + { + auto result = jsoncons::detail::to_integer(as_string_view().data(), as_string_view().length()); + if (result.ec != jsoncons::detail::to_integer_errc()) + { + JSONCONS_THROW(json_runtime_error(make_error_code(result.ec).message())); + } + return result.value; + } + case storage_type::double_val: + return static_cast(var_.double_data_cast()->value()); + case storage_type::int64_val: + return static_cast(var_.int64_data_cast()->value()); + case storage_type::uint64_val: + return static_cast(var_.uint64_data_cast()->value()); + case storage_type::bool_val: + return static_cast(var_.bool_data_cast()->value() ? 1 : 0); + default: + JSONCONS_THROW(json_runtime_error("Not an integer")); + } + } + + double as_double() const + { + switch (var_.type()) + { + case storage_type::short_string_val: + case storage_type::long_string_val: + { + jsoncons::detail::string_to_double to_double; + // to_double() throws std::invalid_argument if conversion fails + return to_double(as_cstring(), as_string_view().length()); + } + case storage_type::double_val: + return var_.double_data_cast()->value(); + case storage_type::int64_val: + return static_cast(var_.int64_data_cast()->value()); + case storage_type::uint64_val: + return static_cast(var_.uint64_data_cast()->value()); +#if !defined(JSONCONS_NO_DEPRECATED) + case storage_type::array_val: + if (tag() == semantic_tag::bigfloat) + { + jsoncons::detail::string_to_double to_double; + auto s = as_string(); + return to_double(s.c_str(), s.length()); + } + else + { + JSONCONS_THROW(json_runtime_error("Not a double")); + } +#endif + default: + JSONCONS_THROW(json_runtime_error("Not a double")); + } + } + + string_view_type as_string_view() const + { + return var_.as_string_view(); + } + + byte_string_view as_byte_string_view() const + { + return var_.as_byte_string_view(); + } + + template > + basic_byte_string as_byte_string() const + { + return var_.template as_byte_string(); + } + + basic_bignum as_bignum() const + { + return var_.as_bignum(); + } + + template > + std::basic_string as_string() const + { + return as_string(basic_json_options(),SAllocator()); + } + + template > + std::basic_string as_string(const SAllocator& allocator) const + { + return as_string(basic_json_options(),allocator); + } + + template > + std::basic_string as_string(const basic_json_options& options) const + { + return as_string(options,SAllocator()); + } + + template > + std::basic_string as_string(const basic_json_options& options, + const SAllocator& allocator) const + { + typedef std::basic_string string_type; + switch (var_.type()) + { + case storage_type::short_string_val: + case storage_type::long_string_val: + { + return string_type(as_string_view().data(),as_string_view().length(),allocator); + } + case storage_type::byte_string_val: + { + string_type s(allocator); + byte_string_chars_format format = jsoncons::detail::resolve_byte_string_chars_format(options.byte_string_format(), + byte_string_chars_format::none, + byte_string_chars_format::base64url); + switch (format) + { + case byte_string_chars_format::base64: + encode_base64(var_.byte_string_data_cast()->begin(), + var_.byte_string_data_cast()->end(), + s); + break; + case byte_string_chars_format::base16: + encode_base16(var_.byte_string_data_cast()->begin(), + var_.byte_string_data_cast()->end(), + s); + break; + default: + encode_base64url(var_.byte_string_data_cast()->begin(), + var_.byte_string_data_cast()->end(), + s); + break; + } + return s; + } + case storage_type::array_val: + { + string_type s(allocator); +#if !defined(JSONCONS_NO_DEPRECATED) + if (tag() == semantic_tag::bigfloat) + { + JSONCONS_ASSERT(size() == 2); + int64_t exp = at(0).template as_integer(); + string_type mantissa = at(1).as_string(); + bignum n(mantissa); + int64_t new_exp = 0; + bignum five(5); + if (exp > 0) + { + new_exp = static_cast(std::floor(exp*std::log(2)/std::log(10))); + bignum five_power = power(five,(unsigned)new_exp); + uint64_t binShift = exp - new_exp; + n = ((n) << (unsigned)binShift)/five_power; + } + else + { + new_exp = static_cast(std::ceil(-exp*std::log(2)/std::log(10))); + bignum five_power = power(five,(unsigned)new_exp); + uint64_t binShift = -exp - new_exp; + n = (n*five_power) >> (unsigned)binShift; + } + + std::string str; + n.dump(str); + if (str[0] == '-') + { + s.push_back('-'); + jsoncons::detail::prettify_string(str.c_str()+1, str.size()-1, -(int)new_exp, -4, 17, s); + } + else + { + jsoncons::detail::prettify_string(str.c_str(), str.size(), -(int)new_exp, -4, 17, s); + } + } + else +#endif + { + basic_json_compressed_encoder> encoder(s,options); + dump(encoder); + } + return s; + } + default: + { + string_type s(allocator); + basic_json_compressed_encoder> encoder(s,options); + dump(encoder); + return s; + } + } + } + + const char_type* as_cstring() const + { + switch (var_.type()) + { + case storage_type::short_string_val: + return var_.short_string_data_cast()->c_str(); + case storage_type::long_string_val: + return var_.string_data_cast()->c_str(); + default: + JSONCONS_THROW(json_runtime_error("Not a cstring")); + } + } + + basic_json& at(const string_view_type& name) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + JSONCONS_THROW(key_not_found(name.data(),name.length())); + case storage_type::object_val: + { + auto it = object_value().find(name); + if (it == object_range().end()) + { + JSONCONS_THROW(key_not_found(name.data(),name.length())); + } + return it->value(); + } + break; + default: + { + JSONCONS_THROW(not_an_object(name.data(),name.length())); + } + } + } + + basic_json& evaluate() + { + return *this; + } + + basic_json& evaluate_with_default() + { + return *this; + } + + const basic_json& evaluate() const + { + return *this; + } + basic_json& evaluate(const string_view_type& name) + { + return at(name); + } + + const basic_json& evaluate(const string_view_type& name) const + { + return at(name); + } + + const basic_json& at(const string_view_type& name) const + { + switch (var_.type()) + { + case storage_type::empty_object_val: + JSONCONS_THROW(key_not_found(name.data(),name.length())); + case storage_type::object_val: + { + auto it = object_value().find(name); + if (it == object_range().end()) + { + JSONCONS_THROW(key_not_found(name.data(),name.length())); + } + return it->value(); + } + break; + default: + { + JSONCONS_THROW(not_an_object(name.data(),name.length())); + } + } + } + + basic_json& at(size_t i) + { + switch (var_.type()) + { + case storage_type::array_val: + if (i >= array_value().size()) + { + JSONCONS_THROW(json_runtime_error("Invalid array subscript")); + } + return array_value().operator[](i); + case storage_type::object_val: + return object_value().at(i); + default: + JSONCONS_THROW(json_runtime_error("Index on non-array value not supported")); + } + } + + const basic_json& at(size_t i) const + { + switch (var_.type()) + { + case storage_type::array_val: + if (i >= array_value().size()) + { + JSONCONS_THROW(json_runtime_error("Invalid array subscript")); + } + return array_value().operator[](i); + case storage_type::object_val: + return object_value().at(i); + default: + JSONCONS_THROW(json_runtime_error("Index on non-array value not supported")); + } + } + + object_iterator find(const string_view_type& name) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + return object_range().end(); + case storage_type::object_val: + return object_value().find(name); + default: + { + JSONCONS_THROW(not_an_object(name.data(),name.length())); + } + } + } + + const_object_iterator find(const string_view_type& name) const + { + switch (var_.type()) + { + case storage_type::empty_object_val: + return object_range().end(); + case storage_type::object_val: + return object_value().find(name); + default: + { + JSONCONS_THROW(not_an_object(name.data(),name.length())); + } + } + } + + template + T get_with_default(const string_view_type& name, const T& default_val) const + { + switch (var_.type()) + { + case storage_type::empty_object_val: + { + return default_val; + } + case storage_type::object_val: + { + const_object_iterator it = object_value().find(name); + if (it != object_range().end()) + { + return it->value().template as(); + } + else + { + return default_val; + } + } + default: + { + JSONCONS_THROW(not_an_object(name.data(),name.length())); + } + } + } + + template> + T get_with_default(const string_view_type& name, const char_type* default_val) const + { + switch (var_.type()) + { + case storage_type::empty_object_val: + { + return T(default_val); + } + case storage_type::object_val: + { + const_object_iterator it = object_value().find(name); + if (it != object_range().end()) + { + return it->value().template as(); + } + else + { + return T(default_val); + } + } + default: + { + JSONCONS_THROW(not_an_object(name.data(),name.length())); + } + } + } + + // Modifiers + + void shrink_to_fit() + { + switch (var_.type()) + { + case storage_type::array_val: + array_value().shrink_to_fit(); + break; + case storage_type::object_val: + object_value().shrink_to_fit(); + break; + default: + break; + } + } + + void clear() + { + switch (var_.type()) + { + case storage_type::array_val: + array_value().clear(); + break; + case storage_type::object_val: + object_value().clear(); + break; + default: + break; + } + } + + void erase(const_object_iterator pos) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + break; + case storage_type::object_val: + object_value().erase(pos); + break; + default: + JSONCONS_THROW(json_runtime_error("Not an object")); + break; + } + } + + void erase(const_object_iterator first, const_object_iterator last) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + break; + case storage_type::object_val: + object_value().erase(first, last); + break; + default: + JSONCONS_THROW(json_runtime_error("Not an object")); + break; + } + } + + void erase(const_array_iterator pos) + { + switch (var_.type()) + { + case storage_type::array_val: + array_value().erase(pos); + break; + default: + JSONCONS_THROW(json_runtime_error("Not an array")); + break; + } + } + + void erase(const_array_iterator first, const_array_iterator last) + { + switch (var_.type()) + { + case storage_type::array_val: + array_value().erase(first, last); + break; + default: + JSONCONS_THROW(json_runtime_error("Not an array")); + break; + } + } + + // Removes all elements from an array value whose index is between from_index, inclusive, and to_index, exclusive. + + void erase(const string_view_type& name) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + break; + case storage_type::object_val: + object_value().erase(name); + break; + default: + JSONCONS_THROW(not_an_object(name.data(),name.length())); + break; + } + } + + template + std::pair insert_or_assign(const string_view_type& name, T&& val) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return object_value().insert_or_assign(name, std::forward(val)); + default: + { + JSONCONS_THROW(not_an_object(name.data(),name.length())); + } + } + } + + template + std::pair try_emplace(const string_view_type& name, Args&&... args) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return object_value().try_emplace(name, std::forward(args)...); + default: + { + JSONCONS_THROW(not_an_object(name.data(),name.length())); + } + } + } + + // merge + + void merge(const basic_json& source) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return object_value().merge(source.object_value()); + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); + } + } + } + + void merge(basic_json&& source) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return object_value().merge(std::move(source.object_value())); + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); + } + } + } + + void merge(object_iterator hint, const basic_json& source) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return object_value().merge(hint, source.object_value()); + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); + } + } + } + + void merge(object_iterator hint, basic_json&& source) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return object_value().merge(hint, std::move(source.object_value())); + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to merge a value that is not an object")); + } + } + } + + // merge_or_update + + void merge_or_update(const basic_json& source) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return object_value().merge_or_update(source.object_value()); + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to merge or update a value that is not an object")); + } + } + } + + void merge_or_update(basic_json&& source) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return object_value().merge_or_update(std::move(source.object_value())); + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to merge or update a value that is not an object")); + } + } + } + + void merge_or_update(object_iterator hint, const basic_json& source) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return object_value().merge_or_update(hint, source.object_value()); + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to merge or update a value that is not an object")); + } + } + } + + void merge_or_update(object_iterator hint, basic_json&& source) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return object_value().merge_or_update(hint, std::move(source.object_value())); + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to merge or update a value that is not an object")); + } + } + } + + template + object_iterator insert_or_assign(object_iterator hint, const string_view_type& name, T&& val) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return object_value().insert_or_assign(hint, name, std::forward(val)); + default: + { + JSONCONS_THROW(not_an_object(name.data(),name.length())); + } + } + } + + template + object_iterator try_emplace(object_iterator hint, const string_view_type& name, Args&&... args) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return object_value().try_emplace(hint, name, std::forward(args)...); + default: + { + JSONCONS_THROW(not_an_object(name.data(),name.length())); + } + } + } + + template + array_iterator insert(const_array_iterator pos, T&& val) + { + switch (var_.type()) + { + case storage_type::array_val: + return array_value().insert(pos, std::forward(val)); + break; + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an array")); + } + } + } + + template + array_iterator insert(const_array_iterator pos, InputIt first, InputIt last) + { + switch (var_.type()) + { + case storage_type::array_val: + return array_value().insert(pos, first, last); + break; + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an array")); + } + } + } + + template + void insert(InputIt first, InputIt last) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + case storage_type::object_val: + return object_value().insert(first, last, get_key_value()); + break; + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an object")); + } + } + } + + template + void insert(sorted_unique_range_tag tag, InputIt first, InputIt last) + { + switch (var_.type()) + { + case storage_type::empty_object_val: + case storage_type::object_val: + return object_value().insert(tag, first, last, get_key_value()); + break; + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an object")); + } + } + } + + template + array_iterator emplace(const_array_iterator pos, Args&&... args) + { + switch (var_.type()) + { + case storage_type::array_val: + return array_value().emplace(pos, std::forward(args)...); + break; + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an array")); + } + } + } + + template + basic_json& emplace_back(Args&&... args) + { + switch (var_.type()) + { + case storage_type::array_val: + return array_value().emplace_back(std::forward(args)...); + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an array")); + } + } + } + + storage_type type() const + { + return var_.type(); + } + + semantic_tag tag() const + { + return var_.tag(); + } + + void swap(basic_json& b) + { + var_.swap(b.var_); + } + + friend void swap(basic_json& a, basic_json& b) + { + a.swap(b); + } + + template + void push_back(T&& val) + { + switch (var_.type()) + { + case storage_type::array_val: + array_value().push_back(std::forward(val)); + break; + default: + { + JSONCONS_THROW(json_runtime_error("Attempting to insert into a value that is not an array")); + } + } + } + +#if !defined(JSONCONS_NO_DEPRECATED) + + JSONCONS_DEPRECATED("Instead, use parse(const string_view_type&)") + static basic_json parse(const char_type* s, size_t length) + { + parse_error_handler_type err_handler; + return parse(s,length,err_handler); + } + + JSONCONS_DEPRECATED("Instead, use parse(const string_view_type&, parse_error_handler)") + static basic_json parse(const char_type* s, size_t length, std::function err_handler) + { + return parse(string_view_type(s,length),err_handler); + } + + JSONCONS_DEPRECATED("Instead, use parse(std::basic_istream&)") + static basic_json parse_file(const std::basic_string& filename) + { + parse_error_handler_type err_handler; + return parse_file(filename,err_handler); + } + + JSONCONS_DEPRECATED("Instead, use parse(std::basic_istream&, std::function)") + static basic_json parse_file(const std::basic_string& filename, + std::function err_handler) + { + std::basic_ifstream is(filename); + return parse(is,err_handler); + } + + JSONCONS_DEPRECATED("Instead, use parse(std::basic_istream&)") + static basic_json parse_stream(std::basic_istream& is) + { + return parse(is); + } + JSONCONS_DEPRECATED("Instead, use parse(std::basic_istream&, std::function)") + static basic_json parse_stream(std::basic_istream& is, std::function err_handler) + { + return parse(is,err_handler); + } + + JSONCONS_DEPRECATED("Instead, use parse(const string_view_type&)") + static basic_json parse_string(const string_view_type& s) + { + return parse(s); + } + + JSONCONS_DEPRECATED("Instead, use parse(parse(const string_view_type&, std::function)") + static basic_json parse_string(const string_view_type& s, std::function err_handler) + { + return parse(s,err_handler); + } + + JSONCONS_DEPRECATED("Instead, use basic_json(double)") + basic_json(double val, uint8_t) + : var_(val, semantic_tag::none) + { + } + + JSONCONS_DEPRECATED("Instead, use basic_json(double,semantic_tag)") + basic_json(double val, + const floating_point_options&, + semantic_tag tag = semantic_tag::none) + : var_(val, tag) + { + } + + JSONCONS_DEPRECATED("Instead, use basic_json(const byte_string_view& ,semantic_tag)") + basic_json(const byte_string_view& bs, + byte_string_chars_format encoding_hint, + semantic_tag tag = semantic_tag::none) + : var_(bs, tag) + { + switch (encoding_hint) + { + { + case byte_string_chars_format::base16: + var_ = variant(bs, semantic_tag::base16); + break; + case byte_string_chars_format::base64: + var_ = variant(bs, semantic_tag::base64); + break; + case byte_string_chars_format::base64url: + var_ = variant(bs, semantic_tag::base64url); + break; + default: + break; + } + } + } + + template + basic_json(InputIterator first, InputIterator last, const Allocator& allocator = Allocator()) + : var_(first,last,allocator) + { + } + JSONCONS_DEPRECATED("Instead, use dump(basic_json_content_handler&)") + void dump_fragment(basic_json_content_handler& handler) const + { + dump(handler); + } + + JSONCONS_DEPRECATED("Instead, use dump(basic_json_content_handler&)") + void dump_body(basic_json_content_handler& handler) const + { + dump(handler); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&, indenting)") + void dump(std::basic_ostream& os, bool pprint) const + { + if (pprint) + { + basic_json_encoder encoder(os); + dump(encoder); + } + else + { + basic_json_compressed_encoder encoder(os); + dump(encoder); + } + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&, const basic_json_options&, indenting)") + void dump(std::basic_ostream& os, const basic_json_options& options, bool pprint) const + { + if (pprint) + { + basic_json_encoder encoder(os, options); + dump(encoder); + } + else + { + basic_json_compressed_encoder encoder(os, options); + dump(encoder); + } + } + + JSONCONS_DEPRECATED("Instead, use dump(basic_json_content_handler&)") + void write_body(basic_json_content_handler& handler) const + { + dump(handler); + } + + JSONCONS_DEPRECATED("Instead, use dump(basic_json_content_handler&)") + void write(basic_json_content_handler& handler) const + { + dump(handler); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&)") + void write(std::basic_ostream& os) const + { + dump(os); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&, const basic_json_options&)") + void write(std::basic_ostream& os, const basic_json_options& options) const + { + dump(os,options); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&, const basic_json_options&, indenting)") + void write(std::basic_ostream& os, const basic_json_options& options, bool pprint) const + { + dump(os,options,pprint); + } + + JSONCONS_DEPRECATED("Instead, use dump(basic_json_content_handler&)") + void to_stream(basic_json_content_handler& handler) const + { + dump(handler); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&)") + void to_stream(std::basic_ostream& os) const + { + dump(os); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&, const basic_json_options&)") + void to_stream(std::basic_ostream& os, const basic_json_options& options) const + { + dump(os,options); + } + + JSONCONS_DEPRECATED("Instead, use dump(std::basic_ostream&, const basic_json_options&, indenting)") + void to_stream(std::basic_ostream& os, const basic_json_options& options, bool pprint) const + { + dump(os,options,pprint ? indenting::indent : indenting::no_indent); + } + + size_t precision() const + { + switch (var_.type()) + { + case storage_type::double_val: + return 0; + default: + JSONCONS_THROW(json_runtime_error("Not a double")); + } + } + + size_t decimal_places() const + { + switch (var_.type()) + { + case storage_type::double_val: + return 0; + default: + JSONCONS_THROW(json_runtime_error("Not a double")); + } + } + + JSONCONS_DEPRECATED("Instead, use tag() == semantic_tag::datetime") + bool is_datetime() const noexcept + { + return var_.tag() == semantic_tag::datetime; + } + + JSONCONS_DEPRECATED("Instead, use tag() == semantic_tag::timestamp") + bool is_epoch_time() const noexcept + { + return var_.tag() == semantic_tag::timestamp; + } + + JSONCONS_DEPRECATED("Instead, use contains(const string_view_type&)") + bool has_key(const string_view_type& name) const + { + return contains(name); + } + + JSONCONS_DEPRECATED("Instead, use is_int64()") + bool is_integer() const noexcept + { + return var_.type() == storage_type::int64_val || (var_.type() == storage_type::uint64_val&& (as_integer() <= static_cast((std::numeric_limits::max)()))); + } + + JSONCONS_DEPRECATED("Instead, use is_uint64()") + bool is_uinteger() const noexcept + { + return var_.type() == storage_type::uint64_val || (var_.type() == storage_type::int64_val&& as_integer() >= 0); + } + + JSONCONS_DEPRECATED("Instead, use as()") + uint64_t as_uinteger() const + { + return as_integer(); + } + + size_t double_precision() const + { + switch (var_.type()) + { + case storage_type::double_val: + return 0; + default: + JSONCONS_THROW(json_runtime_error("Not a double")); + } + } + + JSONCONS_DEPRECATED("Instead, use insert(const_array_iterator, T&&)") + void add(size_t index, const basic_json& value) + { + evaluate_with_default().add(index, value); + } + + JSONCONS_DEPRECATED("Instead, use insert(const_array_iterator, T&&)") + void add(size_t index, basic_json&& value) + { + evaluate_with_default().add(index, std::forward(value)); + } + + template + JSONCONS_DEPRECATED("Instead, use push_back(T&&)") + void add(T&& val) + { + push_back(std::forward(val)); + } + + template + JSONCONS_DEPRECATED("Instead, use insert(const_array_iterator, T&&)") + array_iterator add(const_array_iterator pos, T&& val) + { + return insert(pos, std::forward(val)); + } + + template + std::pair set(const string_view_type& name, T&& val) + { + return insert_or_assign(name, std::forward(val)); + } + + template + JSONCONS_DEPRECATED("Instead, use insert_or_assign(const string_view_type&, T&&)") + object_iterator set(object_iterator hint, const string_view_type& name, T&& val) + { + return insert_or_assign(hint, name, std::forward(val)); + } + + JSONCONS_DEPRECATED("Instead, use resize(size_t)") + void resize_array(size_t n) + { + resize(n); + } + + template + JSONCONS_DEPRECATED("Instead, use resize(size_t, T)") + void resize_array(size_t n, T val) + { + resize(n,val); + } + + JSONCONS_DEPRECATED("Instead, use object_range().begin()") + object_iterator begin_members() + { + return object_range().begin(); + } + + JSONCONS_DEPRECATED("Instead, use object_range().begin()") + const_object_iterator begin_members() const + { + return object_range().begin(); + } + + JSONCONS_DEPRECATED("Instead, use object_range().end()") + object_iterator end_members() + { + return object_range().end(); + } + + JSONCONS_DEPRECATED("Instead, use object_range().end()") + const_object_iterator end_members() const + { + return object_range().end(); + } + + JSONCONS_DEPRECATED("Instead, use array_range().begin()") + array_iterator begin_elements() + { + return array_range().begin(); + } + + JSONCONS_DEPRECATED("Instead, use array_range().begin()") + const_array_iterator begin_elements() const + { + return array_range().begin(); + } + + JSONCONS_DEPRECATED("Instead, use array_range().end()") + array_iterator end_elements() + { + return array_range().end(); + } + + JSONCONS_DEPRECATED("Instead, use array_range().end()") + const_array_iterator end_elements() const + { + return array_range().end(); + } + + template + JSONCONS_DEPRECATED("Instead, use get_with_default(const string_view_type&, T&&)") + basic_json get(const string_view_type& name, T&& default_val) const + { + switch (var_.type()) + { + case storage_type::empty_object_val: + { + return basic_json(std::forward(default_val)); + } + case storage_type::object_val: + { + const_object_iterator it = object_value().find(name); + if (it != object_range().end()) + { + return it->value(); + } + else + { + return basic_json(std::forward(default_val)); + } + } + default: + { + JSONCONS_THROW(not_an_object(name.data(),name.length())); + } + } + } + + JSONCONS_DEPRECATED("Instead, use at(const string_view_type&)") + const basic_json& get(const string_view_type& name) const + { + static const basic_json a_null = null_type(); + + switch (var_.type()) + { + case storage_type::empty_object_val: + return a_null; + case storage_type::object_val: + { + const_object_iterator it = object_value().find(name); + return it != object_range().end() ? it->value() : a_null; + } + default: + { + JSONCONS_THROW(not_an_object(name.data(),name.length())); + } + } + } + + JSONCONS_DEPRECATED("Instead, use is()") + bool is_longlong() const noexcept + { + return var_.type() == storage_type::int64_val; + } + + JSONCONS_DEPRECATED("Instead, use is()") + bool is_ulonglong() const noexcept + { + return var_.type() == storage_type::uint64_val; + } + + JSONCONS_DEPRECATED("Instead, use as()") + long long as_longlong() const + { + return as_integer(); + } + + JSONCONS_DEPRECATED("Instead, use as()") + unsigned long long as_ulonglong() const + { + return as_integer(); + } + + JSONCONS_DEPRECATED("Instead, use as()") + int as_int() const + { + switch (var_.type()) + { + case storage_type::double_val: + return static_cast(var_.double_data_cast()->value()); + case storage_type::int64_val: + return static_cast(var_.int64_data_cast()->value()); + case storage_type::uint64_val: + return static_cast(var_.uint64_data_cast()->value()); + case storage_type::bool_val: + return var_.bool_data_cast()->value() ? 1 : 0; + default: + JSONCONS_THROW(json_runtime_error("Not an int")); + } + } + + JSONCONS_DEPRECATED("Instead, use as()") + unsigned int as_uint() const + { + switch (var_.type()) + { + case storage_type::double_val: + return static_cast(var_.double_data_cast()->value()); + case storage_type::int64_val: + return static_cast(var_.int64_data_cast()->value()); + case storage_type::uint64_val: + return static_cast(var_.uint64_data_cast()->value()); + case storage_type::bool_val: + return var_.bool_data_cast()->value() ? 1 : 0; + default: + JSONCONS_THROW(json_runtime_error("Not an unsigned int")); + } + } + + JSONCONS_DEPRECATED("Instead, use as()") + long as_long() const + { + switch (var_.type()) + { + case storage_type::double_val: + return static_cast(var_.double_data_cast()->value()); + case storage_type::int64_val: + return static_cast(var_.int64_data_cast()->value()); + case storage_type::uint64_val: + return static_cast(var_.uint64_data_cast()->value()); + case storage_type::bool_val: + return var_.bool_data_cast()->value() ? 1 : 0; + default: + JSONCONS_THROW(json_runtime_error("Not a long")); + } + } + + JSONCONS_DEPRECATED("Instead, use as()") + unsigned long as_ulong() const + { + switch (var_.type()) + { + case storage_type::double_val: + return static_cast(var_.double_data_cast()->value()); + case storage_type::int64_val: + return static_cast(var_.int64_data_cast()->value()); + case storage_type::uint64_val: + return static_cast(var_.uint64_data_cast()->value()); + case storage_type::bool_val: + return var_.bool_data_cast()->value() ? 1 : 0; + default: + JSONCONS_THROW(json_runtime_error("Not an unsigned long")); + } + } + + JSONCONS_DEPRECATED("Instead, use contains(const string_view_type&)") + bool has_member(const string_view_type& name) const + { + switch (var_.type()) + { + case storage_type::object_val: + { + const_object_iterator it = object_value().find(name); + return it != object_range().end(); + } + break; + default: + return false; + } + } + + JSONCONS_DEPRECATED("Instead, use erase(const_object_iterator, const_object_iterator)") + void remove_range(size_t from_index, size_t to_index) + { + switch (var_.type()) + { + case storage_type::array_val: + array_value().remove_range(from_index, to_index); + break; + default: + break; + } + } + + JSONCONS_DEPRECATED("Instead, use erase(const string_view_type& name)") + void remove(const string_view_type& name) + { + erase(name); + } + + JSONCONS_DEPRECATED("Instead, use erase(const string_view_type& name)") + void remove_member(const string_view_type& name) + { + erase(name); + } + // Removes a member from an object value + + JSONCONS_DEPRECATED("Instead, use empty()") + bool is_empty() const noexcept + { + return empty(); + } + JSONCONS_DEPRECATED("Instead, use is_number()") + bool is_numeric() const noexcept + { + return is_number(); + } + + template + JSONCONS_DEPRECATED("Instead, use make_array()") + static typename std::enable_if::type make_multi_array() + { + return make_array(); + } + template + JSONCONS_DEPRECATED("Instead, use make_array(size_t)") + static typename std::enable_if::type make_multi_array(size_t n) + { + return make_array(n); + } + template + JSONCONS_DEPRECATED("Instead, use make_array(size_t, T)") + static typename std::enable_if::type make_multi_array(size_t n, T val) + { + return make_array(n,val); + } + template + JSONCONS_DEPRECATED("Instead, use make_array(size_t, size_t)") + static typename std::enable_if::type make_multi_array(size_t m, size_t n) + { + return make_array<2>(m, n); + } + template + JSONCONS_DEPRECATED("Instead, use make_array(size_t, size_t, T)") + static typename std::enable_if::type make_multi_array(size_t m, size_t n, T val) + { + return make_array<2>(m, n, val); + } + template + JSONCONS_DEPRECATED("Instead, use make_array(size_t, size_t, size_t)") + static typename std::enable_if::type make_multi_array(size_t m, size_t n, size_t k) + { + return make_array<3>(m, n, k); + } + template + JSONCONS_DEPRECATED("Instead, use make_array(size_t, size_t, size_t, T)") + static typename std::enable_if::type make_multi_array(size_t m, size_t n, size_t k, T val) + { + return make_array<3>(m, n, k, val); + } + JSONCONS_DEPRECATED("Instead, use object_range()") + range members() + { + return object_range(); + } + + JSONCONS_DEPRECATED("Instead, use object_range()") + range members() const + { + return object_range(); + } + + JSONCONS_DEPRECATED("Instead, use array_range()") + range elements() + { + return array_range(); + } + + JSONCONS_DEPRECATED("Instead, use array_range()") + range elements() const + { + return array_range(); + } + + JSONCONS_DEPRECATED("Instead, use type()") + storage_type get_storage_type() const + { + return var_.type(); + } +#endif + + range object_range() + { + static basic_json empty_object = object(); + switch (var_.type()) + { + case storage_type::empty_object_val: + return range(empty_object.object_range().begin(), empty_object.object_range().end()); + case storage_type::object_val: + return range(object_value().begin(),object_value().end()); + default: + JSONCONS_THROW(json_runtime_error("Not an object")); + } + } + + range object_range() const + { + static const basic_json empty_object = object(); + switch (var_.type()) + { + case storage_type::empty_object_val: + return range(empty_object.object_range().begin(), empty_object.object_range().end()); + case storage_type::object_val: + return range(object_value().begin(),object_value().end()); + default: + JSONCONS_THROW(json_runtime_error("Not an object")); + } + } + + range array_range() + { + switch (var_.type()) + { + case storage_type::array_val: + return range(array_value().begin(),array_value().end()); + default: + JSONCONS_THROW(json_runtime_error("Not an array")); + } + } + + range array_range() const + { + switch (var_.type()) + { + case storage_type::array_val: + return range(array_value().begin(),array_value().end()); + default: + JSONCONS_THROW(json_runtime_error("Not an array")); + } + } + + array& array_value() + { + switch (var_.type()) + { + case storage_type::array_val: + return var_.array_data_cast()->value(); + default: + JSONCONS_THROW(json_runtime_error("Bad array cast")); + break; + } + } + + const array& array_value() const + { + switch (var_.type()) + { + case storage_type::array_val: + return var_.array_data_cast()->value(); + default: + JSONCONS_THROW(json_runtime_error("Bad array cast")); + break; + } + } + + object& object_value() + { + switch (var_.type()) + { + case storage_type::empty_object_val: + create_object_implicitly(); + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return var_.object_data_cast()->value(); + default: + JSONCONS_THROW(json_runtime_error("Bad object cast")); + break; + } + } + + const object& object_value() const + { + switch (var_.type()) + { + case storage_type::empty_object_val: + const_cast(this)->create_object_implicitly(); // HERE + JSONCONS_FALLTHROUGH; + case storage_type::object_val: + return var_.object_data_cast()->value(); + default: + JSONCONS_THROW(json_runtime_error("Bad object cast")); + break; + } + } + +private: + + void dump_noflush(basic_json_content_handler& handler) const + { + switch (var_.type()) + { + case storage_type::short_string_val: + case storage_type::long_string_val: + handler.string_value(as_string_view(), var_.tag()); + break; + case storage_type::byte_string_val: + handler.byte_string_value(var_.byte_string_data_cast()->data(), var_.byte_string_data_cast()->length(), + var_.tag()); + break; + case storage_type::double_val: + handler.double_value(var_.double_data_cast()->value(), + var_.tag()); + break; + case storage_type::int64_val: + handler.int64_value(var_.int64_data_cast()->value(), var_.tag()); + break; + case storage_type::uint64_val: + handler.uint64_value(var_.uint64_data_cast()->value(), var_.tag()); + break; + case storage_type::bool_val: + handler.bool_value(var_.bool_data_cast()->value(), var_.tag()); + break; + case storage_type::null_val: + handler.null_value(var_.tag()); + break; + case storage_type::empty_object_val: + handler.begin_object(0, var_.tag()); + handler.end_object(); + break; + case storage_type::object_val: + { + handler.begin_object(size(), var_.tag()); + const object& o = object_value(); + for (const_object_iterator it = o.begin(); it != o.end(); ++it) + { + handler.name(string_view_type((it->key()).data(),it->key().length())); + it->value().dump_noflush(handler); + } + handler.end_object(); + } + break; + case storage_type::array_val: + { + handler.begin_array(size(), var_.tag()); + const array& o = array_value(); + for (const_array_iterator it = o.begin(); it != o.end(); ++it) + { + it->dump_noflush(handler); + } + handler.end_array(); + } + break; + default: + break; + } + } + + friend std::basic_ostream& operator<<(std::basic_ostream& os, const basic_json& o) + { + o.dump(os); + return os; + } + + friend std::basic_istream& operator>>(std::basic_istream& is, basic_json& o) + { + json_decoder handler; + basic_json_reader> reader(is, handler); + reader.read_next(); + reader.check_done(); + if (!handler.is_valid()) + { + JSONCONS_THROW(json_runtime_error("Failed to parse json stream")); + } + o = handler.get_result(); + return is; + } +}; + +template +void swap(typename Json::key_value_type& a, typename Json::key_value_type& b) +{ + a.swap(b); +} + +typedef basic_json> json; +typedef basic_json> wjson; +typedef basic_json> ojson; +typedef basic_json> wojson; + +#if !defined(JSONCONS_NO_DEPRECATED) +JSONCONS_DEPRECATED("Instead, use wojson") typedef basic_json> owjson; +JSONCONS_DEPRECATED("Instead, use json_decoder") typedef json_decoder json_deserializer; +JSONCONS_DEPRECATED("Instead, use json_decoder") typedef json_decoder wjson_deserializer; +JSONCONS_DEPRECATED("Instead, use json_decoder") typedef json_decoder ojson_deserializer; +JSONCONS_DEPRECATED("Instead, use json_decoder") typedef json_decoder wojson_deserializer; +#endif + +inline namespace literals { + +inline +jsoncons::json operator "" _json(const char* s, std::size_t n) +{ + return jsoncons::json::parse(jsoncons::json::string_view_type(s, n)); +} + +inline +jsoncons::wjson operator "" _json(const wchar_t* s, std::size_t n) +{ + return jsoncons::wjson::parse(jsoncons::wjson::string_view_type(s, n)); +} + +inline +jsoncons::ojson operator "" _ojson(const char* s, std::size_t n) +{ + return jsoncons::ojson::parse(jsoncons::ojson::string_view_type(s, n)); +} + +inline +jsoncons::wojson operator "" _ojson(const wchar_t* s, std::size_t n) +{ + return jsoncons::wojson::parse(jsoncons::wojson::string_view_type(s, n)); +} + +} + +} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/bignum.hpp b/invehicle-apps/3rd-party-libs/jsoncons/bignum.hpp new file mode 100644 index 0000000..f0a650f --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/bignum.hpp @@ -0,0 +1,1604 @@ +// 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_BIGNUM_HPP +#define JSONCONS_BIGNUM_HPP + +#include +#include // std::vector +#include +#include +#include // assert +#include // std::numeric_limits +#include // std::max, std::min, std::reverse +#include // std::string +#include // std::memcpy +#include // std::fmod +#include // std::allocator +#include // std::initializer_list +#include // std::enable_if + +namespace jsoncons { + +/* +This implementation is based on Chapter 2 and Appendix A of +Ammeraal, L. (1996) Algorithms and Data Structures in C++, +Chichester: John Wiley. + +*/ + +template +class basic_bignum_base +{ +public: + typedef Allocator allocator_type; + typedef typename std::allocator_traits:: template rebind_alloc basic_type_allocator_type; + +private: + basic_type_allocator_type allocator_; + +public: + basic_bignum_base() + : allocator_() + { + } + explicit basic_bignum_base(const allocator_type& allocator) + : allocator_(basic_type_allocator_type(allocator)) + { + } + + basic_type_allocator_type allocator() const + { + return allocator_; + } +}; + +template > +class basic_bignum : protected basic_bignum_base +{ +private: + using basic_bignum_base::allocator; + + static constexpr uint64_t max_basic_type = (std::numeric_limits::max)(); + static constexpr uint64_t basic_type_bits = sizeof(uint64_t) * 8; // Number of bits + static constexpr uint64_t basic_type_halfBits = basic_type_bits/2; + + static constexpr uint16_t word_length = 4; // Use multiples of word_length words + static constexpr uint64_t r_mask = (uint64_t(1) << basic_type_halfBits) - 1; + static constexpr uint64_t l_mask = max_basic_type - r_mask; + static constexpr uint64_t l_bit = max_basic_type - (max_basic_type >> 1); + + union + { + size_t capacity_; + uint64_t values_[2]; + }; + uint64_t* data_; + bool neg_; + bool dynamic_; + size_t length_; +public: +// Constructors and Destructor + basic_bignum() + : values_{0,0}, data_(values_), neg_(false), dynamic_(false), length_(0) + { + } + + explicit basic_bignum(const Allocator& allocator) + : basic_bignum_base(allocator), values_{0,0}, data_(values_), neg_(false), dynamic_(false), length_(0) + { + } + + basic_bignum(const basic_bignum& n) + : basic_bignum_base(n.allocator()), neg_(n.neg_), length_(n.length_) + { + if (!n.dynamic_) + { + values_[0] = n.values_[0]; + values_[1] = n.values_[1]; + data_ = values_; + dynamic_ = false; + } + else + { + capacity_ = n.capacity_; + data_ = allocator().allocate(capacity_); + dynamic_ = true; + std::memcpy( data_, n.data_, n.length_*sizeof(uint64_t) ); + } + } + + basic_bignum(basic_bignum&& other) + : basic_bignum_base(other.allocator()), neg_(other.neg_), dynamic_(false), length_(other.length_) + { + initialize(std::move(other)); + } + + template + explicit basic_bignum(const CharT* str) + : values_{0,0} + { + initialize(str, strlen(str)); + } + + template + basic_bignum(const std::basic_string& s) + : values_{0,0} + { + initialize(s.data(), s.length()); + } + + template + basic_bignum(const CharT* data, size_t length) + : values_{0,0} + { + initialize(data, length); + } + + template + basic_bignum(const std::basic_string& s, uint8_t base) + : values_{0,0} + { + initialize(s.data(), s.length(), base); + } + + template + basic_bignum(const CharT* data, size_t length, uint8_t base) + : values_{0,0} + { + initialize(data, length, base); + } + + basic_bignum(int signum, std::initializer_list l) + : values_{0,0} + { + if (l.size() > 0) + { + basic_bignum v = 0; + for (auto c: l) + { + v = (v * 256) + (uint64_t)(c); + } + + if (signum == -1) + { + v = -1 - v; + } + + initialize(v); + } + else + { + neg_ = false; + initialize_from_integer(0u); + } + } + + basic_bignum(int signum, const uint8_t* str, size_t n) + : values_{0,0} + { + if (n > 0) + { + basic_bignum v = 0; + for (size_t i = 0; i < n; i++) + { + v = (v * 256) + (uint64_t)(str[i]); + } + + if (signum == -1) + { + v = -1 - v; + } + + initialize(v); + } + else + { + neg_ = false; + initialize_from_integer(0u); + } + } + + basic_bignum(short i) + : values_{0,0} + { + neg_ = i < 0; + uint64_t u = neg_ ? -i : i; + initialize_from_integer( u ); + } + + basic_bignum(unsigned short u) + : values_{0,0} + { + neg_ = false; + initialize_from_integer( u ); + } + + basic_bignum(int i) + : values_{0,0} + { + neg_ = i < 0; + uint64_t u = neg_ ? -i : i; + initialize_from_integer( u ); + } + + basic_bignum(unsigned int u) + : values_{0,0} + { + neg_ = false; + initialize_from_integer( u ); + } + + basic_bignum(long i) + : values_{0,0} + { + neg_ = i < 0; + uint64_t u = neg_ ? -i : i; + initialize_from_integer( u ); + } + + basic_bignum(unsigned long u) + : values_{0,0} + { + neg_ = false; + initialize_from_integer( u ); + } + + basic_bignum(long long i) + : values_{0,0} + { + neg_ = i < 0; + uint64_t u = neg_ ? -i : i; + initialize_from_integer( u ); + } + + basic_bignum(unsigned long long u) + : values_{0,0} + { + neg_ = false; + initialize_from_integer( u ); + } + + explicit basic_bignum( double x ) + : values_{0,0} + { + bool neg = false; + + if ( x < 0 ) + { + neg = true; + x = -x; + } + basic_bignum v = 0; + + double values = (double)max_basic_type + 1.0; + basic_bignum factor = 1; + + while ( x >= 1 ) + { + uint64_t u = (uint64_t) std::fmod( x, values ); + v = v + factor* basic_bignum(u); + x /= values; + factor = factor*(basic_bignum( max_basic_type ) + basic_bignum(1)); + } + + if ( neg ) + { + v.neg_ = true; + } + initialize( v ); + } + + explicit basic_bignum(long double x) + : values_{0,0} + { + bool neg = false; + + if ( x < 0 ) + { + neg = true; + x = -x; + } + + basic_bignum v = 0; + + long double values = (long double)max_basic_type + 1.0; + basic_bignum factor = 1; + + while ( x >= 1.0 ) + { + uint64_t u = (uint64_t) std::fmod( x, values ); + v = v + factor* basic_bignum(u); + x /= values; + factor = factor*(basic_bignum( max_basic_type ) + basic_bignum(1)); + } + + if ( neg ) + { + v.neg_ = true; + } + initialize( v ); + } + + ~basic_bignum() + { + if ( dynamic_ ) + { + allocator().deallocate(data_, capacity_); + } + } + + size_t capacity() const { return dynamic_ ? capacity_ : 2; } + +// Operators + bool operator!() const + { + return length() == 0 ? true : false; + } + + basic_bignum operator-() const + { + basic_bignum v = *this; + v.neg_ = !v.neg_; + return v; + } + + basic_bignum& operator=( const basic_bignum& y ) + { + if ( this != &y ) + { + set_length( y.length() ); + neg_ = y.neg_; + if ( y.length() > 0 ) + { + std::memcpy( data_, y.data_, y.length()*sizeof(uint64_t) ); + } + } + return *this; + } + + basic_bignum& operator+=( const basic_bignum& y ) + { + if ( neg_ != y.neg_ ) + return *this -= -y; + uint64_t d; + uint64_t carry = 0; + + incr_length( (std::max)(y.length(), length()) + 1 ); + + for (size_t i = 0; i < length(); i++ ) + { + if ( i >= y.length() && carry == 0 ) + break; + d = data_[i] + carry; + carry = d < carry; + if ( i < y.length() ) + { + data_[i] = d + y.data_[i]; + if ( data_[i] < d ) + carry = 1; + } + else + data_[i] = d; + } + reduce(); + return *this; + } + + basic_bignum& operator-=( const basic_bignum& y ) + { + if ( neg_ != y.neg_ ) + return *this += -y; + if ( (!neg_ && y > *this) || (neg_ && y < *this) ) + return *this = -(y - *this); + uint64_t borrow = 0; + uint64_t d; + for (size_t i = 0; i < length(); i++ ) + { + if ( i >= y.length() && borrow == 0 ) + break; + d = data_[i] - borrow; + borrow = d > data_[i]; + if ( i < y.length()) + { + data_[i] = d - y.data_[i]; + if ( data_[i] > d ) + borrow = 1; + } + else + data_[i] = d; + } + reduce(); + return *this; + } + + basic_bignum& operator*=( int64_t y ) + { + *this *= uint64_t(y < 0 ? -y : y); + if ( y < 0 ) + neg_ = !neg_; + return *this; + } + + basic_bignum& operator*=( uint64_t y ) + { + size_t len0 = length(); + uint64_t hi; + uint64_t lo; + uint64_t dig = data_[0]; + uint64_t carry = 0; + + incr_length( length() + 1 ); + + size_t i = 0; + for (i = 0; i < len0; i++ ) + { + DDproduct( dig, y, hi, lo ); + data_[i] = lo + carry; + dig = data_[i+1]; + carry = hi + (data_[i] < lo); + } + data_[i] = carry; + reduce(); + return *this; + } + + basic_bignum& operator*=( basic_bignum y ) + { + if ( length() == 0 || y.length() == 0 ) + return *this = 0; + bool difSigns = neg_ != y.neg_; + if ( length() + y.length() == 2 ) // length() = y.length() = 1 + { + uint64_t a = data_[0], b = y.data_[0]; + data_[0] = a * b; + if ( data_[0] / a != b ) + { + set_length( 2 ); + DDproduct( a, b, data_[1], data_[0] ); + } + neg_ = difSigns; + return *this; + } + if ( length() == 1 ) // && y.length() > 1 + { + uint64_t digit = data_[0]; + *this = y; + *this *= digit; + } + else + { + if ( y.length() == 1 ) + *this *= y.data_[0]; + else + { + size_t lenProd = length() + y.length(), jA, jB; + uint64_t sumHi = 0, sumLo, hi, lo, + sumLo_old, sumHi_old, carry=0; + basic_bignum x = *this; + set_length( lenProd ); // Give *this length lenProd + + for (size_t i = 0; i < lenProd; i++ ) + { + sumLo = sumHi; + sumHi = carry; + carry = 0; + for ( jA=0; jA < x.length(); jA++ ) + { + jB = i - jA; + if ( jB >= 0 && jB < y.length() ) + { + DDproduct( x.data_[jA], y.data_[jB], hi, lo ); + sumLo_old = sumLo; + sumHi_old = sumHi; + sumLo += lo; + if ( sumLo < sumLo_old ) + sumHi++; + sumHi += hi; + carry += (sumHi < sumHi_old); + } + } + data_[i] = sumLo; + } + } + } + reduce(); + neg_ = difSigns; + return *this; + } + + basic_bignum& operator/=( const basic_bignum& divisor ) + { + basic_bignum r; + divide( divisor, *this, r, false ); + return *this; + } + + basic_bignum& operator%=( const basic_bignum& divisor ) + { + basic_bignum q; + divide( divisor, q, *this, true ); + return *this; + } + + basic_bignum& operator<<=( uint64_t k ) + { + size_t q = (size_t)(k / basic_type_bits); + if ( q ) // Increase length_ by q: + { + incr_length(length() + q); + for (size_t i = length(); i-- > 0; ) + data_[i] = ( i < q ? 0 : data_[i - q]); + k %= basic_type_bits; + } + if ( k ) // 0 < k < basic_type_bits: + { + uint64_t k1 = basic_type_bits - k; + uint64_t mask = (1 << k) - 1; + incr_length( length() + 1 ); + for (size_t i = length(); i-- > 0; ) + { + data_[i] <<= k; + if ( i > 0 ) + data_[i] |= (data_[i-1] >> k1) & mask; + } + } + reduce(); + return *this; + } + + basic_bignum& operator>>=(uint64_t k) + { + size_t q = (size_t)(k / basic_type_bits); + if ( q >= length() ) + { + set_length( 0 ); + return *this; + } + if (q > 0) + { + memmove( data_, data_+q, (size_t)((length() - q)*sizeof(uint64_t)) ); + set_length( length() - q ); + k %= basic_type_bits; + if ( k == 0 ) + { + reduce(); + return *this; + } + } + + size_t n = (size_t)(length() - 1); + int64_t k1 = basic_type_bits - k; + uint64_t mask = (1 << k) - 1; + for (size_t i = 0; i <= n; i++) + { + data_[i] >>= k; + if ( i < n ) + data_[i] |= ((data_[i+1] & mask) << k1); + } + reduce(); + return *this; + } + + basic_bignum& operator++() + { + *this += 1; + return *this; + } + + basic_bignum operator++(int) + { + basic_bignum old = *this; + ++(*this); + return old; + } + + basic_bignum& operator--() + { + *this -= 1; + return *this; + } + + basic_bignum operator--(int) + { + basic_bignum old = *this; + --(*this); + return old; + } + + basic_bignum& operator|=( const basic_bignum& a ) + { + if ( length() < a.length() ) + { + incr_length( a.length() ); + } + + const uint64_t* qBegin = a.begin(); + const uint64_t* q = a.end() - 1; + uint64_t* p = begin() + a.length() - 1; + + while ( q >= qBegin ) + { + *p-- |= *q--; + } + + reduce(); + + return *this; + } + + basic_bignum& operator^=( const basic_bignum& a ) + { + if ( length() < a.length() ) + { + incr_length( a.length() ); + } + + const uint64_t* qBegin = a.begin(); + const uint64_t* q = a.end() - 1; + uint64_t* p = begin() + a.length() - 1; + + while ( q >= qBegin ) + { + *p-- ^= *q--; + } + + reduce(); + + return *this; + } + + basic_bignum& operator&=( const basic_bignum& a ) + { + size_t old_length = length(); + + set_length( (std::min)( length(), a.length() ) ); + + const uint64_t* pBegin = begin(); + uint64_t* p = end() - 1; + const uint64_t* q = a.begin() + length() - 1; + + while ( p >= pBegin ) + { + *p-- &= *q--; + } + + if ( old_length > length() ) + { + memset( data_ + length(), 0, old_length - length() ); + } + + reduce(); + + return *this; + } + + explicit operator bool() const + { + return length() != 0 ? true : false; + } + + explicit operator int64_t() const + { + int64_t x = 0; + if ( length() > 0 ) + { + x = data_ [0]; + } + + return neg_ ? -x : x; + } + + explicit operator uint64_t() const + { + uint64_t u = 0; + if ( length() > 0 ) + { + u = data_ [0]; + } + + return u; + } + + explicit operator double() const + { + double x = 0.0; + double factor = 1.0; + double values = (double)max_basic_type + 1.0; + + const uint64_t* p = begin(); + const uint64_t* pEnd = end(); + while ( p < pEnd ) + { + x += *p*factor; + factor *= values; + ++p; + } + + return neg_ ? -x : x; + } + + explicit operator long double() const + { + long double x = 0.0; + long double factor = 1.0; + long double values = (long double)max_basic_type + 1.0; + + const uint64_t* p = begin(); + const uint64_t* pEnd = end(); + while ( p < pEnd ) + { + x += *p*factor; + factor *= values; + ++p; + } + + return neg_ ? -x : x; + } + + template + void dump(int& signum, std::vector& data) const + { + basic_bignum n(*this); + if (neg_) + { + signum = -1; + n = - n -1; + } + else + { + signum = 1; + } + basic_bignum divisor(256); + + while (n >= 256) + { + basic_bignum q; + basic_bignum r; + n.divide(divisor, q, r, true); + n = q; + data.push_back((uint8_t)(uint64_t)r); + } + if (n >= 0) + { + data.push_back((uint8_t)(uint64_t)n); + } + std::reverse(data.begin(),data.end()); + } + + template + void dump(std::basic_string& data) const + { + basic_bignum v(*this); + + int len = int(uint32_t(v.length()) * basic_bignum::basic_type_bits / 3) + 2; + data.resize(len); + + int n = len; + int i = 0; + // 1/3 > ln(2)/ln(10) + static uint64_t p10 = 1; + static uint64_t ip10 = 0; + + if ( v.length() == 0 ) + { + data[0] = '0'; + i = 1; + } + else + { + uint64_t r; + if ( p10 == 1 ) + { + while ( p10 <= (std::numeric_limits::max)()/10 ) + { + p10 *= 10; + ip10++; + } + } // p10 is max unsigned power of 10 + basic_bignum R; + basic_bignum LP10 = p10; // LP10 = p10 = ::pow(10, ip10) + if ( v.neg_ ) + { + data[0] = '-'; + i = 1; + } + do + { + v.divide( LP10, v, R, true ); + r = (R.length() ? R.data_[0] : 0); + for ( size_t j=0; j < ip10; j++ ) + { + data[--n] = char(r % 10 + '0'); + r /= 10; + if ( r + v.length() == 0 ) + break; + } + } while ( v.length() ); + while ( n < len ) + data[i++] = data[n++]; + } + data.resize(i); + } + + template + void dump_hex_string(std::basic_string& data) const + { + basic_bignum v(*this); + + int len = int(uint32_t(v.length()) * basic_bignum::basic_type_bits / 3) + 2; + data.resize(len); + + int n = len; + int i = 0; + // 1/3 > ln(2)/ln(10) + static uint64_t p10 = 1; + static uint64_t ip10 = 0; + + if ( v.length() == 0 ) + { + data[0] = '0'; + i = 1; + } + else + { + uint64_t r; + if ( p10 == 1 ) + { + while ( p10 <= (std::numeric_limits::max)()/16 ) + { + p10 *= 16; + ip10++; + } + } // p10 is max unsigned power of 16 + basic_bignum R; + basic_bignum LP10 = p10; // LP10 = p10 = ::pow(16, ip10) + if ( v.neg_ ) + { + data[0] = '-'; + i = 1; + } + do + { + v.divide( LP10, v, R, true ); + r = (R.length() ? R.data_[0] : 0); + for ( size_t j=0; j < ip10; j++ ) + { + uint8_t c = r % 16; + data[--n] = (c < 10) ? ('0' + c) : ('A' - 10 + c); + r /= 16; + if ( r + v.length() == 0 ) + break; + } + } while ( v.length() ); + while ( n < len ) + data[i++] = data[n++]; + } + data.resize(i); + } + +// Global Operators + + friend bool operator==( const basic_bignum& x, const basic_bignum& y ) + { + return x.compare(y) == 0 ? true : false; + } + + friend bool operator==( const basic_bignum& x, int y ) + { + return x.compare(y) == 0 ? true : false; + } + + friend bool operator!=( const basic_bignum& x, const basic_bignum& y ) + { + return x.compare(y) != 0 ? true : false; + } + + friend bool operator!=( const basic_bignum& x, int y ) + { + return x.compare(basic_bignum(y)) != 0 ? true : false; + } + + friend bool operator<( const basic_bignum& x, const basic_bignum& y ) + { + return x.compare(y) < 0 ? true : false; + } + + friend bool operator<( const basic_bignum& x, int64_t y ) + { + return x.compare(y) < 0 ? true : false; + } + + friend bool operator>( const basic_bignum& x, const basic_bignum& y ) + { + return x.compare(y) > 0 ? true : false; + } + + friend bool operator>( const basic_bignum& x, int y ) + { + return x.compare(basic_bignum(y)) > 0 ? true : false; + } + + friend bool operator<=( const basic_bignum& x, const basic_bignum& y ) + { + return x.compare(y) <= 0 ? true : false; + } + + friend bool operator<=( const basic_bignum& x, int y ) + { + return x.compare(y) <= 0 ? true : false; + } + + friend bool operator>=( const basic_bignum& x, const basic_bignum& y ) + { + return x.compare(y) >= 0 ? true : false; + } + + friend bool operator>=( const basic_bignum& x, int y ) + { + return x.compare(y) >= 0 ? true : false; + } + + friend basic_bignum operator+( basic_bignum x, const basic_bignum& y ) + { + return x += y; + } + + friend basic_bignum operator+( basic_bignum x, int64_t y ) + { + return x += y; + } + + friend basic_bignum operator-( basic_bignum x, const basic_bignum& y ) + { + return x -= y; + } + + friend basic_bignum operator-( basic_bignum x, int64_t y ) + { + return x -= y; + } + + friend basic_bignum operator*( int64_t x, const basic_bignum& y ) + { + return basic_bignum(y) *= x; + } + + friend basic_bignum operator*( basic_bignum x, const basic_bignum& y ) + { + return x *= y; + } + + friend basic_bignum operator*( basic_bignum x, int64_t y ) + { + return x *= y; + } + + friend basic_bignum operator/( basic_bignum x, const basic_bignum& y ) + { + return x /= y; + } + + friend basic_bignum operator/( basic_bignum x, int y ) + { + return x /= y; + } + + friend basic_bignum operator%( basic_bignum x, const basic_bignum& y ) + { + return x %= y; + } + + friend basic_bignum operator<<( basic_bignum u, unsigned k ) + { + return u <<= k; + } + + friend basic_bignum operator<<( basic_bignum u, int k ) + { + return u <<= k; + } + + friend basic_bignum operator>>( basic_bignum u, unsigned k ) + { + return u >>= k; + } + + friend basic_bignum operator>>( basic_bignum u, int k ) + { + return u >>= k; + } + + friend basic_bignum operator|( basic_bignum x, const basic_bignum& y ) + { + return x |= y; + } + + friend basic_bignum operator|( basic_bignum x, int y ) + { + return x |= y; + } + + friend basic_bignum operator|( basic_bignum x, unsigned y ) + { + return x |= y; + } + + friend basic_bignum operator^( basic_bignum x, const basic_bignum& y ) + { + return x ^= y; + } + + friend basic_bignum operator^( basic_bignum x, int y ) + { + return x ^= y; + } + + friend basic_bignum operator^( basic_bignum x, unsigned y ) + { + return x ^= y; + } + + friend basic_bignum operator&( basic_bignum x, const basic_bignum& y ) + { + return x &= y; + } + + friend basic_bignum operator&( basic_bignum x, int y ) + { + return x &= y; + } + + friend basic_bignum operator&( basic_bignum x, unsigned y ) + { + return x &= y; + } + + friend basic_bignum abs( const basic_bignum& a ) + { + if ( a.neg_ ) + { + return -a; + } + return a; + } + + friend basic_bignum power( basic_bignum x, unsigned n ) + { + basic_bignum y = 1; + + while ( n ) + { + if ( n & 1 ) + { + y *= x; + } + x *= x; + n >>= 1; + } + + return y; + } + + friend basic_bignum sqrt( const basic_bignum& a ) + { + basic_bignum x = a; + basic_bignum b = a; + basic_bignum q; + + b <<= 1; + while ( b >>= 2, b > 0 ) + { + x >>= 1; + } + while ( x > (q = a/x) + 1 || x < q - 1 ) + { + x += q; + x >>= 1; + } + return x < q ? x : q; + } + + template + friend std::basic_ostream& operator<<(std::basic_ostream& os, const basic_bignum& v) + { + std::basic_string s; + v.dump(s); + os << s; + + return os; + } + + int compare( const basic_bignum& y ) const + { + if ( neg_ != y.neg_ ) + return y.neg_ - neg_; + int code = 0; + if ( length() == 0 && y.length() == 0 ) + code = 0; + else if ( length() < y.length() ) + code = -1; + else if ( length() > y.length() ) + code = +1; + else + { + for (size_t i = length(); i-- > 0; ) + { + if (data_[i] > y.data_[i]) + { + code = 1; + break; + } + else if (data_[i] < y.data_[i]) + { + code = -1; + break; + } + } + } + return neg_ ? -code : code; + } + +private: + void DDproduct( uint64_t A, uint64_t B, + uint64_t& hi, uint64_t& lo ) const + // Multiplying two digits: (hi, lo) = A * B + { + uint64_t hiA = A >> basic_type_halfBits, loA = A & r_mask, + hiB = B >> basic_type_halfBits, loB = B & r_mask, + mid1, mid2, old; + + lo = loA * loB; + hi = hiA * hiB; + mid1 = loA * hiB; + mid2 = hiA * loB; + old = lo; + lo += mid1 << basic_type_halfBits; + hi += (lo < old) + (mid1 >> basic_type_halfBits); + old = lo; + lo += mid2 << basic_type_halfBits; + hi += (lo < old) + (mid2 >> basic_type_halfBits); + } + + uint64_t DDquotient( uint64_t A, uint64_t B, uint64_t d ) const + // Divide double word (A, B) by d. Quotient = (qHi, qLo) + { + uint64_t left, middle, right, qHi, qLo, x, dLo1, + dHi = d >> basic_type_halfBits, dLo = d & r_mask; + qHi = A/(dHi + 1); + // This initial guess of qHi may be too small. + middle = qHi * dLo; + left = qHi * dHi; + x = B - (middle << basic_type_halfBits); + A -= (middle >> basic_type_halfBits) + left + (x > B); + B = x; + dLo1 = dLo << basic_type_halfBits; + // Increase qHi if necessary: + while ( A > dHi || (A == dHi && B >= dLo1) ) + { + x = B - dLo1; + A -= dHi + (x > B); + B = x; + qHi++; + } + qLo = ((A << basic_type_halfBits) | (B >> basic_type_halfBits))/(dHi + 1); + // This initial guess of qLo may be too small. + right = qLo * dLo; + middle = qLo * dHi; + x = B - right; + A -= (x > B); + B = x; + x = B - (middle << basic_type_halfBits); + A -= (middle >> basic_type_halfBits) + (x > B); + B = x; + // Increase qLo if necessary: + while ( A || B >= d ) + { + x = B - d; + A -= (x > B); + B = x; + qLo++; + } + return (qHi << basic_type_halfBits) + qLo; + } + + void subtractmul( uint64_t* a, uint64_t* b, size_t n, uint64_t& q ) const + // a -= q * b: b in n positions; correct q if necessary + { + uint64_t hi, lo, d, carry = 0; + size_t i; + for ( i = 0; i < n; i++ ) + { + DDproduct( b[i], q, hi, lo ); + d = a[i]; + a[i] -= lo; + if ( a[i] > d ) + carry++; + d = a[i + 1]; + a[i + 1] -= hi + carry; + carry = a[i + 1] > d; + } + if ( carry ) // q was too large + { + q--; + carry = 0; + for ( i = 0; i < n; i++ ) + { + d = a[i] + carry; + carry = d < carry; + a[i] = d + b[i]; + if ( a[i] < d ) + carry = 1; + } + a[n] = 0; + } + } + + int normalize( basic_bignum& denom, basic_bignum& num, int& x ) const + { + size_t r = denom.length() - 1; + uint64_t y = denom.data_[r]; + + x = 0; + while ( (y & l_bit) == 0 ) + { + y <<= 1; + x++; + } + denom <<= x; + num <<= x; + if ( r > 0 && denom.data_[r] < denom.data_[r-1] ) + { + denom *= max_basic_type; + num *= max_basic_type; + return 1; + } + return 0; + } + + void unnormalize( basic_bignum& rem, int x, int secondDone ) const + { + if ( secondDone ) + { + rem /= max_basic_type; + } + if ( x > 0 ) + { + rem >>= x; + } + else + { + rem.reduce(); + } + } + + void divide( basic_bignum denom, basic_bignum& quot, basic_bignum& rem, bool remDesired ) const + { + if ( denom.length() == 0 ) + { + throw std::runtime_error( "Zero divide." ); + } + bool quot_neg = neg_ ^ denom.neg_; + bool rem_neg = neg_; + int x = 0; + basic_bignum num = *this; + num.neg_ = denom.neg_ = false; + if ( num < denom ) + { + quot = uint64_t(0); + rem = num; + rem.neg_ = rem_neg; + return; + } + if ( denom.length() == 1 && num.length() == 1 ) + { + quot = uint64_t( num.data_[0]/denom.data_[0] ); + rem = uint64_t( num.data_[0]%denom.data_[0] ); + quot.neg_ = quot_neg; + rem.neg_ = rem_neg; + return; + } + else if (denom.length() == 1 && (denom.data_[0] & l_mask) == 0 ) + { + // Denominator fits into a half word + uint64_t divisor = denom.data_[0], dHi = 0, + q1, r, q2, dividend; + quot.set_length(length()); + for (size_t i=length(); i-- > 0; ) + { + dividend = (dHi << basic_type_halfBits) | (data_[i] >> basic_type_halfBits); + q1 = dividend/divisor; + r = dividend % divisor; + dividend = (r << basic_type_halfBits) | (data_[i] & r_mask); + q2 = dividend/divisor; + dHi = dividend % divisor; + quot.data_[i] = (q1 << basic_type_halfBits) | q2; + } + quot.reduce(); + rem = dHi; + quot.neg_ = quot_neg; + rem.neg_ = rem_neg; + return; + } + basic_bignum num0 = num, denom0 = denom; + int second_done = normalize(denom, num, x); + size_t l = denom.length() - 1; + size_t n = num.length() - 1; + quot.set_length(n - l); + for (size_t i=quot.length(); i-- > 0; ) + quot.data_[i] = 0; + rem = num; + if ( rem.data_[n] >= denom.data_[l] ) + { + rem.incr_length(rem.length() + 1); + n++; + quot.incr_length(quot.length() + 1); + } + uint64_t d = denom.data_[l]; + for ( size_t k = n; k > l; k-- ) + { + uint64_t q = DDquotient(rem.data_[k], rem.data_[k-1], d); + subtractmul( rem.data_ + k - l - 1, denom.data_, l + 1, q ); + quot.data_[k - l - 1] = q; + } + quot.reduce(); + quot.neg_ = quot_neg; + if ( remDesired ) + { + unnormalize(rem, x, second_done); + rem.neg_ = rem_neg; + } + } + + size_t length() const { return length_; } + uint64_t* begin() { return data_; } + const uint64_t* begin() const { return data_; } + uint64_t* end() { return data_ + length_; } + const uint64_t* end() const { return data_ + length_; } + + void set_length(size_t n) + { + length_ = n; + if ( length_ > capacity() ) + { + if ( dynamic_ ) + { + delete[] data_; + } + capacity_ = round_up(length_); + data_ = allocator().allocate(capacity_); + dynamic_ = true; + } + } + + size_t round_up(size_t i) const // Find suitable new block size + { + return (i/word_length + 1) * word_length; + } + + template + typename std::enable_if::value && + !std::is_signed::value && + sizeof(T) <= sizeof(int64_t),void>::type + initialize_from_integer(T u) + { + data_ = values_; + dynamic_ = false; + length_ = u != 0 ? 1 : 0; + + data_ [0] = u; + } + + template + typename std::enable_if::value && + !std::is_signed::value && + sizeof(int64_t) < sizeof(T) && + sizeof(T) <= sizeof(int64_t)*2, void>::type + initialize_from_integer(T u) + { + data_ = values_; + dynamic_ = false; + length_ = u != 0 ? 2 : 0; + + data_[0] = uint64_t(u & max_basic_type); + u >>= basic_type_bits; + data_[1] = uint64_t(u & max_basic_type); + } + + void initialize( const basic_bignum& n ) + { + neg_ = n.neg_; + length_ = n.length_; + + if ( length_ <= 2 ) + { + data_ = values_; + dynamic_ = false; + values_ [0] = n.data_ [0]; + values_ [1] = n.data_ [1]; + } + else + { + capacity_ = round_up( length_ ); + data_ = allocator().allocate(capacity_); + dynamic_ = true; + if ( length_ > 0 ) + { + std::memcpy( data_, n.data_, length_*sizeof(uint64_t) ); + } + reduce(); + } + } + + void initialize(basic_bignum&& other) + { + neg_ = other.neg_; + length_ = other.length_; + dynamic_ = other.dynamic_; + + if (other.dynamic_) + { + capacity_ = other.capacity_; + data_ = other.data_; + + other.data_ = other.values_; + other.dynamic_ = false; + other.length_ = 0; + other.neg_ = false; + } + else + { + values_[0] = other.data_[0]; + values_[1] = other.data_[1]; + data_ = values_; + } + } + + void reduce() + { + uint64_t* p = end() - 1; + uint64_t* pBegin = begin(); + while ( p >= pBegin ) + { + if ( *p ) + { + break; + } + --length_; + --p; + } + if ( length_ == 0 ) + { + neg_ = false; + } + } + + void incr_length( size_t len_new ) + { + size_t len_old = length_; + length_ = len_new; // length_ > len_old + + if ( length_ > capacity() ) + { + size_t capacity_new = round_up( length_ ); + + uint64_t* data_old = data_; + + data_ = allocator().allocate(capacity_new); + + if ( len_old > 0 ) + { + std::memcpy( data_, data_old, len_old*sizeof(uint64_t) ); + } + if ( dynamic_ ) + { + allocator().deallocate(data_old,capacity_); + } + capacity_ = capacity_new; + dynamic_ = true; + } + + if ( length_ > len_old ) + { + memset( data_+len_old, 0, (length_ - len_old)*sizeof(uint64_t) ); + } + } + + template + void initialize(const CharT* data, size_t length) + { + bool neg; + if (*data == '-') + { + neg = true; + data++; + --length; + } + else + { + neg = false; + } + + basic_bignum v = 0; + for (size_t i = 0; i < length; i++) + { + CharT c = data[i]; + switch (c) + { + case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': + v = (v * 10) + (uint64_t)(c - '0'); + break; + default: + throw std::runtime_error(std::string("Invalid digit ") + "\'" + (char)c + "\'"); + } + } + + if ( neg ) + { + v.neg_ = true; + } + initialize(std::move(v)); + } + + template + void initialize(const CharT* data, size_t length, uint8_t base) + { + if (!(base >= 2 && base <= 16)) + { + throw std::runtime_error("Unsupported base"); + } + + bool neg; + if (*data == '-') + { + neg = true; + data++; + --length; + } + else + { + neg = false; + } + + basic_bignum v = 0; + for (size_t i = 0; i < length; i++) + { + CharT c = data[i]; + uint64_t d; + switch (c) + { + case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': + d = (uint64_t)(c - '0'); + break; + case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': + d = (uint64_t)(c - ('a' - 10)); + break; + case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': + d = (uint64_t)(c - ('A' - 10)); + break; + default: + throw std::runtime_error(std::string("Invalid digit in base ") + std::to_string(base) + ": \'" + (char)c + "\'"); + } + if (d >= base) + { + throw std::runtime_error(std::string("Invalid digit in base ") + std::to_string(base) + ": \'" + (char)c + "\'"); + } + v = (v * base) + d; + } + + if ( neg ) + { + v.neg_ = true; + } + initialize(std::move(v)); + } +}; + +typedef basic_bignum> bignum; + +} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/byte_string.hpp b/invehicle-apps/3rd-party-libs/jsoncons/byte_string.hpp new file mode 100644 index 0000000..4fd586e --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/byte_string.hpp @@ -0,0 +1,719 @@ +// Copyright 2013 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_BYTE_STRING_HPP +#define JSONCONS_BYTE_STRING_HPP + +#include +#include +#include +#include +#include // std::memcmp +#include // std::allocator +#include +#include +#include +#include // std::move +#include +#include + +namespace jsoncons { + +// Algorithms + +namespace detail { +template +typename std::enable_if::value_type,uint8_t>::value,size_t>::type +encode_base64_generic(InputIt first, InputIt last, const char alphabet[65], Container& result) +{ + size_t count = 0; + unsigned char a3[3]; + unsigned char a4[4]; + unsigned char fill = alphabet[64]; + int i = 0; + int j = 0; + + while (first != last) + { + a3[i++] = *first++; + if (i == 3) + { + a4[0] = (a3[0] & 0xfc) >> 2; + a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); + a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); + a4[3] = a3[2] & 0x3f; + + for (i = 0; i < 4; i++) + { + result.push_back(alphabet[a4[i]]); + ++count; + } + i = 0; + } + } + + if (i > 0) + { + for (j = i; j < 3; ++j) + { + a3[j] = 0; + } + + a4[0] = (a3[0] & 0xfc) >> 2; + a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); + a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); + + for (j = 0; j < i + 1; ++j) + { + result.push_back(alphabet[a4[j]]); + ++count; + } + + if (fill != 0) + { + while (i++ < 3) + { + result.push_back(fill); + ++count; + } + } + } + + return count; +} + +// Hack to support vs2015 +template +typename std::enable_if::type +decode_base64_generic(InputIt first, InputIt last, + const uint8_t reverse_alphabet[256], + F f, + Container& result) +{ + uint8_t a4[4], a3[3]; + uint8_t i = 0; + uint8_t j = 0; + + while (first != last && *first != '=') + { + if (!f(*first)) + { + JSONCONS_THROW(json_runtime_error("Cannot decode encoded byte string")); + } + + a4[i++] = *first++; + if (i == 4) + { + for (i = 0; i < 4; ++i) + { + a4[i] = reverse_alphabet[a4[i]]; + } + + a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4); + a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2); + a3[2] = ((a4[2] & 0x3) << 6) + a4[3]; + + for (i = 0; i < 3; i++) + { + result.push_back(a3[i]); + } + i = 0; + } + } + + if (i > 0) + { + for (j = 0; j < i; ++j) + { + a4[j] = reverse_alphabet[a4[j]]; + } + + a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4); + a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2); + + for (j = 0; j < i - 1; ++j) + { + result.push_back(a3[j]); + } + } +} + +} + +template +typename std::enable_if::value_type,uint8_t>::value,size_t>::type +encode_base16(InputIt first, InputIt last, Container& result) +{ + static constexpr char characters[] = "0123456789ABCDEF"; + + for (auto it = first; it != last; ++it) + { + uint8_t c = *it; + result.push_back(characters[c >> 4]); + result.push_back(characters[c & 0xf]); + } + return (last-first)*2; +} + +template +typename std::enable_if::value_type,uint8_t>::value,size_t>::type +encode_base64url(InputIt first, InputIt last, Container& result) +{ + static constexpr char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789-_" + "\0"; + return detail::encode_base64_generic(first, last, alphabet, result); +} + +template +typename std::enable_if::value_type,uint8_t>::value,size_t>::type +encode_base64(InputIt first, InputIt last, Container& result) +{ + static constexpr char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/" + "="; + return detail::encode_base64_generic(first, last, alphabet, result); +} + +template +bool is_base64(Char c) +{ + return (c >= 0 && c < 128) && (isalnum((int)c) || c == '+' || c == '/'); +} + +template +bool is_base64url(Char c) +{ + return (c >= 0 && c < 128) && (isalnum((int)c) || c == '-' || c == '_'); +} + +inline +static bool is_base64url(int c) +{ + return isalnum(c) || c == '-' || c == '_'; +} + +// decode + +// Hack to support vs2015 +template +typename std::enable_if::type +decode_base64url(InputIt first, InputIt last, Container& result) +{ + static constexpr uint8_t reverse_alphabet[256] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 62, 0xff, 0xff, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0xff, 0xff, 0xff, 0xff, 63, + 0xff, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + + jsoncons::detail::decode_base64_generic(first, last, reverse_alphabet, + is_base64url::value_type>, + result); +} + +// Hack to support vs2015 +template +typename std::enable_if::type +decode_base64(InputIt first, InputIt last, Container& result) +{ + static constexpr uint8_t reverse_alphabet[256] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 62, 0xff, 0xff, 0xff, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + jsoncons::detail::decode_base64_generic(first, last, reverse_alphabet, + is_base64::value_type>, + result); +} + +// Hack to support vs2015 +template +typename std::enable_if::type +decode_base16(InputIt first, InputIt last, Container& result) +{ + size_t len = std::distance(first,last); + if (len & 1) + { + JSONCONS_THROW(json_runtime_error("Cannot decode encoded base16 string - odd length")); + } + + InputIt it = first; + while (it != last) + { + uint8_t val; + auto a = *it++; + if (a >= '0' && a <= '9') + { + val = (a - '0') << 4; + } + else if ((a | 0x20) >= 'a' && (a | 0x20) <= 'f') + { + val = ((a | 0x20) - 'a' + 10) << 4; + } + else + { + JSONCONS_THROW(json_runtime_error("Not a hex digit. Cannot decode encoded base16 string")); + } + + auto b = *it++; + if (b >= '0' && b <= '9') + { + val |= (b - '0'); + } + else if ((b | 0x20) >= 'a' && (b | 0x20) <= 'f') + { + val |= ((b | 0x20) - 'a' + 10); + } + else + { + JSONCONS_THROW(json_runtime_error("Not a hex digit. Cannot decode encoded base16 string")); + } + + result.push_back(val); + } +} + +struct byte_traits +{ + typedef uint8_t char_type; + + static constexpr int eof() + { + return std::char_traits::eof(); + } + + static int compare(const char_type* s1, const char_type* s2, std::size_t count) + { + return std::memcmp(s1,s2,count); + } +}; + +// basic_byte_string + +template +class basic_byte_string; + +// byte_string_view +class byte_string_view +{ + const uint8_t* data_; + size_t length_; +public: + typedef byte_traits traits_type; + + typedef const uint8_t* const_iterator; + typedef const uint8_t* iterator; + typedef std::size_t size_type; + typedef uint8_t value_type; + + byte_string_view() + : data_(nullptr), length_(0) + { + } + + byte_string_view(const uint8_t* data, size_t length) + : data_(data), length_(length) + { + } + + byte_string_view(const byte_string_view&) = default; + + byte_string_view(byte_string_view&&) = default; + + byte_string_view& operator=(const byte_string_view&) = default; + + byte_string_view& operator=(byte_string_view&&) = default; + + const uint8_t* data() const + { + return data_; + } + + size_t length() const + { + return length_; + } + + size_t size() const + { + return length_; + } + + // iterator support + const_iterator begin() const noexcept + { + return data_; + } + const_iterator end() const noexcept + { + return data_ + length_; + } + + uint8_t operator[](size_type pos) const + { + return data_[pos]; + } + + int compare(const byte_string_view& s) const + { + const int rc = traits_type::compare(data_, s.data(), (std::min)(length_, s.length())); + return rc != 0 ? rc : (length_ == s.length() ? 0 : length_ < s.length() ? -1 : 1); + } + + template + int compare(const basic_byte_string& s) const + { + const int rc = traits_type::compare(data_, s.data(), (std::min)(length_, s.length())); + return rc != 0 ? rc : (length_ == s.length() ? 0 : length_ < s.length() ? -1 : 1); + } + + template + friend std::basic_ostream& operator<<(std::basic_ostream& os, const byte_string_view& bstr) + { + std::basic_ostringstream ss; + ss.flags(std::ios::hex); + ss.precision(2); + ss.width(2); + ss.fill('0'); + + bool first = true; + for (auto b : bstr) + { + if (first) + { + first = false; + } + else + { + ss << ' '; + } + ss << (int)b; + } + os << ss.str(); + return os; + } +}; + +// basic_byte_string +template > +class basic_byte_string +{ + std::vector data_; +public: + typedef byte_traits traits_type; + + typedef typename std::vector::const_iterator const_iterator; + typedef typename std::vector::const_iterator iterator; + typedef std::size_t size_type; + typedef uint8_t value_type; + + basic_byte_string() = default; + + explicit basic_byte_string(const Allocator& alloc) + : data_(alloc) + { + } + + basic_byte_string(std::initializer_list init) + : data_(std::move(init)) + { + } + + basic_byte_string(std::initializer_list init, const Allocator& alloc) + : data_(std::move(init), alloc) + { + } + + explicit basic_byte_string(const byte_string_view& v) + : data_(v.begin(),v.end()) + { + } + + basic_byte_string(const basic_byte_string& v) + : data_(v.data_) + { + } + + basic_byte_string(basic_byte_string&& v) + { + data_.swap(v.data_); + } + + basic_byte_string(const byte_string_view& v, const Allocator& alloc) + : data_(v.begin(),v.end(),alloc) + { + } + + basic_byte_string(const char* s) + { + while (*s) + { + data_.push_back(*s++); + } + } + + basic_byte_string(const uint8_t* data, size_t length) + : data_(data, data+length) + { + } + + basic_byte_string& operator=(const basic_byte_string& s) = default; + + basic_byte_string& operator=(basic_byte_string&& s) = default; + + operator byte_string_view() const noexcept + { + return byte_string_view(data(),length()); + } + + void reserve(size_t new_cap) + { + data_.reserve(new_cap); + } + + void push_back(uint8_t b) + { + data_.push_back(b); + } + + void assign(const uint8_t* s, size_t count) + { + data_.clear(); + data_.insert(s, s+count); + } + + void append(const uint8_t* s, size_t count) + { + data_.insert(s, s+count); + } + + void clear() + { + data_.clear(); + } + + uint8_t operator[](size_type pos) const + { + return data_[pos]; + } + + // iterator support + const_iterator begin() const noexcept + { + return data_.begin(); + } + const_iterator end() const noexcept + { + return data_.end(); + } + + const uint8_t* data() const + { + return data_.data(); + } + + size_t size() const + { + return data_.size(); + } + + size_t length() const + { + return data_.size(); + } + + int compare(const byte_string_view& s) const + { + const int rc = traits_type::compare(data(), s.data(), (std::min)(length(), s.length())); + return rc != 0 ? rc : (length() == s.length() ? 0 : length() < s.length() ? -1 : 1); + } + + int compare(const basic_byte_string& s) const + { + const int rc = traits_type::compare(data(), s.data(), (std::min)(length(), s.length())); + return rc != 0 ? rc : (length() == s.length() ? 0 : length() < s.length() ? -1 : 1); + } + + template + friend std::basic_ostream& operator<<(std::basic_ostream& os, const basic_byte_string& o) + { + os << byte_string_view(o); + return os; + } +}; + +// == +inline +bool operator==(const byte_string_view& lhs, const byte_string_view& rhs) +{ + return lhs.compare(rhs) == 0; +} +template +bool operator==(const byte_string_view& lhs, const basic_byte_string& rhs) +{ + return lhs.compare(rhs) == 0; +} +template +bool operator==(const basic_byte_string& lhs, const byte_string_view& rhs) +{ + return rhs.compare(lhs) == 0; +} +template +bool operator==(const basic_byte_string& lhs, const basic_byte_string& rhs) +{ + return rhs.compare(lhs) == 0; +} + +// != + +inline +bool operator!=(const byte_string_view& lhs, const byte_string_view& rhs) +{ + return lhs.compare(rhs) != 0; +} +template +bool operator!=(const byte_string_view& lhs, const basic_byte_string& rhs) +{ + return lhs.compare(rhs) != 0; +} +template +bool operator!=(const basic_byte_string& lhs, const byte_string_view& rhs) +{ + return rhs.compare(lhs) != 0; +} +template +bool operator!=(const basic_byte_string& lhs, const basic_byte_string& rhs) +{ + return rhs.compare(lhs) != 0; +} + +// <= + +inline +bool operator<=(const byte_string_view& lhs, const byte_string_view& rhs) +{ + return lhs.compare(rhs) <= 0; +} +template +bool operator<=(const byte_string_view& lhs, const basic_byte_string& rhs) +{ + return lhs.compare(rhs) <= 0; +} +template +bool operator<=(const basic_byte_string& lhs, const byte_string_view& rhs) +{ + return rhs.compare(lhs) >= 0; +} +template +bool operator<=(const basic_byte_string& lhs, const basic_byte_string& rhs) +{ + return rhs.compare(lhs) >= 0; +} + +// < + +inline +bool operator<(const byte_string_view& lhs, const byte_string_view& rhs) +{ + return lhs.compare(rhs) < 0; +} +template +bool operator<(const byte_string_view& lhs, const basic_byte_string& rhs) +{ + return lhs.compare(rhs) < 0; +} +template +bool operator<(const basic_byte_string& lhs, const byte_string_view& rhs) +{ + return rhs.compare(lhs) > 0; +} +template +bool operator<(const basic_byte_string& lhs, const basic_byte_string& rhs) +{ + return rhs.compare(lhs) > 0; +} + +// >= + +inline +bool operator>=(const byte_string_view& lhs, const byte_string_view& rhs) +{ + return lhs.compare(rhs) >= 0; +} +template +bool operator>=(const byte_string_view& lhs, const basic_byte_string& rhs) +{ + return lhs.compare(rhs) >= 0; +} +template +bool operator>=(const basic_byte_string& lhs, const byte_string_view& rhs) +{ + return rhs.compare(lhs) <= 0; +} +template +bool operator>=(const basic_byte_string& lhs, const basic_byte_string& rhs) +{ + return rhs.compare(lhs) <= 0; +} + +// > + +inline +bool operator>(const byte_string_view& lhs, const byte_string_view& rhs) +{ + return lhs.compare(rhs) > 0; +} +template +bool operator>(const byte_string_view& lhs, const basic_byte_string& rhs) +{ + return lhs.compare(rhs) > 0; +} +template +bool operator>(const basic_byte_string& lhs, const byte_string_view& rhs) +{ + return rhs.compare(lhs) < 0; +} +template +bool operator>(const basic_byte_string& lhs, const basic_byte_string& rhs) +{ + return rhs.compare(lhs) < 0; +} + +typedef basic_byte_string> byte_string; + + +} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/config/binary_detail.hpp b/invehicle-apps/3rd-party-libs/jsoncons/config/binary_detail.hpp new file mode 100644 index 0000000..9b94906 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/config/binary_detail.hpp @@ -0,0 +1,547 @@ +// Copyright 2017 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_CONFIG_BINARY_DETAIL_HPP +#define JSONCONS_CONFIG_BINARY_DETAIL_HPP + +#include +#include +#include +#include // std::memcpy +#include +#include // std::enable_if + +#if defined(__apple_build_version__) && ((__clang_major__ < 8) || ((__clang_major__ == 8) && (__clang_minor__ < 1))) +#define APPLE_MISSING_INTRINSICS 1 +#endif + +// The definitions below follow the definitions in compiler_support_p.h, https://github.com/01org/tinycbor +// MIT license + +#ifdef __F16C__ +# include +#endif + +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) || \ + (__has_builtin(__builtin_bswap64) && __has_builtin(__builtin_bswap32)) +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define JSONCONS_BE64_TO_H __builtin_bswap64 +# define JSONCONS_H_TO_BE64 __builtin_bswap64 +# define JSONCONS_BE32_TO_H __builtin_bswap32 +# define JSONCONS_H_TO_BE32 __builtin_bswap32 +# ifdef __INTEL_COMPILER +# define JSONCONS_BE16_TO_H _bswap16 +# define JSONCONS_H_TO_BE16 _bswap16 +# elif (__GNUC__ * 100 + __GNUC_MINOR__ >= 608) || __has_builtin(__builtin_bswap16) +# define JSONCONS_BE16_TO_H __builtin_bswap16 +# define JSONCONS_H_TO_BE16 __builtin_bswap16 +# else +# define JSONCONS_BE16_TO_H(x) (((uint16_t)x >> 8) | ((uint16_t)x << 8)) +# define JSONCONS_H_TO_BE16 JSONCONS_BE16_TO_H +# endif +# define JSONCONS_LE64_TO_H +# define JSONCONS_H_TO_LE64 +# define JSONCONS_LE32_TO_H +# define JSONCONS_H_TO_LE32 +# define JSONCONS_LE16_TO_H +# define JSONCONS_H_TO_LE16 +# else +# define JSONCONS_LE64_TO_H __builtin_bswap64 +# define JSONCONS_H_TO_LE64 __builtin_bswap64 +# define JSONCONS_LE32_TO_H __builtin_bswap32 +# define JSONCONS_H_TO_LE32 __builtin_bswap32 +# ifdef __INTEL_COMPILER +# define JSONCONS_LE16_TO_H _bswap16 +# define JSONCONS_H_TO_LE16 _bswap16 +# elif (__GNUC__ * 100 + __GNUC_MINOR__ >= 608) || __has_builtin(__builtin_bswap16) +# define JSONCONS_LE16_TO_H __builtin_bswap16 +# define JSONCONS_H_TO_LE16 __builtin_bswap16 +# else +# define JSONCONS_LE16_TO_H(x) (((uint16_t)x >> 8) | ((uint16_t)x << 8)) +# define JSONCONS_H_TO_LE16 JSONCONS_LE16_TO_H +# endif +# define JSONCONS_BE64_TO_H +# define JSONCONS_H_TO_BE64 +# define JSONCONS_BE32_TO_H +# define JSONCONS_H_TO_BE32 +# define JSONCONS_BE16_TO_H +# define JSONCONS_H_TO_BE16 +# endif +#elif defined(__sun) +# include +#elif defined(_MSC_VER) +/* MSVC, which implies Windows, which implies little-endian and sizeof(long) == 4 */ +# define JSONCONS_BE64_TO_H _byteswap_uint64 +# define JSONCONS_H_TO_BE64 _byteswap_uint64 +# define JSONCONS_BE32_TO_H _byteswap_ulong +# define JSONCONS_H_TO_BE32 _byteswap_ulong +# define JSONCONS_BE16_TO_H _byteswap_ushort +# define JSONCONS_H_TO_BE16 _byteswap_ushort +# define JSONCONS_LE64_TO_H +# define JSONCONS_H_TO_LE64 +# define JSONCONS_LE32_TO_H +# define JSONCONS_H_TO_LE32 +# define JSONCONS_LE16_TO_H +# define JSONCONS_H_TO_LE16 +#endif +#ifndef JSONCONS_BE16_TO_H +# include +# define JSONCONS_BE16_TO_H ntohs +# define JSONCONS_H_TO_BE16 htons +#endif +#ifndef JSONCONS_BE32_TO_H +# include +# define JSONCONS_BE32_TO_H ntohl +# define JSONCONS_H_TO_BE32 htonl +#endif +#ifndef JSONCONS_BE64_TO_H +# define JSONCONS_BE64_TO_H ntohll +# define JSONCONS_H_TO_BE64 htonll +/* ntohll isn't usually defined */ +# ifndef ntohll +# if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define ntohll +# define htonll +# elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define ntohll(x) ((ntohl((uint32_t)(x)) * UINT64_C(0x100000000)) + (ntohl((x) >> 32))) +# define htonll ntohll +# else +# error "Unable to determine byte order!" +# endif +# endif +#endif + +namespace jsoncons { namespace detail { + +class read_nbytes_failed : public std::invalid_argument, public virtual json_exception +{ +public: + explicit read_nbytes_failed(size_t count) noexcept + : std::invalid_argument("") + { + buffer_.append("Failed attempting to read "); + buffer_.append(std::to_string(count)); + buffer_.append(" bytes from vector"); + } + ~read_nbytes_failed() noexcept + { + } + const char* what() const noexcept override + { + return buffer_.c_str(); + } +private: + std::string buffer_; +}; + +namespace detail { + +static inline bool add_check_overflow(size_t v1, size_t v2, size_t *r) +{ +#if ((defined(__GNUC__) && (__GNUC__ >= 5)) && !defined(__INTEL_COMPILER)) || __has_builtin(__builtin_add_overflow) + return __builtin_add_overflow(v1, v2, r); +#else + // unsigned additions are well-defined + *r = v1 + v2; + return v1 > v1 + v2; +#endif +} + +} + +inline +uint16_t encode_half(double val) +{ +#if defined(__F16C__) && !defined(APPLE_MISSING_INTRINSICS) + return _cvtss_sh((float)val, 3); +#else + uint64_t v; + std::memcpy(&v, &val, sizeof(v)); + int sign = v >> 63 << 15; + int exp = (v >> 52) & 0x7ff; + int mant = v << 12 >> 12 >> (53-11); /* keep only the 11 most significant bits of the mantissa */ + exp -= 1023; + if (exp == 1024) { + /* infinity or NaN */ + exp = 16; + mant >>= 1; + } else if (exp >= 16) { + /* overflow, as largest number */ + exp = 15; + mant = 1023; + } else if (exp >= -14) { + /* regular normal */ + } else if (exp >= -24) { + /* subnormal */ + mant |= 1024; + mant >>= -(exp + 14); + exp = -15; + } else { + /* underflow, make zero */ + return 0; + } + + /* safe cast here as bit operations above guarantee not to overflow */ + return (uint16_t)(sign | ((exp + 15) << 10) | mant); +#endif +} + +/* this function was copied & adapted from RFC 7049 Appendix D */ +inline +double decode_half(uint16_t half) +{ +#if defined(__F16C__) && !defined(APPLE_MISSING_INTRINSICS) + return _cvtsh_ss(half); +#else + int exp = (half >> 10) & 0x1f; + int mant = half & 0x3ff; + double val; + if (exp == 0) + { + val = ldexp((double)mant, -24); + } + else if (exp != 31) + { + val = ldexp(mant + 1024.0, exp - 25); + } + else + { + val = mant == 0 ? INFINITY : NAN; + } + return half & 0x8000 ? -val : val; +#endif +} + +// to_big_endian + + +template +typename std::enable_if::value && sizeof(T) == sizeof(uint8_t),void>::type +to_big_endian(T val, OutputIt d_first) +{ + *d_first = static_cast(val); +} + + +template +typename std::enable_if::value && +sizeof(T) == sizeof(uint16_t),void>::type +to_big_endian(T val, OutputIt d_first) +{ + T x = JSONCONS_H_TO_BE16(val); + + uint8_t where[sizeof(T)]; + std::memcpy(where, &x, sizeof(T)); + + *d_first++ = where[0]; + *d_first++ = where[1]; +} + +template +typename std::enable_if::value && +sizeof(T) == sizeof(uint32_t),void>::type +to_big_endian(T val, OutputIt d_first) +{ + T x = JSONCONS_H_TO_BE32(val); + + uint8_t where[sizeof(T)]; + std::memcpy(where, &x, sizeof(T)); + + *d_first++ = where[0]; + *d_first++ = where[1]; + *d_first++ = where[2]; + *d_first++ = where[3]; +} + +template +typename std::enable_if::value && +sizeof(T) == sizeof(uint64_t),void>::type +to_big_endian(T val, OutputIt d_first) +{ + T x = JSONCONS_H_TO_BE64(val); + + uint8_t where[sizeof(T)]; + std::memcpy(where, &x, sizeof(T)); + + *d_first++ = where[0]; + *d_first++ = where[1]; + *d_first++ = where[2]; + *d_first++ = where[3]; + *d_first++ = where[4]; + *d_first++ = where[5]; + *d_first++ = where[6]; + *d_first++ = where[7]; +} + +template +void to_big_endian(float val, OutputIt d_first) +{ + uint32_t where; + std::memcpy(&where,&val,sizeof(val)); + to_big_endian(where, d_first); +} + +template +void to_big_endian(double val, OutputIt d_first) +{ + uint64_t where; + std::memcpy(&where,&val,sizeof(val)); + to_big_endian(where, d_first); +} + +// to_little_endian + +template +typename std::enable_if::value && +sizeof(T) == sizeof(uint32_t),void>::type +to_little_endian(T val, OutputIt d_first) +{ + T x = JSONCONS_H_TO_LE32(val); + + uint8_t where[sizeof(T)]; + std::memcpy(where, &x, sizeof(T)); + + *d_first++ = where[0]; + *d_first++ = where[1]; + *d_first++ = where[2]; + *d_first++ = where[3]; +} + +template +typename std::enable_if::value && +sizeof(T) == sizeof(uint64_t),void>::type +to_little_endian(T val, OutputIt d_first) +{ + T x = JSONCONS_H_TO_LE64(val); + + uint8_t where[sizeof(T)]; + std::memcpy(where, &x, sizeof(T)); + + *d_first++ = where[0]; + *d_first++ = where[1]; + *d_first++ = where[2]; + *d_first++ = where[3]; + *d_first++ = where[4]; + *d_first++ = where[5]; + *d_first++ = where[6]; + *d_first++ = where[7]; +} + +template +void to_little_endian(float val, OutputIt d_first) +{ + uint32_t where; + std::memcpy(&where,&val,sizeof(val)); + to_little_endian(where, d_first); +} + +template +void to_little_endian(double val, OutputIt d_first) +{ + uint64_t where; + std::memcpy(&where,&val,sizeof(val)); + to_little_endian(where, d_first); +} + +// from_big_endian + +template +typename std::enable_if::value && +sizeof(T) == sizeof(uint8_t),T>::type +from_big_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp) +{ + if (first + sizeof(T) > last) + { + *endp = first; + return 0; + } + else + { + *endp = first + sizeof(T); + return static_cast(*(first)); + } +} + +template +typename std::enable_if::value && +sizeof(T) == sizeof(uint16_t),T>::type +from_big_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp) +{ + if (first + sizeof(T) > last) + { + *endp = first; + return 0; + } + else + { + *endp = first + sizeof(T); + T val; + std::memcpy(&val,first,sizeof(T)); + return JSONCONS_BE16_TO_H(val); + } +} + +template +typename std::enable_if::value && sizeof(T) == sizeof(uint32_t),T>::type +from_big_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp) +{ + if (first + sizeof(T) > last) + { + *endp = first; + return 0; + } + else + { + *endp = first + sizeof(T); + T val; + std::memcpy(&val,first,sizeof(T)); + return JSONCONS_BE32_TO_H(val); + } +} + +template +typename std::enable_if::value && sizeof(T) == sizeof(uint64_t),T>::type +from_big_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp) +{ + if (first + sizeof(T) > last) + { + *endp = first; + return 0; + } + else + { + *endp = first + sizeof(T); + T val; + std::memcpy(&val,first,sizeof(T)); + return JSONCONS_BE64_TO_H(val); + } +} + +template +typename std::enable_if::value && +sizeof(T) == sizeof(uint32_t),T>::type +from_big_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp) +{ + uint32_t data = from_big_endian(first,last,endp); + T val; + std::memcpy(&val,&data,sizeof(T)); + return val; +} + +template +typename std::enable_if::value && +sizeof(T) == sizeof(uint64_t),T>::type +from_big_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp) +{ + uint64_t data = from_big_endian(first,last,endp); + T val; + std::memcpy(&val,&data,sizeof(T)); + return val; +} + +// from_little_endian + +template +typename std::enable_if::value && +sizeof(T) == sizeof(uint8_t),T>::type +from_little_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp) +{ + if (first + sizeof(T) > last) + { + *endp = first; + return 0; + } + else + { + *endp = first + sizeof(T); + return static_cast(*(first)); + } +} + +template +typename std::enable_if::value && +sizeof(T) == sizeof(uint16_t),T>::type +from_little_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp) +{ + if (first + sizeof(T) > last) + { + *endp = first; + return 0; + } + else + { + *endp = first + sizeof(T); + T val; + std::memcpy(&val,first,sizeof(T)); + return JSONCONS_LE16_TO_H(val); + } +} + +template +typename std::enable_if::value && sizeof(T) == sizeof(uint32_t),T>::type +from_little_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp) +{ + if (first + sizeof(T) > last) + { + *endp = first; + return 0; + } + else + { + *endp = first + sizeof(T); + T val; + std::memcpy(&val,first,sizeof(T)); + return JSONCONS_LE32_TO_H(val); + } +} + +template +typename std::enable_if::value && sizeof(T) == sizeof(uint64_t),T>::type +from_little_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp) +{ + if (first + sizeof(T) > last) + { + *endp = first; + return 0; + } + else + { + *endp = first + sizeof(T); + T val; + std::memcpy(&val,first,sizeof(T)); + return JSONCONS_LE64_TO_H(val); + } +} + +template +typename std::enable_if::value && +sizeof(T) == sizeof(uint32_t),T>::type +from_little_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp) +{ + uint32_t data = from_little_endian(first,last,endp); + T val; + std::memcpy(&val,&data,sizeof(T)); + return val; +} + +template +typename std::enable_if::value && +sizeof(T) == sizeof(uint64_t),T>::type +from_little_endian(const uint8_t* first, const uint8_t* last, const uint8_t** endp) +{ + uint64_t data = from_little_endian(first,last,endp); + T val; + std::memcpy(&val,&data,sizeof(T)); + return val; +} + +}} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/config/jsoncons_config.hpp b/invehicle-apps/3rd-party-libs/jsoncons/config/jsoncons_config.hpp new file mode 100644 index 0000000..d4fdf9f --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/config/jsoncons_config.hpp @@ -0,0 +1,142 @@ +// Copyright 2013 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_JSONCONS_CONFIG_HPP +#define JSONCONS_JSONCONS_CONFIG_HPP + +#include +#include +#include +#include +#include + +// Uncomment the following line to suppress deprecated names (recommended for new code) +//#define JSONCONS_NO_DEPRECATED + +// The definitions below follow the definitions in compiler_support_p.h, https://github.com/01org/tinycbor +// MIT license + +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54577 +#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 9 +#define JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR 1 +#endif + +#if defined(__clang__) +# define JSONCONS_FALLTHROUGH [[clang::fallthrough]] +#elif defined(__GNUC__) && ((__GNUC__ >= 7)) +# define JSONCONS_FALLTHROUGH __attribute__((fallthrough)) +#elif defined (__GNUC__) +# define JSONCONS_FALLTHROUGH // FALLTHRU +#else +# define JSONCONS_FALLTHROUGH +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define JSONCONS_LIKELY(x) __builtin_expect(!!(x), 1) +#define JSONCONS_UNLIKELY(x) __builtin_expect(!!(x), 0) +#define JSONCONS_UNREACHABLE() __builtin_unreachable() +#elif defined(_MSC_VER) +#define JSONCONS_LIKELY(x) x +#define JSONCONS_UNLIKELY(x) x +#define JSONCONS_UNREACHABLE() __assume(0) +#else +#define JSONCONS_LIKELY(x) x +#define JSONCONS_UNLIKELY(x) x +#define JSONCONS_UNREACHABLE() do {} while (0) +#endif + +// Follows boost 1_68 +#if !defined(JSONCONS_HAS_STRING_VIEW) +# if defined(__clang__) +# if (__cplusplus >= 201703) +# if __has_include() +# define JSONCONS_HAS_STRING_VIEW 1 +# endif // __has_include() +# endif // (__cplusplus >= 201703) +# endif // defined(__clang__) +# if defined(__GNUC__) +# if (__GNUC__ >= 7) +# if (__cplusplus >= 201703) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) +# define JSONCONS_HAS_STRING_VIEW 1 +# endif // (__cplusplus >= 201703) +# endif // (__GNUC__ >= 7) +# endif // defined(__GNUC__) +# if defined(_MSC_VER) +# if (_MSC_VER >= 1910 && _HAS_CXX17) +# define JSONCONS_HAS_STRING_VIEW +# endif // (_MSC_VER >= 1910 && _HAS_CXX17) +# endif // defined(_MSC_VER) +#endif // !defined(JSONCONS_HAS_STRING_VIEW) + +#define JSONCONS_NO_TO_CHARS + +// Deprecated symbols markup +#if !defined(JSONCONS_DEPRECATED) && defined(_MSC_VER) +#if (_MSC_VER) >= 1400 +#define JSONCONS_DEPRECATED(msg) __declspec(deprecated(msg)) +#endif +#endif + +#if !defined(JSONCONS_DEPRECATED) && defined(__has_extension) +#if __has_extension(attribute_deprecated_with_message) +#define JSONCONS_DEPRECATED(msg) __attribute__((deprecated(msg))) +#endif +#endif + +#if !defined(JSONCONS_DEPRECATED) +#define JSONCONS_DEPRECATED(msg) +#endif + +#if defined(ANDROID) || defined(__ANDROID__) +#define JSONCONS_HAS_STRTOLD_L +#if __ANDROID_API__ >= 21 +#else +#define JSONCONS_NO_LOCALECONV +#endif +#endif + +#if defined(_MSC_VER) +#define JSONCONS_HAS_MSC__STRTOD_L +#define JSONCONS_HAS_FOPEN_S +#endif + +#if !defined(JSONCONS_HAS_STRING_VIEW) +#include +namespace jsoncons { +template > +using basic_string_view = jsoncons::detail::basic_string_view; +using string_view = basic_string_view>; +using wstring_view = basic_string_view>; +} +#else +#include +namespace jsoncons { +template > +using basic_string_view = std::basic_string_view; +using string_view = std::string_view; +using wstring_view = std::wstring_view; +} +#endif + +#define JSONCONS_STRING_LITERAL(name, ...) \ + template \ + const std::basic_string& name##_literal() {\ + static const CharT s[] = { __VA_ARGS__};\ + static const std::basic_string sv(s, sizeof(s) / sizeof(CharT));\ + return sv;\ + } + +#define JSONCONS_EXPAND(X) X +#define JSONCONS_QUOTE(Prefix, A) JSONCONS_EXPAND(Prefix ## #A) + +#define JSONCONS_DEFINE_LITERAL( name ) \ +template CharT const* name##_literal(); \ +template<> inline char const * name##_literal() { return JSONCONS_QUOTE(,name); } \ +template<> inline wchar_t const* name##_literal() { return JSONCONS_QUOTE(L,name); } \ +template<> inline char16_t const* name##_literal() { return JSONCONS_QUOTE(u,name); } \ +template<> inline char32_t const* name##_literal() { return JSONCONS_QUOTE(U,name); } + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/config/version.hpp b/invehicle-apps/3rd-party-libs/jsoncons/config/version.hpp new file mode 100644 index 0000000..08373ec --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/config/version.hpp @@ -0,0 +1,40 @@ +// Copyright 2017 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_VERSION_HPP +#define JSONCONS_VERSION_HPP + +#include + +#define JSONCONS_VERSION_MAJOR 0 +#define JSONCONS_VERSION_MINOR 130 +#define JSONCONS_VERSION_PATCH 0 + +namespace jsoncons { + +struct versioning_info +{ + unsigned int const major; + unsigned int const minor; + unsigned int const patch; + + friend std::ostream& operator<<(std::ostream& os, const versioning_info& ver) + { + os << ver.major << '.' + << ver.minor << '.' + << ver.patch; + return os; + } +}; + +constexpr versioning_info version() +{ + return versioning_info{JSONCONS_VERSION_MAJOR, JSONCONS_VERSION_MINOR, JSONCONS_VERSION_PATCH}; +} + +} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/detail/grisu3.hpp b/invehicle-apps/3rd-party-libs/jsoncons/detail/grisu3.hpp new file mode 100644 index 0000000..d8bd811 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/detail/grisu3.hpp @@ -0,0 +1,405 @@ +/* +Implements the Grisu3 algorithm for printing floating-point numbers. + +Follows Florian Loitsch's grisu3_59_56 implementation, available at +http://florian.loitsch.com/publications, in bench.tar.gz, with +minor modifications. +*/ + +/* + Copyright (c) 2009 Florian Loitsch + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef JSONCONS_GRISU3_HPP +#define JSONCONS_GRISU3_HPP + +#pragma once +#include +#include +#include +#include +#include +#include // std::memmove + +namespace jsoncons { namespace detail { + +// diy_fp + +typedef struct diy_fp_t { + uint64_t f; + int e; +} diy_fp_t; + +inline +diy_fp_t minus(diy_fp_t x, diy_fp_t y) +{ + assert(x.e == y.e); + assert(x.f >= y.f); + diy_fp_t r = { x.f = x.f - y.f, x.e = x.e }; + return r; +} + +inline +diy_fp_t multiply(diy_fp_t x, diy_fp_t y) +{ + uint64_t a, b, c, d, ac, bc, ad, bd, tmp; + diy_fp_t r; uint64_t M32 = 0xFFFFFFFF; + a = x.f >> 32; b = x.f & M32; + c = y.f >> 32; d = y.f & M32; + ac = a * c; bc = b * c; ad = a * d; bd = b * d; + tmp = (bd >> 32) + (ad & M32) + (bc & M32); + tmp += 1U << 31; /// mult_round + r.f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); + r.e = x.e + y.e + 64; + return r; +} + +// k_comp + +inline +int k_comp(int e, int alpha, int /*gamma*/) +{ + constexpr double d_1_log2_10 = 0.30102999566398114; // 1 / lg(10) + return static_cast(std::ceil((alpha - e + 63) * d_1_log2_10)); +} + +// powers_ten_round64 + +constexpr int diy_significand_size = 64; + +static const uint64_t powers_ten[] = { 0xbf29dcaba82fdeae, 0xeef453d6923bd65a, 0x9558b4661b6565f8, 0xbaaee17fa23ebf76, 0xe95a99df8ace6f54, 0x91d8a02bb6c10594, 0xb64ec836a47146fa, 0xe3e27a444d8d98b8, 0x8e6d8c6ab0787f73, 0xb208ef855c969f50, 0xde8b2b66b3bc4724, 0x8b16fb203055ac76, 0xaddcb9e83c6b1794, 0xd953e8624b85dd79, 0x87d4713d6f33aa6c, 0xa9c98d8ccb009506, 0xd43bf0effdc0ba48, 0x84a57695fe98746d, 0xa5ced43b7e3e9188, 0xcf42894a5dce35ea, 0x818995ce7aa0e1b2, 0xa1ebfb4219491a1f, 0xca66fa129f9b60a7, 0xfd00b897478238d1, 0x9e20735e8cb16382, 0xc5a890362fddbc63, 0xf712b443bbd52b7c, 0x9a6bb0aa55653b2d, 0xc1069cd4eabe89f9, 0xf148440a256e2c77, 0x96cd2a865764dbca, 0xbc807527ed3e12bd, 0xeba09271e88d976c, 0x93445b8731587ea3, 0xb8157268fdae9e4c, 0xe61acf033d1a45df, 0x8fd0c16206306bac, 0xb3c4f1ba87bc8697, 0xe0b62e2929aba83c, 0x8c71dcd9ba0b4926, 0xaf8e5410288e1b6f, 0xdb71e91432b1a24b, 0x892731ac9faf056f, 0xab70fe17c79ac6ca, 0xd64d3d9db981787d, 0x85f0468293f0eb4e, 0xa76c582338ed2622, 0xd1476e2c07286faa, 0x82cca4db847945ca, 0xa37fce126597973d, 0xcc5fc196fefd7d0c, 0xff77b1fcbebcdc4f, 0x9faacf3df73609b1, 0xc795830d75038c1e, 0xf97ae3d0d2446f25, 0x9becce62836ac577, 0xc2e801fb244576d5, 0xf3a20279ed56d48a, 0x9845418c345644d7, 0xbe5691ef416bd60c, 0xedec366b11c6cb8f, 0x94b3a202eb1c3f39, 0xb9e08a83a5e34f08, 0xe858ad248f5c22ca, 0x91376c36d99995be, 0xb58547448ffffb2e, 0xe2e69915b3fff9f9, 0x8dd01fad907ffc3c, 0xb1442798f49ffb4b, 0xdd95317f31c7fa1d, 0x8a7d3eef7f1cfc52, 0xad1c8eab5ee43b67, 0xd863b256369d4a41, 0x873e4f75e2224e68, 0xa90de3535aaae202, 0xd3515c2831559a83, 0x8412d9991ed58092, 0xa5178fff668ae0b6, 0xce5d73ff402d98e4, 0x80fa687f881c7f8e, 0xa139029f6a239f72, 0xc987434744ac874f, 0xfbe9141915d7a922, 0x9d71ac8fada6c9b5, 0xc4ce17b399107c23, 0xf6019da07f549b2b, 0x99c102844f94e0fb, 0xc0314325637a193a, 0xf03d93eebc589f88, 0x96267c7535b763b5, 0xbbb01b9283253ca3, 0xea9c227723ee8bcb, 0x92a1958a7675175f, 0xb749faed14125d37, 0xe51c79a85916f485, 0x8f31cc0937ae58d3, 0xb2fe3f0b8599ef08, 0xdfbdcece67006ac9, 0x8bd6a141006042be, 0xaecc49914078536d, 0xda7f5bf590966849, 0x888f99797a5e012d, 0xaab37fd7d8f58179, 0xd5605fcdcf32e1d7, 0x855c3be0a17fcd26, 0xa6b34ad8c9dfc070, 0xd0601d8efc57b08c, 0x823c12795db6ce57, 0xa2cb1717b52481ed, 0xcb7ddcdda26da269, 0xfe5d54150b090b03, 0x9efa548d26e5a6e2, 0xc6b8e9b0709f109a, 0xf867241c8cc6d4c1, 0x9b407691d7fc44f8, 0xc21094364dfb5637, 0xf294b943e17a2bc4, 0x979cf3ca6cec5b5b, 0xbd8430bd08277231, 0xece53cec4a314ebe, 0x940f4613ae5ed137, 0xb913179899f68584, 0xe757dd7ec07426e5, 0x9096ea6f3848984f, 0xb4bca50b065abe63, 0xe1ebce4dc7f16dfc, 0x8d3360f09cf6e4bd, 0xb080392cc4349ded, 0xdca04777f541c568, 0x89e42caaf9491b61, 0xac5d37d5b79b6239, 0xd77485cb25823ac7, 0x86a8d39ef77164bd, 0xa8530886b54dbdec, 0xd267caa862a12d67, 0x8380dea93da4bc60, 0xa46116538d0deb78, 0xcd795be870516656, 0x806bd9714632dff6, 0xa086cfcd97bf97f4, 0xc8a883c0fdaf7df0, 0xfad2a4b13d1b5d6c, 0x9cc3a6eec6311a64, 0xc3f490aa77bd60fd, 0xf4f1b4d515acb93c, 0x991711052d8bf3c5, 0xbf5cd54678eef0b7, 0xef340a98172aace5, 0x9580869f0e7aac0f, 0xbae0a846d2195713, 0xe998d258869facd7, 0x91ff83775423cc06, 0xb67f6455292cbf08, 0xe41f3d6a7377eeca, 0x8e938662882af53e, 0xb23867fb2a35b28e, 0xdec681f9f4c31f31, 0x8b3c113c38f9f37f, 0xae0b158b4738705f, 0xd98ddaee19068c76, 0x87f8a8d4cfa417ca, 0xa9f6d30a038d1dbc, 0xd47487cc8470652b, 0x84c8d4dfd2c63f3b, 0xa5fb0a17c777cf0a, 0xcf79cc9db955c2cc, 0x81ac1fe293d599c0, 0xa21727db38cb0030, 0xca9cf1d206fdc03c, 0xfd442e4688bd304b, 0x9e4a9cec15763e2f, 0xc5dd44271ad3cdba, 0xf7549530e188c129, 0x9a94dd3e8cf578ba, 0xc13a148e3032d6e8, 0xf18899b1bc3f8ca2, 0x96f5600f15a7b7e5, 0xbcb2b812db11a5de, 0xebdf661791d60f56, 0x936b9fcebb25c996, 0xb84687c269ef3bfb, 0xe65829b3046b0afa, 0x8ff71a0fe2c2e6dc, 0xb3f4e093db73a093, 0xe0f218b8d25088b8, 0x8c974f7383725573, 0xafbd2350644eead0, 0xdbac6c247d62a584, 0x894bc396ce5da772, 0xab9eb47c81f5114f, 0xd686619ba27255a3, 0x8613fd0145877586, 0xa798fc4196e952e7, 0xd17f3b51fca3a7a1, 0x82ef85133de648c5, 0xa3ab66580d5fdaf6, 0xcc963fee10b7d1b3, 0xffbbcfe994e5c620, 0x9fd561f1fd0f9bd4, 0xc7caba6e7c5382c9, 0xf9bd690a1b68637b, 0x9c1661a651213e2d, 0xc31bfa0fe5698db8, 0xf3e2f893dec3f126, 0x986ddb5c6b3a76b8, 0xbe89523386091466, 0xee2ba6c0678b597f, 0x94db483840b717f0, 0xba121a4650e4ddec, 0xe896a0d7e51e1566, 0x915e2486ef32cd60, 0xb5b5ada8aaff80b8, 0xe3231912d5bf60e6, 0x8df5efabc5979c90, 0xb1736b96b6fd83b4, 0xddd0467c64bce4a1, 0x8aa22c0dbef60ee4, 0xad4ab7112eb3929e, 0xd89d64d57a607745, 0x87625f056c7c4a8b, 0xa93af6c6c79b5d2e, 0xd389b47879823479, 0x843610cb4bf160cc, 0xa54394fe1eedb8ff, 0xce947a3da6a9273e, 0x811ccc668829b887, 0xa163ff802a3426a9, 0xc9bcff6034c13053, 0xfc2c3f3841f17c68, 0x9d9ba7832936edc1, 0xc5029163f384a931, 0xf64335bcf065d37d, 0x99ea0196163fa42e, 0xc06481fb9bcf8d3a, 0xf07da27a82c37088, 0x964e858c91ba2655, 0xbbe226efb628afeb, 0xeadab0aba3b2dbe5, 0x92c8ae6b464fc96f, 0xb77ada0617e3bbcb, 0xe55990879ddcaabe, 0x8f57fa54c2a9eab7, 0xb32df8e9f3546564, 0xdff9772470297ebd, 0x8bfbea76c619ef36, 0xaefae51477a06b04, 0xdab99e59958885c5, 0x88b402f7fd75539b, 0xaae103b5fcd2a882, 0xd59944a37c0752a2, 0x857fcae62d8493a5, 0xa6dfbd9fb8e5b88f, 0xd097ad07a71f26b2, 0x825ecc24c8737830, 0xa2f67f2dfa90563b, 0xcbb41ef979346bca, 0xfea126b7d78186bd, 0x9f24b832e6b0f436, 0xc6ede63fa05d3144, 0xf8a95fcf88747d94, 0x9b69dbe1b548ce7d, 0xc24452da229b021c, 0xf2d56790ab41c2a3, 0x97c560ba6b0919a6, 0xbdb6b8e905cb600f, 0xed246723473e3813, 0x9436c0760c86e30c, 0xb94470938fa89bcf, 0xe7958cb87392c2c3, 0x90bd77f3483bb9ba, 0xb4ecd5f01a4aa828, 0xe2280b6c20dd5232, 0x8d590723948a535f, 0xb0af48ec79ace837, 0xdcdb1b2798182245, 0x8a08f0f8bf0f156b, 0xac8b2d36eed2dac6, 0xd7adf884aa879177, 0x86ccbb52ea94baeb, 0xa87fea27a539e9a5, 0xd29fe4b18e88640f, 0x83a3eeeef9153e89, 0xa48ceaaab75a8e2b, 0xcdb02555653131b6, 0x808e17555f3ebf12, 0xa0b19d2ab70e6ed6, 0xc8de047564d20a8c, 0xfb158592be068d2f, 0x9ced737bb6c4183d, 0xc428d05aa4751e4d, 0xf53304714d9265e0, 0x993fe2c6d07b7fac, 0xbf8fdb78849a5f97, 0xef73d256a5c0f77d, 0x95a8637627989aae, 0xbb127c53b17ec159, 0xe9d71b689dde71b0, 0x9226712162ab070e, 0xb6b00d69bb55c8d1, 0xe45c10c42a2b3b06, 0x8eb98a7a9a5b04e3, 0xb267ed1940f1c61c, 0xdf01e85f912e37a3, 0x8b61313bbabce2c6, 0xae397d8aa96c1b78, 0xd9c7dced53c72256, 0x881cea14545c7575, 0xaa242499697392d3, 0xd4ad2dbfc3d07788, 0x84ec3c97da624ab5, 0xa6274bbdd0fadd62, 0xcfb11ead453994ba, 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3e, 0xfd87b5f28300ca0e, 0x9e74d1b791e07e48, 0xc612062576589ddb, 0xf79687aed3eec551, 0x9abe14cd44753b53, 0xc16d9a0095928a27, 0xf1c90080baf72cb1, 0x971da05074da7bef, 0xbce5086492111aeb, 0xec1e4a7db69561a5, 0x9392ee8e921d5d07, 0xb877aa3236a4b449, 0xe69594bec44de15b, 0x901d7cf73ab0acd9, 0xb424dc35095cd80f, 0xe12e13424bb40e13, 0x8cbccc096f5088cc, 0xafebff0bcb24aaff, 0xdbe6fecebdedd5bf, 0x89705f4136b4a597, 0xabcc77118461cefd, 0xd6bf94d5e57a42bc, 0x8637bd05af6c69b6, 0xa7c5ac471b478423, 0xd1b71758e219652c, 0x83126e978d4fdf3b, 0xa3d70a3d70a3d70a, 0xcccccccccccccccd, 0x8000000000000000, 0xa000000000000000, 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000, 0xc350000000000000, 0xf424000000000000, 0x9896800000000000, 0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000, 0xba43b74000000000, 0xe8d4a51000000000, 0x9184e72a00000000, 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000, 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000, 0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000, 0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0, 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940984, 0xa18f07d736b90be5, 0xc9f2c9cd04674edf, 0xfc6f7c4045812296, 0x9dc5ada82b70b59e, 0xc5371912364ce305, 0xf684df56c3e01bc7, 0x9a130b963a6c115c, 0xc097ce7bc90715b3, 0xf0bdc21abb48db20, 0x96769950b50d88f4, 0xbc143fa4e250eb31, 0xeb194f8e1ae525fd, 0x92efd1b8d0cf37be, 0xb7abc627050305ae, 0xe596b7b0c643c719, 0x8f7e32ce7bea5c70, 0xb35dbf821ae4f38c, 0xe0352f62a19e306f, 0x8c213d9da502de45, 0xaf298d050e4395d7, 0xdaf3f04651d47b4c, 0x88d8762bf324cd10, 0xab0e93b6efee0054, 0xd5d238a4abe98068, 0x85a36366eb71f041, 0xa70c3c40a64e6c52, 0xd0cf4b50cfe20766, 0x82818f1281ed44a0, 0xa321f2d7226895c8, 0xcbea6f8ceb02bb3a, 0xfee50b7025c36a08, 0x9f4f2726179a2245, 0xc722f0ef9d80aad6, 0xf8ebad2b84e0d58c, 0x9b934c3b330c8577, 0xc2781f49ffcfa6d5, 0xf316271c7fc3908b, 0x97edd871cfda3a57, 0xbde94e8e43d0c8ec, 0xed63a231d4c4fb27, 0x945e455f24fb1cf9, 0xb975d6b6ee39e437, 0xe7d34c64a9c85d44, 0x90e40fbeea1d3a4b, 0xb51d13aea4a488dd, 0xe264589a4dcdab15, 0x8d7eb76070a08aed, 0xb0de65388cc8ada8, 0xdd15fe86affad912, 0x8a2dbf142dfcc7ab, 0xacb92ed9397bf996, 0xd7e77a8f87daf7fc, 0x86f0ac99b4e8dafd, 0xa8acd7c0222311bd, 0xd2d80db02aabd62c, 0x83c7088e1aab65db, 0xa4b8cab1a1563f52, 0xcde6fd5e09abcf27, 0x80b05e5ac60b6178, 0xa0dc75f1778e39d6, 0xc913936dd571c84c, 0xfb5878494ace3a5f, 0x9d174b2dcec0e47b, 0xc45d1df942711d9a, 0xf5746577930d6501, 0x9968bf6abbe85f20, 0xbfc2ef456ae276e9, 0xefb3ab16c59b14a3, 0x95d04aee3b80ece6, 0xbb445da9ca61281f, 0xea1575143cf97227, 0x924d692ca61be758, 0xb6e0c377cfa2e12e, 0xe498f455c38b997a, 0x8edf98b59a373fec, 0xb2977ee300c50fe7, 0xdf3d5e9bc0f653e1, 0x8b865b215899f46d, 0xae67f1e9aec07188, 0xda01ee641a708dea, 0x884134fe908658b2, 0xaa51823e34a7eedf, 0xd4e5e2cdc1d1ea96, 0x850fadc09923329e, 0xa6539930bf6bff46, 0xcfe87f7cef46ff17, 0x81f14fae158c5f6e, 0xa26da3999aef774a, 0xcb090c8001ab551c, 0xfdcb4fa002162a63, 0x9e9f11c4014dda7e, 0xc646d63501a1511e, 0xf7d88bc24209a565, 0x9ae757596946075f, 0xc1a12d2fc3978937, 0xf209787bb47d6b85, 0x9745eb4d50ce6333, 0xbd176620a501fc00, 0xec5d3fa8ce427b00, 0x93ba47c980e98ce0, 0xb8a8d9bbe123f018, 0xe6d3102ad96cec1e, 0x9043ea1ac7e41393, 0xb454e4a179dd1877, 0xe16a1dc9d8545e95, 0x8ce2529e2734bb1d, 0xb01ae745b101e9e4, 0xdc21a1171d42645d, 0x899504ae72497eba, 0xabfa45da0edbde69, 0xd6f8d7509292d603, 0x865b86925b9bc5c2, 0xa7f26836f282b733, 0xd1ef0244af2364ff, 0x8335616aed761f1f, 0xa402b9c5a8d3a6e7, 0xcd036837130890a1, 0x802221226be55a65, 0xa02aa96b06deb0fe, 0xc83553c5c8965d3d, 0xfa42a8b73abbf48d, 0x9c69a97284b578d8, 0xc38413cf25e2d70e, 0xf46518c2ef5b8cd1, 0x98bf2f79d5993803, 0xbeeefb584aff8604, 0xeeaaba2e5dbf6785, 0x952ab45cfa97a0b3, 0xba756174393d88e0, 0xe912b9d1478ceb17, 0x91abb422ccb812ef, 0xb616a12b7fe617aa, 0xe39c49765fdf9d95, 0x8e41ade9fbebc27d, 0xb1d219647ae6b31c, 0xde469fbd99a05fe3, 0x8aec23d680043bee, 0xada72ccc20054aea, 0xd910f7ff28069da4, 0x87aa9aff79042287, 0xa99541bf57452b28, 0xd3fa922f2d1675f2, 0x847c9b5d7c2e09b7, 0xa59bc234db398c25, 0xcf02b2c21207ef2f, 0x8161afb94b44f57d, 0xa1ba1ba79e1632dc, 0xca28a291859bbf93, 0xfcb2cb35e702af78, 0x9defbf01b061adab, 0xc56baec21c7a1916, 0xf6c69a72a3989f5c, 0x9a3c2087a63f6399, 0xc0cb28a98fcf3c80, 0xf0fdf2d3f3c30b9f, 0x969eb7c47859e744, 0xbc4665b596706115, 0xeb57ff22fc0c795a, 0x9316ff75dd87cbd8, 0xb7dcbf5354e9bece, 0xe5d3ef282a242e82, 0x8fa475791a569d11, 0xb38d92d760ec4455, 0xe070f78d3927556b, 0x8c469ab843b89563, 0xaf58416654a6babb, 0xdb2e51bfe9d0696a, 0x88fcf317f22241e2, 0xab3c2fddeeaad25b, 0xd60b3bd56a5586f2, 0x85c7056562757457, 0xa738c6bebb12d16d, 0xd106f86e69d785c8, 0x82a45b450226b39d, 0xa34d721642b06084, 0xcc20ce9bd35c78a5, 0xff290242c83396ce, 0x9f79a169bd203e41, 0xc75809c42c684dd1, 0xf92e0c3537826146, 0x9bbcc7a142b17ccc, 0xc2abf989935ddbfe, 0xf356f7ebf83552fe, 0x98165af37b2153df, 0xbe1bf1b059e9a8d6, 0xeda2ee1c7064130c, 0x9485d4d1c63e8be8, 0xb9a74a0637ce2ee1, 0xe8111c87c5c1ba9a, 0x910ab1d4db9914a0, 0xb54d5e4a127f59c8, 0xe2a0b5dc971f303a, 0x8da471a9de737e24, 0xb10d8e1456105dad, 0xdd50f1996b947519, 0x8a5296ffe33cc930, 0xace73cbfdc0bfb7b, 0xd8210befd30efa5a, 0x8714a775e3e95c78, 0xa8d9d1535ce3b396, 0xd31045a8341ca07c, 0x83ea2b892091e44e, 0xa4e4b66b68b65d61, 0xce1de40642e3f4b9, 0x80d2ae83e9ce78f4, 0xa1075a24e4421731, 0xc94930ae1d529cfd, 0xfb9b7cd9a4a7443c, 0x9d412e0806e88aa6, 0xc491798a08a2ad4f, 0xf5b5d7ec8acb58a3, 0x9991a6f3d6bf1766, 0xbff610b0cc6edd3f, 0xeff394dcff8a948f, 0x95f83d0a1fb69cd9, 0xbb764c4ca7a44410, 0xea53df5fd18d5514, 0x92746b9be2f8552c, 0xb7118682dbb66a77, 0xe4d5e82392a40515, 0x8f05b1163ba6832d, 0xb2c71d5bca9023f8, 0xdf78e4b2bd342cf7, 0x8bab8eefb6409c1a, 0xae9672aba3d0c321, 0xda3c0f568cc4f3e9, 0x8865899617fb1871, 0xaa7eebfb9df9de8e, 0xd51ea6fa85785631, 0x8533285c936b35df, 0xa67ff273b8460357, 0xd01fef10a657842c, 0x8213f56a67f6b29c, 0xa298f2c501f45f43, 0xcb3f2f7642717713, 0xfe0efb53d30dd4d8, 0x9ec95d1463e8a507, 0xc67bb4597ce2ce49, 0xf81aa16fdc1b81db, 0x9b10a4e5e9913129, 0xc1d4ce1f63f57d73, 0xf24a01a73cf2dcd0, 0x976e41088617ca02, 0xbd49d14aa79dbc82, 0xec9c459d51852ba3, 0x93e1ab8252f33b46, 0xb8da1662e7b00a17, 0xe7109bfba19c0c9d, 0x906a617d450187e2, 0xb484f9dc9641e9db, 0xe1a63853bbd26451, 0x8d07e33455637eb3, 0xb049dc016abc5e60, 0xdc5c5301c56b75f7, 0x89b9b3e11b6329bb, 0xac2820d9623bf429, 0xd732290fbacaf134, 0x867f59a9d4bed6c0, 0xa81f301449ee8c70, 0xd226fc195c6a2f8c, 0x83585d8fd9c25db8, 0xa42e74f3d032f526, 0xcd3a1230c43fb26f, 0x80444b5e7aa7cf85, 0xa0555e361951c367, 0xc86ab5c39fa63441, 0xfa856334878fc151, 0x9c935e00d4b9d8d2, 0xc3b8358109e84f07, 0xf4a642e14c6262c9, 0x98e7e9cccfbd7dbe, 0xbf21e44003acdd2d, 0xeeea5d5004981478, 0x95527a5202df0ccb, 0xbaa718e68396cffe, 0xe950df20247c83fd, 0x91d28b7416cdd27e, 0xb6472e511c81471e, 0xe3d8f9e563a198e5, 0x8e679c2f5e44ff8f, 0xb201833b35d63f73, 0xde81e40a034bcf50, 0x8b112e86420f6192, 0xadd57a27d29339f6, 0xd94ad8b1c7380874, 0x87cec76f1c830549, 0xa9c2794ae3a3c69b, 0xd433179d9c8cb841, 0x849feec281d7f329, 0xa5c7ea73224deff3, 0xcf39e50feae16bf0, 0x81842f29f2cce376, 0xa1e53af46f801c53, 0xca5e89b18b602368, 0xfcf62c1dee382c42, 0x9e19db92b4e31ba9, 0xc5a05277621be294, 0xf70867153aa2db39, 0x9a65406d44a5c903, 0xc0fe908895cf3b44, 0xf13e34aabb430a15, 0x96c6e0eab509e64d, 0xbc789925624c5fe1, 0xeb96bf6ebadf77d9, 0x933e37a534cbaae8, 0xb80dc58e81fe95a1, 0xe61136f2227e3b0a, 0x8fcac257558ee4e6, 0xb3bd72ed2af29e20, 0xe0accfa875af45a8, 0x8c6c01c9498d8b89, 0xaf87023b9bf0ee6b, 0xdb68c2ca82ed2a06, 0x892179be91d43a44, 0xab69d82e364948d4 }; +static const int powers_ten_e[] = { -1203, -1200, -1196, -1193, -1190, -1186, -1183, -1180, -1176, -1173, -1170, -1166, -1163, -1160, -1156, -1153, -1150, -1146, -1143, -1140, -1136, -1133, -1130, -1127, -1123, -1120, -1117, -1113, -1110, -1107, -1103, -1100, -1097, -1093, -1090, -1087, -1083, -1080, -1077, -1073, -1070, -1067, -1063, -1060, -1057, -1053, -1050, -1047, -1043, -1040, -1037, -1034, -1030, -1027, -1024, -1020, -1017, -1014, -1010, -1007, -1004, -1000, -997, -994, -990, -987, -984, -980, -977, -974, -970, -967, -964, -960, -957, -954, -950, -947, -944, -940, -937, -934, -931, -927, -924, -921, -917, -914, -911, -907, -904, -901, -897, -894, -891, -887, -884, -881, -877, -874, -871, -867, -864, -861, -857, -854, -851, -847, -844, -841, -838, -834, -831, -828, -824, -821, -818, -814, -811, -808, -804, -801, -798, -794, -791, -788, -784, -781, -778, -774, -771, -768, -764, -761, -758, -754, -751, -748, -744, -741, -738, -735, -731, -728, -725, -721, -718, -715, -711, -708, -705, -701, -698, -695, -691, -688, -685, -681, -678, -675, -671, -668, -665, -661, -658, -655, -651, -648, -645, -642, -638, -635, -632, -628, -625, -622, -618, -615, -612, -608, -605, -602, -598, -595, -592, -588, -585, -582, -578, -575, -572, -568, -565, -562, -558, -555, -552, -549, -545, -542, -539, -535, -532, -529, -525, -522, -519, -515, -512, -509, -505, -502, -499, -495, -492, -489, -485, -482, -479, -475, -472, -469, -465, -462, -459, -455, -452, -449, -446, -442, -439, -436, -432, -429, -426, -422, -419, -416, -412, -409, -406, -402, -399, -396, -392, -389, -386, -382, -379, -376, -372, -369, -366, -362, -359, -356, -353, -349, -346, -343, -339, -336, -333, -329, -326, -323, -319, -316, -313, -309, -306, -303, -299, -296, -293, -289, -286, -283, -279, -276, -273, -269, -266, -263, -259, -256, -253, -250, -246, -243, -240, -236, -233, -230, -226, -223, -220, -216, -213, -210, -206, -203, -200, -196, -193, -190, -186, -183, -180, -176, -173, -170, -166, -163, -160, -157, -153, -150, -147, -143, -140, -137, -133, -130, -127, -123, -120, -117, -113, -110, -107, -103, -100, -97, -93, -90, -87, -83, -80, -77, -73, -70, -67, -63, -60, -57, -54, -50, -47, -44, -40, -37, -34, -30, -27, -24, -20, -17, -14, -10, -7, -4, 0, 3, 6, 10, 13, 16, 20, 23, 26, 30, 33, 36, 39, 43, 46, 49, 53, 56, 59, 63, 66, 69, 73, 76, 79, 83, 86, 89, 93, 96, 99, 103, 106, 109, 113, 116, 119, 123, 126, 129, 132, 136, 139, 142, 146, 149, 152, 156, 159, 162, 166, 169, 172, 176, 179, 182, 186, 189, 192, 196, 199, 202, 206, 209, 212, 216, 219, 222, 226, 229, 232, 235, 239, 242, 245, 249, 252, 255, 259, 262, 265, 269, 272, 275, 279, 282, 285, 289, 292, 295, 299, 302, 305, 309, 312, 315, 319, 322, 325, 328, 332, 335, 338, 342, 345, 348, 352, 355, 358, 362, 365, 368, 372, 375, 378, 382, 385, 388, 392, 395, 398, 402, 405, 408, 412, 415, 418, 422, 425, 428, 431, 435, 438, 441, 445, 448, 451, 455, 458, 461, 465, 468, 471, 475, 478, 481, 485, 488, 491, 495, 498, 501, 505, 508, 511, 515, 518, 521, 524, 528, 531, 534, 538, 541, 544, 548, 551, 554, 558, 561, 564, 568, 571, 574, 578, 581, 584, 588, 591, 594, 598, 601, 604, 608, 611, 614, 617, 621, 624, 627, 631, 634, 637, 641, 644, 647, 651, 654, 657, 661, 664, 667, 671, 674, 677, 681, 684, 687, 691, 694, 697, 701, 704, 707, 711, 714, 717, 720, 724, 727, 730, 734, 737, 740, 744, 747, 750, 754, 757, 760, 764, 767, 770, 774, 777, 780, 784, 787, 790, 794, 797, 800, 804, 807, 810, 813, 817, 820, 823, 827, 830, 833, 837, 840, 843, 847, 850, 853, 857, 860, 863, 867, 870, 873, 877, 880, 883, 887, 890, 893, 897, 900, 903, 907, 910, 913, 916, 920, 923, 926, 930, 933, 936, 940, 943, 946, 950, 953, 956, 960, 963, 966, 970, 973, 976, 980, 983, 986, 990, 993, 996, 1000, 1003, 1006, 1009, 1013, 1016, 1019, 1023, 1026, 1029, 1033, 1036, 1039, 1043, 1046, 1049, 1053, 1056, 1059, 1063, 1066, 1069, 1073, 1076 }; + +inline +diy_fp_t cached_power(int k) +{ + diy_fp_t res; + int index = 343 + k; + res.f = powers_ten[index]; + res.e = powers_ten_e[index]; + return res; +} + +// double + +typedef union { + double d; + uint64_t n; +} converter_t; + +inline +uint64_t double_to_uint64(double d) { converter_t tmp; tmp.d = d; return tmp.n; } + +inline +double uint64_to_double(uint64_t d64) { converter_t tmp; tmp.n = d64; return tmp.d; } + +constexpr int dp_significand_size = 52; +constexpr int dp_exponent_bias = (0x3FF + dp_significand_size); +constexpr int dp_min_exponent = (-dp_exponent_bias); +constexpr uint64_t dp_exponent_mask = 0x7FF0000000000000; +constexpr uint64_t dp_significand_mask = 0x000FFFFFFFFFFFFF; +constexpr uint64_t dp_hidden_bit = 0x0010000000000000; + +inline +diy_fp_t normalize_diy_fp(diy_fp_t in) +{ + diy_fp_t res = in; + /* Normalize now */ + /* the original number could have been a denormal. */ + while (!(res.f & dp_hidden_bit)) + { + res.f <<= 1; + res.e--; + } + /* do the final shifts in one go. Don't forget the hidden bit (the '-1') */ + res.f <<= (diy_significand_size - dp_significand_size - 1); + res.e = res.e - (diy_significand_size - dp_significand_size - 1); + return res; +} + +inline +diy_fp_t double2diy_fp(double d) +{ + uint64_t d64 = double_to_uint64(d); + int biased_e = (d64 & dp_exponent_mask) >> dp_significand_size; + uint64_t significand = (d64 & dp_significand_mask); + diy_fp_t res; + if (biased_e != 0) + { + res.f = significand + dp_hidden_bit; + res.e = biased_e - dp_exponent_bias; + } + else + { + res.f = significand; + res.e = dp_min_exponent + 1; + } + return res; +} + +inline +diy_fp_t normalize_boundary(diy_fp_t in) +{ + diy_fp_t res = in; + /* Normalize now */ + /* the original number could have been a denormal. */ + while (!(res.f & (dp_hidden_bit << 1))) + { + res.f <<= 1; + res.e--; + } + /* do the final shifts in one go. Don't forget the hidden bit (the '-1') */ + res.f <<= (diy_significand_size - dp_significand_size - 2); + res.e = res.e - (diy_significand_size - dp_significand_size - 2); + return res; +} + +inline +void normalized_boundaries(double d, diy_fp_t *out_m_minus, diy_fp_t *out_m_plus) +{ + diy_fp_t v = double2diy_fp(d); + diy_fp_t pl, mi; + bool significand_is_zero = v.f == dp_hidden_bit; + pl.f = (v.f << 1) + 1; pl.e = v.e - 1; + pl = normalize_boundary(pl); + if (significand_is_zero) + { + mi.f = (v.f << 2) - 1; + mi.e = v.e - 2; + } else + { + mi.f = (v.f << 1) - 1; + mi.e = v.e - 1; + } + mi.f <<= mi.e - pl.e; + mi.e = pl.e; + *out_m_plus = pl; + *out_m_minus = mi; +} + +inline +double random_double() +{ + uint64_t tmp = 0; + int i; + for (i = 0; i < 8; i++) + { + tmp <<= 8; + tmp += rand() % 256; + } + return uint64_to_double(tmp); +} + +// fast_exponent +template +void fill_exponent(int K, Result& result) +{ + if (K < 0) + { + result.push_back('-'); + K = -K; + } + else + { + result.push_back('+'); // compatibility with sprintf + } + if (K >= 100) + { + result.push_back((char)('0' + K / 100)); K %= 100; + result.push_back((char)('0' + K / 10)); K %= 10; + result.push_back((char)('0' + K)); + } + else if (K >= 10) + { + result.push_back((char)('0' + K / 10)); K %= 10; + result.push_back((char)('0' + K)); + } + else + { + result.push_back('0'); // compatibility with sprintf + result.push_back((char)('0' + K)); + } +} + +template +void prettify_string(const char *buffer, size_t length, int k, int min_exp, int max_exp, Result& result) +{ + int nb_digits = (int)length; + int offset; + /* v = buffer * 10^k + kk is such that 10^(kk-1) <= v < 10^kk + this way kk gives the position of the decimal point. + */ + int kk = nb_digits + k; + + if (nb_digits <= kk && kk <= max_exp) + { + /* the first digits are already in. Add some 0s and call it a day. */ + /* the max_exp is a personal choice. Only 16 digits could possibly be relevant. + * Basically we want to print 12340000000 rather than 1234.0e7 or 1.234e10 */ + for (int i = 0; i < nb_digits; ++i) + { + result.push_back(buffer[i]); + } + for (int i = nb_digits; i < kk; ++i) + { + result.push_back('0'); + } + result.push_back('.'); + result.push_back('0'); + } + else if (0 < kk && kk <= max_exp) + { + /* comma number. Just insert a '.' at the correct location. */ + for (int i = 0; i < kk; ++i) + { + result.push_back(buffer[i]); + } + result.push_back('.'); + for (int i = kk; i < nb_digits; ++i) + { + result.push_back(buffer[i]); + } + } + else if (min_exp < kk && kk <= 0) + { + offset = 2 - kk; + + result.push_back('0'); + result.push_back('.'); + for (int i = 2; i < offset; ++i) + result.push_back('0'); + for (int i = 0; i < nb_digits; ++i) + { + result.push_back(buffer[i]); + } + } + else if (nb_digits == 1) + { + result.push_back(buffer[0]); + result.push_back('e'); + fill_exponent(kk - 1, result); + } + else + { + result.push_back(buffer[0]); + result.push_back('.'); + for (int i = 1; i < nb_digits; ++i) + { + result.push_back(buffer[i]); + } + result.push_back('e'); + fill_exponent(kk - 1, result); + } +} + +// grisu3 + +inline +bool round_weed(char *buffer, int len, + uint64_t wp_W, uint64_t Delta, + uint64_t rest, uint64_t ten_kappa, + uint64_t ulp) +{ + uint64_t wp_Wup = wp_W - ulp; + uint64_t wp_Wdown = wp_W + ulp; + while (rest < wp_Wup && /// round1 + Delta - rest >= ten_kappa && + (rest + ten_kappa < wp_Wup || /// closer + wp_Wup - rest >= rest + ten_kappa - wp_Wup)) + { + buffer[len - 1]--; rest += ten_kappa; + } + if (rest < wp_Wdown && /// round2 + Delta - rest >= ten_kappa && + (rest + ten_kappa < wp_Wdown || + wp_Wdown - rest > rest + ten_kappa - wp_Wdown)) return 0; + return 2 * ulp <= rest && rest <= Delta - 4 * ulp; /// weed +} + +inline +bool digit_gen(diy_fp_t Wm, diy_fp_t W, diy_fp_t Wp, + char *buffer, int *len, int *K) +{ + const uint32_t TEN2 = 100; + + uint32_t div, p1; uint64_t p2, tmp, unit = 1; + int d, kappa; + diy_fp_t one, wp_W, Delta; + Delta = minus(Wp, Wm); Delta.f += 2 * unit; + wp_W = minus(Wp, W); wp_W.f += unit; + one.f = ((uint64_t)1) << -Wp.e; one.e = Wp.e; + p1 = static_cast((Wp.f + 1) >> -one.e); + p2 = (Wp.f + 1) & (one.f - 1); + *len = 0; kappa = 3; div = TEN2; + while (kappa > 0) + { + d = p1 / div; + if (d || *len) buffer[(*len)++] = (char)('0' + d); + p1 %= div; kappa--; + tmp = (((uint64_t)p1) << -one.e) + p2; + if (tmp < Delta.f) + { + *K += kappa; + return round_weed(buffer, *len, wp_W.f, Delta.f, tmp, + ((uint64_t)div) << -one.e, unit); + } + div /= 10; + } + while (1) + { + p2 *= 10; Delta.f *= 10; unit *= 10; + d = static_cast(p2 >> -one.e); + if (d || *len) buffer[(*len)++] = (char)('0' + d); + p2 &= one.f - 1; kappa--; + if (p2 < Delta.f) + { + *K += kappa; + return round_weed(buffer, *len, wp_W.f * unit, Delta.f, p2, + one.f, unit); + } + } +} + +inline +bool grisu3(double v, char *buffer, int *length, int *K) +{ + diy_fp_t w_m, w_p; + int q = 64, alpha = -59, gamma = -56; + normalized_boundaries(v, &w_m, &w_p); + diy_fp_t w = normalize_diy_fp(double2diy_fp(v)); + int mk = k_comp(w_p.e + q, alpha, gamma); + diy_fp_t c_mk = cached_power(mk); + diy_fp_t W = multiply(w, c_mk); + diy_fp_t Wp = multiply(w_p, c_mk); + diy_fp_t Wm = multiply(w_m, c_mk); + *K = -mk; + bool result = digit_gen(Wm, W, Wp, buffer, length, K); + buffer[*length] = 0; + return result; +} + +}} // namespace detail namespace jsoncons + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/detail/heap_only_string.hpp b/invehicle-apps/3rd-party-libs/jsoncons/detail/heap_only_string.hpp index 5348b43..a90d863 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/detail/heap_only_string.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/detail/heap_only_string.hpp @@ -4,15 +4,16 @@ // See https://github.com/danielaparker/jsoncons for latest version -#ifndef JSONCONS_DETAIL_HEAPONLYSTRING_HPP -#define JSONCONS_DETAIL_HEAPONLYSTRING_HPP +#ifndef JSONCONS_DETAIL_HEAP_ONLY_STRING_HPP +#define JSONCONS_DETAIL_HEAP_ONLY_STRING_HPP #include #include -#include #include #include -#include +#include // std::memcpy +#include // std::allocator +#include namespace jsoncons { namespace detail { @@ -109,7 +110,7 @@ class heap_only_string_factory heap_only_string data; char_type c[1]; }; - typedef typename std::aligned_storage::type storage_type; + typedef typename std::aligned_storage::type storage_type; static size_t aligned_size(size_t n) { @@ -132,7 +133,7 @@ class heap_only_string_factory auto psa = reinterpret_cast(storage); CharT* p = new(&psa->c)char_type[length + 1]; - memcpy(p, s, length*sizeof(char_type)); + std::memcpy(p, s, length*sizeof(char_type)); p[length] = 0; ps->p_ = std::pointer_traits::pointer_to(*p); ps->length_ = length; diff --git a/invehicle-apps/3rd-party-libs/jsoncons/detail/json_type_traits.hpp b/invehicle-apps/3rd-party-libs/jsoncons/detail/json_type_traits.hpp deleted file mode 100644 index 3f53ca8..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/detail/json_type_traits.hpp +++ /dev/null @@ -1,958 +0,0 @@ -// 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_DETAIL_JSON_TYPE_TRAITS_HPP -#define JSONCONS_DETAIL_JSON_TYPE_TRAITS_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wswitch" -#endif - -namespace jsoncons { namespace detail { - -// null_type - -struct null_type -{ -}; - -// json_type_traits - -template -struct json_type_traits -{ - static const bool is_compatible = false; - - static bool is(const Json&) - { - return false; - } -}; - -// is_incompatible -template -struct is_incompatible : std::false_type {}; - - -// is_incompatible -template -struct is_incompatible::is_compatible>::value>::type -> : std::true_type {}; - -// is_compatible_string_type -template -struct is_compatible_string_type : std::false_type {}; - -template -struct is_compatible_string_type::value && - detail::is_string_like::value && - !is_incompatible::value_type>::value ->::type> : std::true_type {}; - -// is_compatible_array_type -template -struct is_compatible_array_type : std::false_type {}; - -template -struct is_compatible_array_type::value && - detail::is_vector_like::value && - !is_incompatible::value_type>::value ->::type> : std::true_type {}; - -// is_compatible_object_type -template -struct is_compatible_object_type : std::false_type {}; - -template -struct is_compatible_object_type::value ->::type> : std::true_type {}; - -// is_std_array -template -struct is_std_array : std::false_type {}; - -template -struct is_std_array> : std::true_type {}; - -template -class json_array_input_iterator -{ -public: - typedef typename Json::const_array_iterator iterator_base; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::difference_type difference_type; - typedef typename std::iterator_traits::pointer pointer; - typedef T reference; - typedef std::input_iterator_tag iterator_category; - - json_array_input_iterator() - { - } - - json_array_input_iterator(iterator_base it) - : it_(it) - { - } - - json_array_input_iterator& operator=(json_array_input_iterator rhs) - { - swap(*this,rhs); - return *this; - } - - json_array_input_iterator& operator++() - { - ++it_; - return *this; - } - - json_array_input_iterator operator++(int) // postfix increment - { - json_array_input_iterator temp(*this); - ++it_; - return temp; - } - - json_array_input_iterator& operator--() - { - --it_; - return *this; - } - - json_array_input_iterator operator--(int) - { - json_array_input_iterator temp(*this); - --it_; - return temp; - } - - reference operator*() const - { - return typename Traits::base_traits::as(*it_); - } - - friend bool operator==(const json_array_input_iterator& it1, const json_array_input_iterator& it2) - { - return it1.it_ == it2.it_; - } - friend bool operator!=(const json_array_input_iterator& it1, const json_array_input_iterator& it2) - { - return !(it1.it_ == it2.it_); - } - friend void swap(json_array_input_iterator& lhs, json_array_input_iterator& rhs) - { - using std::swap; - swap(lhs.it_,rhs.it_); - swap(lhs.empty_,rhs.empty_); - } - -private: - iterator_base it_; -}; - -template -class json_object_input_iterator -{ -public: - typedef typename Json::const_object_iterator iterator_base; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::difference_type difference_type; - typedef typename std::iterator_traits::pointer pointer; - typedef T reference; - typedef std::input_iterator_tag iterator_category; - typedef typename T::first_type key_type; - typedef typename T::second_type mapped_type; - - json_object_input_iterator() - { - } - - json_object_input_iterator(iterator_base it) - : it_(it) - { - } - - json_object_input_iterator& operator=(json_object_input_iterator rhs) - { - swap(*this,rhs); - return *this; - } - - json_object_input_iterator& operator++() - { - ++it_; - return *this; - } - - json_object_input_iterator operator++(int) // postfix increment - { - json_object_input_iterator temp(*this); - ++it_; - return temp; - } - - json_object_input_iterator& operator--() - { - --it_; - return *this; - } - - json_object_input_iterator operator--(int) - { - json_object_input_iterator temp(*this); - --it_; - return temp; - } - - reference operator*() const - { - return T(key_type(it_->key()),typename Traits::base_traits::as(it_->value())); - } - - friend bool operator==(const json_object_input_iterator& it1, const json_object_input_iterator& it2) - { - return it1.it_ == it2.it_; - } - friend bool operator!=(const json_object_input_iterator& it1, const json_object_input_iterator& it2) - { - return !(it1.it_ == it2.it_); - } - friend void swap(json_object_input_iterator& lhs, json_object_input_iterator& rhs) - { - using std::swap; - swap(lhs.it_,rhs.it_); - swap(lhs.empty_,rhs.empty_); - } - -private: - iterator_base it_; -}; - -template -struct json_type_traits::const_pointer_type> -{ - typedef typename Json::char_type char_type; - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - return j.is_string(); - } - static const char_type* as(const Json& j) - { - return j.as_cstring(); - } - template - static Json to_json(Args&&... args) - { - return Json(typename Json::variant(std::forward(args)...)); - } -}; - -template -struct json_type_traits::pointer_type> -{ - typedef typename Json::char_type char_type; - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - return j.is_string(); - } - template - static Json to_json(Args&&... args) - { - return Json(typename Json::variant(std::forward(args)...)); - } -}; - -// integral - -template -struct json_type_traits::value ->::type> -{ - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - if (j.is_integer()) - { - return j.as_integer() >= (std::numeric_limits::min)() && j.as_integer() <= (std::numeric_limits::max)(); - } - else if (j.is_uinteger()) - { - return j.as_uinteger() <= static_cast((std::numeric_limits::max)()); - } - else - { - return false; - } - } - static T as(const Json& j) - { - return static_cast(j.as_integer()); - } - template - static Json to_json(Args&&... args) - { - return Json::from_integer(std::forward(args)...); - } -}; - -template -struct json_type_traits::value ->::type > -{ - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - if (j.is_integer()) - { - return j.as_integer() >= 0 && static_cast(j.as_integer()) <= (std::numeric_limits::max)(); - } - else if (j.is_uinteger()) - { - return j.as_uinteger() <= (std::numeric_limits::max)(); - } - else - { - return false; - } - } - static T as(const Json& j) - { - return static_cast(j.as_uinteger()); - } - - template - static Json to_json(Args&&... args) - { - return Json::from_uinteger(std::forward(args)...); - } -}; - -template -struct json_type_traits::value ->::type> -{ - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - return j.is_double(); - } - static T as(const Json& j) - { - return static_cast(j.as_double()); - } - template - static Json to_json(Args&&... args) - { - return Json::from_floating_point(std::forward(args)...); - } -}; - -template -struct json_type_traits -{ - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - return j.is_object(); - } - template - static Json to_json(Args&&... args) - { - return Json(typename Json::variant(std::forward(args)...)); - } -}; - -template -struct json_type_traits -{ - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - return j.is_array(); - } - template - static Json to_json(Args&&... args) - { - return Json(typename Json::variant(std::forward(args)...)); - } -}; - -template -struct json_type_traits -{ - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json&) JSONCONS_NOEXCEPT - { - return true; - } - static Json as(Json j) - { - return j; - } - static Json to_json(const Json& val) - { - return val; - } - static Json to_json(const Json& val, allocator_type) - { - return val; - } -}; - -template -struct json_type_traits -{ - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - return j.is_null(); - } - static typename jsoncons::null_type as(const Json& j) - { - JSONCONS_ASSERT(j.is_null()); - return jsoncons::null_type(); - } - static Json to_json(jsoncons::null_type) - { - return Json::null(); - } - static Json to_json(jsoncons::null_type, allocator_type) - { - return Json::null(); - } -}; - -template -struct json_type_traits -{ - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - return j.is_bool(); - } - static bool as(const Json& j) - { - return j.as_bool(); - } - template - static Json to_json(Args&&... args) - { - return Json(typename Json::variant(std::forward(args)...)); - } -}; - -template -struct json_type_traits::const_reference>::value, - std::vector::const_reference, - void>::type>::value>::type> -{ - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - return j.is_bool(); - } - static bool as(const Json& j) - { - return j.as_bool(); - } - template - static Json to_json(Args&&... args) - { - return Json(typename Json::variant(std::forward(args)...)); - } -}; - -template -struct json_type_traits::reference> -{ - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - return j.is_bool(); - } - static bool as(const Json& j) - { - return j.as_bool(); - } - template - static Json to_json(Args&&... args) - { - return Json(typename Json::variant(std::forward(args)...)); - } -}; - -template -struct json_type_traits::value && - !detail::is_std_array::value>::type> -{ - typedef typename std::iterator_traits::value_type element_type; - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - bool result = j.is_array(); - if (result) - { - for (auto e : j.array_range()) - { - if (!e.template is()) - { - result = false; - break; - } - } - } - return result; - } - - template - static typename std::enable_if::value && !std::is_same::value),T>::type - as(const Json& j) - { - if (j.is_array()) - { - T v(detail::json_array_input_iterator(j.array_range().begin()), - detail::json_array_input_iterator(j.array_range().end())); - return v; - } - else - { - JSONCONS_THROW(json_exception_impl("Attempt to cast json non-array to array")); - } - } - - template - static typename std::enable_if::value && !std::is_same::value,T>::type - as(const Json& j) - { - if (j.is_array()) - { - T v(detail::json_array_input_iterator(j.array_range().begin()), - detail::json_array_input_iterator(j.array_range().end())); - return v; - } - else if (j.is_byte_string()) - { - T v(j.as_byte_string_view().begin(),j.as_byte_string_view().end()); - return v; - } - else - { - JSONCONS_THROW(json_exception_impl("Attempt to cast json non-array to array")); - } - } - - static Json to_json(const T& val) - { - Json j = typename Json::array(); - auto first = std::begin(val); - auto last = std::end(val); - size_t size = std::distance(first,last); - j.reserve(size); - for (auto it = first; it != last; ++it) - { - j.push_back(*it); - } - return j; - } - - static Json to_json(const T& val, const allocator_type& allocator) - { - Json j = typename Json::array(allocator); - auto first = std::begin(val); - auto last = std::end(val); - size_t size = std::distance(first, last); - j.reserve(size); - for (auto it = first; it != last; ++it) - { - j.push_back(*it); - } - return j; - } -}; - -template -struct json_type_traits::value>::type> -{ - typedef typename std::iterator_traits::value_type element_type; - typedef typename Json::allocator_type allocator_type; - typedef typename T::allocator_type string_allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - return j.is_string(); - } - - static T as(const Json& j) - { - if (j.is_string()) - { - return j.as_string(string_allocator_type()); - } - else - { - T s; - j.dump(s); - return s; - } - } - - static Json to_json(const T& val) - { - return Json(typename Json::variant(val.data(), val.size())); - } - - static Json to_json(const T& val, const allocator_type& allocator) - { - return Json(typename Json::variant(val.data(),val.size(),allocator)); - } -}; - -template -struct json_type_traits::value>::type -> -{ - typedef typename T::mapped_type mapped_type; - typedef typename T::value_type value_type; - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - bool result = j.is_object(); - for (auto member : j.object_range()) - { - if (!member.value().template is()) - { - result = false; - } - } - return result; - } - - static T as(const Json& j) - { - T v(detail::json_object_input_iterator(j.object_range().begin()), - detail::json_object_input_iterator(j.object_range().end())); - return v; - } - - static Json to_json(const T& val) - { - Json j; - j.reserve(val.size()); - for (auto p: val) - { - j.set(p.first, p.second); - } - return j; - } - - static Json to_json(const T& val, const allocator_type& allocator) - { - Json j(allocator); - j.reserve(val.size()); - for (auto p: val) - { - j.set(p.first, p.second); - } - return j; - } -}; - -template -struct json_type_traits> -{ - typedef typename Json::allocator_type allocator_type; - - typedef E element_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - bool result = j.is_array() && j.size() == N; - if (result) - { - for (auto e : j.array_range()) - { - if (!e.template is()) - { - result = false; - break; - } - } - } - return result; - } - - static std::array as(const Json& j) - { - std::array buff; - JSONCONS_ASSERT(j.size() == N); - for (size_t i = 0; i < N; i++) - { - buff[i] = j[i].template as(); - } - return buff; - } - - static Json to_json(const std::array& val) - { - Json j = typename Json::array(); - j.reserve(N); - for (auto it = val.begin(); it != val.end(); ++it) - { - j.push_back(*it); - } - return j; - } - - static Json to_json(const std::array& val, - const allocator_type& allocator) - { - Json j = typename Json::array(allocator); - j.reserve(N); - for (auto it = val.begin(); it != val.end(); ++it) - { - j.push_back(*it); - } - return j; - } -}; - -template -struct json_tuple_helper -{ - using element_type = typename std::tuple_element::type; - using next = json_tuple_helper; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - if(j[Pos - 1].template is()) - { - return next::is(j); - } - else - { - return false; - } - } - - static void as(Tuple& tuple, const Json& j) - { - std::get(tuple) = j[Pos - 1].template as(); - next::as(tuple, j); - } - - static void to_json(const Tuple& tuple, std::array::value>& jsons) - { - jsons[Pos - 1] = typename Traits::base_traits::to_json(std::get(tuple)); - next::to_json(tuple, jsons); - } -}; - -template -struct json_tuple_helper<0, Json, Tuple> -{ - static bool is(const Json&) JSONCONS_NOEXCEPT - { - return true; - } - - static void as(Tuple&, const Json&) - { - } - - static void to_json(const Tuple&, std::array::value>&) - { - } -}; - -template -struct json_type_traits> -{ -private: - using helper = detail::json_tuple_helper>; - -public: - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - return helper::is(j); - } - - static std::tuple as(const Json& j) - { - std::tuple buff; - helper::as(buff, j); - return buff; - } - - static Json to_json(const std::tuple& val) - { - std::array buf; - helper::to_json(val, buf); - return Json(typename Json::array(buf.begin(), buf.end())); - } -}; - -template -struct json_type_traits> -{ -public: - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - return j.is_array() && j.size() == 2; - } - - static std::pair as(const Json& j) - { - return std::make_pair(j[0]. template as(),j[1]. template as()); - } - - static Json to_json(const std::pair& val) - { - return typename Json::array{val.first,val.second}; - } -}; - -template -struct json_type_traits> -{ -public: - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - return j.is_byte_string(); - } - - static basic_byte_string as(const Json& j) - { - return basic_byte_string(j.as_byte_string_view()); - } - - static Json to_json(const basic_byte_string& val) - { - return Json(val.data(),val.length()); - } -}; - -// std::valarray - -template -struct json_type_traits> -{ - typedef typename Json::allocator_type allocator_type; - - static bool is(const Json& j) JSONCONS_NOEXCEPT - { - bool result = j.is_array(); - if (result) - { - for (auto e : j.array_range()) - { - if (!e.template is()) - { - result = false; - break; - } - } - } - return result; - } - - static std::valarray as(const Json& j) - { - if (j.is_array()) - { - std::valarray v(j.size()); - for (size_t i = 0; i < j.size(); ++i) - { - v[i] = j[i].template as(); - } - return v; - } - else - { - JSONCONS_THROW(json_exception_impl("Attempt to cast json non-array to array")); - } - } - - static Json to_json(const std::valarray& val) - { - Json j = typename Json::array(); - auto first = std::begin(val); - auto last = std::end(val); - size_t size = std::distance(first,last); - j.reserve(size); - for (auto it = first; it != last; ++it) - { - j.push_back(*it); - } - return j; - } - - static Json to_json(const std::valarray& val, const allocator_type& allocator) - { - Json j = typename Json::array(allocator); - auto first = std::begin(val); - auto last = std::end(val); - size_t size = std::distance(first,last); - j.reserve(size); - for (auto it = first; it != last; ++it) - { - j.push_back(*it); - } - return j; - } -}; - -}} - -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - -#endif - diff --git a/invehicle-apps/3rd-party-libs/jsoncons/detail/number_parsers.hpp b/invehicle-apps/3rd-party-libs/jsoncons/detail/number_parsers.hpp deleted file mode 100644 index 1a8fc0a..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/detail/number_parsers.hpp +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright 2013 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_DETAIL_NUMBERPARSERS_HPP -#define JSONCONS_DETAIL_NUMBERPARSERS_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace jsoncons { namespace detail { - -struct to_integer_result -{ - int64_t value; - bool overflow; -}; - -// Precondition: s satisfies - -// digit -// digit1-digits -// - digit -// - digit1-digits - -template -to_integer_result to_integer(const CharT* s, size_t length) -{ - JSONCONS_ASSERT(length > 0); - - int64_t n = 0; - bool overflow = false; - const CharT* end = s + length; - if (*s == '-') - { - static const int64_t min_value = (std::numeric_limits::min)(); - static const int64_t min_value_div_10 = min_value / 10; - ++s; - for (; s < end; ++s) - { - int64_t x = *s - '0'; - if (n < min_value_div_10) - { - overflow = true; - break; - } - n = n * 10; - if (n < min_value + x) - { - overflow = true; - break; - } - - n -= x; - } - } - else - { - static const int64_t max_value = (std::numeric_limits::max)(); - static const int64_t max_value_div_10 = max_value / 10; - for (; s < end; ++s) - { - int64_t x = *s - '0'; - if (n > max_value_div_10) - { - overflow = true; - break; - } - n = n * 10; - if (n > max_value - x) - { - overflow = true; - break; - } - - n += x; - } - } - - return to_integer_result({ n,overflow }); -} - -struct to_uinteger_result -{ - uint64_t value; - bool overflow; -}; - -// Precondition: s satisfies - -// digit -// digit1-digits -// - digit -// - digit1-digits - -template -to_uinteger_result to_uinteger(const CharT* s, size_t length) -{ - JSONCONS_ASSERT(length > 0); - - static const uint64_t max_value = (std::numeric_limits::max)(); - static const uint64_t max_value_div_10 = max_value / 10; - uint64_t n = 0; - bool overflow = false; - - const CharT* end = s + length; - for (; s < end; ++s) - { - uint64_t x = *s - '0'; - if (n > max_value_div_10) - { - overflow = true; - break; - } - n = n * 10; - if (n > max_value - x) - { - overflow = true; - break; - } - - n += x; - } - return to_uinteger_result{ n,overflow }; -} - -#if defined(JSONCONS_HAS_MSC__STRTOD_L) - -class string_to_double -{ -private: - _locale_t locale_; -public: - string_to_double() - { - locale_ = _create_locale(LC_NUMERIC, "C"); - } - ~string_to_double() - { - _free_locale(locale_); - } - - char get_decimal_point() const - { - return '.'; - } - - double operator()(const char* s, size_t) const - { - const char *begin = s; - char *end = nullptr; - double val = _strtod_l(begin, &end, locale_); - if (begin == end) - { - JSONCONS_THROW(json_exception_impl("Invalid float value")); - } - return val; - } -private: - // noncopyable and nonmoveable - string_to_double(const string_to_double&) = delete; - string_to_double& operator=(const string_to_double&) = delete; -}; - -#elif defined(JSONCONS_HAS_STRTOLD_L) - -class string_to_double -{ -private: - locale_t locale_; -public: - string_to_double() - { - locale_ = newlocale(LC_ALL_MASK, "C", (locale_t) 0); - } - ~string_to_double() - { - freelocale(locale_); - } - - char get_decimal_point() const - { - return '.'; - } - - double operator()(const char* s, size_t length) const - { - const char *begin = s; - char *end = nullptr; - double val = strtold_l(begin, &end, locale_); - if (begin == end) - { - JSONCONS_THROW(json_exception_impl("Invalid float value")); - } - return val; - } - -private: - // noncopyable and nonmoveable - string_to_double(const string_to_double& fr) = delete; - string_to_double& operator=(const string_to_double& fr) = delete; -}; - -#else -class string_to_double -{ -private: - std::vector buffer_; - char decimal_point_; -public: - string_to_double() - : buffer_() - { - struct lconv * lc = localeconv(); - if (lc != nullptr && lc->decimal_point[0] != 0) - { - decimal_point_ = lc->decimal_point[0]; - } - else - { - decimal_point_ = '.'; - } - buffer_.reserve(100); - } - - char get_decimal_point() const - { - return decimal_point_; - } - - double operator()(const char* s, size_t /*length*/) const - { - char *end = nullptr; - double val = strtod(s, &end); - if (s == end) - { - JSONCONS_THROW(json_exception_impl("string_to_double failed")); - } - return val; - } - -private: - // noncopyable and nonmoveable - string_to_double(const string_to_double& fr) = delete; - string_to_double& operator=(const string_to_double& fr) = delete; -}; -#endif - -}} - -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/detail/number_printers.hpp b/invehicle-apps/3rd-party-libs/jsoncons/detail/number_printers.hpp deleted file mode 100644 index 5877928..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/detail/number_printers.hpp +++ /dev/null @@ -1,374 +0,0 @@ -// Copyright 2013 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_DETAIL_NUMBERPRINTERS_HPP -#define JSONCONS_DETAIL_NUMBERPRINTERS_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace jsoncons { namespace detail { - -// print_integer - -template -void print_integer(int64_t value, Writer& os) -{ - typedef typename Writer::char_type char_type; - - char_type buf[255]; - uint64_t u = (value < 0) ? static_cast(-value) : static_cast(value); - char_type* p = buf; - do - { - *p++ = static_cast(48 + u%10); - } - while (u /= 10); - if (value < 0) - { - os.put('-'); - } - while (--p >= buf) - { - os.put(*p); - } -} - -// print_uinteger - -template -void print_uinteger(uint64_t value, Writer& os) -{ - typedef typename Writer::char_type char_type; - - char_type buf[255]; - char_type* p = buf; - do - { - *p++ = static_cast(48 + value % 10); - } while (value /= 10); - while (--p >= buf) - { - os.put(*p); - } -} - -// print_double - -#if defined(JSONCONS_HAS__ECVT_S) - -class print_double -{ -private: - uint8_t precision_override_; -public: - print_double(uint8_t precision) - : precision_override_(precision) - { - } - - template - void operator()(double val, uint8_t precision, Writer& writer) - { - typedef typename Writer::char_type char_type; - - char buf[_CVTBUFSIZE]; - int decimal_point = 0; - int sign = 0; - - int prec; - if (precision_override_ != 0) - { - prec = precision_override_; - } - else if (precision != 0) - { - prec = precision; - } - else - { - prec = std::numeric_limits::digits10; - } - - int err = _ecvt_s(buf, _CVTBUFSIZE, val, prec, &decimal_point, &sign); - if (err != 0) - { - JSONCONS_THROW(json_exception_impl("Failed attempting double to string conversion")); - } - //std::cout << "prec:" << prec << ", buf:" << buf << std::endl; - char* s = buf; - char* se = s + prec; - - int i, k; - int j; - - if (sign) - { - writer.put('-'); - } - if (decimal_point <= -4 || decimal_point > se - s + 5) - { - writer.put(*s++); - if (s < se) - { - writer.put('.'); - while ((se-1) > s && *(se-1) == '0') - { - --se; - } - - while(s < se) - { - writer.put(*s++); - } - } - writer.put('e'); - /* sprintf(b, "%+.2d", decimal_point - 1); */ - if (--decimal_point < 0) { - writer.put('-'); - decimal_point = -decimal_point; - } - else - writer.put('+'); - for(j = 2, k = 10; 10*k <= decimal_point; j++, k *= 10); - for(;;) - { - i = decimal_point / k; - writer.put(static_cast(i) + '0'); - if (--j <= 0) - break; - decimal_point -= i*k; - decimal_point *= 10; - } - } - else if (decimal_point <= 0) - { - writer.put('0'); - writer.put('.'); - while ((se-1) > s && *(se-1) == '0') - { - --se; - } - for(; decimal_point < 0; decimal_point++) - { - writer.put('0'); - } - while(s < se) - { - writer.put(*s++); - } - } - else { - while(s < se) - { - writer.put(*s++); - if ((--decimal_point == 0) && s < se) - { - writer.put('.'); - while ((se-1) > s && *(se-1) == '0') - { - --se; - } - } - } - for(; decimal_point > 0; decimal_point--) - { - writer.put('0'); - } - } - } -}; - -#elif defined(JSONCONS_NO_LOCALECONV) - -class print_double -{ -private: - uint8_t precision_override_; - basic_obufferedstream os_; -public: - print_double(uint8_t precision) - : precision_override_(precision) - { - os_.imbue(std::locale::classic()); - os_.precision(precision); - } - - template - void operator()(double val, uint8_t precision, Writer& writer) - { - typedef typename Writer::char_type char_type; - - int prec; - if (precision_override_ != 0) - { - prec = precision_override_; - } - else if (precision != 0) - { - prec = precision; - } - else - { - prec = std::numeric_limits::digits10; - } - - os_.clear_sequence(); - os_.precision(prec); - os_ << val; - - //std::cout << "precision_override_:" << (int)precision_override_ << ", precision:" << (int)precision << ", buf:" << os_.data() << std::endl; - - const char_type* sbeg = os_.data(); - const char_type* send = sbeg + os_.length(); - const char_type* pexp = send; - - if (sbeg != send) - { - bool dot = false; - for (pexp = sbeg; *pexp != 'e' && *pexp != 'E' && pexp < send; ++pexp) - { - } - - const char_type* qend = pexp; - while (qend >= sbeg+2 && *(qend-1) == '0' && *(qend-2) != '.') - { - --qend; - } - if (pexp == send) - { - qend = ((qend >= sbeg+2) && *(qend-2) == '.') ? qend : send; - } - - for (const char_type* q = sbeg; q < qend; ++q) - { - if (*q == '.') - { - dot = true; - } - writer.put(*q); - } - if (!dot) - { - writer.put('.'); - writer.put('0'); - dot = true; - } - for (const char_type* q = pexp; q < send; ++q) - { - writer.put(*q); - } - } - } -}; -#else - -class print_double -{ -private: - uint8_t precision_override_; - char decimal_point_; -public: - print_double(uint8_t precision) - : precision_override_(precision) - { - struct lconv * lc = localeconv(); - if (lc != nullptr && lc->decimal_point[0] != 0) - { - decimal_point_ = lc->decimal_point[0]; - } - else - { - decimal_point_ = '.'; - } - } - - template - void operator()(double val, uint8_t precision, Writer& writer) - { - typedef typename Writer::char_type char_type; - - int prec; - if (precision_override_ != 0) - { - prec = precision_override_; - } - else if (precision != 0) - { - prec = precision; - } - else - { - prec = std::numeric_limits::digits10; - } - - char number_buffer[100]; - int length = snprintf(number_buffer, 100, "%1.*g", prec, val); - if (length < 0) - { - JSONCONS_THROW(json_exception_impl("print_double failed.")); - } - - const char* sbeg = number_buffer; - const char* send = sbeg + length; - const char* pexp = send; - - if (sbeg != send) - { - bool dot = false; - for (pexp = sbeg; *pexp != 'e' && *pexp != 'E' && pexp < send; ++pexp) - { - } - - for (const char* q = sbeg; q < pexp; ++q) - { - switch (*q) - { - case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': - writer.put(*q); - break; - default: - if (*q == decimal_point_) - { - dot = true; - writer.put('.'); - } - break; - } - } - if (!dot) - { - writer.put('.'); - writer.put('0'); - dot = true; - } - for (const char* q = pexp; q < send; ++q) - { - writer.put(*q); - } - } - } -}; - -#endif - -}} - -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/detail/obufferedstream.hpp b/invehicle-apps/3rd-party-libs/jsoncons/detail/obufferedstream.hpp deleted file mode 100644 index 7b499f4..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/detail/obufferedstream.hpp +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2016 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_DETAIL_OBUFFEREDSTREAM_HPP -#define JSONCONS_DETAIL_OBUFFEREDSTREAM_HPP - -#include -#include -#include -#include -#include -#include -#include - -namespace jsoncons { - -template< - class CharT, - class Traits = std::char_traits -> class basic_obufferedstream; - -template -class basic_ovectorbuf - : public std::basic_streambuf -{ -private: - std::ios_base::openmode mode_; - std::vector buf_; - -public: - typedef CharT char_type; - typedef typename Traits::int_type int_type; - typedef typename Traits::pos_type pos_type; - typedef typename Traits::off_type off_type; - typedef Traits traits_type; - -public: - - explicit basic_ovectorbuf() JSONCONS_NOEXCEPT - : mode_(std::ios_base::out | std::ios_base::binary), - buf_(100u) - { - // Set write position to beginning of buffer. - this->setp(buf_.data(), buf_.data() + buf_.size()); - this->setg(buf_.data(), 0, buf_.data()); - } - - explicit basic_ovectorbuf(std::size_t length) JSONCONS_NOEXCEPT - : mode_(std::ios_base::out | std::ios_base::binary), - buf_(length) - { - // Set write position to beginning of buffer. - this->setp(buf_.data(), buf_.data() + buf_.size()); - this->setg(buf_.data(), 0, buf_.data()); - } - - virtual ~basic_ovectorbuf() JSONCONS_NOEXCEPT {} - - basic_ovectorbuf(const basic_ovectorbuf&) = delete; - - //basic_ovectorbuf(basic_ovectorbuf&&) = default; - - basic_ovectorbuf& operator=(const basic_ovectorbuf&) = delete; - - //basic_ovectorbuf& operator=(basic_ovectorbuf&&) = default; - - const CharT* data() const - { - return buf_.data(); - } - - size_t length() const - { - return this->pptr() - this->pbase(); - } - - virtual int sync() override - { - return EOF; - } - -protected: - int_type underflow() override - { - return this->gptr() != this->egptr() ? - Traits::to_int_type(*this->gptr()) : Traits::eof(); - } - - int_type pbackfail(int_type c = Traits::eof()) override - { - if (this->gptr() != this->eback()) - { - if (!Traits::eq_int_type(c, Traits::eof())) - { - if (Traits::eq(Traits::to_char_type(c), this->gptr()[-1])) - { - this->gbump(-1); - return c; - } - this->gbump(-1); - *this->gptr() = static_cast(c); - return c; - } - else - { - this->gbump(-1); - return Traits::not_eof(c); - } - } - else - { - return Traits::eof(); - } - } - - int_type overflow(int_type c = Traits::eof()) override - { - if (!Traits::eq_int_type(c, Traits::eof())) - { - size_t pos = buf_.size()+1; - buf_.resize(pos*2); - this->setp(buf_.data(), buf_.data() + buf_.size()); - this->pubseekpos(pos, std::ios_base::out); - *this->pptr() = Traits::to_char_type(c); - this->pbump(1); - this->pubsync(); - return c; - } - else - { - return Traits::not_eof(c); - } - } - - pos_type seekoff(off_type off, std::ios_base::seekdir dir, - std::ios_base::openmode mode = std::ios_base::out) override - { - (void)mode; // Always out - - std::streamoff newoff; - switch (dir) - { - case std::ios_base::beg: - newoff = 0; - break; - case std::ios_base::end: - newoff = static_cast(buf_.size()); - break; - case std::ios_base::cur: - newoff = static_cast(this->pptr() - this->pbase()); - break; - default: - return pos_type(off_type(-1)); - } - - off += newoff; - - std::ptrdiff_t n = this->epptr() - this->pbase(); - - if (off < 0 || off > n) return pos_type(off_type(-1)); - else - { - this->setp(this->pbase(), this->pbase() + n); - this->pbump(static_cast(off)); - } - - return pos_type(off); - } - - pos_type seekoff_beg(off_type off) - { - std::ptrdiff_t n = this->epptr() - this->pbase(); - - if (off < 0 || off > n) - { - return pos_type(off_type(-1)); - } - else - { - this->setp(this->pbase(), this->pbase() + n); - this->pbump(static_cast(off)); - } - - return pos_type(off); - } - - pos_type seekpos(pos_type pos, std::ios_base::openmode mode - = std::ios_base::out) override - { - - (void)mode; // Always out - - return seekoff_beg(pos - pos_type(off_type(0))); - } -}; - -template -class basic_obufferedstream : - public std::basic_ostream -{ -public: - typedef typename std::basic_ios::char_type char_type; - typedef typename std::basic_ios::int_type int_type; - typedef typename std::basic_ios::pos_type pos_type; - typedef typename std::basic_ios::off_type off_type; - typedef typename std::basic_ios::traits_type traits_type; - -private: - typedef basic_ovectorbuf base_ouputbuf; - typedef std::basic_ios base_ios; - - basic_ovectorbuf buf_; - -public: - basic_obufferedstream() JSONCONS_NOEXCEPT - : std::basic_ostream( (std::basic_streambuf*)(&buf_)), - buf_() - {} - basic_obufferedstream(std::size_t length) JSONCONS_NOEXCEPT - : std::basic_ostream( (std::basic_streambuf*)(&buf_)), - buf_(length) - {} - - basic_obufferedstream(const basic_obufferedstream&) = delete; - - //basic_obufferedstream(basic_obufferedstream&&) = default; - - virtual ~basic_obufferedstream() JSONCONS_NOEXCEPT - { - } - - basic_obufferedstream& operator=(const basic_obufferedstream&) = delete; - - //basic_obufferedstream& operator=(basic_obufferedstream&&) = default; - - const CharT* data() const - { - return buf_.data(); - } - - size_t length() const - { - return buf_.length(); - } - - void set_locale(const std::locale& loc) - { - std::locale result = std::basic_ostream::imbue(loc); - //this->pubimbue(loc); - } - - void clear_sequence() - { - this->clear(); - this->seekp(0, std::ios::beg); - } -}; - -} - -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/detail/parse_number.hpp b/invehicle-apps/3rd-party-libs/jsoncons/detail/parse_number.hpp new file mode 100644 index 0000000..221bc45 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/detail/parse_number.hpp @@ -0,0 +1,526 @@ +// Copyright 2013 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_DETAIL_PARSE_NUMBER_HPP +#define JSONCONS_DETAIL_PARSE_NUMBER_HPP + +#include +#include +#include +#include +#include +#include // std::numeric_limits +#include // std::enable_if +#include +#include +#include + +namespace jsoncons { namespace detail { + +enum class to_integer_errc : uint8_t {ok=0,overflow,invalid_digit}; + +template +struct to_integer_result +{ + T value; + to_integer_errc ec; +}; + +class to_integer_error_category_impl + : public std::error_category +{ +public: + const char* name() const noexcept override + { + return "jsoncons/to_integer"; + } + std::string message(int ev) const override + { + switch (static_cast(ev)) + { + case to_integer_errc::overflow: + return "Integer overflow"; + case to_integer_errc::invalid_digit: + return "Invalid digit"; + default: + return "Unknown to_integer error"; + } + } +}; + +inline +const std::error_category& to_integer_error_category() +{ + static to_integer_error_category_impl instance; + return instance; +} + +inline +std::error_code make_error_code(to_integer_errc e) +{ + return std::error_code(static_cast(e),to_integer_error_category()); +} + +template +bool is_integer(const CharT* s, size_t length) +{ + const CharT* end = s + length; + if (s == end) + { + return false; + } + if (*s == '-') + { + ++s; + } + if (s == end) + { + return false; + } + for (;s < end; ++s) + { + if (!(*s >= '0' && *s <= '9')) + { + return false; + } + } + return true; +} + +template +bool is_uinteger(const CharT* s, size_t length) +{ + const CharT* end = s + length; + if (s == end) + { + return false; + } + for (;s < end; ++s) + { + if (!(*s >= '0' && *s <= '9')) + { + return false; + } + } + return true; +} + +// Precondition: s satisfies + +// digit +// digit1-digits +// - digit +// - digit1-digits + +template +typename std::enable_if::value && std::is_signed::value,to_integer_result>::type +to_integer(const CharT* s, size_t length) +{ + static_assert(std::numeric_limits::is_specialized, "Integer type not specialized"); + JSONCONS_ASSERT(length > 0); + + to_integer_errc ec{}; + + T n = 0; + const CharT* end = s + length; + if (*s == '-') + { + static const T min_value = (std::numeric_limits::lowest)(); + static const T min_value_div_10 = min_value / 10; + ++s; + for (; s < end; ++s) + { + T x = *s - '0'; + if (n < min_value_div_10) + { + ec = to_integer_errc::overflow; + break; + } + n = n * 10; + if (n < min_value + x) + { + ec = to_integer_errc::overflow; + break; + } + + n -= x; + } + } + else + { + static const T max_value = (std::numeric_limits::max)(); + static const T max_value_div_10 = max_value / 10; + for (; s < end; ++s) + { + T x = *s - '0'; + if (n > max_value_div_10) + { + ec = to_integer_errc::overflow; + break; + } + n = n * 10; + if (n > max_value - x) + { + ec = to_integer_errc::overflow; + break; + } + + n += x; + } + } + + return to_integer_result({n,ec}); +} + +// Precondition: s satisfies + +// digit +// digit1-digits +// - digit +// - digit1-digits + +template +typename std::enable_if::value && !std::is_signed::value,to_integer_result>::type +to_integer(const CharT* s, size_t length) +{ + static_assert(std::numeric_limits::is_specialized, "Integer type not specialized"); + JSONCONS_ASSERT(length > 0); + + T n = 0; + to_integer_errc ec{}; + + const CharT* end = s + length; + + static const T max_value = (std::numeric_limits::max)(); + static const T max_value_div_10 = max_value / 10; + for (; s < end; ++s) + { + T x = *s - '0'; + if (n > max_value_div_10) + { + ec = to_integer_errc::overflow; + break; + } + n = n * 10; + if (n > max_value - x) + { + ec = to_integer_errc::overflow; + break; + } + + n += x; + } + + return to_integer_result({ n,ec }); +} + +// base16_to_integer + +template +typename std::enable_if::value && std::is_signed::value,to_integer_result>::type +base16_to_integer(const CharT* s, size_t length) +{ + static_assert(std::numeric_limits::is_specialized, "Integer type not specialized"); + JSONCONS_ASSERT(length > 0); + + T n = 0; + to_integer_errc ec{}; + const CharT* end = s + length; + if (*s == '-') + { + static const T min_value = (std::numeric_limits::lowest)(); + static const T min_value_div_16 = min_value / 16; + ++s; + for (; s < end; ++s) + { + CharT c = *s; + T x = 0; + switch (c) + { + case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': + x = c - '0'; + break; + case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': + x = c - ('a' - 10); + break; + case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': + x = c - ('A' - 10); + break; + default: + throw std::runtime_error("Invalid hex digit"); + } + if (n < min_value_div_16) + { + ec = to_integer_errc::overflow; + break; + } + n = n * 16; + if (n < min_value + x) + { + ec = to_integer_errc::overflow; + break; + } + n -= x; + } + } + else + { + static const T max_value = (std::numeric_limits::max)(); + static const T max_value_div_16 = max_value / 16; + for (; s < end; ++s) + { + CharT c = *s; + T x = 0; + switch (c) + { + case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': + x = c - '0'; + break; + case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': + x = c - ('a' - 10); + break; + case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': + x = c - ('A' - 10); + break; + default: + throw std::runtime_error("Invalid hex digit"); + } + if (n > max_value_div_16) + { + ec = to_integer_errc::overflow; + break; + } + n = n * 16; + if (n > max_value - x) + { + ec = to_integer_errc::overflow; + break; + } + + n += x; + } + } + + return to_integer_result({ n,ec }); +} + +template +typename std::enable_if::value && !std::is_signed::value,to_integer_result>::type +base16_to_integer(const CharT* s, size_t length) +{ + static_assert(std::numeric_limits::is_specialized, "Integer type not specialized"); + JSONCONS_ASSERT(length > 0); + + T n = 0; + to_integer_errc ec{}; + const CharT* end = s + length; + + static const T max_value = (std::numeric_limits::max)(); + static const T max_value_div_16 = max_value / 16; + for (; s < end; ++s) + { + CharT c = *s; + T x = *s; + switch (c) + { + case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': + x = c - '0'; + break; + case 'a':case 'b':case 'c':case 'd':case 'e':case 'f': + x = c - ('a' - 10); + break; + case 'A':case 'B':case 'C':case 'D':case 'E':case 'F': + x = c - ('A' - 10); + break; + default: + throw std::runtime_error("Invalid hex digit"); + } + if (n > max_value_div_16) + { + ec = to_integer_errc::overflow; + break; + } + n = n * 16; + if (n > max_value - x) + { + ec = to_integer_errc::overflow; + break; + } + + n += x; + } + + return to_integer_result({ n,ec }); +} + +#if defined(JSONCONS_HAS_MSC__STRTOD_L) + +class string_to_double +{ +private: + _locale_t locale_; +public: + string_to_double() + { + locale_ = _create_locale(LC_NUMERIC, "C"); + } + ~string_to_double() + { + _free_locale(locale_); + } + + char get_decimal_point() const + { + return '.'; + } + + template + typename std::enable_if::value,double>::type + operator()(const CharT* s, size_t) const + { + CharT *end = nullptr; + double val = _strtod_l(s, &end, locale_); + if (s == end) + { + JSONCONS_THROW(json_runtime_error("Convert string to double failed")); + } + return val; + } + + template + typename std::enable_if::value,double>::type + operator()(const CharT* s, size_t) const + { + CharT *end = nullptr; + double val = _wcstod_l(s, &end, locale_); + if (s == end) + { + JSONCONS_THROW(json_runtime_error("Convert string to double failed")); + } + return val; + } +private: + // noncopyable and nonmoveable + string_to_double(const string_to_double&) = delete; + string_to_double& operator=(const string_to_double&) = delete; +}; + +#elif defined(JSONCONS_HAS_STRTOLD_L) + +class string_to_double +{ +private: + locale_t locale_; +public: + string_to_double() + { + locale_ = newlocale(LC_ALL_MASK, "C", (locale_t) 0); + } + ~string_to_double() + { + freelocale(locale_); + } + + char get_decimal_point() const + { + return '.'; + } + + template + typename std::enable_if::value,double>::type + operator()(const CharT* s, size_t length) const + { + char *end = nullptr; + double val = strtold_l(s, &end, locale_); + if (s == end) + { + JSONCONS_THROW(json_runtime_error("Convert string to double failed")); + } + return val; + } + + template + typename std::enable_if::value,double>::type + operator()(const CharT* s, size_t length) const + { + CharT *end = nullptr; + double val = wcstold_l(s, &end, locale_); + if (s == end) + { + JSONCONS_THROW(json_runtime_error("Convert string to double failed")); + } + return val; + } + +private: + // noncopyable and nonmoveable + string_to_double(const string_to_double& fr) = delete; + string_to_double& operator=(const string_to_double& fr) = delete; +}; + +#else +class string_to_double +{ +private: + std::vector buffer_; + char decimal_point_; +public: + string_to_double() + : buffer_() + { + struct lconv * lc = localeconv(); + if (lc != nullptr && lc->decimal_point[0] != 0) + { + decimal_point_ = lc->decimal_point[0]; + } + else + { + decimal_point_ = '.'; + } + buffer_.reserve(100); + } + + char get_decimal_point() const + { + return decimal_point_; + } + + template + typename std::enable_if::value,double>::type + operator()(const CharT* s, size_t /*length*/) const + { + CharT *end = nullptr; + double val = strtod(s, &end); + if (s == end) + { + JSONCONS_THROW(json_runtime_error("Convert string to double failed")); + } + return val; + } + + template + typename std::enable_if::value,double>::type + operator()(const CharT* s, size_t /*length*/) const + { + CharT *end = nullptr; + double val = wcstod(s, &end); + if (s == end) + { + JSONCONS_THROW(json_runtime_error("Convert string to double failed")); + } + return val; + } + +private: + // noncopyable and nonmoveable + string_to_double(const string_to_double& fr) = delete; + string_to_double& operator=(const string_to_double& fr) = delete; +}; +#endif + +}} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/detail/print_number.hpp b/invehicle-apps/3rd-party-libs/jsoncons/detail/print_number.hpp new file mode 100644 index 0000000..8fa870d --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/detail/print_number.hpp @@ -0,0 +1,344 @@ +// Copyright 2013 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_DETAIL_PRINT_NUMBER_HPP +#define JSONCONS_DETAIL_PRINT_NUMBER_HPP + +#include +#include +#include +#include +#include // std::numeric_limits +#include +#include +#include +#include +#include + +namespace jsoncons { namespace detail { + +// print_integer + +template +size_t print_integer(int64_t value, Result& result) +{ + typedef typename Result::value_type char_type; + + size_t count = 0; + + char_type buf[255]; + uint64_t u = (value < 0) ? static_cast(-value) : static_cast(value); + char_type* p = buf; + do + { + *p++ = static_cast(48 + u%10); + } + while (u /= 10); + count += (p-buf); + if (value < 0) + { + result.push_back('-'); + ++count; + } + while (--p >= buf) + { + result.push_back(*p); + } + + return count; +} + +// print_uinteger + +template +size_t print_uinteger(uint64_t value, Result& result) +{ + typedef typename Result::value_type char_type; + + size_t count = 0; + + char_type buf[255]; + char_type* p = buf; + do + { + *p++ = static_cast(48 + value % 10); + } + while (value /= 10); + count += (p-buf); + while (--p >= buf) + { + result.push_back(*p); + } + return count; +} + +// print_integer + +template +size_t integer_to_hex_string(int64_t value, Result& result) +{ + typedef typename Result::value_type char_type; + + size_t count = 0; + + char_type buf[255]; + uint64_t u = (value < 0) ? static_cast(-value) : static_cast(value); + char_type* p = buf; + do + { + *p++ = to_hex_character(u%16); + } + while (u /= 16); + count += (p-buf); + if (value < 0) + { + result.push_back('-'); + ++count; + } + while (--p >= buf) + { + result.push_back(*p); + } + + return count; +} + +// print_uinteger + +template +size_t uinteger_to_hex_string(uint64_t value, Result& result) +{ + typedef typename Result::value_type char_type; + + size_t count = 0; + + char_type buf[255]; + char_type* p = buf; + do + { + *p++ = to_hex_character(value % 16); + } + while (value /= 16); + count += (p-buf); + while (--p >= buf) + { + result.push_back(*p); + } + return count; +} + +// print_double + +template +void dump_buffer(const char* buffer, size_t length, char decimal_point, Result& result) +{ + const char* sbeg = buffer; + const char* send = sbeg + length; + + if (sbeg != send) + { + bool needs_dot = true; + for (const char* q = sbeg; q < send; ++q) + { + switch (*q) + { + case '-':case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':case '+': + result.push_back(*q); + break; + case 'e': + case 'E': + result.push_back('e'); + needs_dot = false; + break; + default: + if (*q == decimal_point) + { + needs_dot = false; + result.push_back('.'); + } + break; + } + } + if (needs_dot) + { + result.push_back('.'); + result.push_back('0'); + needs_dot = true; + } + } +} + +template +bool dtoa(double val, char decimal_point, Result& result, std::false_type) +{ + if (val == 0) + { + result.push_back('0'); + result.push_back('.'); + result.push_back('0'); + return true; + } + + jsoncons::detail::string_to_double to_double_; + + char buffer[100]; + int precision = std::numeric_limits::digits10; + int length = snprintf(buffer, sizeof(buffer), "%1.*g", precision, val); + if (length < 0) + { + return false; + } + if (to_double_(buffer,sizeof(buffer)) != val) + { + const int precision2 = std::numeric_limits::max_digits10; + length = snprintf(buffer, sizeof(buffer), "%1.*g", precision2, val); + if (length < 0) + { + return false; + } + } + dump_buffer(buffer, length, decimal_point, result); + return true; +} + +template +bool dtoa(double v, char decimal_point, Result& result, std::true_type) +{ + if (v == 0) + { + result.push_back('0'); + result.push_back('.'); + result.push_back('0'); + return true; + } + + int length = 0; + int k; + + char buffer[100]; + + double u = std::signbit(v) ? -v : v; + if (jsoncons::detail::grisu3(u, buffer, &length, &k)) + { + if (std::signbit(v)) + { + result.push_back('-'); + } + // min exp: -4 is consistent with sprintf + // max exp: std::numeric_limits::max_digits10 + jsoncons::detail::prettify_string(buffer, length, k, -4, std::numeric_limits::max_digits10, result); + return true; + } + else + { + return dtoa(v, decimal_point, result, std::false_type()); + } +} + +template +bool dtoa(double v, char decimal_point, Result& result) +{ + return dtoa(v, decimal_point, result, std::integral_constant::is_iec559>()); +} + +class print_double +{ +private: + string_to_double to_double_; + floating_point_options override_; + char decimal_point_; +public: + print_double(const floating_point_options& options) + : override_(options) + { +#if !defined(JSONCONS_NO_LOCALECONV) + struct lconv * lc = localeconv(); + if (lc != nullptr && lc->decimal_point[0] != 0) + { + decimal_point_ = lc->decimal_point[0]; + } + else +#endif + { + decimal_point_ = '.'; + } + } + + template + size_t operator()(double val, Result& result) + { + size_t count = 0; + + chars_format format = override_.format() != chars_format() ? override_.format() : chars_format::general; + + int decimal_places; + if (override_.decimal_places() != 0) + { + decimal_places = override_.decimal_places(); + } + else + { + format = chars_format::general; + decimal_places = 0; + } + + char number_buffer[200]; + int length = 0; + + switch (format) + { + case chars_format::fixed: + { + length = snprintf(number_buffer, sizeof(number_buffer), "%1.*f", decimal_places, val); + if (length < 0) + { + JSONCONS_THROW(json_runtime_error("print_double failed.")); + } + dump_buffer(number_buffer, length, decimal_point_, result); + } + break; + case chars_format::scientific: + { + length = snprintf(number_buffer, sizeof(number_buffer), "%1.*e", decimal_places, val); + if (length < 0) + { + JSONCONS_THROW(json_runtime_error("print_double failed.")); + } + dump_buffer(number_buffer, length, decimal_point_, result); + } + break; + case chars_format::general: + { + if (override_.precision() != 0) + { + int precision = override_.precision(); + length = snprintf(number_buffer, sizeof(number_buffer), "%1.*g", precision, val); + if (length < 0) + { + JSONCONS_THROW(json_runtime_error("print_double failed.")); + } + dump_buffer(number_buffer, length, decimal_point_, result); + } + else + { + if (!dtoa(val, decimal_point_, result)) + { + JSONCONS_THROW(json_runtime_error("print_double failed.")); + } + } + break; + } + default: + JSONCONS_THROW(json_runtime_error("print_double failed.")); + break; + } + return count; + } +}; + +}} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/detail/string_view.hpp b/invehicle-apps/3rd-party-libs/jsoncons/detail/string_view.hpp new file mode 100644 index 0000000..e85abff --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/detail/string_view.hpp @@ -0,0 +1,525 @@ +// Copyright 2019 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_STRING_VIEW_HPP +#define JSONCONS_STRING_VIEW_HPP + +#include +#include +#include +#include +#include +#include // std::find, std::min, std::reverse +#include +#include +#include +#include +#include // std::basic_istream + +namespace jsoncons { namespace detail { + +template > +class basic_string_view +{ +private: + const CharT* data_; + size_t length_; +public: + typedef CharT value_type; + typedef const CharT& const_reference; + typedef Traits traits_type; + typedef std::size_t size_type; + static const size_type npos = size_type(-1); + typedef const CharT* const_iterator; + typedef const CharT* iterator; + typedef std::reverse_iterator const_reverse_iterator; + + basic_string_view() + : data_(nullptr), length_(0) + { + } + basic_string_view(const CharT* data, size_t length) + : data_(data), length_(length) + { + } + basic_string_view(const CharT* data) + : data_(data), length_(Traits::length(data)) + { + } + basic_string_view(const basic_string_view& other) = default; + + template + basic_string_view(const std::basic_string& s) + : data_(s.data()), length_(s.length()) + { + } + + template + explicit operator std::basic_string() const + { + return std::basic_string(data_,length_); + } + + // iterator support + const_iterator begin() const noexcept + { + return data_; + } + const_iterator end() const noexcept + { + return data_ + length_; + } + const_iterator cbegin() const noexcept + { + return data_; + } + const_iterator cend() const noexcept + { + return data_ + length_; + } + const_reverse_iterator rbegin() const noexcept + { + return const_reverse_iterator(end()); + } + const_reverse_iterator rend() const noexcept + { + return const_reverse_iterator(begin()); + } + const_reverse_iterator crbegin() const noexcept + { + return const_reverse_iterator(end()); + } + const_reverse_iterator crend() const noexcept + { + return const_reverse_iterator(begin()); + } + + // capacity + + size_t size() const + { + return length_; + } + + size_t length() const + { + return length_; + } + size_type max_size() const noexcept + { + return length_; + } + bool empty() const noexcept + { + return length_ == 0; + } + + // element access + + const_reference operator[](size_type pos) const + { + return data_[pos]; + } + + const_reference at(size_t pos) const + { + if (pos >= length_) + { + throw std::out_of_range("pos exceeds length"); + } + return data_[pos]; + } + + const_reference front() const + { + return data_[0]; + } + const_reference back() const + { + return data_[length_-1]; + } + + const CharT* data() const + { + return data_; + } + + // string operations + + basic_string_view substr(size_type pos, size_type n=npos) const + { + if (pos > length_) + { + throw std::out_of_range("pos exceeds size"); + } + if (n == npos || pos + n > length_) + { + n = length_ - pos; + } + return basic_string_view(data_ + pos, n); + } + + int compare(const basic_string_view& s) const + { + const int rc = Traits::compare(data_, s.data_, (std::min)(length_, s.length_)); + return rc != 0 ? rc : (length_ == s.length_ ? 0 : length_ < s.length_ ? -1 : 1); + } + + int compare(const CharT* data) const + { + const size_t length = Traits::length(data); + const int rc = Traits::compare(data_, data, (std::min)(length_, length)); + return rc != 0 ? rc : (length_ == length? 0 : length_ < length? -1 : 1); + } + + template + int compare(const std::basic_string& s) const + { + const int rc = Traits::compare(data_, s.data(), (std::min)(length_, s.length())); + return rc != 0 ? rc : (length_ == s.length() ? 0 : length_ < s.length() ? -1 : 1); + } + + size_type find(basic_string_view s, size_type pos = 0) const noexcept + { + if (pos > length_) + { + return npos; + } + if (s.length_ == 0) + { + return pos; + } + const_iterator it = std::search(cbegin() + pos, cend(), + s.cbegin(), s.cend(), Traits::eq); + return it == cend() ? npos : std::distance(cbegin(), it); + } + size_type find(CharT ch, size_type pos = 0) const noexcept + { + return find(basic_string_view(&ch, 1), pos); + } + size_type find(const CharT* s, size_type pos, size_type n) const noexcept + { + return find(basic_string_view(s, n), pos); + } + size_type find(const CharT* s, size_type pos = 0) const noexcept + { + return find(basic_string_view(s), pos); + } + + size_type rfind(basic_string_view s, size_type pos = npos) const noexcept + { + if (length_ < s.length_) + { + return npos; + } + if (pos > length_ - s.length_) + { + pos = length_ - s.length_; + } + if (s.length_ == 0) + { + return pos; + } + for (const CharT* p = data_ + pos; true; --p) + { + if (Traits::compare(p, s.data_, s.length_) == 0) + { + return p - data_; + } + if (p == data_) + { + return npos; + } + }; + } + size_type rfind(CharT ch, size_type pos = npos) const noexcept + { + return rfind(basic_string_view(&ch, 1), pos); + } + size_type rfind(const CharT* s, size_type pos, size_type n) const noexcept + { + return rfind(basic_string_view(s, n), pos); + } + size_type rfind(const CharT* s, size_type pos = npos) const noexcept + { + return rfind(basic_string_view(s), pos); + } + + size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept + { + if (pos >= length_ || s.length_ == 0) + { + return npos; + } + const_iterator it = std::find_first_of + (cbegin() + pos, cend(), s.cbegin(), s.cend(), Traits::eq); + return it == cend() ? npos : std::distance (cbegin(), it); + } + size_type find_first_of(CharT ch, size_type pos = 0) const noexcept + { + return find_first_of(basic_string_view(&ch, 1), pos); + } + size_type find_first_of(const CharT* s, size_type pos, size_type n) const noexcept + { + return find_first_of(basic_string_view(s, n), pos); + } + size_type find_first_of(const CharT* s, size_type pos = 0) const noexcept + { + return find_first_of(basic_string_view(s), pos); + } + + size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept + { + if (s.length_ == 0) + { + return npos; + } + if (pos >= length_) + { + pos = 0; + } + else + { + pos = length_ - (pos+1); + } + const_reverse_iterator it = std::find_first_of + (crbegin() + pos, crend(), s.cbegin(), s.cend(), Traits::eq); + return it == crend() ? npos : (length_ - 1 - std::distance(crbegin(), it)); + } + size_type find_last_of(CharT ch, size_type pos = npos) const noexcept + { + return find_last_of(basic_string_view(&ch, 1), pos); + } + size_type find_last_of(const CharT* s, size_type pos, size_type n) const noexcept + { + return find_last_of(basic_string_view(s, n), pos); + } + size_type find_last_of(const CharT* s, size_type pos = npos) const noexcept + { + return find_last_of(basic_string_view(s), pos); + } + + size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept + { + if (pos >= length_) + return npos; + if (s.length_ == 0) + return pos; + + const_iterator it = cend(); + for (auto p = cbegin()+pos; p != cend(); ++p) + { + if (Traits::find(s.data_, s.length_, *p) == 0) + { + it = p; + break; + } + } + return it == cend() ? npos : std::distance (cbegin(), it); + } + size_type find_first_not_of(CharT ch, size_type pos = 0) const noexcept + { + return find_first_not_of(basic_string_view(&ch, 1), pos); + } + size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const noexcept + { + return find_first_not_of(basic_string_view(s, n), pos); + } + size_type find_first_not_of(const CharT* s, size_type pos = 0) const noexcept + { + return find_first_not_of(basic_string_view(s), pos); + } + + size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept + { + if (pos >= length_) + { + pos = length_ - 1; + } + if (s.length_ == 0) + { + return pos; + } + pos = length_ - (pos+1); + + const_iterator it = crend(); + for (auto p = crbegin()+pos; p != crend(); ++p) + { + if (Traits::find(s.data_, s.length_, *p) == 0) + { + it = p; + break; + } + } + return it == crend() ? npos : (length_ - 1 - std::distance(crbegin(), it)); + } + size_type find_last_not_of(CharT ch, size_type pos = npos) const noexcept + { + return find_last_not_of(basic_string_view(&ch, 1), pos); + } + size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const noexcept + { + return find_last_not_of(basic_string_view(s, n), pos); + } + size_type find_last_not_of(const CharT* s, size_type pos = npos) const noexcept + { + return find_last_not_of(basic_string_view(s), pos); + } + + friend std::basic_ostream& operator<<(std::basic_ostream& os, const basic_string_view& sv) + { + os.write(sv.data_,sv.length_); + return os; + } +}; + +// == +template +bool operator==(const basic_string_view& lhs, + const basic_string_view& rhs) +{ + return lhs.compare(rhs) == 0; +} +template +bool operator==(const basic_string_view& lhs, + const std::basic_string& rhs) +{ + return lhs.compare(rhs) == 0; +} +template +bool operator==(const std::basic_string& lhs, + const basic_string_view& rhs) +{ + return rhs.compare(lhs) == 0; +} +template +bool operator==(const basic_string_view& lhs, + const CharT* rhs) +{ + return lhs.compare(rhs) == 0; +} +template +bool operator==(const CharT* lhs, + const basic_string_view& rhs) +{ + return rhs.compare(lhs) == 0; +} + +// != +template +bool operator!=(const basic_string_view& lhs, + const basic_string_view& rhs) +{ + return lhs.compare(rhs) != 0; +} +template +bool operator!=(const basic_string_view& lhs, + const std::basic_string& rhs) +{ + return lhs.compare(rhs) != 0; +} +template +bool operator!=(const std::basic_string& lhs, + const basic_string_view& rhs) +{ + return rhs.compare(lhs) != 0; +} +template +bool operator!=(const basic_string_view& lhs, + const CharT* rhs) +{ + return lhs.compare(rhs) != 0; +} +template +bool operator!=(const CharT* lhs, + const basic_string_view& rhs) +{ + return rhs.compare(lhs) != 0; +} + +// <= +template +bool operator<=(const basic_string_view& lhs, + const basic_string_view& rhs) +{ + return lhs.compare(rhs) <= 0; +} +template +bool operator<=(const basic_string_view& lhs, + const std::basic_string& rhs) +{ + return lhs.compare(rhs) <= 0; +} +template +bool operator<=(const std::basic_string& lhs, + const basic_string_view& rhs) +{ + return rhs.compare(lhs) >= 0; +} + +// < +template +bool operator<(const basic_string_view& lhs, + const basic_string_view& rhs) +{ + return lhs.compare(rhs) < 0; +} +template +bool operator<(const basic_string_view& lhs, + const std::basic_string& rhs) +{ + return lhs.compare(rhs) < 0; +} +template +bool operator<(const std::basic_string& lhs, + const basic_string_view& rhs) +{ + return rhs.compare(lhs) > 0; +} + +// >= +template +bool operator>=(const basic_string_view& lhs, + const basic_string_view& rhs) +{ + return lhs.compare(rhs) >= 0; +} +template +bool operator>=(const basic_string_view& lhs, + const std::basic_string& rhs) +{ + return lhs.compare(rhs) >= 0; +} +template +bool operator>=(const std::basic_string& lhs, + const basic_string_view& rhs) +{ + return rhs.compare(lhs) <= 0; +} + +// > +template +bool operator>(const basic_string_view& lhs, + const basic_string_view& rhs) +{ + return lhs.compare(rhs) > 0; +} +template +bool operator>(const basic_string_view& lhs, + const std::basic_string& rhs) +{ + return lhs.compare(rhs) > 0; +} +template +bool operator>(const std::basic_string& lhs, + const basic_string_view& rhs) +{ + return rhs.compare(lhs) < 0; +} + +}} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/detail/type_traits_helper.hpp b/invehicle-apps/3rd-party-libs/jsoncons/detail/type_traits.hpp similarity index 75% rename from invehicle-apps/3rd-party-libs/jsoncons/detail/type_traits_helper.hpp rename to invehicle-apps/3rd-party-libs/jsoncons/detail/type_traits.hpp index 4dce8e6..53c5514 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/detail/type_traits_helper.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/detail/type_traits.hpp @@ -4,31 +4,19 @@ // See https://github.com/danielaparker/jsoncons for latest version -#ifndef JSONCONS_DETAIL_TYPETRAITSHELPER_HPP -#define JSONCONS_DETAIL_TYPETRAITSHELPER_HPP +#ifndef JSONCONS_DETAIL_TYPE_TRAITS_HPP +#define JSONCONS_DETAIL_TYPE_TRAITS_HPP #include #include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include +#include // std::enable_if, std::true_type #include -#include +#include // std::iterator_traits #include #include -#include -#include +#include #include -#include namespace jsoncons { @@ -93,20 +81,12 @@ struct type_wrapper typedef const T& const_reference; }; -// json_literals - -namespace detail { -JSONCONS_DEFINE_LITERAL(null_literal,"null") -JSONCONS_DEFINE_LITERAL(true_literal,"true") -JSONCONS_DEFINE_LITERAL(false_literal,"false") -} - inline -unsigned char to_hex_character(unsigned char c) +char to_hex_character(uint8_t c) { JSONCONS_ASSERT(c <= 0xF); - return (c < 10) ? ('0' + c) : ('A' - 10 + c); + return (char)((c < 10) ? ('0' + c) : ('A' - 10 + c)); } inline @@ -147,6 +127,17 @@ T * to_plain_pointer(T * ptr) return (ptr); } +// has_char_traits_member_type + +template +struct has_char_traits_member_type : std::false_type {}; + +template +struct has_char_traits_member_type::value +>::type> : std::true_type {}; + + // is_string_like template @@ -154,7 +145,17 @@ struct is_string_like : std::false_type {}; template struct is_string_like::value + typename std::enable_if::value && !std::is_void::value && !std::is_void::value +>::type> : std::true_type {}; + +// is_string_view_like + +template +struct is_string_view_like : std::false_type {}; + +template +struct is_string_view_like::value && !std::is_void::value && !is_string_like::value >::type> : std::true_type {}; // is_integer_like @@ -213,8 +214,9 @@ struct is_vector_like : std::false_type {}; template struct is_vector_like::value && + !std::is_void::value_type>::value && !is_array_like::value && - !is_string_like::value && + !has_char_traits_member_type::value && !is_map_like::value >::type> : std::true_type {}; diff --git a/invehicle-apps/3rd-party-libs/jsoncons/detail/writer.hpp b/invehicle-apps/3rd-party-libs/jsoncons/detail/writer.hpp deleted file mode 100644 index c832f06..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/detail/writer.hpp +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright 2013 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_DETAIL_WRITERS_HPP -#define JSONCONS_DETAIL_WRITERS_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace jsoncons { namespace detail { - -template -class ostream_buffered_writer -{ -public: - typedef basic_string_view_ext string_view_type; - typedef CharT char_type; - typedef std::basic_ostream output_type; -private: - static const size_t default_buffer_length = 16384; - - std::basic_ostream& os_; - std::vector buffer_; - CharT * begin_buffer_; - const CharT* end_buffer_; - CharT* p_; - - // Noncopyable and nonmoveable - ostream_buffered_writer(const ostream_buffered_writer&) = delete; - ostream_buffered_writer& operator=(const ostream_buffered_writer&) = delete; - -public: - ostream_buffered_writer(std::basic_ostream& os) - : os_(os), buffer_(default_buffer_length), begin_buffer_(buffer_.data()), end_buffer_(begin_buffer_+buffer_.size()), p_(begin_buffer_) - { - } - ostream_buffered_writer(std::basic_ostream& os, size_t buflen) - : os_(os), buffer_(buflen), begin_buffer_(buffer_.data()), end_buffer_(begin_buffer_+buffer_.size()), p_(begin_buffer_) - { - } - ~ostream_buffered_writer() - { - os_.write(begin_buffer_, buffer_length()); - os_.flush(); - } - - void flush() - { - os_.write(begin_buffer_, buffer_length()); - p_ = buffer_.data(); - } - - void write(const CharT* s, size_t length) - { - size_t diff = end_buffer_ - p_; - if (diff >= length) - { - std::memcpy(p_, s, length*sizeof(CharT)); - p_ += length; - } - else - { - os_.write(begin_buffer_, buffer_length()); - os_.write(s,length); - p_ = begin_buffer_; - } - } - - void write(const string_view_type& s) - { - write(s.data(),s.length()); - } - - void put(CharT ch) - { - if (p_ < end_buffer_) - { - *p_++ = ch; - } - else - { - os_.write(begin_buffer_, buffer_length()); - p_ = begin_buffer_; - put(ch); - } - } -private: - - size_t buffer_length() const - { - return p_ - begin_buffer_; - } -}; - -template -class string_writer -{ -public: - typedef basic_string_view_ext string_view_type; - typedef CharT char_type; - typedef std::basic_string output_type; -private: - std::basic_string& s_; - - // Noncopyable and nonmoveable - string_writer(const string_writer&) = delete; - string_writer& operator=(const string_writer&) = delete; -public: - - string_writer(std::basic_string& s) - : s_(s) - { - } - - void flush() - { - } - - void write(const CharT* s, size_t length) - { - s_.append(s,length); - } - - void write(const string_view_type& s) - { - s_.append(s.data(),s.length()); - } - - void put(CharT ch) - { - s_.push_back(ch); - } -}; - -}} - -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/encode_decode_json.hpp b/invehicle-apps/3rd-party-libs/jsoncons/encode_decode_json.hpp new file mode 100644 index 0000000..44c648e --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/encode_decode_json.hpp @@ -0,0 +1,276 @@ +// Copyright 2017 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_ENCODE_DECODE_JSON_HPP +#define JSONCONS_ENCODE_DECODE_JSON_HPP + +#include +#include +#include +#include +#include // std::basic_istream +#include +#include + +namespace jsoncons { + +// decode_json + +template +typename std::enable_if::value,T>::type +decode_json(const std::basic_string& s, + const basic_json_decode_options& options = basic_json_options::get_default_options()) +{ + jsoncons::json_decoder decoder; + basic_json_reader> reader(s, decoder, options); + reader.read(); + return decoder.get_result(); +} + +template +typename std::enable_if::value,T>::type +decode_json(const std::basic_string& s, + const basic_json_decode_options& options = basic_json_options::get_default_options()) +{ + basic_json_cursor reader(s, options); + T val = read_from(basic_json(), reader); + return val; +} + +template +typename std::enable_if::value,T>::type +decode_json(std::basic_istream& is, + const basic_json_decode_options& options = basic_json_options::get_default_options()) +{ + jsoncons::json_decoder decoder; + basic_json_reader> reader(is, decoder, options); + reader.read(); + return decoder.get_result(); +} + +template +typename std::enable_if::value,T>::type +decode_json(std::basic_istream& is, + const basic_json_decode_options& options = basic_json_options::get_default_options()) +{ + basic_json_cursor reader(is, options); + T val = read_from(basic_json(), reader); + return val; +} + +template +T decode_json(const basic_json& j, + const std::basic_string& s, + const basic_json_decode_options& options = basic_json_options::get_default_options()) +{ + basic_json_cursor reader(s, options); + T val = read_from(j, reader); + return val; +} + +template +T decode_json(const basic_json& j, + std::basic_istream& is, + const basic_json_decode_options& options = basic_json_options::get_default_options()) +{ + basic_json_cursor reader(is, options); + T val = read_from(j, reader); + return val; +} + +// encode_json + +template +void encode_json(const T& val, + basic_json_content_handler& receiver) +{ + write_to(basic_json(), val, receiver); + receiver.flush(); +} + +// to stream + +template +typename std::enable_if::value>::type +encode_json(const T& val, + std::basic_ostream& os, + const basic_json_encode_options& options = basic_json_options::get_default_options(), + indenting line_indent = indenting::no_indent) +{ + if (line_indent == indenting::indent) + { + basic_json_encoder encoder(os, options); + val.dump(encoder); + } + else + { + basic_json_compressed_encoder encoder(os, options); + val.dump(encoder); + } +} + +template +typename std::enable_if::value>::type +encode_json(const T& val, + std::basic_ostream& os, + const basic_json_encode_options& options = basic_json_options::get_default_options(), + indenting line_indent = indenting::no_indent) +{ + if (line_indent == indenting::indent) + { + basic_json_encoder encoder(os, options); + encode_json(val, encoder); + } + else + { + basic_json_compressed_encoder encoder(os, options); + encode_json(val, encoder); + } +} + +template +void encode_json(const T& val, + std::basic_ostream& os, + indenting line_indent) +{ + encode_json(val, os, basic_json_options::get_default_options(), line_indent); +} + +// to string + +template +typename std::enable_if::value>::type +encode_json(const T& val, + std::basic_string& s, + const basic_json_encode_options& options = basic_json_options::get_default_options(), + indenting line_indent = indenting::no_indent) +{ + if (line_indent == indenting::indent) + { + basic_json_encoder>> encoder(s, options); + val.dump(encoder); + } + else + { + basic_json_compressed_encoder>> encoder(s, options); + val.dump(encoder); + } +} + +template +typename std::enable_if::value>::type +encode_json(const T& val, + std::basic_string& s, + const basic_json_encode_options& options = basic_json_options::get_default_options(), + indenting line_indent = indenting::no_indent) +{ + if (line_indent == indenting::indent) + { + basic_json_encoder>> encoder(s, options); + encode_json(val, encoder); + } + else + { + basic_json_compressed_encoder>> encoder(s, options); + encode_json(val, encoder); + } +} + +template +void encode_json(const T& val, + std::basic_string& s, + indenting line_indent) +{ + encode_json(val, s, basic_json_options::get_default_options(), line_indent); +} + +template +void encode_json(const basic_json& j, + const T& val, + basic_json_content_handler& receiver) +{ + write_to(j, val, receiver); + receiver.flush(); +} + +template +void encode_json(const basic_json& j, + const T& val, + std::basic_ostream& os, + const basic_json_encode_options& options = basic_json_options::get_default_options(), + indenting line_indent = indenting::no_indent) +{ + if (line_indent == indenting::indent) + { + basic_json_encoder encoder(os, options); + encode_json(j, val, encoder); + } + else + { + basic_json_compressed_encoder encoder(os, options); + encode_json(j, val, encoder); + } +} + +template +void encode_json(const basic_json& j, + const T& val, + std::basic_ostream& os, + indenting line_indent) +{ + if (line_indent == indenting::indent) + { + basic_json_encoder encoder(os, basic_json_options::get_default_options()); + encode_json(j, val, encoder); + } + else + { + basic_json_compressed_encoder encoder(os, basic_json_options::get_default_options()); + encode_json(j, val, encoder); + } +} + +template +void encode_json(const basic_json& j, + const T& val, + std::basic_string& s, + const basic_json_encode_options& options = basic_json_options::get_default_options(), + indenting line_indent = indenting::no_indent) +{ + if (line_indent == indenting::indent) + { + basic_json_encoder>> encoder(s, options); + encode_json(j, val, encoder); + } + else + { + basic_json_compressed_encoder>> encoder(s, options); + encode_json(j, val, encoder); + } +} + +template +void encode_json(const basic_json& j, + const T& val, + std::basic_string& s, + indenting line_indent) +{ + if (line_indent == indenting::indent) + { + basic_json_encoder>> encoder(s, basic_json_options::get_default_options()); + encode_json(j, val, encoder); + } + else + { + basic_json_compressed_encoder>> encoder(s, basic_json_options::get_default_options()); + encode_json(j, val, encoder); + } +} + +} + +#endif + diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json.hpp index 9dade69..0dad529 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/json.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/json.hpp @@ -1,4 +1,4 @@ -// Copyright 2013 Daniel Parker +// 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) @@ -7,5048 +7,8 @@ #ifndef JSONCONS_JSON_HPP #define JSONCONS_JSON_HPP -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wswitch" #endif -namespace jsoncons { - -struct sorted_policy -{ - static const bool preserve_order = false; - - template - using object_storage = std::vector; - - template - using array_storage = std::vector; - - template - using key_storage = std::basic_string; - - template - using string_storage = std::basic_string; - - typedef default_parse_error_handler parse_error_handler_type; -}; - -struct preserve_order_policy : public sorted_policy -{ - static const bool preserve_order = true; -}; - -template -class range -{ - IteratorT first_; - IteratorT last_; -public: - range(const IteratorT& first, const IteratorT& last) - : first_(first), last_(last) - { - } - -public: - IteratorT begin() - { - return first_; - } - IteratorT end() - { - return last_; - } -}; - -enum class json_type_tag : uint8_t -{ - null_t = 0, - empty_object_t, - bool_t, - integer_t, - uinteger_t, - double_t, - small_string_t, - string_t, - byte_string_t, - array_t, - object_t -}; - -template -class basic_json -{ -public: - - typedef Allocator allocator_type; - - typedef ImplementationPolicy implementation_policy; - - typedef typename ImplementationPolicy::parse_error_handler_type parse_error_handler_type; - - typedef CharT char_type; - typedef typename std::char_traits char_traits_type; - - typedef basic_string_view_ext string_view_type; - - typedef typename std::allocator_traits:: template rebind_alloc char_allocator_type; - using string_storage_type = typename implementation_policy::template string_storage; - using key_storage_type = typename implementation_policy::template key_storage; - - // string_type is for interface only, not storage - typedef std::basic_string string_type; - - typedef basic_json value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef key_value_pair key_value_pair_type; - -#if !defined(JSONCONS_NO_DEPRECATED) - typedef value_type json_type; - typedef key_value_pair_type kvp_type; - typedef key_value_pair_type member_type; - typedef jsoncons::null_type null_type; -#endif - - typedef typename std::allocator_traits:: template rebind_alloc val_allocator_type; - using array_storage_type = typename implementation_policy::template array_storage; - - typedef typename std::allocator_traits:: template rebind_alloc byte_allocator_type; - using byte_string_storage_type = typename implementation_policy::template array_storage; - - typedef json_array array; - - typedef typename std::allocator_traits:: template rebind_alloc kvp_allocator_type; - - using object_storage_type = typename implementation_policy::template object_storage; - typedef json_object object; - - typedef typename std::allocator_traits:: template rebind_alloc array_allocator; - typedef typename std::allocator_traits:: template rebind_alloc object_allocator; - - typedef typename object::iterator object_iterator; - typedef typename object::const_iterator const_object_iterator; - typedef typename array::iterator array_iterator; - typedef typename array::const_iterator const_array_iterator; - - struct variant - { - struct data_base - { - json_type_tag type_id_; - - data_base(json_type_tag id) - : type_id_(id) - {} - }; - - class null_data final : public data_base - { - public: - null_data() - : data_base(json_type_tag::null_t) - { - } - }; - - class empty_object_data final : public data_base - { - public: - empty_object_data() - : data_base(json_type_tag::empty_object_t) - { - } - }; - - class bool_data final : public data_base - { - bool val_; - public: - bool_data(bool val) - : data_base(json_type_tag::bool_t),val_(val) - { - } - - bool_data(const bool_data& val) - : data_base(json_type_tag::bool_t),val_(val.val_) - { - } - - bool value() const - { - return val_; - } - - }; - - class integer_data final : public data_base - { - int64_t val_; - public: - integer_data(int64_t val) - : data_base(json_type_tag::integer_t),val_(val) - { - } - - integer_data(const integer_data& val) - : data_base(json_type_tag::integer_t),val_(val.val_) - { - } - - int64_t value() const - { - return val_; - } - }; - - class uinteger_data final : public data_base - { - uint64_t val_; - public: - uinteger_data(uint64_t val) - : data_base(json_type_tag::uinteger_t),val_(val) - { - } - - uinteger_data(const uinteger_data& val) - : data_base(json_type_tag::uinteger_t),val_(val.val_) - { - } - - uint64_t value() const - { - return val_; - } - }; - - class double_data final : public data_base - { - chars_format format_; - uint8_t precision_; - uint8_t decimal_places_; - double val_; - public: - double_data(double val) - : data_base(json_type_tag::double_t), - precision_(0), - decimal_places_(0), - val_(val) - { - } - double_data(double val, const number_format& fmt) - : data_base(json_type_tag::double_t), - format_(fmt.floating_point_format()), - precision_(fmt.precision()), - decimal_places_(fmt.decimal_places()), - val_(val) - { - } - - double_data(const double_data& val) - : data_base(json_type_tag::double_t), - precision_(val.precision_), - decimal_places_(val.decimal_places_), - val_(val.val_) - { - } - - double value() const - { - return val_; - } - - uint8_t precision() const - { - return precision_; - } - - uint8_t decimal_places() const - { - return precision_; - } - }; - - class small_string_data final : public data_base - { - static const size_t capacity = 14/sizeof(char_type); - uint8_t length_; - char_type data_[capacity]; - public: - static const size_t max_length = (14 / sizeof(char_type)) - 1; - - small_string_data(const char_type* p, uint8_t length) - : data_base(json_type_tag::small_string_t), length_(length) - { - JSONCONS_ASSERT(length <= max_length); - std::memcpy(data_,p,length*sizeof(char_type)); - data_[length] = 0; - } - - small_string_data(const small_string_data& val) - : data_base(json_type_tag::small_string_t), length_(val.length_) - { - std::memcpy(data_,val.data_,val.length_*sizeof(char_type)); - data_[length_] = 0; - } - - uint8_t length() const - { - return length_; - } - - const char_type* data() const - { - return data_; - } - - const char_type* c_str() const - { - return data_; - } - }; - - // string_data - class string_data final : public data_base - { - typedef typename detail::heap_only_string_factory::string_pointer pointer; - - pointer ptr_; - public: - string_data(const string_data& val) - : data_base(json_type_tag::string_t) - { - ptr_ = detail::heap_only_string_factory::create(val.data(),val.length(),val.get_allocator()); - } - - string_data(string_data&& val) - : data_base(json_type_tag::string_t), ptr_(nullptr) - { - std::swap(val.ptr_,ptr_); - } - - string_data(const string_data& val, const Allocator& a) - : data_base(json_type_tag::string_t) - { - ptr_ = detail::heap_only_string_factory::create(val.data(),val.length(),a); - } - - string_data(const char_type* data, size_t length, const Allocator& a) - : data_base(json_type_tag::string_t) - { - ptr_ = detail::heap_only_string_factory::create(data,length,a); - } - - ~string_data() - { - if (ptr_ != nullptr) - { - detail::heap_only_string_factory::destroy(ptr_); - } - } - - void swap(string_data& val) - { - std::swap(val.ptr_,ptr_); - } - - const char_type* data() const - { - return ptr_->data(); - } - - const char_type* c_str() const - { - return ptr_->c_str(); - } - - size_t length() const - { - return ptr_->length(); - } - - allocator_type get_allocator() const - { - return ptr_->get_allocator(); - } - }; - - // byte_string_data - class byte_string_data final : public data_base - { - typedef typename std::allocator_traits:: template rebind_alloc string_holder_allocator_type; - typedef typename std::allocator_traits::pointer pointer; - - pointer ptr_; - - template - void create(string_holder_allocator_type allocator, Args&& ... args) - { - typename std::allocator_traits:: template rebind_alloc alloc(allocator); - ptr_ = alloc.allocate(1); - try - { - std::allocator_traits:: template rebind_traits::construct(alloc, detail::to_plain_pointer(ptr_), std::forward(args)...); - } - catch (...) - { - alloc.deallocate(ptr_,1); - throw; - } - } - public: - byte_string_data(const byte_string_data& val) - : data_base(json_type_tag::byte_string_t) - { - create(val.ptr_->get_allocator(), *(val.ptr_)); - } - - byte_string_data(byte_string_data&& val) - : data_base(json_type_tag::byte_string_t), ptr_(nullptr) - { - std::swap(val.ptr_,ptr_); - } - - byte_string_data(const byte_string_data& val, const Allocator& a) - : data_base(json_type_tag::byte_string_t) - { - create(string_holder_allocator_type(a), *(val.ptr_), a); - } - - byte_string_data(const uint8_t* data, size_t length, const Allocator& a) - : data_base(json_type_tag::byte_string_t) - { - create(string_holder_allocator_type(a), data, data+length, a); - } - - ~byte_string_data() - { - if (ptr_ != nullptr) - { - typename std::allocator_traits:: template rebind_alloc alloc(ptr_->get_allocator()); - std::allocator_traits:: template rebind_traits::destroy(alloc, detail::to_plain_pointer(ptr_)); - alloc.deallocate(ptr_,1); - } - } - - void swap(byte_string_data& val) - { - std::swap(val.ptr_,ptr_); - } - - const uint8_t* data() const - { - return ptr_->data(); - } - - size_t length() const - { - return ptr_->size(); - } - - allocator_type get_allocator() const - { - return ptr_->get_allocator(); - } - }; - - // array_data - class array_data final : public data_base - { - typedef typename std::allocator_traits::pointer pointer; - pointer ptr_; - - template - void create(array_allocator allocator, Args&& ... args) - { - typename std::allocator_traits:: template rebind_alloc alloc(allocator); - ptr_ = alloc.allocate(1); - try - { - std::allocator_traits:: template rebind_traits::construct(alloc, detail::to_plain_pointer(ptr_), std::forward(args)...); - } - catch (...) - { - alloc.deallocate(ptr_,1); - throw; - } - } - public: - array_data(const array& val) - : data_base(json_type_tag::array_t) - { - create(val.get_allocator(), val); - } - - array_data(const array& val, const Allocator& a) - : data_base(json_type_tag::array_t) - { - create(array_allocator(a), val, a); - } - - array_data(const array_data& val) - : data_base(json_type_tag::array_t) - { - create(val.ptr_->get_allocator(), *(val.ptr_)); - } - - array_data(array_data&& val) - : data_base(json_type_tag::array_t), ptr_(nullptr) - { - std::swap(val.ptr_, ptr_); - } - - array_data(const array_data& val, const Allocator& a) - : data_base(json_type_tag::array_t) - { - create(array_allocator(a), *(val.ptr_), a); - } - ~array_data() - { - if (ptr_ != nullptr) - { - typename std::allocator_traits:: template rebind_alloc alloc(ptr_->get_allocator()); - std::allocator_traits:: template rebind_traits::destroy(alloc, detail::to_plain_pointer(ptr_)); - alloc.deallocate(ptr_,1); - } - } - - allocator_type get_allocator() const - { - return ptr_->get_allocator(); - } - - void swap(array_data& val) - { - std::swap(val.ptr_,ptr_); - } - - array& value() - { - return *ptr_; - } - - const array& value() const - { - return *ptr_; - } - }; - - // object_data - class object_data final : public data_base - { - typedef typename std::allocator_traits::pointer pointer; - pointer ptr_; - - template - void create(Allocator allocator, Args&& ... args) - { - typename std::allocator_traits:: template rebind_alloc alloc(allocator); - ptr_ = alloc.allocate(1); - try - { - std::allocator_traits:: template rebind_traits::construct(alloc, detail::to_plain_pointer(ptr_), std::forward(args)...); - } - catch (...) - { - alloc.deallocate(ptr_,1); - throw; - } - } - public: - explicit object_data(const Allocator& a) - : data_base(json_type_tag::object_t) - { - create(a,a); - } - - explicit object_data(const object& val) - : data_base(json_type_tag::object_t) - { - create(val.get_allocator(), val); - } - - explicit object_data(const object& val, const Allocator& a) - : data_base(json_type_tag::object_t) - { - create(object_allocator(a), val, a); - } - - explicit object_data(const object_data& val) - : data_base(json_type_tag::object_t) - { - create(val.ptr_->get_allocator(), *(val.ptr_)); - } - - explicit object_data(object_data&& val) - : data_base(json_type_tag::object_t), ptr_(nullptr) - { - std::swap(val.ptr_,ptr_); - } - - explicit object_data(const object_data& val, const Allocator& a) - : data_base(json_type_tag::object_t) - { - create(object_allocator(a), *(val.ptr_), a); - } - - ~object_data() - { - if (ptr_ != nullptr) - { - typename std::allocator_traits:: template rebind_alloc alloc(ptr_->get_allocator()); - std::allocator_traits:: template rebind_traits::destroy(alloc, detail::to_plain_pointer(ptr_)); - alloc.deallocate(ptr_,1); - } - } - - void swap(object_data& val) - { - std::swap(val.ptr_,ptr_); - } - - object& value() - { - return *ptr_; - } - - const object& value() const - { - return *ptr_; - } - - allocator_type get_allocator() const - { - return ptr_->get_allocator(); - } - }; - - private: - static const size_t data_size = static_max::value; - static const size_t data_align = static_max::value; - - typedef typename std::aligned_storage::type data_t; - - data_t data_; - public: - variant() - { - new(reinterpret_cast(&data_))empty_object_data(); - } - - variant(const Allocator& a) - { - new(reinterpret_cast(&data_))object_data(a); - } - - variant(const variant& val) - { - Init_(val); - } - - variant(const variant& val, const Allocator& allocator) - { - Init_(val,allocator); - } - - variant(variant&& val) JSONCONS_NOEXCEPT - { - Init_rv_(std::forward(val)); - } - - variant(variant&& val, const Allocator& allocator) JSONCONS_NOEXCEPT - { - Init_rv_(std::forward(val), allocator, - typename std::allocator_traits::propagate_on_container_move_assignment()); - } - - explicit variant(null_type) - { - new(reinterpret_cast(&data_))null_data(); - } - explicit variant(bool val) - { - new(reinterpret_cast(&data_))bool_data(val); - } - explicit variant(int64_t val) - { - new(reinterpret_cast(&data_))integer_data(val); - } - explicit variant(uint64_t val, const Allocator&) - { - new(reinterpret_cast(&data_))uinteger_data(val); - } - explicit variant(uint64_t val) - { - new(reinterpret_cast(&data_))uinteger_data(val); - } - variant(double val) - { - new(reinterpret_cast(&data_))double_data(val); - } - variant(double val, const number_format& fmt) - { - new(reinterpret_cast(&data_))double_data(val, fmt); - } - variant(const char_type* s, size_t length) - { - if (length <= small_string_data::max_length) - { - new(reinterpret_cast(&data_))small_string_data(s, static_cast(length)); - } - else - { - new(reinterpret_cast(&data_))string_data(s, length, char_allocator_type()); - } - } - variant(const uint8_t* s, size_t length) - { - new(reinterpret_cast(&data_))byte_string_data(s, length, byte_allocator_type()); - } - - variant(const uint8_t* s, size_t length, const Allocator& alloc) - { - new(reinterpret_cast(&data_))byte_string_data(s, length, alloc); - } - - variant(const char_type* s) - { - size_t length = char_traits_type::length(s); - if (length <= small_string_data::max_length) - { - new(reinterpret_cast(&data_))small_string_data(s, static_cast(length)); - } - else - { - new(reinterpret_cast(&data_))string_data(s, length, char_allocator_type()); - } - } - - variant(const char_type* s, const Allocator& alloc) - { - size_t length = char_traits_type::length(s); - if (length <= small_string_data::max_length) - { - new(reinterpret_cast(&data_))small_string_data(s, static_cast(length)); - } - else - { - new(reinterpret_cast(&data_))string_data(s, length, alloc); - } - } - - variant(const char_type* s, size_t length, const Allocator& alloc) - { - if (length <= small_string_data::max_length) - { - new(reinterpret_cast(&data_))small_string_data(s, static_cast(length)); - } - else - { - new(reinterpret_cast(&data_))string_data(s, length, alloc); - } - } - variant(const object& val) - { - new(reinterpret_cast(&data_))object_data(val); - } - variant(const object& val, const Allocator& alloc) - { - new(reinterpret_cast(&data_))object_data(val, alloc); - } - variant(const array& val) - { - new(reinterpret_cast(&data_))array_data(val); - } - variant(const array& val, const Allocator& alloc) - { - new(reinterpret_cast(&data_))array_data(val,alloc); - } - - ~variant() - { - Destroy_(); - } - - void Destroy_() - { - switch (type_id()) - { - case json_type_tag::string_t: - reinterpret_cast(&data_)->~string_data(); - break; - case json_type_tag::byte_string_t: - reinterpret_cast(&data_)->~byte_string_data(); - break; - case json_type_tag::object_t: - reinterpret_cast(&data_)->~object_data(); - break; - case json_type_tag::array_t: - reinterpret_cast(&data_)->~array_data(); - break; - default: - break; - } - } - - variant& operator=(const variant& val) - { - if (this !=&val) - { - Destroy_(); - switch (val.type_id()) - { - case json_type_tag::null_t: - new(reinterpret_cast(&data_))null_data(); - break; - case json_type_tag::empty_object_t: - new(reinterpret_cast(&data_))empty_object_data(); - break; - case json_type_tag::bool_t: - new(reinterpret_cast(&data_))bool_data(*(val.bool_data_cast())); - break; - case json_type_tag::integer_t: - new(reinterpret_cast(&data_))integer_data(*(val.integer_data_cast())); - break; - case json_type_tag::uinteger_t: - new(reinterpret_cast(&data_))uinteger_data(*(val.uinteger_data_cast())); - break; - case json_type_tag::double_t: - new(reinterpret_cast(&data_))double_data(*(val.double_data_cast())); - break; - case json_type_tag::small_string_t: - new(reinterpret_cast(&data_))small_string_data(*(val.small_string_data_cast())); - break; - case json_type_tag::string_t: - new(reinterpret_cast(&data_))string_data(*(val.string_data_cast())); - break; - case json_type_tag::byte_string_t: - new(reinterpret_cast(&data_))byte_string_data(*(val.byte_string_data_cast())); - break; - case json_type_tag::array_t: - new(reinterpret_cast(&data_))array_data(*(val.array_data_cast())); - break; - case json_type_tag::object_t: - new(reinterpret_cast(&data_))object_data(*(val.object_data_cast())); - break; - default: - JSONCONS_UNREACHABLE(); - break; - } - } - return *this; - } - - variant& operator=(variant&& val) JSONCONS_NOEXCEPT - { - if (this !=&val) - { - swap(val); - } - return *this; - } - - json_type_tag type_id() const - { - return reinterpret_cast(&data_)->type_id_; - } - - const null_data* null_data_cast() const - { - return reinterpret_cast(&data_); - } - - const empty_object_data* empty_object_data_cast() const - { - return reinterpret_cast(&data_); - } - - const bool_data* bool_data_cast() const - { - return reinterpret_cast(&data_); - } - - const integer_data* integer_data_cast() const - { - return reinterpret_cast(&data_); - } - - const uinteger_data* uinteger_data_cast() const - { - return reinterpret_cast(&data_); - } - - const double_data* double_data_cast() const - { - return reinterpret_cast(&data_); - } - - const small_string_data* small_string_data_cast() const - { - return reinterpret_cast(&data_); - } - - string_data* string_data_cast() - { - return reinterpret_cast(&data_); - } - - const string_data* string_data_cast() const - { - return reinterpret_cast(&data_); - } - - byte_string_data* byte_string_data_cast() - { - return reinterpret_cast(&data_); - } - - const byte_string_data* byte_string_data_cast() const - { - return reinterpret_cast(&data_); - } - - object_data* object_data_cast() - { - return reinterpret_cast(&data_); - } - - const object_data* object_data_cast() const - { - return reinterpret_cast(&data_); - } - - array_data* array_data_cast() - { - return reinterpret_cast(&data_); - } - - const array_data* array_data_cast() const - { - return reinterpret_cast(&data_); - } - - string_view_type as_string_view() const - { - switch (type_id()) - { - case json_type_tag::small_string_t: - return string_view_type(small_string_data_cast()->data(),small_string_data_cast()->length()); - case json_type_tag::string_t: - return string_view_type(string_data_cast()->data(),string_data_cast()->length()); - default: - JSONCONS_THROW(json_exception_impl("Not a string")); - } - } - - byte_string_view as_byte_string_view() const - { - switch (type_id()) - { - case json_type_tag::byte_string_t: - return byte_string_view(byte_string_data_cast()->data(),byte_string_data_cast()->length()); - default: - JSONCONS_THROW(json_exception_impl("Not a byte string")); - } - } - - bool operator==(const variant& rhs) const - { - if (this ==&rhs) - { - return true; - } - switch (type_id()) - { - case json_type_tag::null_t: - switch (rhs.type_id()) - { - case json_type_tag::null_t: - return true; - default: - return false; - } - break; - case json_type_tag::empty_object_t: - switch (rhs.type_id()) - { - case json_type_tag::empty_object_t: - return true; - case json_type_tag::object_t: - return rhs.object_data_cast()->value().size() == 0; - default: - return false; - } - break; - case json_type_tag::bool_t: - switch (rhs.type_id()) - { - case json_type_tag::bool_t: - return bool_data_cast()->value() == rhs.bool_data_cast()->value(); - default: - return false; - } - break; - case json_type_tag::integer_t: - switch (rhs.type_id()) - { - case json_type_tag::integer_t: - return integer_data_cast()->value() == rhs.integer_data_cast()->value(); - case json_type_tag::uinteger_t: - return integer_data_cast()->value() >= 0 ? static_cast(integer_data_cast()->value()) == rhs.uinteger_data_cast()->value() : false; - case json_type_tag::double_t: - return static_cast(integer_data_cast()->value()) == rhs.double_data_cast()->value(); - default: - return false; - } - break; - case json_type_tag::uinteger_t: - switch (rhs.type_id()) - { - case json_type_tag::integer_t: - return rhs.integer_data_cast()->value() >= 0 ? uinteger_data_cast()->value() == static_cast(rhs.integer_data_cast()->value()) : false; - case json_type_tag::uinteger_t: - return uinteger_data_cast()->value() == rhs.uinteger_data_cast()->value(); - case json_type_tag::double_t: - return static_cast(uinteger_data_cast()->value()) == rhs.double_data_cast()->value(); - default: - return false; - } - break; - case json_type_tag::double_t: - switch (rhs.type_id()) - { - case json_type_tag::integer_t: - return double_data_cast()->value() == static_cast(rhs.integer_data_cast()->value()); - case json_type_tag::uinteger_t: - return double_data_cast()->value() == static_cast(rhs.uinteger_data_cast()->value()); - case json_type_tag::double_t: - return double_data_cast()->value() == rhs.double_data_cast()->value(); - default: - return false; - } - break; - case json_type_tag::small_string_t: - switch (rhs.type_id()) - { - case json_type_tag::small_string_t: - return as_string_view() == rhs.as_string_view(); - case json_type_tag::string_t: - return as_string_view() == rhs.as_string_view(); - default: - return false; - } - break; - case json_type_tag::byte_string_t: - switch (rhs.type_id()) - { - case json_type_tag::byte_string_t: - { - return as_byte_string_view() == rhs.as_byte_string_view(); - } - default: - return false; - } - break; - case json_type_tag::string_t: - switch (rhs.type_id()) - { - case json_type_tag::small_string_t: - return as_string_view() == rhs.as_string_view(); - case json_type_tag::string_t: - return as_string_view() == rhs.as_string_view(); - default: - return false; - } - break; - case json_type_tag::array_t: - switch (rhs.type_id()) - { - case json_type_tag::array_t: - return array_data_cast()->value() == rhs.array_data_cast()->value(); - default: - return false; - } - break; - case json_type_tag::object_t: - switch (rhs.type_id()) - { - case json_type_tag::empty_object_t: - return object_data_cast()->value().size() == 0; - case json_type_tag::object_t: - return object_data_cast()->value() == rhs.object_data_cast()->value(); - default: - return false; - } - break; - default: - JSONCONS_UNREACHABLE(); - break; - } - } - - bool operator!=(const variant& rhs) const - { - return !(*this == rhs); - } - - template - typename std::enable_if::pointer>::value,void>::type - swap(variant& other) JSONCONS_NOEXCEPT - { - if (this ==&other) - { - return; - } - - std::swap(data_,other.data_); - } - - template - typename std::enable_if::pointer>::value, void>::type - swap(variant& other) JSONCONS_NOEXCEPT - { - if (this ==&other) - { - return; - } - switch (type_id()) - { - case json_type_tag::null_t: - { - switch (other.type_id()) - { - case json_type_tag::string_t: - { - string_data temp(std::move(*other.string_data_cast())); - new(reinterpret_cast(&(other.data_)))null_data(); - new(reinterpret_cast(&data_))string_data(std::move(temp)); - } - break; - case json_type_tag::byte_string_t: - { - byte_string_data temp(std::move(*other.byte_string_data_cast())); - new(reinterpret_cast(&(other.data_)))null_data(); - new(reinterpret_cast(&data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::array_t: - { - array_data temp(std::move(*other.array_data_cast())); - new(reinterpret_cast(&(other.data_)))null_data(); - new(reinterpret_cast(&data_))array_data(std::move(temp)); - } - break; - case json_type_tag::object_t: - { - object_data temp(std::move(*other.object_data_cast())); - new(reinterpret_cast(&(other.data_)))null_data(); - new(reinterpret_cast(&data_))object_data(std::move(temp)); - } - break; - default: - std::swap(data_,other.data_); - break; - } - } - break; - case json_type_tag::empty_object_t: - { - switch (other.type_id()) - { - case json_type_tag::string_t: - { - string_data temp(std::move(*other.string_data_cast())); - new(reinterpret_cast(&(other.data_)))empty_object_data(); - new(reinterpret_cast(&data_))string_data(std::move(temp)); - } - break; - case json_type_tag::byte_string_t: - { - byte_string_data temp(std::move(*other.byte_string_data_cast())); - new(reinterpret_cast(&(other.data_)))empty_object_data(); - new(reinterpret_cast(&data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::array_t: - { - array_data temp(std::move(*other.array_data_cast())); - new(reinterpret_cast(&(other.data_)))empty_object_data(); - new(reinterpret_cast(&data_))array_data(std::move(temp)); - } - break; - case json_type_tag::object_t: - { - object_data temp(std::move(*other.object_data_cast())); - new(reinterpret_cast(&(other.data_)))empty_object_data(); - new(reinterpret_cast(&data_))object_data(std::move(temp)); - } - break; - default: - std::swap(data_,other.data_); - break; - } - } - break; - case json_type_tag::bool_t: - { - switch (other.type_id()) - { - case json_type_tag::string_t: - { - string_data temp(std::move(*other.string_data_cast())); - new(reinterpret_cast(&(other.data_)))bool_data(*bool_data_cast()); - new(reinterpret_cast(&data_))string_data(std::move(temp)); - } - break; - case json_type_tag::byte_string_t: - { - byte_string_data temp(std::move(*other.byte_string_data_cast())); - new(reinterpret_cast(&(other.data_)))bool_data(*bool_data_cast()); - new(reinterpret_cast(&data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::array_t: - { - array_data temp(std::move(*other.array_data_cast())); - new(reinterpret_cast(&(other.data_)))bool_data(*bool_data_cast()); - new(reinterpret_cast(&data_))array_data(std::move(temp)); - } - break; - case json_type_tag::object_t: - { - object_data temp(std::move(*other.object_data_cast())); - new(reinterpret_cast(&(other.data_)))bool_data(*bool_data_cast()); - new(reinterpret_cast(&data_))object_data(std::move(temp)); - } - break; - default: - std::swap(data_,other.data_); - break; - } - } - break; - case json_type_tag::integer_t: - { - switch (other.type_id()) - { - case json_type_tag::string_t: - { - string_data temp(std::move(*other.string_data_cast())); - new(reinterpret_cast(&(other.data_)))integer_data(*integer_data_cast()); - new(reinterpret_cast(&data_))string_data(std::move(temp)); - } - break; - case json_type_tag::byte_string_t: - { - byte_string_data temp(std::move(*other.byte_string_data_cast())); - new(reinterpret_cast(&(other.data_)))integer_data(*integer_data_cast()); - new(reinterpret_cast(&data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::array_t: - { - array_data temp(std::move(*other.array_data_cast())); - new(reinterpret_cast(&(other.data_)))integer_data(*integer_data_cast()); - new(reinterpret_cast(&data_))array_data(std::move(temp)); - } - break; - case json_type_tag::object_t: - { - object_data temp(std::move(*other.object_data_cast())); - new(reinterpret_cast(&(other.data_)))integer_data(*integer_data_cast()); - new(reinterpret_cast(&data_))object_data(std::move(temp)); - } - break; - default: - std::swap(data_,other.data_); - break; - } - } - break; - case json_type_tag::uinteger_t: - { - switch (other.type_id()) - { - case json_type_tag::string_t: - { - string_data temp(std::move(*other.string_data_cast())); - new(reinterpret_cast(&(other.data_)))uinteger_data(*uinteger_data_cast()); - new(reinterpret_cast(&data_))string_data(std::move(temp)); - } - break; - case json_type_tag::byte_string_t: - { - byte_string_data temp(std::move(*other.byte_string_data_cast())); - new(reinterpret_cast(&(other.data_)))uinteger_data(*uinteger_data_cast()); - new(reinterpret_cast(&data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::array_t: - { - array_data temp(std::move(*other.array_data_cast())); - new(reinterpret_cast(&(other.data_)))uinteger_data(*uinteger_data_cast()); - new(reinterpret_cast(&data_))array_data(std::move(temp)); - } - break; - case json_type_tag::object_t: - { - object_data temp(std::move(*other.object_data_cast())); - new(reinterpret_cast(&(other.data_)))uinteger_data(*uinteger_data_cast()); - new(reinterpret_cast(&data_))object_data(std::move(temp)); - } - break; - default: - std::swap(data_,other.data_); - break; - } - } - break; - case json_type_tag::double_t: - { - switch (other.type_id()) - { - case json_type_tag::string_t: - { - string_data temp(std::move(*other.string_data_cast())); - new(reinterpret_cast(&(other.data_)))double_data(*double_data_cast()); - new(reinterpret_cast(&data_))string_data(std::move(temp)); - } - break; - case json_type_tag::byte_string_t: - { - byte_string_data temp(std::move(*other.byte_string_data_cast())); - new(reinterpret_cast(&(other.data_)))double_data(*double_data_cast()); - new(reinterpret_cast(&data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::array_t: - { - array_data temp(std::move(*other.array_data_cast())); - new(reinterpret_cast(&(other.data_)))double_data(*double_data_cast()); - new(reinterpret_cast(&data_))array_data(std::move(temp)); - } - break; - case json_type_tag::object_t: - { - object_data temp(std::move(*other.object_data_cast())); - new(reinterpret_cast(&(other.data_)))double_data(*double_data_cast()); - new(reinterpret_cast(&data_))object_data(std::move(temp)); - } - break; - default: - std::swap(data_,other.data_); - break; - } - } - break; - case json_type_tag::small_string_t: - { - switch (other.type_id()) - { - case json_type_tag::string_t: - { - string_data temp(std::move(*other.string_data_cast())); - new(reinterpret_cast(&(other.data_)))small_string_data(*small_string_data_cast()); - new(reinterpret_cast(&data_))string_data(std::move(temp)); - } - break; - case json_type_tag::byte_string_t: - { - byte_string_data temp(std::move(*other.byte_string_data_cast())); - new(reinterpret_cast(&(other.data_)))small_string_data(*small_string_data_cast()); - new(reinterpret_cast(&data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::array_t: - { - array_data temp(std::move(*other.array_data_cast())); - new(reinterpret_cast(&(other.data_)))small_string_data(*small_string_data_cast()); - new(reinterpret_cast(&data_))array_data(std::move(temp)); - } - break; - case json_type_tag::object_t: - { - object_data temp(std::move(*other.object_data_cast())); - new(reinterpret_cast(&(other.data_)))small_string_data(*small_string_data_cast()); - new(reinterpret_cast(&data_))object_data(std::move(temp)); - } - break; - default: - std::swap(data_,other.data_); - break; - } - } - break; - case json_type_tag::string_t: - { - switch (other.type_id()) - { - case json_type_tag::null_t: - { - string_data temp(std::move(*string_data_cast())); - new(reinterpret_cast(&data_))null_data(); - new(reinterpret_cast(&other.data_))string_data(std::move(temp)); - } - break; - case json_type_tag::empty_object_t: - { - string_data temp(std::move(*string_data_cast())); - new(reinterpret_cast(&data_))empty_object_data(); - new(reinterpret_cast(&other.data_))string_data(std::move(temp)); - } - break; - case json_type_tag::bool_t: - { - string_data temp(std::move(*string_data_cast())); - new(reinterpret_cast(&data_))bool_data(*(other.bool_data_cast())); - new(reinterpret_cast(&other.data_))string_data(std::move(temp)); - } - break; - case json_type_tag::integer_t: - { - string_data temp(std::move(*string_data_cast())); - new(reinterpret_cast(&data_))integer_data(*(other.integer_data_cast())); - new(reinterpret_cast(&other.data_))string_data(std::move(temp)); - } - break; - case json_type_tag::uinteger_t: - { - string_data temp(std::move(*string_data_cast())); - new(reinterpret_cast(&data_))uinteger_data(*(other.uinteger_data_cast())); - new(reinterpret_cast(&other.data_))string_data(std::move(temp)); - } - break; - case json_type_tag::double_t: - { - string_data temp(std::move(*string_data_cast())); - new(reinterpret_cast(&data_))double_data(*(other.double_data_cast())); - new(reinterpret_cast(&other.data_))string_data(std::move(temp)); - } - break; - case json_type_tag::small_string_t: - { - string_data temp(std::move(*string_data_cast())); - new(reinterpret_cast(&data_))small_string_data(*(other.small_string_data_cast())); - new(reinterpret_cast(&other.data_))string_data(std::move(temp)); - } - break; - case json_type_tag::string_t: - { - string_data_cast()->swap(*other.string_data_cast()); - } - break; - case json_type_tag::byte_string_t: - { - string_data temp(std::move(*string_data_cast())); - new(reinterpret_cast(&data_))byte_string_data(std::move(*other.byte_string_data_cast())); - new(reinterpret_cast(&other.data_))string_data(std::move(temp)); - } - break; - case json_type_tag::array_t: - { - string_data temp(std::move(*string_data_cast())); - new(reinterpret_cast(&data_))array_data(std::move(*other.array_data_cast())); - new(reinterpret_cast(&other.data_))string_data(std::move(temp)); - } - break; - case json_type_tag::object_t: - { - string_data temp(std::move(*string_data_cast())); - new(reinterpret_cast(&data_))object_data(std::move(*other.object_data_cast())); - new(reinterpret_cast(&other.data_))string_data(std::move(temp)); - } - break; - default: - JSONCONS_UNREACHABLE(); - break; - } - } - break; - case json_type_tag::byte_string_t: - { - switch (other.type_id()) - { - case json_type_tag::null_t: - { - byte_string_data temp(std::move(*byte_string_data_cast())); - new(reinterpret_cast(&data_))null_data(); - new(reinterpret_cast(&other.data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::empty_object_t: - { - byte_string_data temp(std::move(*byte_string_data_cast())); - new(reinterpret_cast(&data_))empty_object_data(); - new(reinterpret_cast(&other.data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::bool_t: - { - byte_string_data temp(std::move(*byte_string_data_cast())); - new(reinterpret_cast(&data_))bool_data(*(other.bool_data_cast())); - new(reinterpret_cast(&other.data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::integer_t: - { - byte_string_data temp(std::move(*byte_string_data_cast())); - new(reinterpret_cast(&data_))integer_data(*(other.integer_data_cast())); - new(reinterpret_cast(&other.data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::uinteger_t: - { - byte_string_data temp(std::move(*byte_string_data_cast())); - new(reinterpret_cast(&data_))uinteger_data(*(other.uinteger_data_cast())); - new(reinterpret_cast(&other.data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::double_t: - { - byte_string_data temp(std::move(*byte_string_data_cast())); - new(reinterpret_cast(&data_))double_data(*(other.double_data_cast())); - new(reinterpret_cast(&other.data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::small_string_t: - { - byte_string_data temp(std::move(*byte_string_data_cast())); - new(reinterpret_cast(&data_))small_string_data(*(other.small_string_data_cast())); - new(reinterpret_cast(&other.data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::string_t: - { - byte_string_data temp(std::move(*byte_string_data_cast())); - new(reinterpret_cast(&data_))string_data(*(other.string_data_cast())); - new(reinterpret_cast(&other.data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::byte_string_t: - { - byte_string_data_cast()->swap(*other.byte_string_data_cast()); - } - break; - case json_type_tag::array_t: - { - byte_string_data temp(std::move(*byte_string_data_cast())); - new(reinterpret_cast(&data_))array_data(std::move(*other.array_data_cast())); - new(reinterpret_cast(&other.data_))byte_string_data(std::move(temp)); - } - break; - case json_type_tag::object_t: - { - byte_string_data temp(std::move(*byte_string_data_cast())); - new(reinterpret_cast(&data_))object_data(std::move(*other.object_data_cast())); - new(reinterpret_cast(&other.data_))byte_string_data(std::move(temp)); - } - break; - default: - JSONCONS_UNREACHABLE(); - break; - } - } - break; - case json_type_tag::array_t: - { - switch (other.type_id()) - { - case json_type_tag::null_t: - { - array_data temp(std::move(*array_data_cast())); - new(reinterpret_cast(&data_))null_data(); - new(reinterpret_cast(&(other.data_)))array_data(std::move(temp)); - } - break; - case json_type_tag::empty_object_t: - { - array_data temp(std::move(*array_data_cast())); - new(reinterpret_cast(&data_))empty_object_data(); - new(reinterpret_cast(&(other.data_)))array_data(std::move(temp)); - } - break; - case json_type_tag::bool_t: - { - array_data temp(std::move(*array_data_cast())); - new(reinterpret_cast(&data_))bool_data(*(other.bool_data_cast())); - new(reinterpret_cast(&(other.data_)))array_data(std::move(temp)); - } - break; - case json_type_tag::integer_t: - { - array_data temp(std::move(*array_data_cast())); - new(reinterpret_cast(&data_))integer_data(*(other.integer_data_cast())); - new(reinterpret_cast(&(other.data_)))array_data(std::move(temp)); - } - break; - case json_type_tag::uinteger_t: - { - array_data temp(std::move(*array_data_cast())); - new(reinterpret_cast(&data_))uinteger_data(*(other.uinteger_data_cast())); - new(reinterpret_cast(&(other.data_)))array_data(std::move(temp)); - } - break; - case json_type_tag::double_t: - { - array_data temp(std::move(*array_data_cast())); - new(reinterpret_cast(&data_))double_data(*(other.double_data_cast())); - new(reinterpret_cast(&(other.data_)))array_data(std::move(temp)); - } - break; - case json_type_tag::small_string_t: - { - array_data temp(std::move(*array_data_cast())); - new(reinterpret_cast(&data_))small_string_data(*(other.small_string_data_cast())); - new(reinterpret_cast(&(other.data_)))array_data(std::move(temp)); - } - break; - case json_type_tag::string_t: - { - array_data temp(std::move(*array_data_cast())); - new(reinterpret_cast(&data_))string_data(std::move(*other.string_data_cast())); - new(reinterpret_cast(&(other.data_)))array_data(std::move(temp)); - } - break; - case json_type_tag::byte_string_t: - { - array_data temp(std::move(*array_data_cast())); - new(reinterpret_cast(&data_))byte_string_data(std::move(*other.byte_string_data_cast())); - new(reinterpret_cast(&(other.data_)))array_data(std::move(temp)); - } - break; - case json_type_tag::array_t: - { - array_data_cast()->swap(*other.array_data_cast()); - } - break; - case json_type_tag::object_t: - { - array_data temp(std::move(*array_data_cast())); - new(reinterpret_cast(&data_))object_data(std::move(*other.object_data_cast())); - new(reinterpret_cast(&(other.data_)))array_data(std::move(temp)); - } - break; - default: - JSONCONS_UNREACHABLE(); - break; - } - } - break; - case json_type_tag::object_t: - { - switch (other.type_id()) - { - case json_type_tag::null_t: - { - object_data temp(std::move(*object_data_cast())); - new(reinterpret_cast(&data_))null_data(); - new(reinterpret_cast(&(other.data_)))object_data(std::move(temp)); - } - break; - case json_type_tag::empty_object_t: - { - object_data temp(std::move(*object_data_cast())); - new(reinterpret_cast(&data_))empty_object_data(); - new(reinterpret_cast(&(other.data_)))object_data(std::move(temp)); - } - break; - case json_type_tag::bool_t: - { - object_data temp(std::move(*object_data_cast())); - new(reinterpret_cast(&data_))bool_data(*(other.bool_data_cast())); - new(reinterpret_cast(&(other.data_)))object_data(std::move(temp)); - } - break; - case json_type_tag::integer_t: - { - object_data temp(std::move(*object_data_cast())); - new(reinterpret_cast(&data_))integer_data(*(other.integer_data_cast())); - new(reinterpret_cast(&(other.data_)))object_data(std::move(temp)); - } - break; - case json_type_tag::uinteger_t: - { - object_data temp(std::move(*object_data_cast())); - new(reinterpret_cast(&data_))uinteger_data(*(other.uinteger_data_cast())); - new(reinterpret_cast(&(other.data_)))object_data(std::move(temp)); - } - break; - case json_type_tag::double_t: - { - object_data temp(std::move(*object_data_cast())); - new(reinterpret_cast(&data_))double_data(*(other.double_data_cast())); - new(reinterpret_cast(&(other.data_)))object_data(std::move(temp)); - } - break; - case json_type_tag::small_string_t: - { - object_data temp(std::move(*object_data_cast())); - new(reinterpret_cast(&data_))small_string_data(*(other.small_string_data_cast())); - new(reinterpret_cast(&(other.data_)))object_data(std::move(temp)); - } - break; - case json_type_tag::string_t: - { - object_data temp(std::move(*object_data_cast())); - new(reinterpret_cast(&data_))string_data(std::move(*other.string_data_cast())); - new(reinterpret_cast(&(other.data_)))object_data(std::move(temp)); - } - break; - case json_type_tag::byte_string_t: - { - object_data temp(std::move(*object_data_cast())); - new(reinterpret_cast(&data_))byte_string_data(std::move(*other.byte_string_data_cast())); - new(reinterpret_cast(&(other.data_)))object_data(std::move(temp)); - } - break; - case json_type_tag::array_t: - { - object_data temp(std::move(*object_data_cast())); - new(reinterpret_cast(&data_))array_data(std::move(*other.array_data_cast())); - new(reinterpret_cast(&(other.data_)))object_data(std::move(temp)); - } - break; - case json_type_tag::object_t: - { - object_data_cast()->swap(*other.object_data_cast()); - } - break; - default: - JSONCONS_UNREACHABLE(); - break; - } - } - break; - default: - JSONCONS_UNREACHABLE(); - break; - } - } - private: - - void Init_(const variant& val) - { - switch (val.type_id()) - { - case json_type_tag::null_t: - new(reinterpret_cast(&data_))null_data(); - break; - case json_type_tag::empty_object_t: - new(reinterpret_cast(&data_))empty_object_data(); - break; - case json_type_tag::bool_t: - new(reinterpret_cast(&data_))bool_data(*(val.bool_data_cast())); - break; - case json_type_tag::integer_t: - new(reinterpret_cast(&data_))integer_data(*(val.integer_data_cast())); - break; - case json_type_tag::uinteger_t: - new(reinterpret_cast(&data_))uinteger_data(*(val.uinteger_data_cast())); - break; - case json_type_tag::double_t: - new(reinterpret_cast(&data_))double_data(*(val.double_data_cast())); - break; - case json_type_tag::small_string_t: - new(reinterpret_cast(&data_))small_string_data(*(val.small_string_data_cast())); - break; - case json_type_tag::string_t: - new(reinterpret_cast(&data_))string_data(*(val.string_data_cast())); - break; - case json_type_tag::byte_string_t: - new(reinterpret_cast(&data_))byte_string_data(*(val.byte_string_data_cast())); - break; - case json_type_tag::object_t: - new(reinterpret_cast(&data_))object_data(*(val.object_data_cast())); - break; - case json_type_tag::array_t: - new(reinterpret_cast(&data_))array_data(*(val.array_data_cast())); - break; - default: - break; - } - } - - void Init_(const variant& val, const Allocator& a) - { - switch (val.type_id()) - { - case json_type_tag::null_t: - case json_type_tag::empty_object_t: - case json_type_tag::bool_t: - case json_type_tag::integer_t: - case json_type_tag::uinteger_t: - case json_type_tag::double_t: - case json_type_tag::small_string_t: - Init_(val); - break; - case json_type_tag::string_t: - new(reinterpret_cast(&data_))string_data(*(val.string_data_cast()),a); - break; - case json_type_tag::byte_string_t: - new(reinterpret_cast(&data_))byte_string_data(*(val.byte_string_data_cast()),a); - break; - case json_type_tag::array_t: - new(reinterpret_cast(&data_))array_data(*(val.array_data_cast()),a); - break; - case json_type_tag::object_t: - new(reinterpret_cast(&data_))object_data(*(val.object_data_cast()),a); - break; - default: - break; - } - } - - void Init_rv_(variant&& val) JSONCONS_NOEXCEPT - { - switch (val.type_id()) - { - case json_type_tag::null_t: - case json_type_tag::empty_object_t: - case json_type_tag::double_t: - case json_type_tag::integer_t: - case json_type_tag::uinteger_t: - case json_type_tag::bool_t: - case json_type_tag::small_string_t: - Init_(val); - break; - case json_type_tag::string_t: - { - new(reinterpret_cast(&data_))string_data(std::move(*val.string_data_cast())); - new(reinterpret_cast(&val.data_))null_data(); - } - break; - case json_type_tag::byte_string_t: - { - new(reinterpret_cast(&data_))byte_string_data(std::move(*val.byte_string_data_cast())); - new(reinterpret_cast(&val.data_))null_data(); - } - break; - case json_type_tag::array_t: - { - new(reinterpret_cast(&data_))array_data(std::move(*val.array_data_cast())); - new(reinterpret_cast(&val.data_))null_data(); - } - break; - case json_type_tag::object_t: - { - new(reinterpret_cast(&data_))object_data(std::move(*val.object_data_cast())); - new(reinterpret_cast(&val.data_))null_data(); - } - break; - default: - JSONCONS_UNREACHABLE(); - break; - } - } - - void Init_rv_(variant&& val, const Allocator& a, std::true_type) JSONCONS_NOEXCEPT - { - Init_rv_(std::forward(val)); - } - - void Init_rv_(variant&& val, const Allocator& a, std::false_type) JSONCONS_NOEXCEPT - { - switch (val.type_id()) - { - case json_type_tag::null_t: - case json_type_tag::empty_object_t: - case json_type_tag::double_t: - case json_type_tag::integer_t: - case json_type_tag::uinteger_t: - case json_type_tag::bool_t: - case json_type_tag::small_string_t: - Init_(std::forward(val)); - break; - case json_type_tag::string_t: - { - if (a == val.string_data_cast()->get_allocator()) - { - Init_rv_(std::forward(val), a, std::true_type()); - } - else - { - Init_(val,a); - } - } - break; - case json_type_tag::byte_string_t: - { - if (a == val.byte_string_data_cast()->get_allocator()) - { - Init_rv_(std::forward(val), a, std::true_type()); - } - else - { - Init_(val,a); - } - } - break; - case json_type_tag::object_t: - { - if (a == val.object_data_cast()->get_allocator()) - { - Init_rv_(std::forward(val), a, std::true_type()); - } - else - { - Init_(val,a); - } - } - break; - case json_type_tag::array_t: - { - if (a == val.array_data_cast()->get_allocator()) - { - Init_rv_(std::forward(val), a, std::true_type()); - } - else - { - Init_(val,a); - } - } - break; - default: - break; - } - } - }; - - template - class json_proxy - { - private: - typedef json_proxy proxy_type; - - ParentT& parent_; - key_storage_type key_; - - json_proxy() = delete; - json_proxy& operator = (const json_proxy& other) = delete; - - json_proxy(ParentT& parent, key_storage_type&& name) - : parent_(parent), key_(std::forward(name)) - { - } - - basic_json& evaluate() - { - return parent_.evaluate(string_view_type(key_.data(),key_.size())); - } - - const basic_json& evaluate() const - { - return parent_.evaluate(string_view_type(key_.data(),key_.size())); - } - - basic_json& evaluate_with_default() - { - basic_json& val = parent_.evaluate_with_default(); - auto it = val.find(string_view_type(key_.data(),key_.size())); - if (it == val.object_range().end()) - { - it = val.set_(val.object_range().begin(),std::move(key_),object(val.object_value().get_allocator())); - } - return it->value(); - } - - basic_json& evaluate(size_t index) - { - return evaluate().at(index); - } - - const basic_json& evaluate(size_t index) const - { - return evaluate().at(index); - } - - basic_json& evaluate(const string_view_type& index) - { - return evaluate().at(index); - } - - const basic_json& evaluate(const string_view_type& index) const - { - return evaluate().at(index); - } - public: - - friend class basic_json; - - range object_range() - { - return evaluate().object_range(); - } - - range object_range() const - { - return evaluate().object_range(); - } - - range array_range() - { - return evaluate().array_range(); - } - - range array_range() const - { - return evaluate().array_range(); - } - - size_t size() const JSONCONS_NOEXCEPT - { - return evaluate().size(); - } - - json_type_tag type_id() const - { - return evaluate().type_id(); - } - - size_t count(const string_view_type& name) const - { - return evaluate().count(name); - } - - bool has_key(const string_view_type& name) const - { - return evaluate().has_key(name); - } - - bool is_null() const JSONCONS_NOEXCEPT - { - return evaluate().is_null(); - } - - bool empty() const - { - return evaluate().empty(); - } - - size_t capacity() const - { - return evaluate().capacity(); - } - - void reserve(size_t n) - { - evaluate().reserve(n); - } - - void resize(size_t n) - { - evaluate().resize(n); - } - - template - void resize(size_t n, T val) - { - evaluate().resize(n,val); - } - - template - bool is(Args&&... args) const - { - return evaluate().template is(std::forward(args)...); - } - - bool is_string() const JSONCONS_NOEXCEPT - { - return evaluate().is_string(); - } - - bool is_byte_string() const JSONCONS_NOEXCEPT - { - return evaluate().is_byte_string(); - } - - bool is_number() const JSONCONS_NOEXCEPT - { - return evaluate().is_number(); - } - bool is_bool() const JSONCONS_NOEXCEPT - { - return evaluate().is_bool(); - } - - bool is_object() const JSONCONS_NOEXCEPT - { - return evaluate().is_object(); - } - - bool is_array() const JSONCONS_NOEXCEPT - { - return evaluate().is_array(); - } - bool is_integer() const JSONCONS_NOEXCEPT - { - return evaluate().is_integer(); - } - - bool is_uinteger() const JSONCONS_NOEXCEPT - { - return evaluate().is_uinteger(); - } - - bool is_double() const JSONCONS_NOEXCEPT - { - return evaluate().is_double(); - } - - string_view_type as_string_view() const - { - return evaluate().as_string_view(); - } - - byte_string_view as_byte_string_view() const - { - return evaluate().as_byte_string_view(); - } - - string_type as_string() const - { - return evaluate().as_string(); - } - - template - string_type as_string(const SAllocator& allocator) const - { - return evaluate().as_string(allocator); - } - - string_type as_string(const basic_json_serializing_options& options) const - { - return evaluate().as_string(options); - } - - template - string_type as_string(const basic_json_serializing_options& options, - const SAllocator& allocator) const - { - return evaluate().as_string(options,allocator); - } - - template - T as(Args&&... args) const - { - return evaluate().template as(std::forward(args)...); - } - - template - typename std::enable_if::value,T>::type - as(const char_allocator_type& allocator) const - { - return evaluate().template as(allocator); - } - bool as_bool() const - { - return evaluate().as_bool(); - } - - double as_double() const - { - return evaluate().as_double(); - } - - int64_t as_integer() const - { - return evaluate().as_integer(); - } - - unsigned long long as_ulonglong() const - { - return evaluate().as_ulonglong(); - } - - uint64_t as_uinteger() const - { - return evaluate().as_uinteger(); - } - - template - json_proxy& operator=(T&& val) - { - parent_.evaluate_with_default().set_(std::move(key_), std::forward(val)); - return *this; - } - - bool operator==(const basic_json& val) const - { - return evaluate() == val; - } - - bool operator!=(const basic_json& val) const - { - return evaluate() != val; - } - - basic_json& operator[](size_t i) - { - return evaluate_with_default().at(i); - } - - const basic_json& operator[](size_t i) const - { - return evaluate().at(i); - } - - json_proxy operator[](const string_view_type& name) - { - return json_proxy(*this,key_storage_type(name.begin(),name.end(),key_.get_allocator())); - } - - const basic_json& operator[](const string_view_type& name) const - { - return at(name); - } - - basic_json& at(const string_view_type& name) - { - return evaluate().at(name); - } - - const basic_json& at(const string_view_type& name) const - { - return evaluate().at(name); - } - - const basic_json& at(size_t index) - { - return evaluate().at(index); - } - - const basic_json& at(size_t index) const - { - return evaluate().at(index); - } - - object_iterator find(const string_view_type& name) - { - return evaluate().find(name); - } - - const_object_iterator find(const string_view_type& name) const - { - return evaluate().find(name); - } - - template - basic_json get(const string_view_type& name, T&& default_val) const - { - return evaluate().get(name,std::forward(default_val)); - } - - template - T get_with_default(const string_view_type& name, const T& default_val) const - { - return evaluate().get_with_default(name,default_val); - } - - const CharT* get_with_default(const string_view_type& name, const CharT* default_val) const - { - return evaluate().get_with_default(name,default_val); - } - - void shrink_to_fit() - { - evaluate_with_default().shrink_to_fit(); - } - - void clear() - { - evaluate().clear(); - } - // Remove all elements from an array or object - - void erase(const_object_iterator pos) - { - evaluate().erase(pos); - } - // Remove a range of elements from an object - - void erase(const_object_iterator first, const_object_iterator last) - { - evaluate().erase(first, last); - } - // Remove a range of elements from an object - - void erase(const string_view_type& name) - { - evaluate().erase(name); - } - - void erase(const_array_iterator pos) - { - evaluate().erase(pos); - } - // Removes the element at pos - - void erase(const_array_iterator first, const_array_iterator last) - { - evaluate().erase(first, last); - } - // Remove a range of elements from an array - - // merge - - void merge(const basic_json& source) - { - return evaluate().merge(source); - } - - void merge(basic_json&& source) - { - return evaluate().merge(std::forward(source)); - } - - void merge(object_iterator hint, const basic_json& source) - { - return evaluate().merge(hint, source); - } - - void merge(object_iterator hint, basic_json&& source) - { - return evaluate().merge(hint, std::forward(source)); - } - - // merge_or_update - - void merge_or_update(const basic_json& source) - { - return evaluate().merge_or_update(source); - } - - void merge_or_update(basic_json&& source) - { - return evaluate().merge_or_update(std::forward(source)); - } - - void merge_or_update(object_iterator hint, const basic_json& source) - { - return evaluate().merge_or_update(hint, source); - } - - void merge_or_update(object_iterator hint, basic_json&& source) - { - return evaluate().merge_or_update(hint, std::forward(source)); - } - - // set - - template - std::pair set(const string_view_type& name, T&& val) - { - return evaluate().set(name,std::forward(val)); - } - - template - std::pair insert_or_assign(const string_view_type& name, T&& val) - { - return evaluate().insert_or_assign(name,std::forward(val)); - } - - template - void set_(key_storage_type&& name, T&& val) - { - evaluate().set_(std::forward(name),std::forward(val)); - } - - // emplace - - template - std::pair try_emplace(const string_view_type& name, Args&&... args) - { - return evaluate().try_emplace(name,std::forward(args)...); - } - - template - object_iterator set(object_iterator hint, const string_view_type& name, T&& val) - { - return evaluate().set(hint, name, std::forward(val)); - } - - template - object_iterator insert_or_assign(object_iterator hint, const string_view_type& name, T&& val) - { - return evaluate().insert_or_assign(hint, name, std::forward(val)); - } - - template - object_iterator try_emplace(object_iterator hint, const string_view_type& name, Args&&... args) - { - return evaluate().try_emplace(hint, name, std::forward(args)...); - } - - template - object_iterator set_(object_iterator hint, key_storage_type&& name, T&& val) - { - return evaluate().set_(hint, std::forward(name), std::forward(val)); - } - - template - array_iterator emplace(const_array_iterator pos, Args&&... args) - { - evaluate_with_default().emplace(pos, std::forward(args)...); - } - - template - basic_json& emplace_back(Args&&... args) - { - return evaluate_with_default().emplace_back(std::forward(args)...); - } - - template - void add(T&& val) - { - evaluate_with_default().add(std::forward(val)); - } - - template - void push_back(T&& val) - { - evaluate_with_default().push_back(std::forward(val)); - } - - template - array_iterator add(const_array_iterator pos, T&& val) - { - return evaluate_with_default().add(pos, std::forward(val)); - } - - template - array_iterator insert(const_array_iterator pos, T&& val) - { - return evaluate_with_default().insert(pos, std::forward(val)); - } - - template - array_iterator insert(const_array_iterator pos, InputIt first, InputIt last) - { - return evaluate_with_default().insert(pos, first, last); - } - - template - void dump(std::basic_string& s) const - { - evaluate().dump(s); - } - - template - void dump(std::basic_string& s, - indenting line_indent) const - { - evaluate().dump(s, line_indent); - } - - template - void dump(std::basic_string& s, - const basic_json_serializing_options& options) const - { - evaluate().dump(s,options); - } - - template - void dump(std::basic_string& s, - const basic_json_serializing_options& options, - indenting line_indent) const - { - evaluate().dump(s,options,line_indent); - } - - void dump(basic_json_content_handler& handler) const - { - evaluate().dump(handler); - } - - void dump(std::basic_ostream& os) const - { - evaluate().dump(os); - } - - void dump(std::basic_ostream& os, indenting line_indent) const - { - evaluate().dump(os, line_indent); - } - - void dump(std::basic_ostream& os, const basic_json_serializing_options& options) const - { - evaluate().dump(os,options); - } - - void dump(std::basic_ostream& os, const basic_json_serializing_options& options, indenting line_indent) const - { - evaluate().dump(os,options,line_indent); - } -#if !defined(JSONCONS_NO_DEPRECATED) - - void dump(std::basic_ostream& os, const basic_json_serializing_options& options, bool pprint) const - { - evaluate().dump(os,options,pprint); - } - - void dump(std::basic_ostream& os, bool pprint) const - { - evaluate().dump(os, pprint); - } - - string_type to_string(const char_allocator_type& allocator = char_allocator_type()) const JSONCONS_NOEXCEPT - { - return evaluate().to_string(allocator); - } - void write(basic_json_content_handler& handler) const - { - evaluate().write(handler); - } - - void write(std::basic_ostream& os) const - { - evaluate().write(os); - } - - void write(std::basic_ostream& os, const basic_json_serializing_options& options) const - { - evaluate().write(os,options); - } - - void write(std::basic_ostream& os, const basic_json_serializing_options& options, bool pprint) const - { - evaluate().write(os,options,pprint); - } - - string_type to_string(const basic_json_serializing_options& options, char_allocator_type& allocator = char_allocator_type()) const - { - return evaluate().to_string(options,allocator); - } - - range members() - { - return evaluate().members(); - } - - range members() const - { - return evaluate().members(); - } - - range elements() - { - return evaluate().elements(); - } - - range elements() const - { - return evaluate().elements(); - } - void to_stream(basic_json_content_handler& handler) const - { - evaluate().to_stream(handler); - } - - void to_stream(std::basic_ostream& os) const - { - evaluate().to_stream(os); - } - - void to_stream(std::basic_ostream& os, const basic_json_serializing_options& options) const - { - evaluate().to_stream(os,options); - } - - void to_stream(std::basic_ostream& os, const basic_json_serializing_options& options, bool pprint) const - { - evaluate().to_stream(os,options,pprint); - } -#endif - void swap(basic_json& val) - { - evaluate_with_default().swap(val); - } - - friend std::basic_ostream& operator<<(std::basic_ostream& os, const json_proxy& o) - { - o.dump(os); - return os; - } - -#if !defined(JSONCONS_NO_DEPRECATED) - - void resize_array(size_t n) - { - evaluate().resize_array(n); - } - - template - void resize_array(size_t n, T val) - { - evaluate().resize_array(n,val); - } - - object_iterator begin_members() - { - return evaluate().begin_members(); - } - - const_object_iterator begin_members() const - { - return evaluate().begin_members(); - } - - object_iterator end_members() - { - return evaluate().end_members(); - } - - const_object_iterator end_members() const - { - return evaluate().end_members(); - } - - array_iterator begin_elements() - { - return evaluate().begin_elements(); - } - - const_array_iterator begin_elements() const - { - return evaluate().begin_elements(); - } - - array_iterator end_elements() - { - return evaluate().end_elements(); - } - - const_array_iterator end_elements() const - { - return evaluate().end_elements(); - } - - const basic_json& get(const string_view_type& name) const - { - return evaluate().get(name); - } - - bool is_ulonglong() const JSONCONS_NOEXCEPT - { - return evaluate().is_ulonglong(); - } - - bool is_longlong() const JSONCONS_NOEXCEPT - { - return evaluate().is_longlong(); - } - - int as_int() const - { - return evaluate().as_int(); - } - - unsigned int as_uint() const - { - return evaluate().as_uint(); - } - - long as_long() const - { - return evaluate().as_long(); - } - - unsigned long as_ulong() const - { - return evaluate().as_ulong(); - } - - long long as_longlong() const - { - return evaluate().as_longlong(); - } - - void add(size_t index, const basic_json& value) - { - evaluate_with_default().add(index, value); - } - - void add(size_t index, basic_json&& value) - { - evaluate_with_default().add(index, std::forward(value)); - } - - bool has_member(const key_storage_type& name) const - { - return evaluate().has_member(name); - } - - // Remove a range of elements from an array - void remove_range(size_t from_index, size_t to_index) - { - evaluate().remove_range(from_index, to_index); - } - // Remove a range of elements from an array - void remove(const string_view_type& name) - { - evaluate().remove(name); - } - void remove_member(const string_view_type& name) - { - evaluate().remove(name); - } - bool is_empty() const JSONCONS_NOEXCEPT - { - return empty(); - } - bool is_numeric() const JSONCONS_NOEXCEPT - { - return is_number(); - } -#endif - }; - - static basic_json parse(std::basic_istream& is) - { - parse_error_handler_type err_handler; - return parse(is,err_handler); - } - - static basic_json parse(std::basic_istream& is, parse_error_handler& err_handler) - { - json_decoder> handler; - basic_json_reader reader(is, handler, err_handler); - reader.read_next(); - reader.check_done(); - if (!handler.is_valid()) - { - JSONCONS_THROW(json_exception_impl("Failed to parse json stream")); - } - return handler.get_result(); - } - - static basic_json parse(const string_view_type& s) - { - parse_error_handler_type err_handler; - return parse(s,err_handler); - } - -#if !defined(JSONCONS_NO_DEPRECATED) - static basic_json parse(const char_type* s, size_t length) - { - parse_error_handler_type err_handler; - return parse(s,length,err_handler); - } - - static basic_json parse(const char_type* s, size_t length, parse_error_handler& err_handler) - { - return parse(string_view_type(s,length),err_handler); - } -#endif - - static basic_json parse(const string_view_type& s, parse_error_handler& err_handler) - { - json_decoder decoder; - basic_json_parser parser(decoder,err_handler); - - auto result = unicons::skip_bom(s.begin(), s.end()); - if (result.ec != unicons::encoding_errc()) - { - throw parse_error(result.ec,1,1); - } - size_t offset = result.it - s.begin(); - parser.set_source(s.data()+offset,s.size()-offset); - parser.parse_some(); - parser.end_parse(); - parser.check_done(); - if (!decoder.is_valid()) - { - JSONCONS_THROW(json_exception_impl("Failed to parse json string")); - } - return decoder.get_result(); - } - - static basic_json parse(std::basic_istream& is, const basic_json_serializing_options& options) - { - parse_error_handler_type err_handler; - return parse(is,options,err_handler); - } - - static basic_json parse(std::basic_istream& is, const basic_json_serializing_options& options, parse_error_handler& err_handler) - { - json_decoder> handler; - basic_json_reader reader(is, handler, options, err_handler); - reader.read_next(); - reader.check_done(); - if (!handler.is_valid()) - { - JSONCONS_THROW(json_exception_impl("Failed to parse json stream")); - } - return handler.get_result(); - } - - static basic_json parse(const string_view_type& s, const basic_json_serializing_options& options) - { - parse_error_handler_type err_handler; - return parse(s,options,err_handler); - } - - static basic_json parse(const string_view_type& s, const basic_json_serializing_options& options, parse_error_handler& err_handler) - { - json_decoder decoder; - basic_json_parser parser(decoder,options,err_handler); - - auto result = unicons::skip_bom(s.begin(), s.end()); - if (result.ec != unicons::encoding_errc()) - { - throw parse_error(result.ec,1,1); - } - size_t offset = result.it - s.begin(); - parser.set_source(s.data()+offset,s.size()-offset); - parser.parse_some(); - parser.end_parse(); - parser.check_done(); - if (!decoder.is_valid()) - { - JSONCONS_THROW(json_exception_impl("Failed to parse json string")); - } - return decoder.get_result(); - } - - static basic_json make_array() - { - return basic_json(variant(array())); - } - - static basic_json make_array(const array& a) - { - return basic_json(variant(a)); - } - - static basic_json make_array(const array& a, allocator_type allocator) - { - return basic_json(variant(a,allocator)); - } - - static basic_json make_array(std::initializer_list init, const Allocator& allocator = Allocator()) - { - return array(std::move(init),allocator); - } - - static basic_json make_array(size_t n, const Allocator& allocator = Allocator()) - { - return array(n,allocator); - } - - template - static basic_json make_array(size_t n, const T& val, const Allocator& allocator = Allocator()) - { - return basic_json::array(n, val,allocator); - } - - template - static typename std::enable_if::type make_array(size_t n) - { - return array(n); - } - - template - static typename std::enable_if::type make_array(size_t n, const T& val, const Allocator& allocator = Allocator()) - { - return array(n,val,allocator); - } - - template - static typename std::enable_if<(dim>1),basic_json>::type make_array(size_t n, Args... args) - { - const size_t dim1 = dim - 1; - - basic_json val = make_array(args...); - val.resize(n); - for (size_t i = 0; i < n; ++i) - { - val[i] = make_array(args...); - } - return val; - } - - static const basic_json& null() - { - static basic_json a_null = basic_json(variant(null_type())); - return a_null; - } - - variant var_; - - basic_json() - : var_() - { - } - - explicit basic_json(const Allocator& allocator) - : var_(allocator) - { - } - - basic_json(const basic_json& val) - : var_(val.var_) - { - } - - basic_json(const basic_json& val, const Allocator& allocator) - : var_(val.var_,allocator) - { - } - - basic_json(basic_json&& other) JSONCONS_NOEXCEPT - : var_(std::move(other.var_)) - { - } - - basic_json(basic_json&& other, const Allocator& allocator) JSONCONS_NOEXCEPT - : var_(std::move(other.var_) /*,allocator*/ ) - { - } - - basic_json(const variant& val) - : var_(val) - { - } - - basic_json(variant&& other) - : var_(std::forward(other)) - { - } - - basic_json(const array& val) - : var_(val) - { - } - - basic_json(array&& other) - : var_(std::forward(other)) - { - } - - basic_json(const object& other) - : var_(other) - { - } - - basic_json(object&& other) - : var_(std::forward(other)) - { - } - - template - basic_json(const json_proxy& proxy) - : var_(proxy.evaluate().var_) - { - } - - template - basic_json(const json_proxy& proxy, const Allocator& allocator) - : var_(proxy.evaluate().var_,allocator) - { - } - - template - basic_json(const T& val) - : var_(json_type_traits::to_json(val).var_) - { - } - - template - basic_json(const T& val, const Allocator& allocator) - : var_(json_type_traits::to_json(val,allocator).var_) - { - } - - basic_json(const char_type* s) - : var_(s) - { - } - - basic_json(const char_type* s, const Allocator& allocator) - : var_(s,allocator) - { - } - - basic_json(double val, uint8_t precision) - : var_(val, number_format(precision, 0)) - { - } - - basic_json(double val, const number_format& fmt) - : var_(val, fmt) - { - } - - basic_json(const char_type *s, size_t length) - : var_(s, length) - { - } - - basic_json(const char_type *s, size_t length, const Allocator& allocator) - : var_(s, length, allocator) - { - } - - basic_json(const uint8_t* s, size_t length) - : var_(s, length) - { - } - - explicit basic_json(const byte_string_view& s) - : var_(s.data(), s.length()) - { - } - - basic_json(const uint8_t* s, size_t length, const Allocator& allocator) - : var_(s, length, allocator) - { - } -#if !defined(JSONCONS_NO_DEPRECATED) - template - basic_json(InputIterator first, InputIterator last, const Allocator& allocator = Allocator()) - : var_(first,last,allocator) - { - } -#endif - - ~basic_json() - { - } - - basic_json& operator=(const basic_json& rhs) - { - if (this != &rhs) - { - var_ = rhs.var_; - } - return *this; - } - - basic_json& operator=(basic_json&& rhs) JSONCONS_NOEXCEPT - { - if (this !=&rhs) - { - var_ = std::move(rhs.var_); - } - return *this; - } - - template - basic_json& operator=(const T& val) - { - var_ = json_type_traits::to_json(val).var_; - return *this; - } - - basic_json& operator=(const char_type* s) - { - var_ = variant(s); - return *this; - } - - bool operator!=(const basic_json& rhs) const - { - return !(*this == rhs); - } - - bool operator==(const basic_json& rhs) const - { - return var_ == rhs.var_; - } - - size_t size() const JSONCONS_NOEXCEPT - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - return 0; - case json_type_tag::object_t: - return object_value().size(); - case json_type_tag::array_t: - return array_value().size(); - default: - return 0; - } - } - - basic_json& operator[](size_t i) - { - return at(i); - } - - const basic_json& operator[](size_t i) const - { - return at(i); - } - - json_proxy operator[](const string_view_type& name) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return json_proxy(*this, key_storage_type(name.begin(),name.end(),char_allocator_type(object_value().get_allocator()))); - break; - default: - JSONCONS_THROW(not_an_object(name.data(),name.length())); - break; - } - } - - const basic_json& operator[](const string_view_type& name) const - { - return at(name); - } - - template - void dump(std::basic_string& s) const - { - basic_json_serializer> serializer(s); - dump(serializer); - } - - template - void dump(std::basic_string& s, indenting line_indent) const - { - basic_json_serializer> serializer(s, line_indent); - dump(serializer); - } - - template - void dump(std::basic_string& s, - const basic_json_serializing_options& options) const - { - basic_json_serializer> serializer(s, options); - dump(serializer); - } - - template - void dump(std::basic_string& s, - const basic_json_serializing_options& options, - indenting line_indent) const - { - basic_json_serializer> serializer(s, options, line_indent); - dump(serializer); - } - -#if !defined(JSONCONS_NO_DEPRECATED) - void dump_body(basic_json_content_handler& handler) const - { - dump_fragment(handler); - } -#endif - void dump_fragment(basic_json_content_handler& handler) const - { - switch (var_.type_id()) - { - case json_type_tag::small_string_t: - case json_type_tag::string_t: - handler.string_value(as_string_view()); - break; - case json_type_tag::byte_string_t: - handler.byte_string_value(var_.byte_string_data_cast()->data(), var_.byte_string_data_cast()->length()); - break; - case json_type_tag::double_t: - handler.double_value(var_.double_data_cast()->value(), number_format(var_.double_data_cast()->precision(), var_.double_data_cast()->decimal_places())); - break; - case json_type_tag::integer_t: - handler.integer_value(var_.integer_data_cast()->value()); - break; - case json_type_tag::uinteger_t: - handler.uinteger_value(var_.uinteger_data_cast()->value()); - break; - case json_type_tag::bool_t: - handler.bool_value(var_.bool_data_cast()->value()); - break; - case json_type_tag::null_t: - handler.null_value(); - break; - case json_type_tag::empty_object_t: - handler.begin_object(0); - handler.end_object(); - break; - case json_type_tag::object_t: - { - handler.begin_object(size()); - const object& o = object_value(); - for (const_object_iterator it = o.begin(); it != o.end(); ++it) - { - handler.name(string_view_type((it->key()).data(),it->key().length())); - it->value().dump_fragment(handler); - } - handler.end_object(); - } - break; - case json_type_tag::array_t: - { - handler.begin_array(size()); - const array& o = array_value(); - for (const_array_iterator it = o.begin(); it != o.end(); ++it) - { - it->dump_fragment(handler); - } - handler.end_array(); - } - break; - default: - break; - } - } - void dump(basic_json_content_handler& handler) const - { - handler.begin_json(); - dump_fragment(handler); - handler.end_json(); - } - - void dump(std::basic_ostream& os) const - { - basic_json_serializer serializer(os); - dump(serializer); - } - - void dump(std::basic_ostream& os, indenting line_indent) const - { - basic_json_serializer serializer(os, line_indent); - dump(serializer); - } - - void dump(std::basic_ostream& os, const basic_json_serializing_options& options) const - { - basic_json_serializer serializer(os, options); - dump(serializer); - } - - void dump(std::basic_ostream& os, const basic_json_serializing_options& options, indenting line_indent) const - { - basic_json_serializer serializer(os, options, line_indent); - dump(serializer); - } - - string_type to_string(const char_allocator_type& allocator=char_allocator_type()) const JSONCONS_NOEXCEPT - { - string_type s(allocator); - basic_json_serializer> serializer(s); - dump_fragment(serializer); - return s; - } - - string_type to_string(const basic_json_serializing_options& options, - const char_allocator_type& allocator=char_allocator_type()) const - { - string_type s(allocator); - basic_json_serializer> serializer(s,options); - dump_fragment(serializer); - return s; - } - -#if !defined(JSONCONS_NO_DEPRECATED) - - void dump(std::basic_ostream& os, bool pprint) const - { - basic_json_serializer serializer(os, pprint); - dump(serializer); - } - - void dump(std::basic_ostream& os, const basic_json_serializing_options& options, bool pprint) const - { - basic_json_serializer serializer(os, options, pprint); - dump(serializer); - } - - void write_body(basic_json_content_handler& handler) const - { - dump(handler); - } - void write(basic_json_content_handler& handler) const - { - dump(handler); - } - - void write(std::basic_ostream& os) const - { - dump(os); - } - - void write(std::basic_ostream& os, const basic_json_serializing_options& options) const - { - dump(os,options); - } - - void write(std::basic_ostream& os, const basic_json_serializing_options& options, bool pprint) const - { - dump(os,options,pprint); - } - - void to_stream(basic_json_content_handler& handler) const - { - handler.begin_json(); - dump_fragment(handler); - handler.end_json(); - } - - void to_stream(std::basic_ostream& os) const - { - basic_json_serializer serializer(os); - to_stream(serializer); - } - - void to_stream(std::basic_ostream& os, const basic_json_serializing_options& options) const - { - basic_json_serializer serializer(os, options); - to_stream(serializer); - } - - void to_stream(std::basic_ostream& os, const basic_json_serializing_options& options, bool pprint) const - { - basic_json_serializer serializer(os, options, pprint); - to_stream(serializer); - } -#endif - bool is_null() const JSONCONS_NOEXCEPT - { - return var_.type_id() == json_type_tag::null_t; - } - - bool has_key(const string_view_type& name) const - { - switch (var_.type_id()) - { - case json_type_tag::object_t: - { - const_object_iterator it = object_value().find(name); - return it != object_range().end(); - } - break; - default: - return false; - } - } - - size_t count(const string_view_type& name) const - { - switch (var_.type_id()) - { - case json_type_tag::object_t: - { - auto it = object_value().find(name); - if (it == object_range().end()) - { - return 0; - } - size_t count = 0; - while (it != object_range().end()&& it->key() == name) - { - ++count; - ++it; - } - return count; - } - break; - default: - return 0; - } - } - - template - bool is(Args&&... args) const - { - return json_type_traits::is(*this,std::forward(args)...); - } - - bool is_string() const JSONCONS_NOEXCEPT - { - return (var_.type_id() == json_type_tag::string_t) || (var_.type_id() == json_type_tag::small_string_t); - } - - bool is_byte_string() const JSONCONS_NOEXCEPT - { - return (var_.type_id() == json_type_tag::byte_string_t); - } - - bool is_bool() const JSONCONS_NOEXCEPT - { - return var_.type_id() == json_type_tag::bool_t; - } - - bool is_object() const JSONCONS_NOEXCEPT - { - return var_.type_id() == json_type_tag::object_t || var_.type_id() == json_type_tag::empty_object_t; - } - - bool is_array() const JSONCONS_NOEXCEPT - { - return var_.type_id() == json_type_tag::array_t; - } - - bool is_integer() const JSONCONS_NOEXCEPT - { - return var_.type_id() == json_type_tag::integer_t || (var_.type_id() == json_type_tag::uinteger_t&& (as_uinteger() <= static_cast((std::numeric_limits::max)()))); - } - - bool is_uinteger() const JSONCONS_NOEXCEPT - { - return var_.type_id() == json_type_tag::uinteger_t || (var_.type_id() == json_type_tag::integer_t&& as_integer() >= 0); - } - - bool is_double() const JSONCONS_NOEXCEPT - { - return var_.type_id() == json_type_tag::double_t; - } - - bool is_number() const JSONCONS_NOEXCEPT - { - return var_.type_id() == json_type_tag::integer_t || var_.type_id() == json_type_tag::uinteger_t || var_.type_id() == json_type_tag::double_t; - } - - bool empty() const JSONCONS_NOEXCEPT - { - switch (var_.type_id()) - { - case json_type_tag::small_string_t: - return var_.small_string_data_cast()->length() == 0; - case json_type_tag::string_t: - return var_.string_data_cast()->length() == 0; - case json_type_tag::array_t: - return array_value().size() == 0; - case json_type_tag::empty_object_t: - return true; - case json_type_tag::object_t: - return object_value().size() == 0; - default: - return false; - } - } - - size_t capacity() const - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - return array_value().capacity(); - case json_type_tag::object_t: - return object_value().capacity(); - default: - return 0; - } - } - - template - typename std::enable_if::value,void>::type - create_object_implicitly() - { - var_ = variant(Allocator()); - } - - template - typename std::enable_if::value,void>::type - create_object_implicitly() const - { - JSONCONS_THROW(json_exception_impl("Cannot create object implicitly - allocator is not default constructible.")); - } - - void reserve(size_t n) - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - array_value().reserve(n); - break; - case json_type_tag::empty_object_t: - { - create_object_implicitly(); - object_value().reserve(n); - } - break; - case json_type_tag::object_t: - { - object_value().reserve(n); - } - break; - default: - break; - } - } - - void resize(size_t n) - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - array_value().resize(n); - break; - default: - break; - } - } - - template - void resize(size_t n, T val) - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - array_value().resize(n, val); - break; - default: - break; - } - } - - template - T as(Args&&... args) const - { - return json_type_traits::as(*this,std::forward(args)...); - } - - template - typename std::enable_if::value,T>::type - as(const char_allocator_type& allocator) const - { - return json_type_traits::as(*this,allocator); - } - - bool as_bool() const - { - switch (var_.type_id()) - { - case json_type_tag::small_string_t: - case json_type_tag::string_t: - try - { - basic_json j = basic_json::parse(as_string_view()); - return j.as_bool(); - } - catch (...) - { - JSONCONS_THROW(json_exception_impl("Not a bool")); - } - break; - case json_type_tag::bool_t: - return var_.bool_data_cast()->value(); - case json_type_tag::double_t: - return var_.double_data_cast()->value() != 0.0; - case json_type_tag::integer_t: - return var_.integer_data_cast()->value() != 0; - case json_type_tag::uinteger_t: - return var_.uinteger_data_cast()->value() != 0; - default: - JSONCONS_THROW(json_exception_impl("Not a bool")); - } - } - - int64_t as_integer() const - { - switch (var_.type_id()) - { - case json_type_tag::small_string_t: - case json_type_tag::string_t: - try - { - basic_json j = basic_json::parse(as_string_view()); - return j.as(); - } - catch (...) - { - JSONCONS_THROW(json_exception_impl("Not an integer")); - } - break; - case json_type_tag::double_t: - return static_cast(var_.double_data_cast()->value()); - case json_type_tag::integer_t: - return static_cast(var_.integer_data_cast()->value()); - case json_type_tag::uinteger_t: - return static_cast(var_.uinteger_data_cast()->value()); - case json_type_tag::bool_t: - return var_.bool_data_cast()->value() ? 1 : 0; - default: - JSONCONS_THROW(json_exception_impl("Not an integer")); - } - } - - uint64_t as_uinteger() const - { - switch (var_.type_id()) - { - case json_type_tag::small_string_t: - case json_type_tag::string_t: - try - { - basic_json j = basic_json::parse(as_string_view()); - return j.as(); - } - catch (...) - { - JSONCONS_THROW(json_exception_impl("Not an unsigned integer")); - } - break; - case json_type_tag::double_t: - return static_cast(var_.double_data_cast()->value()); - case json_type_tag::integer_t: - return static_cast(var_.integer_data_cast()->value()); - case json_type_tag::uinteger_t: - return static_cast(var_.uinteger_data_cast()->value()); - case json_type_tag::bool_t: - return var_.bool_data_cast()->value() ? 1 : 0; - default: - JSONCONS_THROW(json_exception_impl("Not an unsigned integer")); - } - } - - size_t precision() const - { - switch (var_.type_id()) - { - case json_type_tag::double_t: - return var_.double_data_cast()->precision(); - default: - JSONCONS_THROW(json_exception_impl("Not a double")); - } - } - - size_t decimal_places() const - { - switch (var_.type_id()) - { - case json_type_tag::double_t: - return var_.double_data_cast()->decimal_places(); - default: - JSONCONS_THROW(json_exception_impl("Not a double")); - } - } - - double as_double() const - { - switch (var_.type_id()) - { - case json_type_tag::small_string_t: - case json_type_tag::string_t: - try - { - basic_json j = basic_json::parse(as_string_view()); - return j.as(); - } - catch (...) - { - JSONCONS_THROW(json_exception_impl("Not a double")); - } - break; - case json_type_tag::double_t: - return var_.double_data_cast()->value(); - case json_type_tag::integer_t: - return static_cast(var_.integer_data_cast()->value()); - case json_type_tag::uinteger_t: - return static_cast(var_.uinteger_data_cast()->value()); - //case json_type_tag::null_t: - // return std::numeric_limits::quiet_NaN(); - default: - JSONCONS_THROW(json_exception_impl("Not a double")); - } - } - - string_view_type as_string_view() const - { - return var_.as_string_view(); - } - - byte_string_view as_byte_string_view() const - { - return var_.as_byte_string_view(); - } - - string_type as_string() const - { - switch (var_.type_id()) - { - case json_type_tag::small_string_t: - case json_type_tag::string_t: - return string_type(as_string_view().data(),as_string_view().length()); - default: - return to_string(); - } - } - - template - string_type as_string(const SAllocator& allocator) const - { - switch (var_.type_id()) - { - case json_type_tag::small_string_t: - case json_type_tag::string_t: - return string_type(as_string_view().data(),as_string_view().length(),allocator); - default: - return to_string(allocator); - } - } - - string_type as_string(const basic_json_serializing_options& options) const - { - switch (var_.type_id()) - { - case json_type_tag::small_string_t: - case json_type_tag::string_t: - return string_type(as_string_view().data(),as_string_view().length()); - default: - return to_string(options); - } - } - - template - string_type as_string(const basic_json_serializing_options& options, - const SAllocator& allocator) const - { - switch (var_.type_id()) - { - case json_type_tag::small_string_t: - case json_type_tag::string_t: - return string_type(as_string_view().data(),as_string_view().length(),allocator); - default: - return to_string(options,allocator); - } - } - - const char_type* as_cstring() const - { - switch (var_.type_id()) - { - case json_type_tag::small_string_t: - return var_.small_string_data_cast()->c_str(); - case json_type_tag::string_t: - return var_.string_data_cast()->c_str(); - default: - JSONCONS_THROW(json_exception_impl("Not a cstring")); - } - } - -#if !defined(JSONCONS_NO_DEPRECATED) - - size_t double_precision() const - { - switch (var_.type_id()) - { - case json_type_tag::double_t: - return var_.double_data_cast()->precision(); - default: - JSONCONS_THROW(json_exception_impl("Not a double")); - } - } -#endif - - basic_json& at(const string_view_type& name) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - JSONCONS_THROW(key_not_found(name.data(),name.length())); - case json_type_tag::object_t: - { - auto it = object_value().find(name); - if (it == object_range().end()) - { - JSONCONS_THROW(key_not_found(name.data(),name.length())); - } - return it->value(); - } - break; - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - basic_json& evaluate() - { - return *this; - } - - basic_json& evaluate_with_default() - { - return *this; - } - - const basic_json& evaluate() const - { - return *this; - } - basic_json& evaluate(const string_view_type& name) - { - return at(name); - } - - const basic_json& evaluate(const string_view_type& name) const - { - return at(name); - } - - const basic_json& at(const string_view_type& name) const - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - JSONCONS_THROW(key_not_found(name.data(),name.length())); - case json_type_tag::object_t: - { - auto it = object_value().find(name); - if (it == object_range().end()) - { - JSONCONS_THROW(key_not_found(name.data(),name.length())); - } - return it->value(); - } - break; - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - basic_json& at(size_t i) - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - if (i >= array_value().size()) - { - JSONCONS_THROW(json_exception_impl("Invalid array subscript")); - } - return array_value().operator[](i); - case json_type_tag::object_t: - return object_value().at(i); - default: - JSONCONS_THROW(json_exception_impl("Index on non-array value not supported")); - } - } - - const basic_json& at(size_t i) const - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - if (i >= array_value().size()) - { - JSONCONS_THROW(json_exception_impl("Invalid array subscript")); - } - return array_value().operator[](i); - case json_type_tag::object_t: - return object_value().at(i); - default: - JSONCONS_THROW(json_exception_impl("Index on non-array value not supported")); - } - } - - object_iterator find(const string_view_type& name) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - return object_range().end(); - case json_type_tag::object_t: - return object_value().find(name); - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - const_object_iterator find(const string_view_type& name) const - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - return object_range().end(); - case json_type_tag::object_t: - return object_value().find(name); - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - template - basic_json get(const string_view_type& name, T&& default_val) const - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - { - return basic_json(std::forward(default_val)); - } - case json_type_tag::object_t: - { - const_object_iterator it = object_value().find(name); - if (it != object_range().end()) - { - return it->value(); - } - else - { - return basic_json(std::forward(default_val)); - } - } - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - template - T get_with_default(const string_view_type& name, const T& default_val) const - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - { - return default_val; - } - case json_type_tag::object_t: - { - const_object_iterator it = object_value().find(name); - if (it != object_range().end()) - { - return it->value().template as(); - } - else - { - return default_val; - } - } - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - const CharT* get_with_default(const string_view_type& name, const CharT* default_val) const - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - { - return default_val; - } - case json_type_tag::object_t: - { - const_object_iterator it = object_value().find(name); - if (it != object_range().end()) - { - return it->value().as_cstring(); - } - else - { - return default_val; - } - } - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - // Modifiers - - void shrink_to_fit() - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - array_value().shrink_to_fit(); - break; - case json_type_tag::object_t: - object_value().shrink_to_fit(); - break; - default: - break; - } - } - - void clear() - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - array_value().clear(); - break; - case json_type_tag::object_t: - object_value().clear(); - break; - default: - break; - } - } - - void erase(const_object_iterator pos) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - break; - case json_type_tag::object_t: - object_value().erase(pos); - break; - default: - JSONCONS_THROW(json_exception_impl("Not an object")); - break; - } - } - - void erase(const_object_iterator first, const_object_iterator last) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - break; - case json_type_tag::object_t: - object_value().erase(first, last); - break; - default: - JSONCONS_THROW(json_exception_impl("Not an object")); - break; - } - } - - void erase(const_array_iterator pos) - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - array_value().erase(pos); - break; - default: - JSONCONS_THROW(json_exception_impl("Not an array")); - break; - } - } - - void erase(const_array_iterator first, const_array_iterator last) - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - array_value().erase(first, last); - break; - default: - JSONCONS_THROW(json_exception_impl("Not an array")); - break; - } - } - - // Removes all elements from an array value whose index is between from_index, inclusive, and to_index, exclusive. - - void erase(const string_view_type& name) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - break; - case json_type_tag::object_t: - object_value().erase(name); - break; - default: - JSONCONS_THROW(not_an_object(name.data(),name.length())); - break; - } - } - - template - std::pair set(const string_view_type& name, T&& val) - { - return insert_or_assign(name, std::forward(val)); - } - - template - std::pair insert_or_assign(const string_view_type& name, T&& val) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return object_value().insert_or_assign(name, std::forward(val)); - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - template - std::pair try_emplace(const string_view_type& name, Args&&... args) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return object_value().try_emplace(name, std::forward(args)...); - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - template - void set_(key_storage_type&& name, T&& val) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - object_value().set_(std::forward(name), std::forward(val)); - break; - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - // merge - - void merge(const basic_json& source) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return object_value().merge(source.object_value()); - default: - { - JSONCONS_THROW(json_exception_impl("Attempting to merge a value that is not an object")); - } - } - } - - void merge(basic_json&& source) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return object_value().merge(std::move(source.object_value())); - default: - { - JSONCONS_THROW(json_exception_impl("Attempting to merge a value that is not an object")); - } - } - } - - void merge(object_iterator hint, const basic_json& source) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return object_value().merge(hint, source.object_value()); - default: - { - JSONCONS_THROW(json_exception_impl("Attempting to merge a value that is not an object")); - } - } - } - - void merge(object_iterator hint, basic_json&& source) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return object_value().merge(hint, std::move(source.object_value())); - default: - { - JSONCONS_THROW(json_exception_impl("Attempting to merge a value that is not an object")); - } - } - } - - // merge_or_update - - void merge_or_update(const basic_json& source) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return object_value().merge_or_update(source.object_value()); - default: - { - JSONCONS_THROW(json_exception_impl("Attempting to merge or update a value that is not an object")); - } - } - } - - void merge_or_update(basic_json&& source) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return object_value().merge_or_update(std::move(source.object_value())); - default: - { - JSONCONS_THROW(json_exception_impl("Attempting to merge or update a value that is not an object")); - } - } - } - - void merge_or_update(object_iterator hint, const basic_json& source) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return object_value().merge_or_update(hint, source.object_value()); - default: - { - JSONCONS_THROW(json_exception_impl("Attempting to merge or update a value that is not an object")); - } - } - } - - void merge_or_update(object_iterator hint, basic_json&& source) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return object_value().merge_or_update(hint, std::move(source.object_value())); - default: - { - JSONCONS_THROW(json_exception_impl("Attempting to merge or update a value that is not an object")); - } - } - } - - // set - - template - object_iterator set(object_iterator hint, const string_view_type& name, T&& val) - { - return insert_or_assign(hint, name, std::forward(val)); - } - - template - object_iterator insert_or_assign(object_iterator hint, const string_view_type& name, T&& val) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return object_value().insert_or_assign(hint, name, std::forward(val)); - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - template - object_iterator try_emplace(object_iterator hint, const string_view_type& name, Args&&... args) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return object_value().try_emplace(hint, name, std::forward(args)...); - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - template - object_iterator set_(object_iterator hint, key_storage_type&& name, T&& val) - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return object_value().set_(hint, std::forward(name), std::forward(val)); - break; - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - template - void add(T&& val) - { - push_back(std::forward(val)); - } - - template - void push_back(T&& val) - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - array_value().push_back(std::forward(val)); - break; - default: - { - JSONCONS_THROW(json_exception_impl("Attempting to insert into a value that is not an array")); - } - } - } - - template - array_iterator add(const_array_iterator pos, T&& val) - { - return insert(pos, std::forward(val)); - } - - template - array_iterator insert(const_array_iterator pos, T&& val) - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - return array_value().insert(pos, std::forward(val)); - break; - default: - { - JSONCONS_THROW(json_exception_impl("Attempting to insert into a value that is not an array")); - } - } - } - - template - array_iterator insert(const_array_iterator pos, InputIt first, InputIt last) - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - return array_value().insert(pos, first, last); - break; - default: - { - JSONCONS_THROW(json_exception_impl("Attempting to insert into a value that is not an array")); - } - } - } - - template - array_iterator emplace(const_array_iterator pos, Args&&... args) - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - return array_value().emplace(pos, std::forward(args)...); - break; - default: - { - JSONCONS_THROW(json_exception_impl("Attempting to insert into a value that is not an array")); - } - } - } - - template - basic_json& emplace_back(Args&&... args) - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - return array_value().emplace_back(std::forward(args)...); - default: - { - JSONCONS_THROW(json_exception_impl("Attempting to insert into a value that is not an array")); - } - } - } - - json_type_tag type_id() const - { - return var_.type_id(); - } - - void swap(basic_json& b) - { - var_.swap(b.var_); - } - - friend void swap(basic_json& a, basic_json& b) - { - a.swap(b); - } - - static basic_json make_string(const string_view_type& s) - { - return basic_json(variant(s.data(),s.length())); - } - - static basic_json make_string(const char_type* rhs, size_t length) - { - return basic_json(variant(rhs,length)); - } - - static basic_json make_string(const string_view_type& s, allocator_type allocator) - { - return basic_json(variant(s.data(),s.length(),allocator)); - } - - static basic_json from_integer(int64_t val) - { - return basic_json(variant(val)); - } - - static basic_json from_integer(int64_t val, allocator_type) - { - return basic_json(variant(val)); - } - - static basic_json from_uinteger(uint64_t val) - { - return basic_json(variant(val)); - } - - static basic_json from_uinteger(uint64_t val, allocator_type) - { - return basic_json(variant(val)); - } - - static basic_json from_floating_point(double val) - { - return basic_json(variant(val)); - } - - static basic_json from_floating_point(double val, allocator_type) - { - return basic_json(variant(val)); - } - - static basic_json from_bool(bool val) - { - return basic_json(variant(val)); - } - - static basic_json make_object(const object& o) - { - return basic_json(variant(o)); - } - - static basic_json make_object(const object& o, allocator_type allocator) - { - return basic_json(variant(o,allocator)); - } - -#if !defined(JSONCONS_NO_DEPRECATED) - - static basic_json parse_file(const std::basic_string& filename) - { - parse_error_handler_type err_handler; - return parse_file(filename,err_handler); - } - - static basic_json parse_file(const std::basic_string& filename, - parse_error_handler& err_handler) - { - std::basic_ifstream is(filename); - return parse(is,err_handler); - } - - static basic_json parse_stream(std::basic_istream& is) - { - return parse(is); - } - static basic_json parse_stream(std::basic_istream& is, parse_error_handler& err_handler) - { - return parse(is,err_handler); - } - - static basic_json parse_string(const string_type& s) - { - return parse(s); - } - - static basic_json parse_string(const string_type& s, parse_error_handler& err_handler) - { - return parse(s,err_handler); - } - - void resize_array(size_t n) - { - resize(n); - } - - template - void resize_array(size_t n, T val) - { - resize(n,val); - } - - object_iterator begin_members() - { - return object_range().begin(); - } - - const_object_iterator begin_members() const - { - return object_range().begin(); - } - - object_iterator end_members() - { - return object_range().end(); - } - - const_object_iterator end_members() const - { - return object_range().end(); - } - - array_iterator begin_elements() - { - return array_range().begin(); - } - - const_array_iterator begin_elements() const - { - return array_range().begin(); - } - - array_iterator end_elements() - { - return array_range().end(); - } - - const_array_iterator end_elements() const - { - return array_range().end(); - } - - const basic_json& get(const string_view_type& name) const - { - static const basic_json a_null = null_type(); - - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - return a_null; - case json_type_tag::object_t: - { - const_object_iterator it = object_value().find(name); - return it != object_range().end() ? it->value() : a_null; - } - default: - { - JSONCONS_THROW(not_an_object(name.data(),name.length())); - } - } - } - - bool is_longlong() const JSONCONS_NOEXCEPT - { - return var_.type_id() == json_type_tag::integer_t; - } - - bool is_ulonglong() const JSONCONS_NOEXCEPT - { - return var_.type_id() == json_type_tag::uinteger_t; - } - - long long as_longlong() const - { - return as_integer(); - } - - unsigned long long as_ulonglong() const - { - return as_uinteger(); - } - - int as_int() const - { - switch (var_.type_id()) - { - case json_type_tag::double_t: - return static_cast(var_.double_data_cast()->value()); - case json_type_tag::integer_t: - return static_cast(var_.integer_data_cast()->value()); - case json_type_tag::uinteger_t: - return static_cast(var_.uinteger_data_cast()->value()); - case json_type_tag::bool_t: - return var_.bool_data_cast()->value() ? 1 : 0; - default: - JSONCONS_THROW(json_exception_impl("Not an int")); - } - } - - unsigned int as_uint() const - { - switch (var_.type_id()) - { - case json_type_tag::double_t: - return static_cast(var_.double_data_cast()->value()); - case json_type_tag::integer_t: - return static_cast(var_.integer_data_cast()->value()); - case json_type_tag::uinteger_t: - return static_cast(var_.uinteger_data_cast()->value()); - case json_type_tag::bool_t: - return var_.bool_data_cast()->value() ? 1 : 0; - default: - JSONCONS_THROW(json_exception_impl("Not an unsigned int")); - } - } - - long as_long() const - { - switch (var_.type_id()) - { - case json_type_tag::double_t: - return static_cast(var_.double_data_cast()->value()); - case json_type_tag::integer_t: - return static_cast(var_.integer_data_cast()->value()); - case json_type_tag::uinteger_t: - return static_cast(var_.uinteger_data_cast()->value()); - case json_type_tag::bool_t: - return var_.bool_data_cast()->value() ? 1 : 0; - default: - JSONCONS_THROW(json_exception_impl("Not a long")); - } - } - - unsigned long as_ulong() const - { - switch (var_.type_id()) - { - case json_type_tag::double_t: - return static_cast(var_.double_data_cast()->value()); - case json_type_tag::integer_t: - return static_cast(var_.integer_data_cast()->value()); - case json_type_tag::uinteger_t: - return static_cast(var_.uinteger_data_cast()->value()); - case json_type_tag::bool_t: - return var_.bool_data_cast()->value() ? 1 : 0; - default: - JSONCONS_THROW(json_exception_impl("Not an unsigned long")); - } - } - - bool has_member(const key_storage_type& name) const - { - switch (var_.type_id()) - { - case json_type_tag::object_t: - { - const_object_iterator it = object_value().find(name); - return it != object_range().end(); - } - break; - default: - return false; - } - } - - void remove_range(size_t from_index, size_t to_index) - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - array_value().remove_range(from_index, to_index); - break; - default: - break; - } - } - // Removes all elements from an array value whose index is between from_index, inclusive, and to_index, exclusive. - - void remove(const string_view_type& name) - { - erase(name); - } - void remove_member(const string_view_type& name) - { - erase(name); - } - // Removes a member from an object value - - bool is_empty() const JSONCONS_NOEXCEPT - { - return empty(); - } - bool is_numeric() const JSONCONS_NOEXCEPT - { - return is_number(); - } - - template - static typename std::enable_if::type make_multi_array() - { - return make_array(); - } - template - static typename std::enable_if::type make_multi_array(size_t n) - { - return make_array(n); - } - template - static typename std::enable_if::type make_multi_array(size_t n, T val) - { - return make_array(n,val); - } - template - static typename std::enable_if::type make_multi_array(size_t m, size_t n) - { - return make_array<2>(m, n); - } - template - static typename std::enable_if::type make_multi_array(size_t m, size_t n, T val) - { - return make_array<2>(m, n, val); - } - template - static typename std::enable_if::type make_multi_array(size_t m, size_t n, size_t k) - { - return make_array<3>(m, n, k); - } - template - static typename std::enable_if::type make_multi_array(size_t m, size_t n, size_t k, T val) - { - return make_array<3>(m, n, k, val); - } - range members() - { - return object_range(); - } - - range members() const - { - return object_range(); - } - - range elements() - { - return array_range(); - } - - range elements() const - { - return array_range(); - } -#endif - - range object_range() - { - static basic_json empty_object = object(); - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - return range(empty_object.object_range().begin(), empty_object.object_range().end()); - case json_type_tag::object_t: - return range(object_value().begin(),object_value().end()); - default: - JSONCONS_THROW(json_exception_impl("Not an object")); - } - } - - range object_range() const - { - static const basic_json empty_object = object(); - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - return range(empty_object.object_range().begin(), empty_object.object_range().end()); - case json_type_tag::object_t: - return range(object_value().begin(),object_value().end()); - default: - JSONCONS_THROW(json_exception_impl("Not an object")); - } - } - - range array_range() - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - return range(array_value().begin(),array_value().end()); - default: - JSONCONS_THROW(json_exception_impl("Not an array")); - } - } - - range array_range() const - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - return range(array_value().begin(),array_value().end()); - default: - JSONCONS_THROW(json_exception_impl("Not an array")); - } - } - - array& array_value() - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - return var_.array_data_cast()->value(); - default: - JSONCONS_THROW(json_exception_impl("Bad array cast")); - break; - } - } - - const array& array_value() const - { - switch (var_.type_id()) - { - case json_type_tag::array_t: - return var_.array_data_cast()->value(); - default: - JSONCONS_THROW(json_exception_impl("Bad array cast")); - break; - } - } - - object& object_value() - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - create_object_implicitly(); - // FALLTHRU - case json_type_tag::object_t: - return var_.object_data_cast()->value(); - default: - JSONCONS_THROW(json_exception_impl("Bad object cast")); - break; - } - } - - const object& object_value() const - { - switch (var_.type_id()) - { - case json_type_tag::empty_object_t: - const_cast(this)->create_object_implicitly(); // HERE - // FALLTHRU - case json_type_tag::object_t: - return var_.object_data_cast()->value(); - default: - JSONCONS_THROW(json_exception_impl("Bad object cast")); - break; - } - } - -private: - - friend std::basic_ostream& operator<<(std::basic_ostream& os, const basic_json& o) - { - o.dump(os); - return os; - } - - friend std::basic_istream& operator<<(std::basic_istream& is, basic_json& o) - { - json_decoder handler; - basic_json_reader reader(is, handler); - reader.read_next(); - reader.check_done(); - if (!handler.is_valid()) - { - JSONCONS_THROW(json_exception_impl("Failed to parse json stream")); - } - o = handler.get_result(); - return is; - } -}; - -template -void swap(typename Json::key_value_pair_type& a, typename Json::key_value_pair_type& b) -{ - a.swap(b); -} - -template -std::basic_istream& operator>>(std::basic_istream& is, Json& o) -{ - json_decoder handler; - basic_json_reader reader(is, handler); - reader.read_next(); - reader.check_done(); - if (!handler.is_valid()) - { - JSONCONS_THROW(json_exception_impl("Failed to parse json stream")); - } - o = handler.get_result(); - return is; -} - -template -class json_printable -{ -public: - typedef typename Json::char_type char_type; - - json_printable(const Json& o, indenting line_indent) - : o_(&o), indenting_(line_indent) - { - } - - json_printable(const Json& o, - const basic_json_serializing_options& options, - indenting line_indent) - : o_(&o), options_(options), indenting_(line_indent) - { - } - - void dump(std::basic_ostream& os) const - { - o_->dump(os, options_, indenting_); - } - - friend std::basic_ostream& operator<<(std::basic_ostream& os, const json_printable& o) - { - o.dump(os); - return os; - } - - const Json *o_; - basic_json_serializing_options options_; - indenting indenting_; -private: - json_printable(); -}; - -template -json_printable print(const Json& val) -{ - return json_printable(val, indenting::no_indent); -} - -template -json_printable print(const Json& val, - const basic_json_serializing_options& options) -{ - return json_printable(val, options, indenting::no_indent); -} - -template -json_printable pretty_print(const Json& val) -{ - return json_printable(val, indenting::indent); -} - -template -json_printable pretty_print(const Json& val, - const basic_json_serializing_options& options) -{ - return json_printable(val, options, indenting::indent); -} - -typedef basic_json> json; -typedef basic_json> wjson; -typedef basic_json> ojson; -typedef basic_json> wojson; - -#if !defined(JSONCONS_NO_DEPRECATED) -typedef basic_json> owjson; -typedef json_decoder json_deserializer; -typedef json_decoder wjson_deserializer; -typedef json_decoder ojson_deserializer; -typedef json_decoder wojson_deserializer; -#endif - -#if defined(JSONCONS_HAS_USER_DEFINED_LITERALS) -namespace literals { - -inline -jsoncons::json operator "" _json(const char* s, std::size_t n) -{ - return jsoncons::json::parse(jsoncons::json::string_view_type(s, n)); -} - -inline -jsoncons::wjson operator "" _json(const wchar_t* s, std::size_t n) -{ - return jsoncons::wjson::parse(jsoncons::wjson::string_view_type(s, n)); -} - -inline -jsoncons::ojson operator "" _ojson(const char* s, std::size_t n) -{ - return jsoncons::ojson::parse(jsoncons::ojson::string_view_type(s, n)); -} - -inline -jsoncons::wojson operator "" _ojson(const wchar_t* s, std::size_t n) -{ - return jsoncons::wojson::parse(jsoncons::wojson::string_view_type(s, n)); -} - -} -#endif - -} - -#include - -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_container_types.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_container_types.hpp new file mode 100644 index 0000000..5b13eb7 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_container_types.hpp @@ -0,0 +1,1962 @@ +// Copyright 2013 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_JSON_CONTAINER_TYPES_HPP +#define JSONCONS_JSON_CONTAINER_TYPES_HPP + +#include +#include +#include +#include +#include +#include // std::sort, std::stable_sort, std::lower_bound, std::unique +#include +#include +#include // std::iterator_traits +#include // std::allocator +#include // std::move +#include // std::enable_if +#include +#include + +namespace jsoncons { + +// key_value + +template +class key_value +{ +public: + typedef KeyT key_type; + typedef ValueT value_type; + typedef typename ValueT::allocator_type allocator_type; + typedef typename value_type::string_view_type string_view_type; +private: + key_type key_; + value_type value_; +public: + + key_value() + { + } + + key_value(const key_type& name, const value_type& val) + : key_(name), value_(val) + { + } + + key_value(const string_view_type& name) + : key_(name) + { + } + + template + key_value(key_type&& name, T&& val) + : key_(std::forward(name)), + value_(std::forward(val)) + { + } + + template + key_value(key_type&& name, + T&& val, + const allocator_type& allocator) + : key_(std::forward(name)), value_(std::forward(val), allocator) + { + } + + key_value(const key_value& member) + : key_(member.key_), value_(member.value_) + { + } + + key_value(key_value&& member) + : key_(std::move(member.key_)), value_(std::move(member.value_)) + { + } + + const key_type& key() const + { + return key_; + } + + value_type& value() + { + return value_; + } + + const value_type& value() const + { + return value_; + } + + template + void value(T&& value) + { + value_ = std::forward(value); + } + + void swap(key_value& member) + { + key_.swap(member.key_); + value_.swap(member.value_); + } + + key_value& operator=(const key_value& member) + { + if (this != & member) + { + key_ = member.key_; + value_ = member.value_; + } + return *this; + } + + key_value& operator=(key_value&& member) + { + if (this != &member) + { + key_.swap(member.key_); + value_.swap(member.value_); + } + return *this; + } + + void shrink_to_fit() + { + key_.shrink_to_fit(); + value_.shrink_to_fit(); + } +#if !defined(JSONCONS_NO_DEPRECATED) + const key_type& name() const + { + return key_; + } +#endif + + friend bool operator==(const key_value& lhs, const key_value& rhs) + { + return lhs.key_ == rhs.key_ && lhs.value_ == rhs.value_; + } + + friend bool operator!=(const key_value& lhs, const key_value& rhs) + { + return !(lhs == rhs); + } + + friend bool operator<(const key_value& lhs, const key_value& rhs) + { + if (lhs.key_ < rhs.key_) + { + return true; + } + if (lhs.key_ == rhs.key_ && lhs.value_ < rhs.value_) + { + return true; + } + return false; + } + + friend bool operator<=(const key_value& lhs, const key_value& rhs) + { + return !(rhs < lhs); + } + + friend bool operator>(const key_value& lhs, const key_value& rhs) + { + return !(lhs <= rhs); + } + + friend bool operator>=(const key_value& lhs, const key_value& rhs) + { + return !(lhs < rhs); + } +}; + +template +struct get_key_value +{ + typedef key_value key_value_type; + + template + key_value_type operator()(const std::pair& p) + { + return key_value_type(p.first,p.second); + } + template + key_value_type operator()(std::pair&& p) + { + return key_value_type(std::forward(p.first),std::forward(p.second)); + } + template + const key_value_type& operator()(const key_value& p) + { + return p; + } + template + key_value_type operator()(key_value&& p) + { + return std::move(p); + } +}; + +// json_array + +template +class container_base +{ +public: + typedef Allocator allocator_type; +private: + allocator_type allocator_; +public: + container_base() + : allocator_() + { + } + container_base(const allocator_type& allocator) + : allocator_(allocator) + { + } + + allocator_type get_allocator() const + { + return allocator_; + } +}; + +// json_array + +template +class json_array : public container_base +{ +public: + typedef typename Json::allocator_type allocator_type; + typedef Json value_type; +private: + typedef typename Json::implementation_policy implementation_policy; + typedef typename std::allocator_traits:: template rebind_alloc value_allocator_type; + using value_container_type = typename implementation_policy::template sequence_container_type; + value_container_type elements_; +public: + typedef typename value_container_type::iterator iterator; + typedef typename value_container_type::const_iterator const_iterator; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::reference const_reference; + + using container_base::get_allocator; + + json_array() + { + } + + explicit json_array(const allocator_type& allocator) + : container_base(allocator), + elements_(value_allocator_type(allocator)) + { + } + + explicit json_array(size_t n, + const allocator_type& allocator = allocator_type()) + : container_base(allocator), + elements_(n,Json(),value_allocator_type(allocator)) + { + } + + explicit json_array(size_t n, + const Json& value, + const allocator_type& allocator = allocator_type()) + : container_base(allocator), + elements_(n,value,value_allocator_type(allocator)) + { + } + + template + json_array(InputIterator begin, InputIterator end, const allocator_type& allocator = allocator_type()) + : container_base(allocator), + elements_(begin,end,value_allocator_type(allocator)) + { + } + json_array(const json_array& val) + : container_base(val.get_allocator()), + elements_(val.elements_) + { + } + json_array(const json_array& val, const allocator_type& allocator) + : container_base(allocator), + elements_(val.elements_,value_allocator_type(allocator)) + { + } + + json_array(json_array&& val) noexcept + : container_base(val.get_allocator()), + elements_(std::move(val.elements_)) + { + } + json_array(json_array&& val, const allocator_type& allocator) + : container_base(allocator), + elements_(std::move(val.elements_),value_allocator_type(allocator)) + { + } + + json_array(std::initializer_list init) + : container_base(), + elements_(std::move(init)) + { + } + + json_array(std::initializer_list init, + const allocator_type& allocator) + : container_base(allocator), + elements_(std::move(init),value_allocator_type(allocator)) + { + } + ~json_array() + { + } + + void swap(json_array& val) + { + elements_.swap(val.elements_); + } + + size_t size() const {return elements_.size();} + + size_t capacity() const {return elements_.capacity();} + + void clear() {elements_.clear();} + + void shrink_to_fit() + { + for (size_t i = 0; i < elements_.size(); ++i) + { + elements_[i].shrink_to_fit(); + } + elements_.shrink_to_fit(); + } + + void reserve(size_t n) {elements_.reserve(n);} + + void resize(size_t n) {elements_.resize(n);} + + void resize(size_t n, const Json& val) {elements_.resize(n,val);} + +#if !defined(JSONCONS_NO_DEPRECATED) + void remove_range(size_t from_index, size_t to_index) + { + JSONCONS_ASSERT(from_index <= to_index); + JSONCONS_ASSERT(to_index <= elements_.size()); + elements_.erase(elements_.cbegin()+from_index,elements_.cbegin()+to_index); + } +#endif + void erase(const_iterator pos) + { +#if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + elements_.erase(it); +#else + elements_.erase(pos); +#endif + } + + void erase(const_iterator first, const_iterator last) + { +#if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it1 = elements_.begin() + (first - elements_.begin()); + iterator it2 = elements_.begin() + (last - elements_.begin()); + elements_.erase(it1,it2); +#else + elements_.erase(first,last); +#endif + } + + Json& operator[](size_t i) {return elements_[i];} + + const Json& operator[](size_t i) const {return elements_[i];} + + // push_back + + template + typename std::enable_if::value,void>::type + push_back(T&& value) + { + elements_.emplace_back(std::forward(value)); + } + + template + typename std::enable_if::value,void>::type + push_back(T&& value) + { + elements_.emplace_back(std::forward(value),get_allocator()); + } + + template + typename std::enable_if::value,iterator>::type + insert(const_iterator pos, T&& value) + { +#if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + return elements_.emplace(it, std::forward(value)); +#else + return elements_.emplace(pos, std::forward(value)); +#endif + } + template + typename std::enable_if::value,iterator>::type + insert(const_iterator pos, T&& value) + { +#if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + return elements_.emplace(it, std::forward(value), get_allocator()); +#else + return elements_.emplace(pos, std::forward(value), get_allocator()); +#endif + } + + template + iterator insert(const_iterator pos, InputIt first, InputIt last) + { +#if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + elements_.insert(it, first, last); + return first == last ? it : it + 1; +#else + return elements_.insert(pos, first, last); +#endif + } + + template + typename std::enable_if::value,iterator>::type + emplace(const_iterator pos, Args&&... args) + { +#if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + return elements_.emplace(it, std::forward(args)...); +#else + return elements_.emplace(pos, std::forward(args)...); +#endif + } + + template + Json& emplace_back(Args&&... args) + { + elements_.emplace_back(std::forward(args)...); + return elements_.back(); + } + + iterator begin() {return elements_.begin();} + + iterator end() {return elements_.end();} + + const_iterator begin() const {return elements_.begin();} + + const_iterator end() const {return elements_.end();} + + bool operator==(const json_array& rhs) const + { + return elements_ == rhs.elements_; + } + + bool operator<(const json_array& rhs) const + { + return elements_ < rhs.elements_; + } +private: + + json_array& operator=(const json_array&) = delete; +}; + +struct sorted_unique_range_tag +{ +}; + +// json_object + +template +class json_object +{ +}; + +// Sort keys +template +class json_object::type> : + public container_base +{ +public: + typedef typename Json::allocator_type allocator_type; + typedef KeyT key_type; + typedef key_value key_value_type; + typedef typename Json::char_type char_type; + typedef typename Json::string_view_type string_view_type; +private: + typedef typename Json::implementation_policy implementation_policy; + typedef typename std::allocator_traits:: template rebind_alloc key_value_allocator_type; + using key_value_container_type = typename implementation_policy::template sequence_container_type; + + key_value_container_type members_; +public: + typedef typename key_value_container_type::iterator iterator; + typedef typename key_value_container_type::const_iterator const_iterator; + + using container_base::get_allocator; + + json_object() + { + } + + explicit json_object(const allocator_type& allocator) + : container_base(allocator), + members_(key_value_allocator_type(allocator)) + { + } + + json_object(const json_object& val) + : container_base(val.get_allocator()), + members_(val.members_) + { + } + + json_object(json_object&& val) + : container_base(val.get_allocator()), + members_(std::move(val.members_)) + { + } + + json_object(const json_object& val, const allocator_type& allocator) + : container_base(allocator), + members_(val.members_,key_value_allocator_type(allocator)) + { + } + + json_object(json_object&& val,const allocator_type& allocator) + : container_base(allocator), members_(std::move(val.members_),key_value_allocator_type(allocator)) + { + } + + template + json_object(InputIt first, InputIt last) + { + size_t count = std::distance(first,last); + members_.reserve(count); + for (auto s = first; s != last; ++s) + { + members_.emplace_back(get_key_value()(*s)); + } + std::stable_sort(members_.begin(),members_.end(), + [](const key_value_type& a, const key_value_type& b) -> bool {return a.key().compare(b.key()) < 0;}); + auto it = std::unique(members_.begin(), members_.end(), + [](const key_value_type& a, const key_value_type& b) -> bool { return !(a.key().compare(b.key()));}); + members_.erase(it, members_.end()); + } + + template + json_object(InputIt first, InputIt last, + const allocator_type& allocator) + : container_base(allocator), + members_(key_value_allocator_type(allocator)) + { + size_t count = std::distance(first,last); + members_.reserve(count); + for (auto s = first; s != last; ++s) + { + members_.emplace_back(get_key_value()(*s)); + } + std::stable_sort(members_.begin(),members_.end(), + [](const key_value_type& a, const key_value_type& b) -> bool {return a.key().compare(b.key()) < 0;}); + auto it = std::unique(members_.begin(), members_.end(), + [](const key_value_type& a, const key_value_type& b) -> bool { return !(a.key().compare(b.key()));}); + members_.erase(it, members_.end()); + } + + json_object(std::initializer_list init) + { + for (const auto& element : init) + { + if (element.size() != 2 || !element[0].is_string()) + { + JSONCONS_THROW(json_runtime_error("Cannot create object from initializer list")); + break; + } + } + for (auto& element : init) + { + insert_or_assign(element[0].as_string_view(), std::move(element[1])); + } + } + + json_object(std::initializer_list init, + const allocator_type& allocator) + : container_base(allocator), + members_(key_value_allocator_type(allocator)) + { + for (const auto& element : init) + { + if (element.size() != 2 || !element[0].is_string()) + { + JSONCONS_THROW(json_runtime_error("Cannot create object from initializer list")); + break; + } + } + for (auto& element : init) + { + insert_or_assign(element[0].as_string_view(), std::move(element[1])); + } + } + + void swap(json_object& val) + { + members_.swap(val.members_); + } + + iterator begin() + { + return members_.begin(); + } + + iterator end() + { + return members_.end(); + } + + const_iterator begin() const + { + return members_.begin(); + } + + const_iterator end() const + { + return members_.end(); + } + + size_t size() const {return members_.size();} + + size_t capacity() const {return members_.capacity();} + + void clear() {members_.clear();} + + void shrink_to_fit() + { + for (size_t i = 0; i < members_.size(); ++i) + { + members_[i].shrink_to_fit(); + } + members_.shrink_to_fit(); + } + + void reserve(size_t n) {members_.reserve(n);} + + Json& at(size_t i) + { + if (i >= members_.size()) + { + JSONCONS_THROW(json_runtime_error("Invalid array subscript")); + } + return members_[i].value(); + } + + const Json& at(size_t i) const + { + if (i >= members_.size()) + { + JSONCONS_THROW(json_runtime_error("Invalid array subscript")); + } + return members_[i].value(); + } + + iterator find(const string_view_type& name) + { + auto it = std::lower_bound(members_.begin(),members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + auto result = (it != members_.end() && it->key() == name) ? it : members_.end(); + return result; + } + + const_iterator find(const string_view_type& name) const + { + auto it = std::lower_bound(members_.begin(),members_.end(), + name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + auto result = (it != members_.end() && it->key() == name) ? it : members_.end(); + return result; + } + + void erase(const_iterator pos) + { +#if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it = members_.begin() + (pos - members_.begin()); + members_.erase(it); +#else + members_.erase(pos); +#endif + } + + void erase(const_iterator first, const_iterator last) + { +#if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it1 = members_.begin() + (first - members_.begin()); + iterator it2 = members_.begin() + (last - members_.begin()); + members_.erase(it1,it2); +#else + members_.erase(first,last); +#endif + } + + void erase(const string_view_type& name) + { + auto it = std::lower_bound(members_.begin(),members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + if (it != members_.end() && it->key() == name) + { + members_.erase(it); + } + } + + template + void insert(InputIt first, InputIt last, Convert convert) + { + size_t count = std::distance(first,last); + members_.reserve(members_.size() + count); + for (auto s = first; s != last; ++s) + { + members_.emplace_back(convert(*s)); + } + std::stable_sort(members_.begin(),members_.end(), + [](const key_value_type& a, const key_value_type& b) -> bool {return a.key().compare(b.key()) < 0;}); + auto it = std::unique(members_.begin(), members_.end(), + [](const key_value_type& a, const key_value_type& b) -> bool { return !(a.key().compare(b.key()));}); + members_.erase(it, members_.end()); + } + + template + void insert(sorted_unique_range_tag, InputIt first, InputIt last, Convert convert) + { + if (first != last) + { + size_t count = std::distance(first,last); + members_.reserve(members_.size() + count); + + auto it = find(convert(*first).key()); + if (it != members_.end()) + { + for (auto s = first; s != last; ++s) + { + it = members_.emplace(it, convert(*s)); + } + } + else + { + for (auto s = first; s != last; ++s) + { + members_.emplace_back(convert(*s)); + } + } + } + } + + // insert_or_assign + + template + typename std::enable_if::value,std::pair>::type + insert_or_assign(const string_view_type& name, T&& value) + { + bool inserted; + auto it = std::lower_bound(members_.begin(),members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + if (it == members_.end()) + { + members_.emplace_back(key_type(name.begin(),name.end()), + std::forward(value)); + inserted = true; + it = members_.begin() + members_.size() - 1; + } + else if (it->key() == name) + { + it->value(Json(std::forward(value))); + inserted = false; // assigned + } + else + { + it = members_.emplace(it, + key_type(name.begin(),name.end()), + std::forward(value)); + inserted = true; + } + return std::make_pair(it,inserted); + } + + template + typename std::enable_if::value,std::pair>::type + insert_or_assign(const string_view_type& name, T&& value) + { + bool inserted; + auto it = std::lower_bound(members_.begin(),members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + if (it == members_.end()) + { + members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()), + std::forward(value),get_allocator()); + inserted = true; + it = members_.begin() + members_.size() - 1; + } + else if (it->key() == name) + { + it->value(Json(std::forward(value), get_allocator())); + inserted = false; // assigned + } + else + { + it = members_.emplace(it, + key_type(name.begin(),name.end(), get_allocator()), + std::forward(value),get_allocator()); + inserted = true; + } + return std::make_pair(it,inserted); + } + + // try_emplace + + template + typename std::enable_if::value,std::pair>::type + try_emplace(const string_view_type& name, Args&&... args) + { + bool inserted; + auto it = std::lower_bound(members_.begin(),members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + if (it == members_.end()) + { + members_.emplace_back(key_type(name.begin(),name.end()), + std::forward(args)...); + it = members_.begin() + members_.size() - 1; + inserted = true; + } + else if (it->key() == name) + { + inserted = false; + } + else + { + it = members_.emplace(it, + key_type(name.begin(),name.end()), + std::forward(args)...); + inserted = true; + } + return std::make_pair(it,inserted); + } + + template + typename std::enable_if::value,std::pair>::type + try_emplace(const string_view_type& name, Args&&... args) + { + bool inserted; + auto it = std::lower_bound(members_.begin(),members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + if (it == members_.end()) + { + members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()), + std::forward(args)...); + it = members_.begin() + members_.size() - 1; + inserted = true; + } + else if (it->key() == name) + { + inserted = false; + } + else + { + it = members_.emplace(it, + key_type(name.begin(),name.end(), get_allocator()), + std::forward(args)...); + inserted = true; + } + return std::make_pair(it,inserted); + } + + template + typename std::enable_if::value,iterator>::type + try_emplace(iterator hint, const string_view_type& name, Args&&... args) + { + iterator it = hint; + + if (hint != members_.end() && hint->key() <= name) + { + it = std::lower_bound(hint,members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + } + else + { + it = std::lower_bound(members_.begin(),members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + } + + if (it == members_.end()) + { + members_.emplace_back(key_type(name.begin(),name.end()), + std::forward(args)...); + it = members_.begin() + (members_.size() - 1); + } + else if (it->key() == name) + { + } + else + { + it = members_.emplace(it, + key_type(name.begin(),name.end()), + std::forward(args)...); + } + + return it; + } + + template + typename std::enable_if::value,iterator>::type + try_emplace(iterator hint, const string_view_type& name, Args&&... args) + { + iterator it = hint; + if (hint != members_.end() && hint->key() <= name) + { + it = std::lower_bound(hint,members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + } + else + { + it = std::lower_bound(members_.begin(),members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + } + + if (it == members_.end()) + { + members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()), + std::forward(args)...); + it = members_.begin() + (members_.size() - 1); + } + else if (it->key() == name) + { + } + else + { + it = members_.emplace(it, + key_type(name.begin(),name.end(), get_allocator()), + std::forward(args)...); + } + return it; + } + + // insert_or_assign + + template + typename std::enable_if::value,iterator>::type + insert_or_assign(iterator hint, const string_view_type& name, T&& value) + { + iterator it; + if (hint != members_.end() && hint->key() <= name) + { + it = std::lower_bound(hint,members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + } + else + { + it = std::lower_bound(members_.begin(),members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + } + + if (it == members_.end()) + { + members_.emplace_back(key_type(name.begin(),name.end()), + std::forward(value)); + it = members_.begin() + (members_.size() - 1); + } + else if (it->key() == name) + { + it->value(Json(std::forward(value))); + } + else + { + it = members_.emplace(it, + key_type(name.begin(),name.end()), + std::forward(value)); + } + return it; + } + + template + typename std::enable_if::value,iterator>::type + insert_or_assign(iterator hint, const string_view_type& name, T&& value) + { + iterator it; + if (hint != members_.end() && hint->key() <= name) + { + it = std::lower_bound(hint,members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + } + else + { + it = std::lower_bound(members_.begin(),members_.end(), name, + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + } + + if (it == members_.end()) + { + members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()), + std::forward(value),get_allocator()); + it = members_.begin() + (members_.size() - 1); + } + else if (it->key() == name) + { + it->value(Json(std::forward(value),get_allocator())); + } + else + { + it = members_.emplace(it, + key_type(name.begin(),name.end(), get_allocator()), + std::forward(value),get_allocator()); + } + return it; + } + + // merge + + void merge(const json_object& source) + { + for (auto it = source.begin(); it != source.end(); ++it) + { + try_emplace(it->key(),it->value()); + } + } + + void merge(json_object&& source) + { + auto it = std::make_move_iterator(source.begin()); + auto end = std::make_move_iterator(source.end()); + for (; it != end; ++it) + { + auto pos = std::lower_bound(members_.begin(),members_.end(), it->key(), + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + if (pos == members_.end() ) + { + members_.emplace_back(*it); + } + else if (it->key() != pos->key()) + { + members_.emplace(pos,*it); + } + } + } + + void merge(iterator hint, const json_object& source) + { + for (auto it = source.begin(); it != source.end(); ++it) + { + hint = try_emplace(hint, it->key(),it->value()); + } + } + + void merge(iterator hint, json_object&& source) + { + auto it = std::make_move_iterator(source.begin()); + auto end = std::make_move_iterator(source.end()); + for (; it != end; ++it) + { + iterator pos; + if (hint != members_.end() && hint->key() <= it->key()) + { + pos = std::lower_bound(hint,members_.end(), it->key(), + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + } + else + { + pos = std::lower_bound(members_.begin(),members_.end(), it->key(), + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + } + if (pos == members_.end() ) + { + members_.emplace_back(*it); + hint = members_.begin() + (members_.size() - 1); + } + else if (it->key() != pos->key()) + { + hint = members_.emplace(pos,*it); + } + } + } + + // merge_or_update + + void merge_or_update(const json_object& source) + { + for (auto it = source.begin(); it != source.end(); ++it) + { + insert_or_assign(it->key(),it->value()); + } + } + + void merge_or_update(json_object&& source) + { + auto it = std::make_move_iterator(source.begin()); + auto end = std::make_move_iterator(source.end()); + for (; it != end; ++it) + { + auto pos = std::lower_bound(members_.begin(),members_.end(), it->key(), + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + if (pos == members_.end() ) + { + members_.emplace_back(*it); + } + else + { + pos->value(it->value()); + } + } + } + + void merge_or_update(iterator hint, const json_object& source) + { + for (auto it = source.begin(); it != source.end(); ++it) + { + hint = insert_or_assign(hint, it->key(),it->value()); + } + } + + void merge_or_update(iterator hint, json_object&& source) + { + auto it = std::make_move_iterator(source.begin()); + auto end = std::make_move_iterator(source.end()); + for (; it != end; ++it) + { + iterator pos; + if (hint != members_.end() && hint->key() <= it->key()) + { + pos = std::lower_bound(hint,members_.end(), it->key(), + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + } + else + { + pos = std::lower_bound(members_.begin(),members_.end(), it->key(), + [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + } + if (pos == members_.end() ) + { + members_.emplace_back(*it); + hint = members_.begin() + (members_.size() - 1); + } + else + { + pos->value(it->value()); + hint = pos; + } + } + } + + bool operator==(const json_object& rhs) const + { + return members_ == rhs.members_; + } + + bool operator<(const json_object& rhs) const + { + return members_ < rhs.members_; + } +private: + json_object& operator=(const json_object&) = delete; +}; + +// Preserve order +template +class json_object::type> : + public container_base +{ +public: + typedef typename Json::allocator_type allocator_type; + typedef typename Json::char_type char_type; + typedef KeyT key_type; + typedef typename Json::string_view_type string_view_type; + typedef key_value key_value_type; +private: + typedef typename Json::implementation_policy implementation_policy; + typedef typename std::allocator_traits:: template rebind_alloc key_value_allocator_type; + using key_value_container_type = typename implementation_policy::template sequence_container_type; + typedef typename std::allocator_traits:: template rebind_alloc index_allocator_type; + using index_container_type = typename implementation_policy::template sequence_container_type; + + key_value_container_type members_; + index_container_type index_; +public: + typedef typename key_value_container_type::iterator iterator; + typedef typename key_value_container_type::const_iterator const_iterator; + + using container_base::get_allocator; + + json_object() + { + } + json_object(const allocator_type& allocator) + : container_base(allocator), + members_(key_value_allocator_type(allocator)), + index_(index_allocator_type(allocator)) + { + } + + json_object(const json_object& val) + : container_base(val.get_allocator()), + members_(val.members_), + index_(val.index_) + { + } + + json_object(json_object&& val) + : container_base(val.get_allocator()), + members_(std::move(val.members_)), + index_(std::move(val.index_)) + { + } + + json_object(const json_object& val, const allocator_type& allocator) + : container_base(allocator), + members_(val.members_,key_value_allocator_type(allocator)), + index_(val.index_,index_allocator_type(allocator)) + { + } + + json_object(json_object&& val,const allocator_type& allocator) + : container_base(allocator), + members_(std::move(val.members_),key_value_allocator_type(allocator)), + index_(std::move(val.index_),index_allocator_type(allocator)) + { + } + + template + json_object(InputIt first, InputIt last) + { + size_t count = std::distance(first,last); + members_.reserve(count); + for (auto s = first; s != last; ++s) + { + members_.emplace_back(get_key_value()(*s)); + } + + build_index(); + auto last_unique = std::unique(index_.begin(), index_.end(), + [&](size_t a, size_t b) { return !(members_.at(a).key().compare(members_.at(b).key())); }); + + if (last_unique != index_.end()) + { + index_.erase(last_unique, index_.end()); + std::sort(index_.begin(), index_.end()); + + auto result = index_.rbegin(); + if (*result != members_.size()) + { + members_.erase(members_.begin() + (*result + 1), members_.end()); + } + for (auto it = index_.rbegin() + 1; it != index_.rend(); ++it, ++result) + { + if (*result - *it > 1) + { + members_.erase(members_.begin() + (*it + 1), members_.begin() + *result); + } + } + } + build_index(); + } + + template + json_object(InputIt first, InputIt last, + const allocator_type& allocator) + : container_base(allocator), + members_(key_value_allocator_type(allocator)), + index_(index_allocator_type(allocator)) + { + size_t count = std::distance(first,last); + members_.reserve(count); + for (auto s = first; s != last; ++s) + { + members_.emplace_back(get_key_value()(*s)); + } + + build_index(); + auto last_unique = std::unique(index_.begin(), index_.end(), + [&](size_t a, size_t b) { return !(members_.at(a).key().compare(members_.at(b).key())); }); + + if (last_unique != index_.end()) + { + index_.erase(last_unique, index_.end()); + std::sort(index_.begin(), index_.end()); + + auto result = index_.rbegin(); + if (*result != members_.size()) + { + members_.erase(members_.begin() + (*result + 1), members_.end()); + } + for (auto it = index_.rbegin() + 1; it != index_.rend(); ++it, ++result) + { + if (*result - *it > 1) + { + members_.erase(members_.begin() + (*it + 1), members_.begin() + *result); + } + } + } + build_index(); + } + + json_object(std::initializer_list init) + { + for (const auto& element : init) + { + if (element.size() != 2 || !element[0].is_string()) + { + JSONCONS_THROW(json_runtime_error("Cannot create object from initializer list")); + break; + } + } + for (auto& element : init) + { + insert_or_assign(element[0].as_string_view(), std::move(element[1])); + } + } + + json_object(std::initializer_list init, + const allocator_type& allocator) + : container_base(allocator), + members_(key_value_allocator_type(allocator)), + index_(index_allocator_type(allocator)) + { + for (const auto& element : init) + { + if (element.size() != 2 || !element[0].is_string()) + { + JSONCONS_THROW(json_runtime_error("Cannot create object from initializer list")); + break; + } + } + for (auto& element : init) + { + insert_or_assign(element[0].as_string_view(), std::move(element[1])); + } + } + + void swap(json_object& val) + { + members_.swap(val.members_); + } + + iterator begin() + { + return members_.begin(); + } + + iterator end() + { + return members_.end(); + } + + const_iterator begin() const + { + return members_.begin(); + } + + const_iterator end() const + { + return members_.end(); + } + + size_t size() const {return members_.size();} + + size_t capacity() const {return members_.capacity();} + + void clear() + { + members_.clear(); + index_.clear(); + } + + void shrink_to_fit() + { + for (size_t i = 0; i < members_.size(); ++i) + { + members_[i].shrink_to_fit(); + } + members_.shrink_to_fit(); + index_.shrink_to_fit(); + } + + void reserve(size_t n) {members_.reserve(n);} + + Json& at(size_t i) + { + if (i >= members_.size()) + { + JSONCONS_THROW(json_runtime_error("Invalid array subscript")); + } + return members_[i].value(); + } + + const Json& at(size_t i) const + { + if (i >= members_.size()) + { + JSONCONS_THROW(json_runtime_error("Invalid array subscript")); + } + return members_[i].value(); + } + + iterator find(const string_view_type& name) + { + auto it = std::lower_bound(index_.begin(),index_.end(), name, + [&](size_t i, const string_view_type& k) -> bool {return string_view_type(members_.at(i).key()).compare(k) < 0;}); + if (it != index_.end() && members_.at(*it).key() == name) + { + return members_.begin() + *it; + } + else + { + return members_.end(); + } + } + + const_iterator find(const string_view_type& name) const + { + auto it = std::lower_bound(index_.begin(),index_.end(), name, + [&](size_t i, const string_view_type& k) -> bool {return string_view_type(members_.at(i).key()).compare(k) < 0;}); + if (it != index_.end() && members_.at(*it).key() == name) + { + return members_.begin() + *it; + } + else + { + return members_.end(); + } + } + + void erase(const_iterator first, const_iterator last) + { + size_t pos1 = first == members_.end() ? members_.size() : first - members_.begin(); + size_t pos2 = last == members_.end() ? members_.size() : last - members_.begin(); + + if (pos1 < members_.size() && pos2 <= members_.size()) + { + erase_index_entries(pos1,pos2); + +#if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it1 = members_.begin() + (first - members_.begin()); + iterator it2 = members_.begin() + (last - members_.begin()); + members_.erase(it1,it2); +#else + members_.erase(first,last); +#endif + } + } + + void erase(const string_view_type& name) + { + auto pos = find(name); + if (pos != members_.end()) + { + erase_index_entry(name); +#if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it = members_.begin() + (pos - members_.begin()); + members_.erase(it); +#else + members_.erase(pos); +#endif + } + } + + template + void insert(InputIt first, InputIt last, Convert convert) + { + size_t count = std::distance(first,last); + members_.reserve(members_.size() + count); + for (auto s = first; s != last; ++s) + { + members_.emplace_back(convert(*s)); + } + + build_index(); + auto last_unique = std::unique(index_.begin(), index_.end(), + [&](size_t a, size_t b) { return !(members_.at(a).key().compare(members_.at(b).key())); }); + + if (last_unique != index_.end()) + { + index_.erase(last_unique, index_.end()); + std::sort(index_.begin(), index_.end()); + + auto result = index_.rbegin(); + if (*result != members_.size()) + { + members_.erase(members_.begin() + (*result + 1), members_.end()); + } + for (auto it = index_.rbegin() + 1; it != index_.rend(); ++it, ++result) + { + if (*result - *it > 1) + { + members_.erase(members_.begin() + (*it + 1), members_.begin() + *result); + } + } + } + build_index(); + } + + template + void insert(sorted_unique_range_tag, InputIt first, InputIt last, Convert convert) + { + size_t count = std::distance(first,last); + + members_.reserve(members_.size() + count); + for (auto s = first; s != last; ++s) + { + members_.emplace_back(convert(*s)); + } + + build_index(); + } + + template + typename std::enable_if::value,std::pair>::type + insert_or_assign(const string_view_type& name, T&& value) + { + auto result = insert_index_entry(name,members_.size()); + if (result.second) + { + members_.emplace_back(key_type(name.begin(), name.end()), std::forward(value)); + auto it = members_.begin() + result.first; + return std::make_pair(it,true); + } + else + { + auto it = members_.begin() + result.first; + it->value(Json(std::forward(value))); + return std::make_pair(it,false); + } + } + + template + typename std::enable_if::value,std::pair>::type + insert_or_assign(const string_view_type& name, T&& value) + { + auto result = insert_index_entry(name,members_.size()); + if (result.second) + { + members_.emplace_back(key_type(name.begin(),name.end(),get_allocator()), + std::forward(value),get_allocator()); + auto it = members_.begin() + result.first; + return std::make_pair(it,true); + } + else + { + auto it = members_.begin() + result.first; + it->value(Json(std::forward(value),get_allocator())); + return std::make_pair(it,false); + } + } + + template + typename std::enable_if::value,iterator>::type + insert_or_assign(iterator hint, const string_view_type& key, T&& value) + { + if (hint == members_.end()) + { + auto result = insert_or_assign(key, std::forward(value)); + return result.first; + } + else + { + size_t pos = hint - members_.begin(); + auto result = insert_index_entry(key,pos); + + if (result.second) + { + auto it = members_.emplace(hint, key_type(key.begin(), key.end()), std::forward(value)); + return it; + } + else + { + auto it = members_.begin() + result.first; + it->value(Json(std::forward(value))); + return it; + } + } + } + + template + typename std::enable_if::value,iterator>::type + insert_or_assign(iterator hint, const string_view_type& key, T&& value) + { + if (hint == members_.end()) + { + auto result = insert_or_assign(key, std::forward(value)); + return result.first; + } + else + { + size_t pos = hint - members_.begin(); + auto result = insert_index_entry(key,pos); + + if (result.second) + { + auto it = members_.emplace(hint, + key_type(key.begin(),key.end(),get_allocator()), + std::forward(value),get_allocator()); + return it; + } + else + { + auto it = members_.begin() + result.first; + it->value(Json(std::forward(value),get_allocator())); + return it; + } + } + } + + // merge + + void merge(const json_object& source) + { + for (auto it = source.begin(); it != source.end(); ++it) + { + try_emplace(it->key(),it->value()); + } + } + + void merge(json_object&& source) + { + auto it = std::make_move_iterator(source.begin()); + auto end = std::make_move_iterator(source.end()); + for (; it != end; ++it) + { + auto pos = find(it->key()); + if (pos == members_.end() ) + { + try_emplace(it->key(),std::move(it->value())); + } + } + } + + void merge(iterator hint, const json_object& source) + { + size_t pos = hint - members_.begin(); + for (auto it = source.begin(); it != source.end(); ++it) + { + hint = try_emplace(hint, it->key(),it->value()); + size_t newpos = hint - members_.begin(); + if (newpos == pos) + { + ++hint; + pos = hint - members_.begin(); + } + else + { + hint = members_.begin() + pos; + } + } + } + + void merge(iterator hint, json_object&& source) + { + size_t pos = hint - members_.begin(); + + auto it = std::make_move_iterator(source.begin()); + auto end = std::make_move_iterator(source.end()); + for (; it != end; ++it) + { + hint = try_emplace(hint, it->key(), std::move(it->value())); + size_t newpos = hint - members_.begin(); + if (newpos == pos) + { + ++hint; + pos = hint - members_.begin(); + } + else + { + hint = members_.begin() + pos; + } + } + } + + // merge_or_update + + void merge_or_update(const json_object& source) + { + for (auto it = source.begin(); it != source.end(); ++it) + { + insert_or_assign(it->key(),it->value()); + } + } + + void merge_or_update(json_object&& source) + { + auto it = std::make_move_iterator(source.begin()); + auto end = std::make_move_iterator(source.end()); + for (; it != end; ++it) + { + auto pos = find(it->key()); + if (pos == members_.end() ) + { + insert_or_assign(it->key(),std::move(it->value())); + } + else + { + pos->value(std::move(it->value())); + } + } + } + + void merge_or_update(iterator hint, const json_object& source) + { + size_t pos = hint - members_.begin(); + for (auto it = source.begin(); it != source.end(); ++it) + { + hint = insert_or_assign(hint, it->key(),it->value()); + size_t newpos = hint - members_.begin(); + if (newpos == pos) + { + ++hint; + pos = hint - members_.begin(); + } + else + { + hint = members_.begin() + pos; + } + } + } + + void merge_or_update(iterator hint, json_object&& source) + { +/* + auto it = std::make_move_iterator(source.begin()); + auto end = std::make_move_iterator(source.end()); + for (; it != end; ++it) + { + auto pos = find(it->key()); + if (pos == members_.end() ) + { + hint = try_emplace(hint,it->key(),std::move(it->value())); + } + else + { + pos->value(std::move(it->value())); + hint = pos; + } + } +*/ + size_t pos = hint - members_.begin(); + auto it = std::make_move_iterator(source.begin()); + auto end = std::make_move_iterator(source.end()); + for (; it != end; ++it) + { + hint = insert_or_assign(hint, it->key(),std::move(it->value())); + size_t newpos = hint - members_.begin(); + if (newpos == pos) + { + ++hint; + pos = hint - members_.begin(); + } + else + { + hint = members_.begin() + pos; + } + } + } + + // try_emplace + + template + typename std::enable_if::value,std::pair>::type + try_emplace(const string_view_type& name, Args&&... args) + { + auto result = insert_index_entry(name,members_.size()); + if (result.second) + { + members_.emplace_back(key_type(name.begin(), name.end()), std::forward(args)...); + auto it = members_.begin() + result.first; + return std::make_pair(it,true); + } + else + { + auto it = members_.begin() + result.first; + return std::make_pair(it,false); + } + } + + template + typename std::enable_if::value,std::pair>::type + try_emplace(const string_view_type& key, Args&&... args) + { + auto result = insert_index_entry(key,members_.size()); + if (result.second) + { + members_.emplace_back(key_type(key.begin(),key.end(), get_allocator()), + std::forward(args)...); + auto it = members_.begin() + result.first; + return std::make_pair(it,true); + } + else + { + auto it = members_.begin() + result.first; + return std::make_pair(it,false); + } + } + + template + typename std::enable_if::value,iterator>::type + try_emplace(iterator hint, const string_view_type& key, Args&&... args) + { + if (hint == members_.end()) + { + auto result = try_emplace(key, std::forward(args)...); + return result.first; + } + else + { + size_t pos = hint - members_.begin(); + auto result = insert_index_entry(key, pos); + + if (result.second) + { + auto it = members_.emplace(hint, key_type(key.begin(), key.end()), std::forward(args)...); + return it; + } + else + { + auto it = members_.begin() + result.first; + return it; + } + } + } + + template + typename std::enable_if::value,iterator>::type + try_emplace(iterator hint, const string_view_type& key, Args&&... args) + { + if (hint == members_.end()) + { + auto result = try_emplace(key, std::forward(args)...); + return result.first; + } + else + { + size_t pos = hint - members_.begin(); + auto result = insert_index_entry(key, pos); + + if (result.second) + { + auto it = members_.emplace(hint, + key_type(key.begin(),key.end(), get_allocator()), + std::forward(args)...); + return it; + } + else + { + auto it = members_.begin() + result.first; + return it; + } + } + } + + bool operator==(const json_object& rhs) const + { + return members_ == rhs.members_; + } + + bool operator<(const json_object& rhs) const + { + return members_ < rhs.members_; + } +private: + + std::pair insert_index_entry(const string_view_type& key, size_t pos) + { + JSONCONS_ASSERT(pos <= index_.size()); + + auto it = std::lower_bound(index_.begin(),index_.end(), key, + [&](size_t i, const string_view_type& k) -> bool {return string_view_type(members_.at(i).key()).compare(k) < 0;}); + + if (it == index_.end()) + { + size_t count = index_.size() - pos; + for (size_t i = 0; count > 0 && i < index_.size(); ++i) + { + if (index_[i] >= pos) + { + ++index_[i]; + --count; + } + } + index_.push_back(pos); + return std::make_pair(pos,true); + } + else if (members_.at(*it).key() != key) + { + size_t count = index_.size() - pos; + for (size_t i = 0; count > 0 && i < index_.size(); ++i) + { + if (index_[i] >= pos) + { + ++index_[i]; + --count; + } + } + auto it2 = index_.insert(it, pos); + return std::make_pair(*it2,true); + } + else + { + return std::make_pair(*it,false); + } + } + + void erase_index_entry(const string_view_type& key) + { + auto it = std::lower_bound(index_.begin(),index_.end(), key, + [&](size_t i, const string_view_type& k) -> bool {return string_view_type(members_.at(i).key()).compare(k) < 0;}); + + if (it != index_.end() && members_.at(*it).key() != key) + { + size_t pos = *it; + size_t count = index_.size() - pos; + for (size_t i = 0; i < index_.size() && count > 0; ++i) + { + if (index_[i] > pos) + { + --index_[i]; + --count; + } + } + index_.erase(it); + } + } + + void erase_index_entries(size_t pos1, size_t pos2) + { + for (size_t i = 0; i < index_.size(); ++i) + { + if (index_[i] >= pos1 && index_[i] < pos2) + { + index_.erase(index_.begin()+index_[i]); + } + else if (index_[i] > pos2) + { + --index_[i]; + } + } + } + + void build_index() + { + index_.clear(); + index_.reserve(members_.size()); + for (size_t i = 0; i < members_.size(); ++i) + { + index_.push_back(i); + } + std::stable_sort(index_.begin(),index_.end(), + [&](size_t a, size_t b) -> bool {return members_.at(a).key().compare(members_.at(b).key()) < 0;}); + } + + json_object& operator=(const json_object&) = delete; +}; + +} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_content_handler.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_content_handler.hpp index 98bcfa0..80b21cb 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_content_handler.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_content_handler.hpp @@ -9,368 +9,483 @@ #include #include -#include -#include +#include +#include +#include + +namespace jsoncons { + +// null_type + +struct null_type +{ +}; + +enum class semantic_tag : uint8_t +{ + none = 0, + undefined = 0x01, + datetime = 0x02, + timestamp = 0x03, + bigint = 0x04, + bigdec = 0x05, + bigfloat = 0x06, + base16 = 0x07, + base64 = 0x08, + base64url = 0x09, + uri = 0x0a #if !defined(JSONCONS_NO_DEPRECATED) -#include // for null_type + , big_integer = bigint + , big_decimal = bigdec + , big_float = bigfloat + , date_time = datetime #endif +}; -namespace jsoncons { +inline +std::ostream& operator<<(std::ostream& os, semantic_tag tag) +{ + switch (tag) + { + case semantic_tag::none: + { + os << "n/a"; + break; + } + case semantic_tag::undefined: + { + os << "undefined"; + break; + } + case semantic_tag::datetime: + { + os << "datetime"; + break; + } + case semantic_tag::timestamp: + { + os << "timestamp"; + break; + } + case semantic_tag::bigint: + { + os << "bigint"; + break; + } + case semantic_tag::bigdec: + { + os << "bigdec"; + break; + } + case semantic_tag::bigfloat: + { + os << "bigfloat"; + break; + } + case semantic_tag::base16: + { + os << "base16"; + break; + } + case semantic_tag::base64: + { + os << "base64"; + break; + } + case semantic_tag::base64url: + { + os << "base64url"; + break; + } + case semantic_tag::uri: + { + os << "uri"; + break; + } + } + return os; +} + +#if !defined(JSONCONS_NO_DEPRECATED) + JSONCONS_DEPRECATED("Instead, use semantic_tag") typedef semantic_tag semantic_tag_type; +#endif template class basic_json_content_handler { +#if !defined(JSONCONS_NO_DEPRECATED) + std::basic_string buffer_; +#endif public: typedef CharT char_type; typedef std::char_traits char_traits_type; - typedef basic_string_view_ext string_view_type; - - virtual ~basic_json_content_handler() {} - - void begin_json() - { - do_begin_json(); - } - - void end_json() - { - do_end_json(); - } - - void begin_object() - { - do_begin_object(null_serializing_context()); - } - - void begin_object(const serializing_context& context) - { - do_begin_object(context); - } - - void begin_object(size_t length) - { - do_begin_object(length, null_serializing_context()); - } - - void begin_object(size_t length, const serializing_context& context) - { - do_begin_object(length, context); - } - - void end_object() - { - do_end_object(null_serializing_context()); - } - - void end_object(const serializing_context& context) - { - do_end_object(context); - } + typedef basic_string_view string_view_type; - void begin_array() - { - do_begin_array(null_serializing_context()); - } + basic_json_content_handler(basic_json_content_handler&&) = default; - void begin_array(size_t length) - { - do_begin_array(length, null_serializing_context()); - } + basic_json_content_handler& operator=(basic_json_content_handler&&) = default; - void begin_array(const serializing_context& context) - { - do_begin_array(context); - } + basic_json_content_handler() = default; - void begin_array(size_t length, const serializing_context& context) - { - do_begin_array(length, context); - } + virtual ~basic_json_content_handler() {} - void end_array() + void flush() { - do_end_array(null_serializing_context()); + do_flush(); } - void end_array(const serializing_context& context) + bool begin_object(semantic_tag tag=semantic_tag::none, + const ser_context& context=null_ser_context()) { - do_end_array(context); + return do_begin_object(tag, context); } - void name(const string_view_type& name) + bool begin_object(size_t length, + semantic_tag tag=semantic_tag::none, + const ser_context& context = null_ser_context()) { - do_name(name, null_serializing_context()); + return do_begin_object(length, tag, context); } - void name(const string_view_type& name, const serializing_context& context) + bool end_object(const ser_context& context = null_ser_context()) { - do_name(name, context); + return do_end_object(context); } - void string_value(const string_view_type& value) + bool begin_array(semantic_tag tag=semantic_tag::none, + const ser_context& context=null_ser_context()) { - do_string_value(value, null_serializing_context()); + return do_begin_array(tag, context); } - void string_value(const string_view_type& value, const serializing_context& context) + bool begin_array(size_t length, + semantic_tag tag=semantic_tag::none, + const ser_context& context=null_ser_context()) { - do_string_value(value, context); + return do_begin_array(length, tag, context); } - void byte_string_value(const uint8_t* data, size_t length) + bool end_array(const ser_context& context=null_ser_context()) { - do_byte_string_value(data, length, null_serializing_context()); + return do_end_array(context); } - void byte_string_value(const uint8_t* data, size_t length, const serializing_context& context) + bool name(const string_view_type& name, const ser_context& context=null_ser_context()) { - do_byte_string_value(data, length, context); + return do_name(name, context); } - void integer_value(int64_t value) + bool string_value(const string_view_type& value, + semantic_tag tag = semantic_tag::none, + const ser_context& context=null_ser_context()) { - do_integer_value(value,null_serializing_context()); + return do_string_value(value, tag, context); } - void integer_value(int64_t value, const serializing_context& context) + bool byte_string_value(const byte_string_view& b, + semantic_tag tag=semantic_tag::none, + const ser_context& context=null_ser_context()) { - do_integer_value(value,context); + return do_byte_string_value(b, tag, context); } - void uinteger_value(uint64_t value) + bool byte_string_value(const uint8_t* p, size_t size, + semantic_tag tag=semantic_tag::none, + const ser_context& context=null_ser_context()) { - do_uinteger_value(value,null_serializing_context()); + return do_byte_string_value(byte_string(p, size), tag, context); } - void uinteger_value(uint64_t value, const serializing_context& context) + bool int64_value(int64_t value, + semantic_tag tag = semantic_tag::none, + const ser_context& context=null_ser_context()) { - do_uinteger_value(value,context); + return do_int64_value(value, tag, context); } - void double_value(double value) + bool uint64_value(uint64_t value, + semantic_tag tag = semantic_tag::none, + const ser_context& context=null_ser_context()) { - do_double_value(value, number_format(), null_serializing_context()); + return do_uint64_value(value, tag, context); } - void double_value(double value, uint8_t precision) + bool double_value(double value, + semantic_tag tag = semantic_tag::none, + const ser_context& context=null_ser_context()) { - do_double_value(value, number_format(precision, 0), null_serializing_context()); + return do_double_value(value, tag, context); } - void double_value(double value, const number_format& fmt) + bool bool_value(bool value, + semantic_tag tag = semantic_tag::none, + const ser_context& context=null_ser_context()) { - do_double_value(value, fmt, null_serializing_context()); + return do_bool_value(value, tag, context); } - void double_value(double value, const serializing_context& context) + bool null_value(semantic_tag tag = semantic_tag::none, + const ser_context& context=null_ser_context()) { - do_double_value(value, number_format(), context); + return do_null_value(tag, context); } - void double_value(double value, uint8_t precision, const serializing_context& context) - { - do_double_value(value, number_format(precision, 0), context); - } +#if !defined(JSONCONS_NO_DEPRECATED) - void double_value(double value, const number_format& fmt, const serializing_context& context) + JSONCONS_DEPRECATED("Instead, use const byte_string_view&, semantic_tag=semantic_tag::none, const ser_context&=null_ser_context()") + bool byte_string_value(const byte_string_view& b, + byte_string_chars_format encoding_hint, + semantic_tag tag=semantic_tag::none, + const ser_context& context=null_ser_context()) { - do_double_value(value, fmt, context); + switch (encoding_hint) + { + case byte_string_chars_format::base16: + tag = semantic_tag::base16; + break; + case byte_string_chars_format::base64: + tag = semantic_tag::base64; + break; + case byte_string_chars_format::base64url: + tag = semantic_tag::base64url; + break; + default: + break; + } + return do_byte_string_value(b, tag, context); } - void bool_value(bool value) + JSONCONS_DEPRECATED("Instead, use const byte_string_view&, semantic_tag=semantic_tag::none, const ser_context&=null_ser_context()") + bool byte_string_value(const uint8_t* p, size_t size, + byte_string_chars_format encoding_hint, + semantic_tag tag=semantic_tag::none, + const ser_context& context=null_ser_context()) { - do_bool_value(value,null_serializing_context()); + switch (encoding_hint) + { + case byte_string_chars_format::base16: + tag = semantic_tag::base16; + break; + case byte_string_chars_format::base64: + tag = semantic_tag::base64; + break; + case byte_string_chars_format::base64url: + tag = semantic_tag::base64url; + break; + default: + break; + } + return do_byte_string_value(byte_string(p, size), tag, context); } - - void bool_value(bool value, const serializing_context& context) + bool big_integer_value(const string_view_type& s, const ser_context& context=null_ser_context()) { - do_bool_value(value,context); + return do_string_value(s, semantic_tag::bigint, context); } - void null_value() + bool big_decimal_value(const string_view_type& s, const ser_context& context=null_ser_context()) { - do_null_value(null_serializing_context()); + return do_string_value(s, semantic_tag::bigdec, context); } - void null_value(const serializing_context& context) + bool date_time_value(const string_view_type& s, const ser_context& context=null_ser_context()) { - do_null_value(context); + return do_string_value(s, semantic_tag::datetime, context); } -#if !defined(JSONCONS_NO_DEPRECATED) - - void name(const CharT* p, size_t length, const serializing_context& context) + bool timestamp_value(int64_t val, const ser_context& context=null_ser_context()) { - do_name(string_view_type(p, length), context); + return do_int64_value(val, semantic_tag::timestamp, context); } - void value(const std::basic_string& value, const serializing_context& context) + JSONCONS_DEPRECATED("Not needed") + bool begin_document() { - do_string_value(value, context); + return true; } - void value(const CharT* p, size_t length, const serializing_context& context) + JSONCONS_DEPRECATED("Instead, use flush() when serializing") + bool end_document() { - do_string_value(string_view_type(p, length), context); + flush(); + return true; } - void value(const CharT* p, const serializing_context& context) + JSONCONS_DEPRECATED("Not needed") + void begin_json() { - do_string_value(string_view_type(p), context); } - void value(int value, const serializing_context& context) + JSONCONS_DEPRECATED("Instead, use flush() when serializing") + void end_json() { - do_integer_value(value,context); + end_document(); } - void value(long value, const serializing_context& context) + void name(const CharT* p, size_t length, const ser_context& context) { - do_integer_value(value,context); + name(string_view_type(p, length), context); } - void value(long long value, const serializing_context& context) + void integer_value(int64_t value) { - do_integer_value(value,context); + int64_value(value); } - void value(unsigned int value, const serializing_context& context) + void integer_value(int64_t value, const ser_context& context) { - do_uinteger_value(value,context); + int64_value(value,context); } - void value(unsigned long value, const serializing_context& context) + void uinteger_value(uint64_t value) { - do_uinteger_value(value,context); + uint64_value(value); } - void value(unsigned long long value, const serializing_context& context) + void uinteger_value(uint64_t value, const ser_context& context) { - do_uinteger_value(value,context); + uint64_value(value,context); } - void value(float value, uint8_t precision, const serializing_context& context) + bool bignum_value(const string_view_type& s, const ser_context& context=null_ser_context()) { - do_double_value(value, number_format(precision, 0), context); + return do_string_value(s, semantic_tag::bigint, context); } - void value(double value, uint8_t precision, const serializing_context& context) + bool decimal_value(const string_view_type& s, const ser_context& context=null_ser_context()) { - do_double_value(value, number_format(precision, 0), context); + return do_string_value(s, semantic_tag::bigdec, context); } - void value(bool value, const serializing_context& context) + bool epoch_time_value(int64_t val, const ser_context& context=null_ser_context()) { - do_bool_value(value,context); + return do_int64_value(val, semantic_tag::timestamp, context); } - void value(null_type, const serializing_context& context) - { - do_null_value(context); - } #endif private: - virtual void do_begin_json() = 0; + virtual void do_flush() = 0; - virtual void do_end_json() = 0; + virtual bool do_begin_object(semantic_tag, const ser_context& context) = 0; - virtual void do_begin_object(const serializing_context& context) = 0; - - virtual void do_begin_object(size_t length, const serializing_context& context) + virtual bool do_begin_object(size_t, semantic_tag tag, const ser_context& context) { - do_begin_object(context); + return do_begin_object(tag, context); } - virtual void do_end_object(const serializing_context& context) = 0; + virtual bool do_end_object(const ser_context& context) = 0; - virtual void do_begin_array(const serializing_context& context) = 0; + virtual bool do_begin_array(semantic_tag, const ser_context& context) = 0; - virtual void do_begin_array(size_t length, const serializing_context& context) + virtual bool do_begin_array(size_t, semantic_tag tag, const ser_context& context) { - do_begin_array(context); + return do_begin_array(tag, context); } - virtual void do_end_array(const serializing_context& context) = 0; + virtual bool do_end_array(const ser_context& context) = 0; - virtual void do_name(const string_view_type& name, const serializing_context& context) = 0; + virtual bool do_name(const string_view_type& name, const ser_context& context) = 0; - virtual void do_null_value(const serializing_context& context) = 0; + virtual bool do_null_value(semantic_tag, const ser_context& context) = 0; - virtual void do_string_value(const string_view_type& value, const serializing_context& context) = 0; + virtual bool do_string_value(const string_view_type& value, semantic_tag tag, const ser_context& context) = 0; - virtual void do_byte_string_value(const uint8_t* data, size_t length, const serializing_context& context) = 0; + virtual bool do_byte_string_value(const byte_string_view& b, + semantic_tag tag, + const ser_context& context) = 0; - virtual void do_double_value(double value, const number_format& fmt, const serializing_context& context) = 0; + virtual bool do_double_value(double value, + semantic_tag tag, + const ser_context& context) = 0; - virtual void do_integer_value(int64_t value, const serializing_context& context) = 0; + virtual bool do_int64_value(int64_t value, + semantic_tag tag, + const ser_context& context) = 0; - virtual void do_uinteger_value(uint64_t value, const serializing_context& context) = 0; + virtual bool do_uint64_value(uint64_t value, + semantic_tag tag, + const ser_context& context) = 0; - virtual void do_bool_value(bool value, const serializing_context& context) = 0; + virtual bool do_bool_value(bool value, semantic_tag tag, const ser_context& context) = 0; }; template class basic_null_json_content_handler final : public basic_json_content_handler { public: - using typename basic_json_content_handler::string_view_type ; + using typename basic_json_content_handler::string_view_type; private: - void do_begin_json() override - { - } - - void do_end_json() override + void do_flush() override { } - void do_begin_object(const serializing_context&) override + bool do_begin_object(semantic_tag, const ser_context&) override { + return true; } - void do_end_object(const serializing_context&) override + bool do_end_object(const ser_context&) override { + return true; } - void do_begin_array(const serializing_context&) override + bool do_begin_array(semantic_tag, const ser_context&) override { + return true; } - void do_end_array(const serializing_context&) override + bool do_end_array(const ser_context&) override { + return true; } - void do_name(const string_view_type&, const serializing_context&) override + bool do_name(const string_view_type&, const ser_context&) override { + return true; } - void do_null_value(const serializing_context&) override + bool do_null_value(semantic_tag, const ser_context&) override { + return true; } - void do_string_value(const string_view_type&, const serializing_context&) override + bool do_string_value(const string_view_type&, semantic_tag, const ser_context&) override { + return true; } - void do_byte_string_value(const uint8_t* data, size_t length, const serializing_context&) override + bool do_byte_string_value(const byte_string_view&, + semantic_tag, + const ser_context&) override { + return true; } - void do_double_value(double, const number_format& fmt, const serializing_context&) override + bool do_int64_value(int64_t, + semantic_tag, + const ser_context&) override { + return true; } - void do_integer_value(int64_t, const serializing_context&) override + bool do_uint64_value(uint64_t, + semantic_tag, + const ser_context&) override { + return true; } - void do_uinteger_value(uint64_t, const serializing_context&) override + bool do_double_value(double, + semantic_tag, + const ser_context&) override { + return true; } - void do_bool_value(bool, const serializing_context&) override + bool do_bool_value(bool, semantic_tag, const ser_context&) override { + return true; } }; diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_conversion_traits.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_conversion_traits.hpp new file mode 100644 index 0000000..c87fd88 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_conversion_traits.hpp @@ -0,0 +1,197 @@ +// Copyright 2017 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_JSON_CONVERSION_TRAITS_HPP +#define JSONCONS_JSON_CONVERSION_TRAITS_HPP + +#include +#include +#include +#include +#include // std::enable_if +#include +#include +#include +#include +#include +#include +#include + +namespace jsoncons { + +template +T read_from(const Json& j, basic_staj_reader& reader, std::error_code& ec); + +template +T read_from(const Json& j, basic_staj_reader& reader) +{ + std::error_code ec; + T val = read_from(j, reader, ec); + if (ec) + { + throw ser_error(ec, reader.context().line(), reader.context().column()); + } + return val; +} + +template +void write_to(const T&val, basic_json_content_handler& receiver); + +} // namespace jsoncons + +#include + +namespace jsoncons { + +template +struct json_conversion_traits +{ + template + static T decode(basic_staj_reader& reader, std::error_code& ec) + { + json_decoder decoder; + reader.read_to(decoder, ec); + return decoder.get_result().template as(); + } + + template + static void encode(const T& val, basic_json_content_handler& receiver) + { + auto j = json_type_traits::to_json(val); + j.dump(receiver); + } +}; + +// specializations + +// vector like + +template +struct json_conversion_traits::value && jsoncons::detail::is_vector_like::value +>::type> +{ + typedef typename T::value_type value_type; + + template + static T decode(basic_staj_reader& reader, std::error_code& ec) + { + T v; + basic_staj_array_iterator end; + basic_staj_array_iterator it(reader, ec); + + while (it != end && !ec) + { + v.push_back(*it); + it.increment(ec); + } + return v; + } + + template + static void encode(const T& val, basic_json_content_handler& receiver) + { + receiver.begin_array(); + for (auto it = std::begin(val); it != std::end(val); ++it) + { + json_conversion_traits::template encode(*it,receiver); + } + receiver.end_array(); + receiver.flush(); + } +}; +// std::array + +template +struct json_conversion_traits> +{ + typedef typename std::array::value_type value_type; + + template + static std::array decode(basic_staj_reader& reader, std::error_code& ec) + { + std::array v; + v.fill(T{}); + basic_staj_array_iterator end; + basic_staj_array_iterator it(reader, ec); + + for (size_t i = 0; it != end && i < N && !ec; ++i) + { + v[i] = *it; + it.increment(ec); + } + return v; + } + + template + static void encode(const std::array& val, basic_json_content_handler& receiver) + { + receiver.begin_array(); + for (auto it = std::begin(val); it != std::end(val); ++it) + { + json_conversion_traits::template encode(*it,receiver); + } + receiver.end_array(); + receiver.flush(); + } +}; + +// map like + +template +struct json_conversion_traits::value && jsoncons::detail::is_map_like::value +>::type> +{ + typedef typename T::mapped_type mapped_type; + typedef typename T::value_type value_type; + typedef typename T::key_type key_type; + + template + static T decode(basic_staj_reader& reader, std::error_code& ec) + { + T m; + basic_staj_object_iterator end; + basic_staj_object_iterator it(reader, ec); + + while (it != end && !ec) + { + m.emplace(it->first,it->second); + it.increment(ec); + } + return m; + } + + template + static void encode(const T& val, basic_json_content_handler& receiver) + { + receiver.begin_object(); + for (auto it = std::begin(val); it != std::end(val); ++it) + { + receiver.name(it->first); + json_conversion_traits::template encode(it->second,receiver); + } + receiver.end_object(); + receiver.flush(); + } +}; + +template +T read_from(const Json&, basic_staj_reader& reader, std::error_code& ec) +{ + return json_conversion_traits::template decode(reader,ec); +} + +template +void write_to(const Json&, const T&val, basic_json_content_handler& receiver) +{ + json_conversion_traits::template encode(val, receiver); +} + +} + +#endif + diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_convert_traits.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_convert_traits.hpp deleted file mode 100644 index b9cec88..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_convert_traits.hpp +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright 2017 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_JSONCONVERTTRAITS_HPP -#define JSONCONS_JSONCONVERTTRAITS_HPP - -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wswitch" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace jsoncons { - -// json_convert_traits - -template -struct json_convert_traits -{ - template - static T decode(std::basic_istringstream& is, - const basic_json_serializing_options& options) - { - basic_json j = basic_json::parse(is, options); - return j. template as(); - } - - template - static void encode(const T& val, basic_json_content_handler& serializer) - { - auto j = json_type_traits, T>::to_json(val); - j.dump(serializer); - } -}; - -// json_convert_traits specializations - -// vector like - -template -struct json_convert_traits::value ->::type> -{ - typedef typename std::iterator_traits::value_type value_type; - - template - static T decode(std::basic_istringstream& is, - const basic_json_serializing_options& options) - { - basic_json j = basic_json::parse(is, options); - return j. template as(); - } - - template - static void encode(const T& val, basic_json_content_handler& serializer) - { - serializer.begin_json(); - serializer.begin_array(); - for (auto it = std::begin(val); it != std::end(val); ++it) - { - json_convert_traits::encode(*it,serializer); - } - serializer.end_array(); - serializer.end_json(); - } -}; - -// std::array - -template -struct json_convert_traits> -{ - typedef typename std::array::value_type value_type; - - template - static std::array decode(std::basic_istringstream& is, - const basic_json_serializing_options& options) - { - basic_json j = basic_json::parse(is,options); - return j. template as>(); - } - - template - static void encode(const std::array& val, std::basic_string& s) - { - basic_json_serializer> serializer(s); - encode(val,serializer); - } - - template - static void encode(const std::array& val, basic_json_content_handler& serializer) - { - serializer.begin_json(); - serializer.begin_array(); - for (auto it = std::begin(val); it != std::end(val); ++it) - { - json_convert_traits::encode(*it,serializer); - } - serializer.end_array(); - serializer.end_json(); - } -}; - -// map like - -template -struct json_convert_traits::value ->::type> -{ - typedef typename T::mapped_type mapped_type; - typedef typename T::value_type value_type; - - template - static T decode(std::basic_istringstream& is, - const basic_json_serializing_options& options) - { - basic_json j = basic_json::parse(is, options); - return j. template as(); - } - - template - static void encode(const T& val, basic_json_content_handler& serializer) - { - serializer.begin_json(); - serializer.begin_object(); - for (auto it = std::begin(val); it != std::end(val); ++it) - { - serializer.name(it->first); - json_convert_traits::encode(it->second,serializer); - } - serializer.end_object(); - serializer.end_json(); - } -}; - -// std::tuple - -namespace detail { namespace streaming { - -template -struct tuple_helper -{ - using element_type = typename std::tuple_element::value - Pos, Tuple>::type; - using next = tuple_helper; - - template - static void encode(const Tuple& tuple, basic_json_content_handler& handler) - { - json_convert_traits::encode(std::get::value - Pos>(tuple),handler); - next::encode(tuple, handler); - } -}; - -template -struct tuple_helper<0, Tuple> -{ - template - static void encode(const Tuple&, basic_json_content_handler&) - { - } -}; - -}} - -template -struct json_convert_traits> -{ -private: - using helper = detail::streaming::tuple_helper>; -public: - - template - static std::tuple decode(std::basic_istringstream& is, - const basic_json_serializing_options& options) - { - basic_json j = basic_json::parse(is, options); - return j. template as>(); - } - - template - static void encode(const std::tuple& val, basic_json_content_handler& serializer) - { - serializer.begin_array(); - helper::encode(val, serializer); - serializer.end_array(); - } -}; - -// decode_json - -template -T decode_json(const std::basic_string& s) -{ - std::basic_istringstream is(s); - return json_convert_traits::decode(is, basic_json_serializing_options()); -} - -template -T decode_json(const std::basic_string& s, - const basic_json_serializing_options& options) -{ - std::basic_istringstream is(s); - return json_convert_traits::decode(is, options); -} - -template -T decode_json(std::basic_istringstream& is) -{ - return json_convert_traits::decode(is, basic_json_serializing_options()); -} - -template -T decode_json(std::basic_istringstream& is, - const basic_json_serializing_options& options) -{ - return json_convert_traits::decode(is, options); -} - -// encode_json - -template -void encode_json(const T& val, basic_json_content_handler& handler) -{ - handler.begin_json(); - json_convert_traits::encode(val,handler); - handler.end_json(); -} - -template -void encode_fragment(const T& val, basic_json_content_handler& handler) -{ - json_convert_traits::encode(val,handler); -} - -template -void encode_json(const T& val, std::basic_ostream& os) -{ - basic_json_serializer serializer(os); - encode_json(val, serializer); -} - -template -void encode_json(const T& val, const basic_json_serializing_options& options, - std::basic_ostream& os) -{ - basic_json_serializer serializer(os, options); - encode_json(val, serializer); -} - -template -void encode_json(const T& val, std::basic_ostream& os, indenting line_indent) -{ - basic_json_serializer serializer(os, line_indent); - encode_json(val, serializer); -} - -template -void encode_json(const T& val, const basic_json_serializing_options& options, - std::basic_ostream& os, indenting line_indent) -{ - basic_json_serializer serializer(os, options, line_indent); - encode_json(val, serializer); -} - -template -void encode_json(const T& val, std::basic_string& s) -{ - basic_json_serializer> serializer(s); - encode_json(val, serializer); -} - -template -void encode_json(const T& val, const basic_json_serializing_options& options, - std::basic_string& s) -{ - basic_json_serializer> serializer(s, options); - encode_json(val, serializer); -} - -template -void encode_json(const T& val, std::basic_string& s, indenting line_indent) -{ - basic_json_serializer> serializer(s, line_indent); - encode_json(val, serializer); -} - -template -void encode_json(const T& val, const basic_json_serializing_options& options, - std::basic_string>& s, indenting line_indent) -{ - basic_json_serializer serializer(s, options, line_indent); - encode_json(val, serializer); -} - -} -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - -#endif - diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_cursor.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_cursor.hpp new file mode 100644 index 0000000..98206f0 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_cursor.hpp @@ -0,0 +1,431 @@ +// 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_JSON_CURSOR_HPP +#define JSONCONS_JSON_CURSOR_HPP + +#include // std::allocator +#include +#include +#include +#include +#include +#include // std::basic_istream +#include +#include +#include +#include +#include +#include +#include + +namespace jsoncons { + +template,class Allocator=std::allocator> +class basic_json_cursor : public basic_staj_reader, private virtual ser_context +{ +public: + typedef Src source_type; + typedef CharT char_type; + typedef Allocator allocator_type; +private: + static const size_t default_max_buffer_length = 16384; + + basic_staj_event_handler event_handler_; + + typedef typename std::allocator_traits:: template rebind_alloc char_allocator_type; + + basic_json_parser parser_; + source_type source_; + std::vector buffer_; + size_t buffer_length_; + bool eof_; + bool begin_; + + // Noncopyable and nonmoveable + basic_json_cursor(const basic_json_cursor&) = delete; + basic_json_cursor& operator=(const basic_json_cursor&) = delete; + +public: + typedef basic_string_view string_view_type; + + // Constructors that throw parse exceptions + + template + basic_json_cursor(Source&& source, + const basic_json_decode_options& options = basic_json_options::get_default_options(), + std::function err_handler = default_json_parsing()) + : basic_json_cursor(std::forward(source), + accept, + options, + err_handler) + { + } + + template + basic_json_cursor(Source&& source, + std::function&, const ser_context&)> filter, + const basic_json_decode_options& options = basic_json_options::get_default_options(), + std::function err_handler = default_json_parsing(), + typename std::enable_if,Source>::value>::type* = 0) + : event_handler_(filter), + parser_(options,err_handler), + source_(source), + buffer_length_(default_max_buffer_length), + eof_(false), + begin_(true) + { + buffer_.reserve(buffer_length_); + if (!done()) + { + next(); + } + } + + template + basic_json_cursor(Source&& source, + std::function&, const ser_context&)> filter, + const basic_json_decode_options& options = basic_json_options::get_default_options(), + std::function err_handler = default_json_parsing(), + typename std::enable_if,Source>::value>::type* = 0) + : event_handler_(filter), + parser_(options,err_handler), + buffer_length_(0), + eof_(false), + begin_(false) + { + basic_string_view sv(std::forward(source)); + auto result = unicons::skip_bom(sv.begin(), sv.end()); + if (result.ec != unicons::encoding_errc()) + { + throw ser_error(result.ec,parser_.line(),parser_.column()); + } + size_t offset = result.it - sv.begin(); + parser_.update(sv.data()+offset,sv.size()-offset); + if (!done()) + { + next(); + } + } + + + // Constructors that set parse error codes + template + basic_json_cursor(Source&& source, + std::error_code& ec) + : basic_json_cursor(std::forward(source), + accept, + basic_json_options::get_default_options(), + default_json_parsing(), + ec) + { + } + + template + basic_json_cursor(Source&& source, + const basic_json_decode_options& options, + std::error_code& ec) + : basic_json_cursor(std::forward(source), + accept, + options, + default_json_parsing(), + ec) + { + } + + template + basic_json_cursor(Source&& source, + std::function&, const ser_context&)> filter, + std::error_code& ec) + : basic_json_cursor(std::forward(source), + filter, + basic_json_options::get_default_options(), + default_json_parsing(), + ec) + { + } + + template + basic_json_cursor(Source&& source, + std::function&, const ser_context&)> filter, + const basic_json_decode_options& options, + std::error_code& ec) + : basic_json_cursor(std::forward(source), + filter, + options, + default_json_parsing(), + ec) + { + } + + template + basic_json_cursor(Source&& source, + std::function&, const ser_context&)> filter, + const basic_json_decode_options& options, + std::function err_handler, + std::error_code& ec, + typename std::enable_if,Source>::value>::type* = 0) + : event_handler_(filter), + parser_(options,err_handler), + source_(source), + eof_(false), + buffer_length_(default_max_buffer_length), + begin_(true) + { + buffer_.reserve(buffer_length_); + if (!done()) + { + next(ec); + } + } + + template + basic_json_cursor(Source&& source, + std::function&, const ser_context&)> filter, + const basic_json_decode_options& options, + std::function err_handler, + std::error_code& ec, + typename std::enable_if,Source>::value>::type* = 0) + : event_handler_(filter), + parser_(options,err_handler), + eof_(false), + buffer_length_(0), + begin_(false) + { + basic_string_view sv(std::forward(source)); + auto result = unicons::skip_bom(sv.begin(), sv.end()); + if (result.ec != unicons::encoding_errc()) + { + ec = result.ec; + return; + } + size_t offset = result.it - sv.begin(); + parser_.update(sv.data()+offset,sv.size()-offset); + if (!done()) + { + next(ec); + } + } + + size_t buffer_length() const + { + return buffer_length_; + } + + void buffer_length(size_t length) + { + buffer_length_ = length; + buffer_.reserve(buffer_length_); + } + + bool done() const override + { + return parser_.done(); + } + + const basic_staj_event& current() const override + { + return event_handler_.event(); + } + + void read_to(basic_json_content_handler& handler) override + { + std::error_code ec; + read_to(handler, ec); + if (ec) + { + throw ser_error(ec,parser_.line(),parser_.column()); + } + } + + void read_to(basic_json_content_handler& handler, + std::error_code& ec) override + { + if (!staj_to_saj_event(event_handler_.event(), handler, *this)) + { + return; + } + read_next(handler, ec); + } + + void next() override + { + std::error_code ec; + next(ec); + if (ec) + { + throw ser_error(ec,parser_.line(),parser_.column()); + } + } + + void next(std::error_code& ec) override + { + read_next(ec); + } + + static bool accept(const basic_staj_event&, const ser_context&) + { + return true; + } + + void read_buffer(std::error_code& ec) + { + buffer_.clear(); + buffer_.resize(buffer_length_); + size_t count = source_.read(buffer_.data(), buffer_length_); + buffer_.resize(static_cast(count)); + if (buffer_.size() == 0) + { + eof_ = true; + } + else if (begin_) + { + auto result = unicons::skip_bom(buffer_.begin(), buffer_.end()); + if (result.ec != unicons::encoding_errc()) + { + ec = result.ec; + return; + } + size_t offset = result.it - buffer_.begin(); + parser_.update(buffer_.data()+offset,buffer_.size()-offset); + begin_ = false; + } + else + { + parser_.update(buffer_.data(),buffer_.size()); + } + } + + void read_next(std::error_code& ec) + { + read_next(event_handler_, ec); + } + + void read_next(basic_json_content_handler& handler, std::error_code& ec) + { + parser_.restart(); + while (!parser_.stopped()) + { + if (parser_.source_exhausted()) + { + if (!source_.eof()) + { + read_buffer(ec); + if (ec) return; + } + else + { + eof_ = true; + } + } + parser_.parse_some(handler, ec); + if (ec) return; + } + } + + void check_done() + { + std::error_code ec; + check_done(ec); + if (ec) + { + throw ser_error(ec,parser_.line(),parser_.column()); + } + } + + const ser_context& context() const override + { + return *this; + } + + void check_done(std::error_code& ec) + { + try + { + if (source_.is_error()) + { + ec = json_errc::source_error; + return; + } + if (eof_) + { + parser_.check_done(ec); + if (ec) return; + } + else + { + while (!eof_) + { + if (parser_.source_exhausted()) + { + if (!source_.eof()) + { + read_buffer(ec); + if (ec) return; + } + else + { + eof_ = true; + } + } + if (!eof_) + { + parser_.check_done(ec); + if (ec) return; + } + } + } + } + catch (const ser_error& e) + { + ec = e.code(); + } + } + + bool eof() const + { + return eof_; + } + + size_t line() const override + { + return parser_.line(); + } + + size_t column() const override + { + return parser_.column(); + } +private: +}; + +typedef basic_json_cursor json_cursor; +typedef basic_json_cursor wjson_cursor; + +#if !defined(JSONCONS_NO_DEPRECATED) +template> +using basic_json_pull_reader = basic_json_cursor; + +JSONCONS_DEPRECATED("Instead, use json_cursor") typedef json_cursor json_pull_reader; +JSONCONS_DEPRECATED("Instead, use wjson_cursor") typedef wjson_cursor wjson_pull_reader; + +template> +using basic_json_stream_reader = basic_json_cursor; + +template> +using basic_json_staj_reader = basic_json_cursor; + +JSONCONS_DEPRECATED("Instead, use json_cursor") typedef json_cursor json_stream_reader; +JSONCONS_DEPRECATED("Instead, use wjson_cursor") typedef wjson_cursor wjson_stream_reader; + +JSONCONS_DEPRECATED("Instead, use json_cursor") typedef json_cursor json_staj_reader; +JSONCONS_DEPRECATED("Instead, use wjson_cursor") typedef wjson_cursor wjson_staj_reader; +#endif + +} + +#endif + diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_decoder.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_decoder.hpp index 562d611..4aa5554 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_decoder.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_decoder.hpp @@ -8,11 +8,11 @@ #define JSONCONS_JSON_DECODER_HPP #include -#include #include -#include -#include -#include +#include // std::true_type +#include // std::allocator +#include // std::make_move_iterator +#include // std::move #include #include @@ -25,30 +25,31 @@ class json_decoder final : public basic_json_content_handler::string_view_type; - typedef typename Json::key_value_pair_type key_value_pair_type; - typedef typename Json::key_storage_type key_storage_type; - typedef typename Json::string_type string_type; + typedef typename Json::key_value_type key_value_type; + typedef typename Json::key_type key_type; typedef typename Json::array array; typedef typename Json::object object; typedef typename Json::allocator_type json_allocator_type; - typedef typename string_type::allocator_type json_string_allocator; + typedef typename key_type::allocator_type json_string_allocator; typedef typename array::allocator_type json_array_allocator; typedef typename object::allocator_type json_object_allocator; - + typedef typename std::allocator_traits:: template rebind_alloc json_byte_allocator_type; +private: json_string_allocator string_allocator_; json_object_allocator object_allocator_; json_array_allocator array_allocator_; + json_byte_allocator_type byte_allocator_; Json result_; struct stack_item { - stack_item(key_storage_type&& name) - : name_(std::forward(name)) - { - } - stack_item(Json&& value) - : value_(std::forward(value)) + key_type name_; + Json value_; + + template + stack_item(key_type&& name, Args&& ... args) + : name_(std::move(name)), value_(std::forward(args)...) { } @@ -57,24 +58,29 @@ class json_decoder final : public basic_json_content_handler:: template rebind_alloc stack_item_allocator_type; - typedef typename std::allocator_traits:: template rebind_alloc size_t_allocator_type; - + typedef typename std::allocator_traits:: template rebind_alloc size_t_allocator_type; - std::vector stack_; - std::vector stack_offsets_; + key_type name_; + std::vector item_stack_; + std::vector structure_stack_; bool is_valid_; public: @@ -85,8 +91,9 @@ class json_decoder final : public basic_json_content_handler(name_), object(object_allocator_), tag); + structure_stack_.emplace_back(structure_type::object_t, item_stack_.size()-1); + return true; } - void do_end_json() override + bool do_end_object(const ser_context&) override { - if (stack_.size() == 1) + JSONCONS_ASSERT(structure_stack_.size() > 0); + JSONCONS_ASSERT(structure_stack_.back().type_ == structure_type::object_t); + const size_t structure_index = structure_stack_.back().offset_; + JSONCONS_ASSERT(item_stack_.size() > structure_index); + const size_t count = item_stack_.size() - (structure_index + 1); + auto first = item_stack_.begin() + (structure_index+1); + auto last = first + count; + item_stack_[structure_index].value_.object_value().insert( + std::make_move_iterator(first), + std::make_move_iterator(last), + [](stack_item&& val){return key_value_type(std::move(val.name_), std::move(val.value_));} + ); + item_stack_.erase(item_stack_.begin()+structure_index+1, item_stack_.end()); + structure_stack_.pop_back(); + if (structure_stack_.back().type_ == structure_type::root_t) { - result_.swap(stack_.front().value_); - stack_.pop_back(); + result_.swap(item_stack_.front().value_); + item_stack_.pop_back(); is_valid_ = true; + return false; } + return true; } - void do_begin_object(const serializing_context&) override - { - push_object(); - } - - void do_end_object(const serializing_context&) override - { - end_structure(); - pop_object(); - } - - void do_begin_array(const serializing_context&) override + bool do_begin_array(semantic_tag tag, const ser_context&) override { - push_array(); - } - - void do_end_array(const serializing_context&) override - { - end_structure(); - pop_array(); + if (structure_stack_.back().type_ == structure_type::root_t) + { + item_stack_.clear(); + is_valid_ = false; + } + item_stack_.emplace_back(std::forward(name_), array(array_allocator_), tag); + structure_stack_.emplace_back(structure_type::array_t, item_stack_.size()-1); + return true; } - void end_structure() + bool do_end_array(const ser_context&) override { - JSONCONS_ASSERT(stack_offsets_.size() > 0); - const size_t structure_index = stack_offsets_.back().offset_; - JSONCONS_ASSERT(stack_.size() > structure_index); - const size_t count = stack_.size() - (structure_index + 1); - - auto first = stack_.begin() + (structure_index+1); + JSONCONS_ASSERT(structure_stack_.size() > 0); + JSONCONS_ASSERT(structure_stack_.back().type_ == structure_type::array_t); + const size_t structure_index = structure_stack_.back().offset_; + JSONCONS_ASSERT(item_stack_.size() > structure_index); + const size_t count = item_stack_.size() - (structure_index + 1); + auto first = item_stack_.begin() + (structure_index+1); auto last = first + count; - if (stack_offsets_.back().is_object_) + auto& j = item_stack_[structure_index].value_; + j.reserve(count); + while (first != last) { - stack_[structure_index].value_.object_value().insert( - std::make_move_iterator(first), - std::make_move_iterator(last), - [](stack_item&& val){return key_value_pair_type(std::move(val.name_),std::move(val.value_));}); + j.push_back(std::move(first->value_)); + ++first; } - else + item_stack_.erase(item_stack_.begin()+structure_index+1, item_stack_.end()); + structure_stack_.pop_back(); + if (structure_stack_.back().type_ == structure_type::root_t) { - auto& j = stack_[structure_index].value_; - j.reserve(count); - while (first != last) - { - j.push_back(std::move(first->value_)); - ++first; - } + result_.swap(item_stack_.front().value_); + item_stack_.pop_back(); + is_valid_ = true; + return false; } + return true; } - void do_name(const string_view_type& name, const serializing_context&) override + bool do_name(const string_view_type& name, const ser_context&) override { - stack_.push_back(key_storage_type(name.begin(),name.end(),string_allocator_)); + name_ = key_type(name.data(),name.length()); + return true; } - void do_string_value(const string_view_type& val, const serializing_context&) override + bool do_string_value(const string_view_type& sv, semantic_tag tag, const ser_context&) override { - if (stack_offsets_.back().is_object_) + switch (structure_stack_.back().type_) { - stack_.back().value_ = Json(val.data(),val.length(),string_allocator_); - } - else - { - stack_.push_back(Json(val.data(),val.length(),string_allocator_)); + case structure_type::object_t: + case structure_type::array_t: + item_stack_.emplace_back(std::forward(name_), sv, tag, string_allocator_); + break; + case structure_type::root_t: + result_ = Json(sv, tag, string_allocator_); + is_valid_ = true; + return false; } + return true; } - void do_byte_string_value(const uint8_t* data, size_t length, const serializing_context&) override + bool do_byte_string_value(const byte_string_view& b, semantic_tag tag, const ser_context&) override { - if (stack_offsets_.back().is_object_) - { - stack_.back().value_ = Json(data,length,string_allocator_); - } - else + switch (structure_stack_.back().type_) { - stack_.push_back(Json(data,length,string_allocator_)); + case structure_type::object_t: + case structure_type::array_t: + item_stack_.emplace_back(std::forward(name_), b, tag, byte_allocator_); + break; + case structure_type::root_t: + result_ = Json(b, tag, byte_allocator_); + is_valid_ = true; + return false; } + return true; } - void do_integer_value(int64_t value, const serializing_context&) override + bool do_int64_value(int64_t value, + semantic_tag tag, + const ser_context&) override { - if (stack_offsets_.back().is_object_) + switch (structure_stack_.back().type_) { - stack_.back().value_ = value; - } - else - { - stack_.push_back(Json(value)); + case structure_type::object_t: + case structure_type::array_t: + item_stack_.emplace_back(std::forward(name_), value, tag); + break; + case structure_type::root_t: + result_ = Json(value,tag); + is_valid_ = true; + return false; } + return true; } - void do_uinteger_value(uint64_t value, const serializing_context&) override + bool do_uint64_value(uint64_t value, + semantic_tag tag, + const ser_context&) override { - if (stack_offsets_.back().is_object_) - { - stack_.back().value_ = value; - } - else + switch (structure_stack_.back().type_) { - stack_.push_back(Json(value)); + case structure_type::object_t: + case structure_type::array_t: + item_stack_.emplace_back(std::forward(name_), value, tag); + break; + case structure_type::root_t: + result_ = Json(value,tag); + is_valid_ = true; + return false; } + return true; } - void do_double_value(double value, const number_format& fmt, const serializing_context&) override + bool do_double_value(double value, + semantic_tag tag, + const ser_context&) override { - if (stack_offsets_.back().is_object_) - { - stack_.back().value_ = Json(value,fmt); - } - else + switch (structure_stack_.back().type_) { - stack_.push_back(Json(value,fmt)); + case structure_type::object_t: + case structure_type::array_t: + item_stack_.emplace_back(std::forward(name_), value, tag); + break; + case structure_type::root_t: + result_ = Json(value, tag); + is_valid_ = true; + return false; } + return true; } - void do_bool_value(bool value, const serializing_context&) override + bool do_bool_value(bool value, semantic_tag tag, const ser_context&) override { - if (stack_offsets_.back().is_object_) + switch (structure_stack_.back().type_) { - stack_.back().value_ = value; - } - else - { - stack_.push_back(Json(value)); + case structure_type::object_t: + case structure_type::array_t: + item_stack_.emplace_back(std::forward(name_), value, tag); + break; + case structure_type::root_t: + result_ = Json(value, tag); + is_valid_ = true; + return false; } + return true; } - void do_null_value(const serializing_context&) override + bool do_null_value(semantic_tag tag, const ser_context&) override { - if (stack_offsets_.back().is_object_) - { - stack_.back().value_ = Json::null(); - } - else + switch (structure_stack_.back().type_) { - stack_.push_back(Json(Json::null())); + case structure_type::object_t: + case structure_type::array_t: + item_stack_.emplace_back(std::forward(name_), null_type(), tag); + break; + case structure_type::root_t: + result_ = Json(null_type(), tag); + is_valid_ = true; + return false; } + return true; } }; diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_decoder.hpp.orig b/invehicle-apps/3rd-party-libs/jsoncons/json_decoder.hpp.orig new file mode 100644 index 0000000..6199a8d --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_decoder.hpp.orig @@ -0,0 +1,379 @@ +// Copyright 2013-2016 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_JSON_DECODER_HPP +#define JSONCONS_JSON_DECODER_HPP + +#include +#include +#include // std::true_type +#include // std::allocator +#include // std::make_move_iterator +#include // std::move +#include +#include + +namespace jsoncons { + +template > +class json_decoder final : public basic_json_content_handler +{ +public: + typedef typename Json::char_type char_type; + using typename basic_json_content_handler::string_view_type; + + typedef typename Json::key_value_type key_value_type; + typedef typename Json::string_type string_type; + typedef typename Json::array array; + typedef typename Json::object object; + typedef typename Json::allocator_type json_allocator_type; + typedef typename string_type::allocator_type json_string_allocator; + typedef typename array::allocator_type json_array_allocator; + typedef typename object::allocator_type json_object_allocator; + typedef typename std::allocator_traits:: template rebind_alloc json_byte_allocator_type; +private: + json_string_allocator string_allocator_; + json_object_allocator object_allocator_; + json_array_allocator array_allocator_; + json_byte_allocator_type byte_allocator_; + + Json result_; + + struct stack_item + { + template + stack_item(std::true_type, Args&& ... args) + : name_(std::forward(args)...) + { + } + template + stack_item(std::false_type, Args&& ... args) + : value_(std::forward(args)...) + { + } + + stack_item() = default; + stack_item(const stack_item&) = default; + stack_item(stack_item&&) = default; + stack_item& operator=(const stack_item&) = default; + stack_item& operator=(stack_item&&) = default; + + string_type name_; + Json value_; + }; + + enum class structure_type {root_t, array_t, object_t}; + + struct structure_info + { + structure_type type_; + size_t offset_; +<<<<<<< HEAD + structure_type type_; +======= + + structure_info(structure_type type, size_t offset) + : type_(type), offset_(offset) + { + } + +>>>>>>> 0b4f23251859b01d47d7d7f4a729da0f2275af04 + }; + + typedef Allocator allocator_type; + typedef typename std::allocator_traits:: template rebind_alloc stack_item_allocator_type; + typedef typename std::allocator_traits:: template rebind_alloc size_t_allocator_type; + + + std::vector item_stack_; + std::vector structure_stack_; + bool is_valid_; + +public: + json_decoder(const json_allocator_type& jallocator = json_allocator_type()) + : string_allocator_(jallocator), + object_allocator_(jallocator), + array_allocator_(jallocator), + is_valid_(false) + + { + item_stack_.reserve(1000); + structure_stack_.reserve(100); +<<<<<<< HEAD + structure_stack_.push_back({0,structure_type::root_t}); +======= + structure_stack_.emplace_back(structure_type::root_t, 0); +>>>>>>> 0b4f23251859b01d47d7d7f4a729da0f2275af04 + } + + bool is_valid() const + { + return is_valid_; + } + + Json get_result() + { + is_valid_ = false; + return std::move(result_); + } + +#if !defined(JSONCONS_NO_DEPRECATED) + Json& root() + { + return result_; + } +#endif + +private: + + void do_flush() override + { + } + + bool do_begin_object(semantic_tag tag, const ser_context&) override + { + switch (structure_stack_.back().type_) + { + case structure_type::object_t: + item_stack_.back().value_ = Json(object(object_allocator_), tag); + break; + case structure_type::array_t: + item_stack_.emplace_back(std::false_type(), object(object_allocator_), tag); + break; + case structure_type::root_t: + item_stack_.clear(); + is_valid_ = false; + item_stack_.emplace_back(std::false_type(), object(object_allocator_), tag); + break; + } +<<<<<<< HEAD + structure_stack_.push_back({item_stack_.size()-1,structure_type::object_t}); +======= + structure_stack_.emplace_back(structure_type::object_t, item_stack_.size()-1); +>>>>>>> 0b4f23251859b01d47d7d7f4a729da0f2275af04 + return true; + } + + bool do_end_object(const ser_context&) override + { + JSONCONS_ASSERT(structure_stack_.size() > 0); + JSONCONS_ASSERT(structure_stack_.back().type_ == structure_type::object_t); + const size_t structure_index = structure_stack_.back().offset_; + JSONCONS_ASSERT(item_stack_.size() > structure_index); + const size_t count = item_stack_.size() - (structure_index + 1); + auto first = item_stack_.begin() + (structure_index+1); + auto last = first + count; + item_stack_[structure_index].value_.object_value().insert( + std::make_move_iterator(first), + std::make_move_iterator(last), + [](stack_item&& val){return key_value_type(std::move(val.name_), std::move(val.value_));} + ); + item_stack_.erase(item_stack_.begin()+structure_index+1, item_stack_.end()); + structure_stack_.pop_back(); + if (structure_stack_.back().type_ == structure_type::root_t) + { + result_.swap(item_stack_.front().value_); + item_stack_.pop_back(); + is_valid_ = true; + return false; + } + return true; + } + + bool do_begin_array(semantic_tag tag, const ser_context&) override + { + switch (structure_stack_.back().type_) + { + case structure_type::object_t: + item_stack_.back().value_ = Json(array(array_allocator_), tag); + break; + case structure_type::array_t: + item_stack_.emplace_back(std::false_type(), array(array_allocator_), tag); + break; + case structure_type::root_t: + item_stack_.clear(); + is_valid_ = false; + item_stack_.emplace_back(std::false_type(), array(array_allocator_), tag); + break; + } +<<<<<<< HEAD + structure_stack_.push_back({item_stack_.size()-1,structure_type::array_t}); +======= + structure_stack_.emplace_back(structure_type::array_t, item_stack_.size()-1); +>>>>>>> 0b4f23251859b01d47d7d7f4a729da0f2275af04 + return true; + } + + bool do_end_array(const ser_context&) override + { + JSONCONS_ASSERT(structure_stack_.size() > 0); + JSONCONS_ASSERT(structure_stack_.back().type_ == structure_type::array_t); + const size_t structure_index = structure_stack_.back().offset_; + JSONCONS_ASSERT(item_stack_.size() > structure_index); + const size_t count = item_stack_.size() - (structure_index + 1); + auto first = item_stack_.begin() + (structure_index+1); + auto last = first + count; + auto& j = item_stack_[structure_index].value_; + j.reserve(count); + while (first != last) + { + j.push_back(std::move(first->value_)); + ++first; + } + item_stack_.erase(item_stack_.begin()+structure_index+1, item_stack_.end()); + structure_stack_.pop_back(); + if (structure_stack_.back().type_ == structure_type::root_t) + { + result_.swap(item_stack_.front().value_); + item_stack_.pop_back(); + is_valid_ = true; + return false; + } + return true; + } + + bool do_name(const string_view_type& name, const ser_context&) override + { + item_stack_.emplace_back(std::true_type(), name.data(), name.length(), string_allocator_); + return true; + } + + bool do_string_value(const string_view_type& sv, semantic_tag tag, const ser_context&) override + { + switch (structure_stack_.back().type_) + { + case structure_type::object_t: + item_stack_.back().value_ = Json(sv, tag, string_allocator_); + break; + case structure_type::array_t: + item_stack_.emplace_back(std::false_type(), sv, tag, string_allocator_); + break; + case structure_type::root_t: + result_ = Json(sv, tag, string_allocator_); + is_valid_ = true; + return false; + } + return true; + } + + bool do_byte_string_value(const byte_string_view& b, semantic_tag tag, const ser_context&) override + { + switch (structure_stack_.back().type_) + { + case structure_type::object_t: + item_stack_.back().value_ = Json(b, tag, byte_allocator_); + break; + case structure_type::array_t: + item_stack_.emplace_back(std::false_type(), b, tag, byte_allocator_); + break; + case structure_type::root_t: + result_ = Json(b, tag, byte_allocator_); + is_valid_ = true; + return false; + } + return true; + } + + bool do_int64_value(int64_t value, + semantic_tag tag, + const ser_context&) override + { + switch (structure_stack_.back().type_) + { + case structure_type::object_t: + item_stack_.back().value_ = Json(value,tag); + break; + case structure_type::array_t: + item_stack_.emplace_back(std::false_type(), value, tag); + break; + case structure_type::root_t: + result_ = Json(value,tag); + is_valid_ = true; + return false; + } + return true; + } + + bool do_uint64_value(uint64_t value, + semantic_tag tag, + const ser_context&) override + { + switch (structure_stack_.back().type_) + { + case structure_type::object_t: + item_stack_.back().value_ = Json(value,tag); + break; + case structure_type::array_t: + item_stack_.emplace_back(std::false_type(), value, tag); + break; + case structure_type::root_t: + result_ = Json(value,tag); + is_valid_ = true; + return false; + } + return true; + } + + bool do_double_value(double value, + semantic_tag tag, + const ser_context&) override + { + switch (structure_stack_.back().type_) + { + case structure_type::object_t: + item_stack_.back().value_ = Json(value, tag); + break; + case structure_type::array_t: + item_stack_.emplace_back(std::false_type(), value, tag); + break; + case structure_type::root_t: + result_ = Json(value, tag); + is_valid_ = true; + return false; + } + return true; + } + + bool do_bool_value(bool value, semantic_tag tag, const ser_context&) override + { + switch (structure_stack_.back().type_) + { + case structure_type::object_t: + item_stack_.back().value_ = Json(value, tag); + break; + case structure_type::array_t: + item_stack_.emplace_back(std::false_type(), value, tag); + break; + case structure_type::root_t: + result_ = Json(value, tag); + is_valid_ = true; + return false; + } + return true; + } + + bool do_null_value(semantic_tag tag, const ser_context&) override + { + switch (structure_stack_.back().type_) + { + case structure_type::object_t: + item_stack_.back().value_ = Json(null_type(),tag); + break; + case structure_type::array_t: + item_stack_.emplace_back(std::false_type(), null_type(), tag); + break; + case structure_type::root_t: + result_ = Json(null_type(), tag); + is_valid_ = true; + return false; + } + return true; + } +}; + +} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_deserializer.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_deserializer.hpp deleted file mode 100644 index 05b44a4..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_deserializer.hpp +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2013-2016 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_JSON_DESERIALIZER_HPP -#define JSONCONS_JSON_DESERIALIZER_HPP - -#include - -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_encoder.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_encoder.hpp new file mode 100644 index 0000000..d760e10 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_encoder.hpp @@ -0,0 +1,1473 @@ +// Copyright 2013 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_JSON_ENCODER_HPP +#define JSONCONS_JSON_ENCODER_HPP + +#include // std::array +#include +#include +#include // std::isfinite, std::isnan +#include // std::numeric_limits +#include +#include // std::move +#include +#include +#include +#include +#include +#include +#include +#include + +namespace jsoncons { namespace detail { +template +size_t escape_string(const CharT* s, size_t length, + bool escape_all_non_ascii, bool escape_solidus, + Result& result) +{ + size_t count = 0; + const CharT* begin = s; + const CharT* end = s + length; + for (const CharT* it = begin; it != end; ++it) + { + CharT c = *it; + switch (c) + { + case '\\': + result.push_back('\\'); + result.push_back('\\'); + count += 2; + break; + case '"': + result.push_back('\\'); + result.push_back('\"'); + count += 2; + break; + case '\b': + result.push_back('\\'); + result.push_back('b'); + count += 2; + break; + case '\f': + result.push_back('\\'); + result.push_back('f'); + count += 2; + break; + case '\n': + result.push_back('\\'); + result.push_back('n'); + count += 2; + break; + case '\r': + result.push_back('\\'); + result.push_back('r'); + count += 2; + break; + case '\t': + result.push_back('\\'); + result.push_back('t'); + count += 2; + break; + default: + if (escape_solidus && c == '/') + { + result.push_back('\\'); + result.push_back('/'); + count += 2; + } + else if (is_control_character(c) || escape_all_non_ascii) + { + // convert utf8 to codepoint + unicons::sequence_generator g(it, end, unicons::conv_flags::strict); + if (g.done() || g.status() != unicons::conv_errc()) + { + throw ser_error(json_errc::illegal_codepoint); + } + uint32_t cp = g.get().codepoint(); + it += (g.get().length() - 1); + if (is_non_ascii_codepoint(cp) || is_control_character(c)) + { + if (cp > 0xFFFF) + { + cp -= 0x10000; + uint32_t first = (cp >> 10) + 0xD800; + uint32_t second = ((cp & 0x03FF) + 0xDC00); + + result.push_back('\\'); + result.push_back('u'); + result.push_back(to_hex_character(first >> 12 & 0x000F)); + result.push_back(to_hex_character(first >> 8 & 0x000F)); + result.push_back(to_hex_character(first >> 4 & 0x000F)); + result.push_back(to_hex_character(first & 0x000F)); + result.push_back('\\'); + result.push_back('u'); + result.push_back(to_hex_character(second >> 12 & 0x000F)); + result.push_back(to_hex_character(second >> 8 & 0x000F)); + result.push_back(to_hex_character(second >> 4 & 0x000F)); + result.push_back(to_hex_character(second & 0x000F)); + count += 12; + } + else + { + result.push_back('\\'); + result.push_back('u'); + result.push_back(to_hex_character(cp >> 12 & 0x000F)); + result.push_back(to_hex_character(cp >> 8 & 0x000F)); + result.push_back(to_hex_character(cp >> 4 & 0x000F)); + result.push_back(to_hex_character(cp & 0x000F)); + count += 6; + } + } + else + { + result.push_back(c); + ++count; + } + } + else + { + result.push_back(c); + ++count; + } + break; + } + } + return count; +} + +inline +byte_string_chars_format resolve_byte_string_chars_format(byte_string_chars_format format1, + byte_string_chars_format format2, + byte_string_chars_format default_format = byte_string_chars_format::base64url) +{ + byte_string_chars_format result; + switch (format1) + { + case byte_string_chars_format::base16: + case byte_string_chars_format::base64: + case byte_string_chars_format::base64url: + result = format1; + break; + default: + switch (format2) + { + case byte_string_chars_format::base64url: + case byte_string_chars_format::base64: + case byte_string_chars_format::base16: + result = format2; + break; + default: // base64url + { + result = default_format; + break; + } + } + break; + } + return result; +} + +}} + +namespace jsoncons { + +template> +class basic_json_encoder final : public basic_json_content_handler +{ + static const std::array& null_k() + { + static constexpr std::array k{'n','u','l','l'}; + return k; + } + static const std::array& true_k() + { + static constexpr std::array k{'t','r','u','e'}; + return k; + } + static const std::array& false_k() + { + static constexpr std::array k{'f','a','l','s','e'}; + return k; + } +public: + typedef CharT char_type; + using typename basic_json_content_handler::string_view_type; + typedef Result result_type; + typedef typename basic_json_options::string_type string_type; + +private: + enum class container_type {object, array}; + + class encoding_context + { + container_type type_; + size_t count_; + line_split_kind line_splits_; + bool indent_before_; + bool new_line_after_; + size_t begin_pos_; + size_t data_pos_; + public: + encoding_context(container_type type, line_split_kind split_lines, bool indent_once, + size_t begin_pos, size_t data_pos) + : type_(type), count_(0), line_splits_(split_lines), indent_before_(indent_once), new_line_after_(false), + begin_pos_(begin_pos), data_pos_(data_pos) + { + } + + void set_position(size_t pos) + { + data_pos_ = pos; + } + + size_t begin_pos() const + { + return begin_pos_; + } + + size_t data_pos() const + { + return data_pos_; + } + + size_t count() const + { + return count_; + } + + void increment_count() + { + ++count_; + } + + bool new_line_after() const + { + return new_line_after_; + } + + void new_line_after(bool value) + { + new_line_after_ = value; + } + + bool is_object() const + { + return type_ == container_type::object; + } + + bool is_array() const + { + return type_ == container_type::array; + } + + bool is_same_line() const + { + return line_splits_ == line_split_kind::same_line; + } + + bool is_new_line() const + { + return line_splits_ == line_split_kind::new_line; + } + + bool is_multi_line() const + { + return line_splits_ == line_split_kind::multi_line; + } + + bool is_indent_once() const + { + return count_ == 0 ? indent_before_ : false; + } + + }; + + size_t indent_size_; + + const basic_json_encode_options& options_; + + jsoncons::detail::print_double fp_; + + Result result_; + + std::vector stack_; + int indent_amount_; + size_t column_; + std::basic_string colon_str_; + std::basic_string comma_str_; + std::basic_string open_object_brace_str_; + std::basic_string close_object_brace_str_; + std::basic_string open_array_bracket_str_; + std::basic_string close_array_bracket_str_; + + // Noncopyable and nonmoveable + basic_json_encoder(const basic_json_encoder&) = delete; + basic_json_encoder& operator=(const basic_json_encoder&) = delete; +public: + basic_json_encoder(result_type result) + : basic_json_encoder(std::move(result), basic_json_options::get_default_options()) + { + } + + basic_json_encoder(result_type result, + const basic_json_encode_options& options) + : options_(options), + fp_(floating_point_options(options.floating_point_format(), + options.precision(), + 0)), + result_(std::move(result)), + indent_amount_(0), + column_(0) + { + switch (options.spaces_around_colon()) + { + case spaces_option::space_after: + colon_str_ = std::basic_string({':',' '}); + break; + case spaces_option::space_before: + colon_str_ = std::basic_string({' ',':'}); + break; + case spaces_option::space_before_and_after: + colon_str_ = std::basic_string({' ',':',' '}); + break; + default: + colon_str_.push_back(':'); + break; + } + switch (options.spaces_around_comma()) + { + case spaces_option::space_after: + comma_str_ = std::basic_string({',',' '}); + break; + case spaces_option::space_before: + comma_str_ = std::basic_string({' ',','}); + break; + case spaces_option::space_before_and_after: + comma_str_ = std::basic_string({' ',',',' '}); + break; + default: + comma_str_.push_back(','); + break; + } + if (options.pad_inside_object_braces()) + { + open_object_brace_str_ = std::basic_string({'{', ' '}); + close_object_brace_str_ = std::basic_string({' ', '}'}); + } + else + { + open_object_brace_str_.push_back('{'); + close_object_brace_str_.push_back('}'); + } + if (options.pad_inside_array_brackets()) + { + open_array_bracket_str_ = std::basic_string({'[', ' '}); + close_array_bracket_str_ = std::basic_string({' ', ']'}); + } + else + { + open_array_bracket_str_.push_back('['); + close_array_bracket_str_.push_back(']'); + } + } + + ~basic_json_encoder() + { + try + { + result_.flush(); + } + catch (...) + { + } + } + +private: + // Implementing methods + void do_flush() override + { + result_.flush(); + } + + bool do_begin_object(semantic_tag, const ser_context&) override + { + if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) + { + result_.append(comma_str_.data(),comma_str_.length()); + column_ += comma_str_.length(); + } + + if (!stack_.empty()) // object or array + { + if (stack_.back().is_object()) + { + switch (options_.object_object_line_splits()) + { + case line_split_kind::same_line: + if (column_ >= options_.line_length_limit()) + { + break_line(); + } + break; + case line_split_kind::new_line: + if (column_ >= options_.line_length_limit()) + { + break_line(); + } + break; + default: // multi_line + break; + } + stack_.emplace_back(container_type::object,options_.object_object_line_splits(), false, + column_, column_+open_object_brace_str_.length()); + } + else // array + { + switch (options_.array_object_line_splits()) + { + case line_split_kind::same_line: + if (column_ >= options_.line_length_limit()) + { + //stack_.back().new_line_after(true); + new_line(); + } + break; + case line_split_kind::new_line: + stack_.back().new_line_after(true); + new_line(); + break; + default: // multi_line + stack_.back().new_line_after(true); + new_line(); + break; + } + stack_.emplace_back(container_type::object,options_.array_object_line_splits(), false, + column_, column_+open_object_brace_str_.length()); + } + } + else + { + stack_.emplace_back(container_type::object, line_split_kind::multi_line, false, + column_, column_+open_object_brace_str_.length()); + } + indent(); + + result_.append(open_object_brace_str_.data(), open_object_brace_str_.length()); + column_ += open_object_brace_str_.length(); + return true; + } + + bool do_end_object(const ser_context&) override + { + JSONCONS_ASSERT(!stack_.empty()); + unindent(); + if (stack_.back().new_line_after()) + { + new_line(); + } + stack_.pop_back(); + result_.append(close_object_brace_str_.data(), close_object_brace_str_.length()); + column_ += close_object_brace_str_.length(); + + end_value(); + return true; + } + + bool do_begin_array(semantic_tag, const ser_context&) override + { + if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) + { + result_.append(comma_str_.data(),comma_str_.length()); + column_ += comma_str_.length(); + } + if (!stack_.empty()) + { + if (stack_.back().is_object()) + { + switch (options_.object_array_line_splits()) + { + case line_split_kind::same_line: + stack_.emplace_back(container_type::array,options_.object_array_line_splits(),false, + column_, column_ + open_array_bracket_str_.length()); + break; + case line_split_kind::new_line: + { + stack_.emplace_back(container_type::array,options_.object_array_line_splits(),true, + column_, column_+open_array_bracket_str_.length()); + break; + } + default: // multi_line + stack_.emplace_back(container_type::array,options_.object_array_line_splits(),true, + column_, column_+open_array_bracket_str_.length()); + break; + } + } + else // array + { + switch (options_.array_array_line_splits()) + { + case line_split_kind::same_line: + if (stack_.back().is_multi_line()) + { + stack_.back().new_line_after(true); + new_line(); + } + stack_.emplace_back(container_type::array,options_.array_array_line_splits(), false, + column_, column_+open_array_bracket_str_.length()); + break; + case line_split_kind::new_line: + stack_.back().new_line_after(true); + new_line(); + stack_.emplace_back(container_type::array,options_.array_array_line_splits(), false, + column_, column_+open_array_bracket_str_.length()); + break; + default: // multi_line + stack_.back().new_line_after(true); + new_line(); + stack_.emplace_back(container_type::array,options_.array_array_line_splits(), false, + column_, column_+open_array_bracket_str_.length()); + //new_line(); + break; + } + } + } + else + { + stack_.emplace_back(container_type::array, line_split_kind::multi_line, false, + column_, column_+open_array_bracket_str_.length()); + } + indent(); + result_.append(open_array_bracket_str_.data(), open_array_bracket_str_.length()); + column_ += open_array_bracket_str_.length(); + return true; + } + + bool do_end_array(const ser_context&) override + { + JSONCONS_ASSERT(!stack_.empty()); + unindent(); + if (stack_.back().new_line_after()) + { + new_line(); + } + stack_.pop_back(); + result_.append(close_array_bracket_str_.data(), close_array_bracket_str_.length()); + column_ += close_array_bracket_str_.length(); + end_value(); + return true; + } + + bool do_name(const string_view_type& name, const ser_context&) override + { + JSONCONS_ASSERT(!stack_.empty()); + if (stack_.back().count() > 0) + { + result_.append(comma_str_.data(),comma_str_.length()); + column_ += comma_str_.length(); + } + + if (stack_.back().is_multi_line()) + { + stack_.back().new_line_after(true); + new_line(); + } + else if (stack_.back().count() > 0 && column_ >= options_.line_length_limit()) + { + //stack_.back().new_line_after(true); + new_line(stack_.back().data_pos()); + } + + if (stack_.back().count() == 0) + { + stack_.back().set_position(column_); + } + result_.push_back('\"'); + size_t length = jsoncons::detail::escape_string(name.data(), name.length(),options_.escape_all_non_ascii(),options_.escape_solidus(),result_); + result_.push_back('\"'); + result_.append(colon_str_.data(),colon_str_.length()); + column_ += (length+2+colon_str_.length()); + return true; + } + + bool do_null_value(semantic_tag, const ser_context&) override + { + if (!stack_.empty()) + { + if (stack_.back().is_array()) + { + begin_scalar_value(); + } + if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) + { + break_line(); + } + } + + result_.append(null_k().data(), null_k().size()); + column_ += null_k().size(); + + end_value(); + return true; + } + + bool do_string_value(const string_view_type& sv, semantic_tag tag, const ser_context&) override + { + if (!stack_.empty()) + { + if (stack_.back().is_array()) + { + begin_scalar_value(); + } + if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) + { + break_line(); + } + } + + switch (tag) + { + case semantic_tag::bigint: + write_bigint_value(sv); + break; + default: + { + result_.push_back('\"'); + size_t length = jsoncons::detail::escape_string(sv.data(), sv.length(),options_.escape_all_non_ascii(),options_.escape_solidus(),result_); + result_.push_back('\"'); + column_ += (length+2); + break; + } + } + + end_value(); + return true; + } + + bool do_byte_string_value(const byte_string_view& b, + semantic_tag tag, + const ser_context&) override + { + if (!stack_.empty()) + { + if (stack_.back().is_array()) + { + begin_scalar_value(); + } + if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) + { + break_line(); + } + } + + byte_string_chars_format encoding_hint; + switch (tag) + { + case semantic_tag::base16: + encoding_hint = byte_string_chars_format::base16; + break; + case semantic_tag::base64: + encoding_hint = byte_string_chars_format::base64; + break; + case semantic_tag::base64url: + encoding_hint = byte_string_chars_format::base64url; + break; + default: + encoding_hint = byte_string_chars_format::none; + break; + } + + byte_string_chars_format format = jsoncons::detail::resolve_byte_string_chars_format(options_.byte_string_format(), + encoding_hint, + byte_string_chars_format::base64url); + switch (format) + { + case byte_string_chars_format::base16: + { + result_.push_back('\"'); + size_t length = encode_base16(b.begin(),b.end(),result_); + result_.push_back('\"'); + column_ += (length + 2); + break; + } + case byte_string_chars_format::base64: + { + result_.push_back('\"'); + size_t length = encode_base64(b.begin(), b.end(), result_); + result_.push_back('\"'); + column_ += (length + 2); + break; + } + case byte_string_chars_format::base64url: + { + result_.push_back('\"'); + size_t length = encode_base64url(b.begin(),b.end(),result_); + result_.push_back('\"'); + column_ += (length + 2); + break; + } + default: + { + JSONCONS_UNREACHABLE(); + } + } + + end_value(); + return true; + } + + bool do_double_value(double value, + semantic_tag, + const ser_context& context) override + { + if (!stack_.empty()) + { + if (stack_.back().is_array()) + { + begin_scalar_value(); + } + if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) + { + break_line(); + } + } + + if (!std::isfinite(value)) + { + if ((std::isnan)(value)) + { + if (options_.is_nan_to_num()) + { + result_.append(options_.nan_to_num().data(), options_.nan_to_num().length()); + column_ += options_.nan_to_num().length(); + } + else if (options_.is_nan_to_str()) + { + do_string_value(options_.nan_to_str(), semantic_tag::none, context); + } + else + { + result_.append(null_k().data(), null_k().size()); + column_ += null_k().size(); + } + } + else if (value == std::numeric_limits::infinity()) + { + if (options_.is_inf_to_num()) + { + result_.append(options_.inf_to_num().data(), options_.inf_to_num().length()); + column_ += options_.inf_to_num().length(); + } + else if (options_.is_inf_to_str()) + { + do_string_value(options_.inf_to_str(), semantic_tag::none, context); + } + else + { + result_.append(null_k().data(), null_k().size()); + column_ += null_k().size(); + } + } + else + { + if (options_.is_neginf_to_num()) + { + result_.append(options_.neginf_to_num().data(), options_.neginf_to_num().length()); + column_ += options_.neginf_to_num().length(); + } + else if (options_.is_neginf_to_str()) + { + do_string_value(options_.neginf_to_str(), semantic_tag::none, context); + } + else + { + result_.append(null_k().data(), null_k().size()); + column_ += null_k().size(); + } + } + } + else + { + size_t length = fp_(value, result_); + column_ += length; + } + + end_value(); + return true; + } + + bool do_int64_value(int64_t value, + semantic_tag, + const ser_context&) override + { + if (!stack_.empty()) + { + if (stack_.back().is_array()) + { + begin_scalar_value(); + } + if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) + { + break_line(); + } + } + size_t length = jsoncons::detail::print_integer(value, result_); + column_ += length; + end_value(); + return true; + } + + bool do_uint64_value(uint64_t value, + semantic_tag, + const ser_context&) override + { + if (!stack_.empty()) + { + if (stack_.back().is_array()) + { + begin_scalar_value(); + } + if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) + { + break_line(); + } + } + size_t length = jsoncons::detail::print_uinteger(value, result_); + column_ += length; + end_value(); + return true; + } + + bool do_bool_value(bool value, semantic_tag, const ser_context&) override + { + if (!stack_.empty()) + { + if (stack_.back().is_array()) + { + begin_scalar_value(); + } + if (!stack_.back().is_multi_line() && column_ >= options_.line_length_limit()) + { + break_line(); + } + } + + if (value) + { + result_.append(true_k().data(), true_k().size()); + column_ += true_k().size(); + } + else + { + result_.append(false_k().data(), false_k().size()); + column_ += false_k().size(); + } + + end_value(); + return true; + } + + void begin_scalar_value() + { + if (!stack_.empty()) + { + if (stack_.back().count() > 0) + { + result_.append(comma_str_.data(),comma_str_.length()); + column_ += comma_str_.length(); + } + if (stack_.back().is_multi_line() || stack_.back().is_indent_once()) + { + stack_.back().new_line_after(true); + new_line(); + } + } + } + + void write_bigint_value(const string_view_type& sv) + { + switch (options_.bigint_format()) + { + case bigint_chars_format::number: + { + result_.append(sv.data(),sv.size()); + column_ += sv.size(); + break; + } + case bigint_chars_format::base64: + { + bignum n(sv.data(), sv.length()); + int signum; + std::vector v; + n.dump(signum, v); + + result_.push_back('\"'); + if (signum == -1) + { + result_.push_back('~'); + ++column_; + } + size_t length = encode_base64(v.begin(), v.end(), result_); + result_.push_back('\"'); + column_ += (length+2); + break; + } + case bigint_chars_format::base64url: + { + bignum n(sv.data(), sv.length()); + int signum; + std::vector v; + n.dump(signum, v); + + result_.push_back('\"'); + if (signum == -1) + { + result_.push_back('~'); + ++column_; + } + size_t length = encode_base64url(v.begin(), v.end(), result_); + result_.push_back('\"'); + column_ += (length+2); + break; + } + default: + { + result_.push_back('\"'); + result_.append(sv.data(),sv.size()); + result_.push_back('\"'); + column_ += (sv.size() + 2); + break; + } + } + } + + void end_value() + { + if (!stack_.empty()) + { + stack_.back().increment_count(); + } + } + + void indent() + { + indent_amount_ += static_cast(options_.indent_size()); + } + + void unindent() + { + indent_amount_ -= static_cast(options_.indent_size()); + } + + void new_line() + { + result_.append(options_.new_line_chars().data(),options_.new_line_chars().length()); + for (int i = 0; i < indent_amount_; ++i) + { + result_.push_back(' '); + } + column_ = indent_amount_; + } + + void new_line(size_t len) + { + result_.append(options_.new_line_chars().data(),options_.new_line_chars().length()); + for (size_t i = 0; i < len; ++i) + { + result_.push_back(' '); + } + column_ = len; + } + + void break_line() + { + stack_.back().new_line_after(true); + new_line(); + } +}; + +template> +class basic_json_compressed_encoder final : public basic_json_content_handler +{ + static const std::array& null_k() + { + static constexpr std::array k{'n','u','l','l'}; + return k; + } + static const std::array& true_k() + { + static constexpr std::array k{'t','r','u','e'}; + return k; + } + static const std::array& false_k() + { + static constexpr std::array k{'f','a','l','s','e'}; + return k; + } +public: + typedef CharT char_type; + using typename basic_json_content_handler::string_view_type; + typedef Result result_type; + typedef typename basic_json_options::string_type string_type; + +private: + enum class container_type {object, array}; + + class encoding_context + { + container_type type_; + size_t count_; + public: + encoding_context(container_type type) + : type_(type), count_(0) + { + } + + size_t count() const + { + return count_; + } + + void increment_count() + { + ++count_; + } + + bool is_array() const + { + return type_ == container_type::array; + } + }; + + const basic_json_encode_options& options_; + + std::vector stack_; + jsoncons::detail::print_double fp_; + Result result_; + + // Noncopyable and nonmoveable + basic_json_compressed_encoder(const basic_json_compressed_encoder&) = delete; + basic_json_compressed_encoder& operator=(const basic_json_compressed_encoder&) = delete; +public: + basic_json_compressed_encoder(result_type result) + : basic_json_compressed_encoder(std::move(result), basic_json_options::get_default_options()) + { + } + + basic_json_compressed_encoder(result_type result, + const basic_json_encode_options& options) + : options_(options), + fp_(floating_point_options(options.floating_point_format(), + options.precision(), + 0)), + result_(std::move(result)) + { + } + + ~basic_json_compressed_encoder() + { + try + { + result_.flush(); + } + catch (...) + { + } + } + + +private: + // Implementing methods + void do_flush() override + { + result_.flush(); + } + + bool do_begin_object(semantic_tag, const ser_context&) override + { + if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) + { + result_.push_back(','); + } + + stack_.emplace_back(container_type::object); + result_.push_back('{'); + return true; + } + + bool do_end_object(const ser_context&) override + { + JSONCONS_ASSERT(!stack_.empty()); + stack_.pop_back(); + result_.push_back('}'); + + if (!stack_.empty()) + { + stack_.back().increment_count(); + } + return true; + } + + + bool do_begin_array(semantic_tag, const ser_context&) override + { + if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) + { + result_.push_back(','); + } + stack_.emplace_back(container_type::array); + result_.push_back('['); + return true; + } + + bool do_end_array(const ser_context&) override + { + JSONCONS_ASSERT(!stack_.empty()); + stack_.pop_back(); + result_.push_back(']'); + if (!stack_.empty()) + { + stack_.back().increment_count(); + } + return true; + } + + bool do_name(const string_view_type& name, const ser_context&) override + { + if (!stack_.empty() && stack_.back().count() > 0) + { + result_.push_back(','); + } + + result_.push_back('\"'); + jsoncons::detail::escape_string(name.data(), name.length(),options_.escape_all_non_ascii(),options_.escape_solidus(),result_); + result_.push_back('\"'); + result_.push_back(':'); + return true; + } + + bool do_null_value(semantic_tag, const ser_context&) override + { + if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) + { + result_.push_back(','); + } + + result_.append(null_k().data(), null_k().size()); + + if (!stack_.empty()) + { + stack_.back().increment_count(); + } + return true; + } + + void write_bigint_value(const string_view_type& sv) + { + switch (options_.bigint_format()) + { + case bigint_chars_format::number: + { + result_.append(sv.data(),sv.size()); + break; + } + case bigint_chars_format::base64: + { + bignum n(sv.data(), sv.length()); + int signum; + std::vector v; + n.dump(signum, v); + + result_.push_back('\"'); + if (signum == -1) + { + result_.push_back('~'); + } + encode_base64(v.begin(), v.end(), result_); + result_.push_back('\"'); + break; + } + case bigint_chars_format::base64url: + { + bignum n(sv.data(), sv.length()); + int signum; + std::vector v; + n.dump(signum, v); + + result_.push_back('\"'); + if (signum == -1) + { + result_.push_back('~'); + } + encode_base64url(v.begin(), v.end(), result_); + result_.push_back('\"'); + break; + } + default: + { + result_.push_back('\"'); + result_.append(sv.data(),sv.size()); + result_.push_back('\"'); + break; + } + } + } + + bool do_string_value(const string_view_type& sv, semantic_tag tag, const ser_context&) override + { + if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) + { + result_.push_back(','); + } + + switch (tag) + { + case semantic_tag::bigint: + write_bigint_value(sv); + break; + default: + { + result_.push_back('\"'); + jsoncons::detail::escape_string(sv.data(), sv.length(),options_.escape_all_non_ascii(),options_.escape_solidus(),result_); + result_.push_back('\"'); + break; + } + } + + if (!stack_.empty()) + { + stack_.back().increment_count(); + } + return true; + } + + bool do_byte_string_value(const byte_string_view& b, + semantic_tag tag, + const ser_context&) override + { + if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) + { + result_.push_back(','); + } + + byte_string_chars_format encoding_hint; + switch (tag) + { + case semantic_tag::base16: + encoding_hint = byte_string_chars_format::base16; + break; + case semantic_tag::base64: + encoding_hint = byte_string_chars_format::base64; + break; + case semantic_tag::base64url: + encoding_hint = byte_string_chars_format::base64url; + break; + default: + encoding_hint = byte_string_chars_format::none; + break; + } + + byte_string_chars_format format = jsoncons::detail::resolve_byte_string_chars_format(options_.byte_string_format(), + encoding_hint, + byte_string_chars_format::base64url); + switch (format) + { + case byte_string_chars_format::base16: + { + result_.push_back('\"'); + encode_base16(b.begin(),b.end(),result_); + result_.push_back('\"'); + break; + } + case byte_string_chars_format::base64: + { + result_.push_back('\"'); + encode_base64(b.begin(), b.end(), result_); + result_.push_back('\"'); + break; + } + case byte_string_chars_format::base64url: + { + result_.push_back('\"'); + encode_base64url(b.begin(),b.end(),result_); + result_.push_back('\"'); + break; + } + default: + { + JSONCONS_UNREACHABLE(); + } + } + + if (!stack_.empty()) + { + stack_.back().increment_count(); + } + return true; + } + + bool do_double_value(double value, + semantic_tag, + const ser_context& context) override + { + if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) + { + result_.push_back(','); + } + + if (JSONCONS_UNLIKELY(!std::isfinite(value))) + { + if ((std::isnan)(value)) + { + if (options_.is_nan_to_num()) + { + result_.append(options_.nan_to_num().data(), options_.nan_to_num().length()); + } + else if (options_.is_nan_to_str()) + { + do_string_value(options_.nan_to_str(), semantic_tag::none, context); + } + else + { + result_.append(null_k().data(), null_k().size()); + } + } + else if (value == std::numeric_limits::infinity()) + { + if (options_.is_inf_to_num()) + { + result_.append(options_.inf_to_num().data(), options_.inf_to_num().length()); + } + else if (options_.is_inf_to_str()) + { + do_string_value(options_.inf_to_str(), semantic_tag::none, context); + } + else + { + result_.append(null_k().data(), null_k().size()); + } + } + else + { + if (options_.is_neginf_to_num()) + { + result_.append(options_.neginf_to_num().data(), options_.neginf_to_num().length()); + } + else if (options_.is_neginf_to_str()) + { + do_string_value(options_.neginf_to_str(), semantic_tag::none, context); + } + else + { + result_.append(null_k().data(), null_k().size()); + } + } + } + else + { + fp_(value, result_); + } + + if (!stack_.empty()) + { + stack_.back().increment_count(); + } + return true; + } + + bool do_int64_value(int64_t value, + semantic_tag, + const ser_context&) override + { + if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) + { + result_.push_back(','); + } + jsoncons::detail::print_integer(value, result_); + if (!stack_.empty()) + { + stack_.back().increment_count(); + } + return true; + } + + bool do_uint64_value(uint64_t value, + semantic_tag, + const ser_context&) override + { + if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) + { + result_.push_back(','); + } + jsoncons::detail::print_uinteger(value, result_); + if (!stack_.empty()) + { + stack_.back().increment_count(); + } + return true; + } + + bool do_bool_value(bool value, semantic_tag, const ser_context&) override + { + if (!stack_.empty() && stack_.back().is_array() && stack_.back().count() > 0) + { + result_.push_back(','); + } + + if (value) + { + result_.append(true_k().data(), true_k().size()); + } + else + { + result_.append(false_k().data(), false_k().size()); + } + + if (!stack_.empty()) + { + stack_.back().increment_count(); + } + return true; + } +}; + +typedef basic_json_encoder> json_stream_encoder; +typedef basic_json_encoder> wjson_stream_encoder; +typedef basic_json_compressed_encoder> json_compressed_stream_encoder; +typedef basic_json_compressed_encoder> wjson_compressed_stream_encoder; + +typedef basic_json_encoder> json_string_encoder; +typedef basic_json_encoder> wjson_string_encoder; +typedef basic_json_compressed_encoder> json_compressed_string_encoder; +typedef basic_json_compressed_encoder> wjson_compressed_string_encoder; + +#if !defined(JSONCONS_NO_DEPRECATED) +template> +using basic_json_serializer = basic_json_encoder; + +template> +using basic_json_compressed_serializer = basic_json_compressed_encoder; + +JSONCONS_DEPRECATED("Instead, use json_stream_encoder") typedef json_stream_encoder json_encoder; +JSONCONS_DEPRECATED("Instead, use wjson_stream_encoder") typedef wjson_stream_encoder wjson_encoder; +JSONCONS_DEPRECATED("Instead, use json_compressed_stream_encoder") typedef json_compressed_stream_encoder json_compressed_encoder; +JSONCONS_DEPRECATED("Instead, use wjson_compressed_stream_encoder") typedef wjson_compressed_stream_encoder wjson_compressed_encoder; + +JSONCONS_DEPRECATED("Instead, use json_stream_encoder") typedef basic_json_encoder> json_serializer; +JSONCONS_DEPRECATED("Instead, use wjson_stream_encoder") typedef basic_json_encoder> wjson_serializer; + +JSONCONS_DEPRECATED("Instead, use json_compressed_stream_encoder") typedef basic_json_compressed_encoder> json_compressed_serializer; +JSONCONS_DEPRECATED("Instead, use wjson_compressed_stream_encoder") typedef basic_json_compressed_encoder> wjson_compressed_serializer; + +JSONCONS_DEPRECATED("Instead, use json_string_encoder") typedef basic_json_encoder> json_string_serializer; +JSONCONS_DEPRECATED("Instead, use wjson_string_encoder") typedef basic_json_encoder> wjson_string_serializer; + +JSONCONS_DEPRECATED("Instead, use json_compressed_string_encoder") typedef basic_json_compressed_encoder> json_compressed_string_serializer; +JSONCONS_DEPRECATED("Instead, use wjson_compressed_string_encoder") typedef basic_json_compressed_encoder> wjson_compressed_string_serializer; +#endif + +} +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_error_category.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_error.hpp similarity index 60% rename from invehicle-apps/3rd-party-libs/jsoncons/json_error_category.hpp rename to invehicle-apps/3rd-party-libs/jsoncons/json_error.hpp index c09b847..ff10546 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_error_category.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_error.hpp @@ -4,15 +4,15 @@ // See https://github.com/danielaparker/jsoncons for latest version -#ifndef JSONCONS_JSON_ERROR_CATEGORY_HPP -#define JSONCONS_JSON_ERROR_CATEGORY_HPP +#ifndef JSONCONS_JSON_ERROR_HPP +#define JSONCONS_JSON_ERROR_HPP #include -#include +#include namespace jsoncons { - enum class json_parser_errc + enum class json_errc { ok = 0, unexpected_eof = 1, @@ -50,71 +50,71 @@ class json_error_category_impl : public std::error_category { public: - virtual const char* name() const JSONCONS_NOEXCEPT + const char* name() const noexcept override { - return "jsoncons"; + return "jsoncons/json"; } - virtual std::string message(int ev) const + std::string message(int ev) const override { - switch (static_cast(ev)) + switch (static_cast(ev)) { - case json_parser_errc::unexpected_eof: + case json_errc::unexpected_eof: return "Unexpected end of file"; - case json_parser_errc::source_error: + case json_errc::source_error: return "Source error"; - case json_parser_errc::invalid_json_text: + case json_errc::invalid_json_text: return "Invalid JSON text"; - case json_parser_errc::extra_character: + case json_errc::extra_character: return "Unexpected non-whitespace character after JSON text"; - case json_parser_errc::max_depth_exceeded: + case json_errc::max_depth_exceeded: return "Maximum JSON depth exceeded"; - case json_parser_errc::single_quote: + case json_errc::single_quote: return "JSON strings cannot be quoted with single quotes"; - case json_parser_errc::illegal_character_in_string: + case json_errc::illegal_character_in_string: return "Illegal character in string"; - case json_parser_errc::extra_comma: + case json_errc::extra_comma: return "Extra comma"; - case json_parser_errc::expected_name: + case json_errc::expected_name: return "Expected object member name"; - case json_parser_errc::expected_value: + case json_errc::expected_value: return "Expected value"; - case json_parser_errc::invalid_value: + case json_errc::invalid_value: return "Invalid value"; - case json_parser_errc::expected_colon: + case json_errc::expected_colon: return "Expected name separator ':'"; - case json_parser_errc::illegal_control_character: + case json_errc::illegal_control_character: return "Illegal control character in string"; - case json_parser_errc::illegal_escaped_character: + case json_errc::illegal_escaped_character: return "Illegal escaped character in string"; - case json_parser_errc::expected_codepoint_surrogate_pair: + case json_errc::expected_codepoint_surrogate_pair: return "Invalid codepoint, expected another \\u token to begin the second half of a codepoint surrogate pair."; - case json_parser_errc::invalid_hex_escape_sequence: + case json_errc::invalid_hex_escape_sequence: return "Invalid codepoint, expected hexadecimal digit."; - case json_parser_errc::invalid_unicode_escape_sequence: + case json_errc::invalid_unicode_escape_sequence: return "Invalid codepoint, expected four hexadecimal digits."; - case json_parser_errc::leading_zero: + case json_errc::leading_zero: return "A number cannot have a leading zero"; - case json_parser_errc::invalid_number: + case json_errc::invalid_number: return "Invalid number"; - case json_parser_errc::expected_comma_or_right_brace: - return "Expected comma or right brace ']'"; - case json_parser_errc::expected_comma_or_right_bracket: + case json_errc::expected_comma_or_right_brace: + return "Expected comma or right brace '}'"; + case json_errc::expected_comma_or_right_bracket: return "Expected comma or right bracket ']'"; - case json_parser_errc::unexpected_right_brace: + case json_errc::unexpected_right_brace: return "Unexpected right brace '}'"; - case json_parser_errc::unexpected_right_bracket: + case json_errc::unexpected_right_bracket: return "Unexpected right bracket ']'"; - case json_parser_errc::illegal_comment: + case json_errc::illegal_comment: return "Illegal comment"; - case json_parser_errc::expected_continuation_byte: + case json_errc::expected_continuation_byte: return "Expected continuation byte"; - case json_parser_errc::over_long_utf8_sequence: + case json_errc::over_long_utf8_sequence: return "Over long UTF-8 sequence"; - case json_parser_errc::illegal_codepoint: + case json_errc::illegal_codepoint: return "Illegal codepoint (>= 0xd800 && <= 0xdfff)"; - case json_parser_errc::illegal_surrogate_value: + case json_errc::illegal_surrogate_value: return "UTF-16 surrogate values are illegal in UTF-32"; - case json_parser_errc::unpaired_high_surrogate: + case json_errc::unpaired_high_surrogate: return "Expected low surrogate following the high surrogate"; default: return "Unknown JSON parser error"; @@ -130,17 +130,22 @@ const std::error_category& json_error_category() } inline -std::error_code make_error_code(json_parser_errc result) +std::error_code make_error_code(json_errc result) { return std::error_code(static_cast(result),json_error_category()); } +#if !defined(JSONCONS_NO_DEPRECATED) +JSONCONS_DEPRECATED("Instead, use json_errc") typedef json_errc json_parser_errc; + +JSONCONS_DEPRECATED("Instead, use json_errc") typedef json_errc json_parse_errc; +#endif } namespace std { template<> - struct is_error_code_enum : public true_type + struct is_error_code_enum : public true_type { }; } diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_exception.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_exception.hpp index 668fa3c..f360dc2 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_exception.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_exception.hpp @@ -7,17 +7,11 @@ #ifndef JSON_EXCEPTION_HPP #define JSON_EXCEPTION_HPP -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include // std::string +#include // std::ostringstream +#include // std::error_code +#include // unicons::convert +#include namespace jsoncons { @@ -26,21 +20,21 @@ namespace jsoncons { class json_exception { public: - virtual const char* what() const JSONCONS_NOEXCEPT = 0; + virtual const char* what() const noexcept = 0; }; template -class json_exception_impl : public Base, public virtual json_exception +class json_runtime_error : public Base, public virtual json_exception { public: - json_exception_impl(const std::string& s) JSONCONS_NOEXCEPT + json_runtime_error(const std::string& s) noexcept : Base(""), message_(s) { } - ~json_exception_impl() JSONCONS_NOEXCEPT + ~json_runtime_error() noexcept { } - const char* what() const JSONCONS_NOEXCEPT override + const char* what() const noexcept override { return message_.c_str(); } @@ -52,7 +46,7 @@ class key_not_found : public std::out_of_range, public virtual json_exception { public: template - explicit key_not_found(const CharT* key, size_t length) JSONCONS_NOEXCEPT + explicit key_not_found(const CharT* key, size_t length) noexcept : std::out_of_range("") { buffer_.append("Key '"); @@ -60,10 +54,10 @@ class key_not_found : public std::out_of_range, public virtual json_exception unicons::conv_flags::strict); buffer_.append("' not found"); } - ~key_not_found() JSONCONS_NOEXCEPT + ~key_not_found() noexcept { } - const char* what() const JSONCONS_NOEXCEPT override + const char* what() const noexcept override { return buffer_.c_str(); } @@ -75,7 +69,7 @@ class not_an_object : public std::runtime_error, public virtual json_exception { public: template - explicit not_an_object(const CharT* key, size_t length) JSONCONS_NOEXCEPT + explicit not_an_object(const CharT* key, size_t length) noexcept : std::runtime_error("") { buffer_.append("Attempting to access or modify '"); @@ -83,10 +77,10 @@ class not_an_object : public std::runtime_error, public virtual json_exception unicons::conv_flags::strict); buffer_.append("' on a value that is not an object"); } - ~not_an_object() JSONCONS_NOEXCEPT + ~not_an_object() noexcept { } - const char* what() const JSONCONS_NOEXCEPT override + const char* what() const noexcept override { return buffer_.c_str(); } @@ -94,12 +88,96 @@ class not_an_object : public std::runtime_error, public virtual json_exception std::string buffer_; }; +class ser_error : public std::system_error, public virtual json_exception +{ +public: + ser_error(std::error_code ec) + : std::system_error(ec), line_number_(0), column_number_(0) + { + } + ser_error(std::error_code ec, size_t position) + : std::system_error(ec), line_number_(0), column_number_(position) + { + } + ser_error(std::error_code ec, size_t line, size_t column) + : std::system_error(ec), line_number_(line), column_number_(column) + { + } + ser_error(const ser_error& other) = default; + + ser_error(ser_error&& other) = default; + + const char* what() const noexcept override + { + try + { + std::ostringstream os; + os << this->code().message(); + if (line_number_ != 0 && column_number_ != 0) + { + os << " at line " << line_number_ << " and column " << column_number_; + } + else if (column_number_ != 0) + { + os << " at position " << column_number_; + } + const_cast(buffer_) = os.str(); + return buffer_.c_str(); + } + catch (...) + { + return std::system_error::what(); + } + } + + size_t line() const noexcept + { + return line_number_; + } + + size_t column() const noexcept + { + return column_number_; + } + +#if !defined(JSONCONS_NO_DEPRECATED) + JSONCONS_DEPRECATED("Instead, use line()") + size_t line_number() const noexcept + { + return line(); + } + + JSONCONS_DEPRECATED("Instead, use column()") + size_t column_number() const noexcept + { + return column(); + } +#endif +private: + std::string buffer_; + size_t line_number_; + size_t column_number_; +}; + +#if !defined(JSONCONS_NO_DEPRECATED) +JSONCONS_DEPRECATED("Instead, use ser_error") typedef ser_error serialization_error; +JSONCONS_DEPRECATED("Instead, use ser_error") typedef ser_error json_parse_exception; +JSONCONS_DEPRECATED("Instead, use ser_error") typedef ser_error parse_exception; +JSONCONS_DEPRECATED("Instead, use ser_error") typedef ser_error parse_error; +#endif + #define JSONCONS_STR2(x) #x #define JSONCONS_STR(x) JSONCONS_STR2(x) +#ifdef _DEBUG #define JSONCONS_ASSERT(x) if (!(x)) { \ - throw jsoncons::json_exception_impl("assertion '" #x "' failed at " __FILE__ ":" \ + throw jsoncons::json_runtime_error("assertion '" #x "' failed at " __FILE__ ":" \ JSONCONS_STR(__LINE__)); } +#else +#define JSONCONS_ASSERT(x) if (!(x)) { \ + throw jsoncons::json_runtime_error("assertion '" #x "' failed at <> :" \ + JSONCONS_STR( 0 )); } +#endif // _DEBUG #define JSONCONS_THROW(x) throw (x) diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_filter.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_filter.hpp index c5bb5ab..2b5bc91 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_filter.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_filter.hpp @@ -10,7 +10,6 @@ #include #include -#include namespace jsoncons { @@ -18,124 +17,134 @@ template class basic_json_filter : public basic_json_content_handler { public: - using typename basic_json_content_handler::string_view_type ; + using typename basic_json_content_handler::string_view_type; private: - basic_json_content_handler& content_handler_; - basic_json_content_handler& downstream_handler_; + basic_json_content_handler& to_handler_; // noncopyable and nonmoveable basic_json_filter(const basic_json_filter&) = delete; basic_json_filter& operator=(const basic_json_filter&) = delete; public: basic_json_filter(basic_json_content_handler& handler) - : content_handler_(*this), - downstream_handler_(handler) + : to_handler_(handler) { } + basic_json_content_handler& to_handler() + { + return to_handler_; + } + #if !defined(JSONCONS_NO_DEPRECATED) + JSONCONS_DEPRECATED("Instead, use to_handler") basic_json_content_handler& input_handler() { - return downstream_handler_; + return to_handler_; } -#endif + JSONCONS_DEPRECATED("Instead, use to_handler") basic_json_content_handler& downstream_handler() { - return downstream_handler_; + return to_handler_; } -private: - void do_begin_json() override + JSONCONS_DEPRECATED("Instead, use to_handler") + basic_json_content_handler& destination_handler() { - downstream_handler_.begin_json(); + return to_handler_; } +#endif - void do_end_json() override +private: + void do_flush() override { - downstream_handler_.end_json(); + to_handler_.flush(); } - void do_begin_object(const serializing_context& context) override + bool do_begin_object(semantic_tag tag, const ser_context& context) override { - downstream_handler_.begin_object(context); + return to_handler_.begin_object(tag, context); } - void do_begin_object(size_t length, const serializing_context& context) override + bool do_begin_object(size_t length, semantic_tag tag, const ser_context& context) override { - downstream_handler_.begin_object(length, context); + return to_handler_.begin_object(length, tag, context); } - void do_end_object(const serializing_context& context) override + bool do_end_object(const ser_context& context) override { - downstream_handler_.end_object(context); + return to_handler_.end_object(context); } - void do_begin_array(const serializing_context& context) override + bool do_begin_array(semantic_tag tag, const ser_context& context) override { - downstream_handler_.begin_array(context); + return to_handler_.begin_array(tag, context); } - void do_begin_array(size_t length, const serializing_context& context) override + bool do_begin_array(size_t length, semantic_tag tag, const ser_context& context) override { - downstream_handler_.begin_array(length, context); + return to_handler_.begin_array(length, tag, context); } - void do_end_array(const serializing_context& context) override + bool do_end_array(const ser_context& context) override { - downstream_handler_.end_array(context); + return to_handler_.end_array(context); } - void do_name(const string_view_type& name, - const serializing_context& context) override + bool do_name(const string_view_type& name, + const ser_context& context) override { - downstream_handler_.name(name,context); + return to_handler_.name(name, context); } - void do_string_value(const string_view_type& value, - const serializing_context& context) override + bool do_string_value(const string_view_type& value, + semantic_tag tag, + const ser_context& context) override { - downstream_handler_.string_value(value,context); + return to_handler_.string_value(value, tag, context); } - void do_byte_string_value(const uint8_t* data, size_t length, - const serializing_context& context) override + bool do_byte_string_value(const byte_string_view& b, + semantic_tag tag, + const ser_context& context) override { - downstream_handler_.byte_string_value(data, length, context); + return to_handler_.byte_string_value(b, tag, context); } - void do_double_value(double value, const number_format& fmt, - const serializing_context& context) override + bool do_double_value(double value, + semantic_tag tag, + const ser_context& context) override { - downstream_handler_.double_value(value, fmt, context); + return to_handler_.double_value(value, tag, context); } - void do_integer_value(int64_t value, - const serializing_context& context) override + bool do_int64_value(int64_t value, + semantic_tag tag, + const ser_context& context) override { - downstream_handler_.integer_value(value,context); + return to_handler_.int64_value(value, tag, context); } - void do_uinteger_value(uint64_t value, - const serializing_context& context) override + bool do_uint64_value(uint64_t value, + semantic_tag tag, + const ser_context& context) override { - downstream_handler_.uinteger_value(value,context); + return to_handler_.uint64_value(value, tag, context); } - void do_bool_value(bool value, - const serializing_context& context) override + bool do_bool_value(bool value, semantic_tag tag, const ser_context& context) override { - downstream_handler_.bool_value(value,context); + return to_handler_.bool_value(value, tag, context); } - void do_null_value(const serializing_context& context) override + bool do_null_value(semantic_tag tag, const ser_context& context) override { - downstream_handler_.null_value(context); + return to_handler_.null_value(tag, context); } }; -// Filters out begin_json and end_json events +// Filters out begin_document and end_document events template class basic_json_fragment_filter : public basic_json_filter { @@ -147,11 +156,7 @@ class basic_json_fragment_filter : public basic_json_filter { } private: - void do_begin_json() override - { - } - - void do_end_json() override + void do_flush() override { } }; @@ -175,20 +180,195 @@ class basic_rename_object_member_filter : public basic_json_filter } private: - void do_name(const string_view_type& name, - const serializing_context& context) override + bool do_name(const string_view_type& name, + const ser_context& context) override { if (name == name_) { - this->downstream_handler().name(new_name_,context); + return this->to_handler().name(new_name_,context); } else { - this->downstream_handler().name(name,context); + return this->to_handler().name(name,context); } } }; +template +class json_content_handler_adaptor : public From +{ +public: + using typename From::string_view_type; +private: + To* to_handler_; + + // noncopyable + json_content_handler_adaptor(const json_content_handler_adaptor&) = delete; + json_content_handler_adaptor& operator=(const json_content_handler_adaptor&) = delete; +public: + + json_content_handler_adaptor() + : to_handler_(nullptr) + { + } + json_content_handler_adaptor(To& handler) + : to_handler_(std::addressof(handler)) + { + } + + // moveable + json_content_handler_adaptor(json_content_handler_adaptor&&) = default; + json_content_handler_adaptor& operator=(json_content_handler_adaptor&&) = default; + + To& to_handler() + { + return *to_handler_; + } + +private: + void do_flush() override + { + to_handler_->flush(); + } + + bool do_begin_object(semantic_tag tag, + const ser_context& context) override + { + return to_handler_->begin_object(tag, context); + } + + bool do_begin_object(size_t length, + semantic_tag tag, + const ser_context& context) override + { + return to_handler_->begin_object(length, tag, context); + } + + bool do_end_object(const ser_context& context) override + { + return to_handler_->end_object(context); + } + + bool do_begin_array(semantic_tag tag, + const ser_context& context) override + { + return to_handler_->begin_array(tag, context); + } + + bool do_begin_array(size_t length, + semantic_tag tag, + const ser_context& context) override + { + return to_handler_->begin_array(length, tag, context); + } + + bool do_end_array(const ser_context& context) override + { + return to_handler_->end_array(context); + } + + bool do_name(const string_view_type& name, + const ser_context& context) override + { + std::basic_string target; + auto result = unicons::convert(name.begin(),name.end(),std::back_inserter(target),unicons::conv_flags::strict); + if (result.ec != unicons::conv_errc()) + { + throw ser_error(result.ec); + } + return to_handler().name(target, context); + } + + bool do_string_value(const string_view_type& value, + semantic_tag tag, + const ser_context& context) override + { + std::basic_string target; + auto result = unicons::convert(value.begin(),value.end(),std::back_inserter(target),unicons::conv_flags::strict); + if (result.ec != unicons::conv_errc()) + { + throw ser_error(result.ec); + } + return to_handler().string_value(target, tag, context); + } + + bool do_byte_string_value(const byte_string_view& b, + semantic_tag tag, + const ser_context& context) override + { + return to_handler_->byte_string_value(b, tag, context); + } + + bool do_double_value(double value, + semantic_tag tag, + const ser_context& context) override + { + return to_handler_->double_value(value, tag, context); + } + + bool do_int64_value(int64_t value, + semantic_tag tag, + const ser_context& context) override + { + return to_handler_->int64_value(value, tag, context); + } + + bool do_uint64_value(uint64_t value, + semantic_tag tag, + const ser_context& context) override + { + return to_handler_->uint64_value(value, tag, context); + } + + bool do_bool_value(bool value, semantic_tag tag, const ser_context& context) override + { + return to_handler_->bool_value(value, tag, context); + } + + bool do_null_value(semantic_tag tag, const ser_context& context) override + { + return to_handler_->null_value(tag, context); + } + +}; + +template +class json_content_handler_adaptor::value>::type> +{ +public: + typedef typename From::char_type char_type; + typedef typename From::char_traits_type char_traits_type; + typedef typename From::string_view_type string_view_type; +private: + To* to_handler_; +public: + json_content_handler_adaptor() + : to_handler_(nullptr) + { + } + json_content_handler_adaptor(To& handler) + : to_handler_(std::addressof(handler)) + { + } + + operator From&() { return *to_handler_; } + + // moveable + json_content_handler_adaptor(json_content_handler_adaptor&&) = default; + json_content_handler_adaptor& operator=(json_content_handler_adaptor&&) = default; + + To& to_handler() + { + return *to_handler_; + } +}; + +template +json_content_handler_adaptor make_json_content_handler_adaptor(To& to) +{ + return json_content_handler_adaptor(to); +} + typedef basic_json_filter json_filter; typedef basic_json_filter wjson_filter; typedef basic_rename_object_member_filter rename_object_member_filter; diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_fwd.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_fwd.hpp index 6ef5a5a..d9b44cf 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_fwd.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_fwd.hpp @@ -4,15 +4,10 @@ // See https://github.com/danielaparker/jsoncons for latest version -#ifndef JSONCONS_JSONFWD_HPP -#define JSONCONS_JSONFWD_HPP +#ifndef JSONCONS_JSON_FWD_HPP +#define JSONCONS_JSON_FWD_HPP -#include - -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wswitch" -#endif +#include // std::allocator namespace jsoncons { @@ -25,8 +20,4 @@ class basic_json; } -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - #endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_options.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_options.hpp new file mode 100644 index 0000000..b882d48 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_options.hpp @@ -0,0 +1,859 @@ +// Copyright 2013 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_JSON_OPTIONS_HPP +#define JSONCONS_JSON_OPTIONS_HPP + +#include +#include // std::numeric_limits +#include +#include +#include + +namespace jsoncons { + +#if !defined(JSONCONS_NO_TO_CHARS) +using chars_format = std::chars_format; +#else +enum class chars_format : uint8_t {fixed=1,scientific=2,hex=4,general=fixed|scientific}; +#endif + +// floating_point_options + +class floating_point_options +{ + chars_format format_; + int precision_; + uint8_t decimal_places_; +public: + floating_point_options() + : format_(chars_format::general), precision_(0), decimal_places_(0) + { + } + + floating_point_options(chars_format format, int precision, uint8_t decimal_places = 0) + : format_(format), precision_(precision), decimal_places_(decimal_places) + { + } + + explicit floating_point_options(chars_format format) + : format_(format), precision_(0), decimal_places_(0) + { + } + + floating_point_options(const floating_point_options&) = default; + floating_point_options(floating_point_options&&) = default; + floating_point_options& operator=(const floating_point_options& e) = default; + floating_point_options& operator=(floating_point_options&& e) = default; + + int precision() const + { + return precision_; + } + + uint8_t decimal_places() const + { + return decimal_places_; + } + + chars_format format() const + { + return format_; + } +}; + +enum class indenting : uint8_t {no_indent = 0, indent = 1}; + +enum class line_split_kind : uint8_t {same_line,new_line,multi_line}; + +enum class bigint_chars_format : uint8_t {number, base10, base64, base64url +#if !defined(JSONCONS_NO_DEPRECATED) +,integer = number +#endif +}; + +#if !defined(JSONCONS_NO_DEPRECATED) +JSONCONS_DEPRECATED("Instead, use bigint_chars_format") typedef bigint_chars_format bignum_chars_format; +JSONCONS_DEPRECATED("Instead, use bigint_chars_format") typedef bigint_chars_format big_integer_chars_format; +#endif + +enum class byte_string_chars_format : uint8_t {none=0,base16,base64,base64url}; + +enum class spaces_option{no_spaces=0,space_after,space_before,space_before_and_after}; + +template +class basic_json_decode_options +{ +public: + typedef std::basic_string string_type; + + virtual ~basic_json_decode_options() = default; + + virtual size_t max_nesting_depth() const = 0; + + virtual bool is_str_to_nan() const = 0; + + virtual std::basic_string nan_to_str() const = 0; + + virtual bool is_str_to_inf() const = 0; + + virtual std::basic_string inf_to_str() const = 0; + + virtual bool is_str_to_neginf() const = 0; + + virtual std::basic_string neginf_to_str() const = 0; + + virtual bool lossless_number() const = 0; +}; + +template +class basic_json_encode_options +{ +public: + typedef std::basic_string string_type; + + virtual ~basic_json_encode_options() = default; + + virtual size_t max_nesting_depth() const = 0; + + virtual byte_string_chars_format byte_string_format() const = 0; + + virtual bigint_chars_format bigint_format() const = 0; + + virtual line_split_kind object_object_line_splits() const = 0; + + virtual line_split_kind array_object_line_splits() const = 0; + + virtual line_split_kind object_array_line_splits() const = 0; + + virtual line_split_kind array_array_line_splits() const = 0; + + virtual size_t indent_size() const = 0; + + virtual size_t line_length_limit() const = 0; + + virtual chars_format floating_point_format() const = 0; + + virtual int precision() const = 0; + + virtual bool escape_all_non_ascii() const = 0; + + virtual bool escape_solidus() const = 0; + + virtual spaces_option spaces_around_colon() const = 0; + + virtual spaces_option spaces_around_comma() const = 0; + + virtual bool pad_inside_object_braces() const = 0; + + virtual bool pad_inside_array_brackets() const = 0; + + virtual std::basic_string new_line_chars() const = 0; + + virtual bool is_nan_to_num() const = 0; + + virtual std::basic_string nan_to_num() const = 0; + + virtual bool is_inf_to_num() const = 0; + + virtual std::basic_string inf_to_num() const = 0; + + virtual bool is_neginf_to_num() const = 0; + + virtual std::basic_string neginf_to_num() const = 0; + + virtual bool is_nan_to_str() const = 0; + + virtual std::basic_string nan_to_str() const = 0; + + virtual bool is_inf_to_str() const = 0; + + virtual std::basic_string inf_to_str() const = 0; + + virtual bool is_neginf_to_str() const = 0; + + virtual std::basic_string neginf_to_str() const = 0; +}; + +template +class basic_json_options : public virtual basic_json_decode_options, + public virtual basic_json_encode_options +{ +public: + typedef CharT char_type; + typedef std::basic_string string_type; +private: + size_t indent_size_; + chars_format floating_point_format_; + int precision_; +#if !defined(JSONCONS_NO_DEPRECATED) + bool can_read_nan_replacement_; + bool can_read_pos_inf_replacement_; + bool can_read_neg_inf_replacement_; + string_type nan_replacement_; + string_type pos_inf_replacement_; + string_type neg_inf_replacement_; +#endif + bool escape_all_non_ascii_; + bool escape_solidus_; + byte_string_chars_format byte_string_format_; + bigint_chars_format bigint_format_; + line_split_kind object_object_line_splits_; + line_split_kind object_array_line_splits_; + line_split_kind array_array_line_splits_; + line_split_kind array_object_line_splits_; + size_t line_length_limit_; + + size_t max_nesting_depth_; + spaces_option spaces_around_colon_; + spaces_option spaces_around_comma_; + bool pad_inside_object_braces_; + bool pad_inside_array_brackets_; + std::basic_string new_line_chars_; + + bool is_nan_to_num_; + bool is_inf_to_num_; + bool is_neginf_to_num_; + bool is_nan_to_str_; + bool is_inf_to_str_; + bool is_neginf_to_str_; + bool is_str_to_nan_; + bool is_str_to_inf_; + bool is_str_to_neginf_; + + std::basic_string nan_to_num_; + std::basic_string inf_to_num_; + std::basic_string neginf_to_num_; + std::basic_string nan_to_str_; + std::basic_string inf_to_str_; + std::basic_string neginf_to_str_; + + bool lossless_number_; +public: + static const size_t indent_size_default = 4; + static const size_t line_length_limit_default = 120; + + static const basic_json_options& get_default_options() + { + static basic_json_options options{}; + return options; + } + +// Constructors + + basic_json_options() + : indent_size_(indent_size_default), + floating_point_format_(chars_format()), + precision_(0), +#if !defined(JSONCONS_NO_DEPRECATED) + can_read_nan_replacement_(false), + can_read_pos_inf_replacement_(false), + can_read_neg_inf_replacement_(false), +#endif + escape_all_non_ascii_(false), + escape_solidus_(false), + byte_string_format_(byte_string_chars_format::none), + bigint_format_(bigint_chars_format::base10), + object_object_line_splits_(line_split_kind::multi_line), + object_array_line_splits_(line_split_kind::same_line), + array_array_line_splits_(line_split_kind::new_line), + array_object_line_splits_(line_split_kind::multi_line), + line_length_limit_(line_length_limit_default), + max_nesting_depth_((std::numeric_limits::max)()), + spaces_around_colon_(spaces_option::space_after), + spaces_around_comma_(spaces_option::space_after), + pad_inside_object_braces_(false), + pad_inside_array_brackets_(false), + is_nan_to_num_(false), + is_inf_to_num_(false), + is_neginf_to_num_(false), + is_nan_to_str_(false), + is_inf_to_str_(false), + is_neginf_to_str_(false), + is_str_to_nan_(false), + is_str_to_inf_(false), + is_str_to_neginf_(false), + lossless_number_(false) + { + new_line_chars_.push_back('\n'); + } + +// Properties + byte_string_chars_format byte_string_format() const override {return byte_string_format_;} + basic_json_options& byte_string_format(byte_string_chars_format value) {byte_string_format_ = value; return *this;} + + bigint_chars_format bigint_format() const override {return bigint_format_;} + basic_json_options& bigint_format(bigint_chars_format value) {bigint_format_ = value; return *this;} + + line_split_kind object_object_line_splits() const override {return object_object_line_splits_;} + basic_json_options& object_object_line_splits(line_split_kind value) {object_object_line_splits_ = value; return *this;} + + line_split_kind array_object_line_splits() const override {return array_object_line_splits_;} + basic_json_options& array_object_line_splits(line_split_kind value) {array_object_line_splits_ = value; return *this;} + + line_split_kind object_array_line_splits() const override {return object_array_line_splits_;} + basic_json_options& object_array_line_splits(line_split_kind value) {object_array_line_splits_ = value; return *this;} + + line_split_kind array_array_line_splits() const override {return array_array_line_splits_;} + basic_json_options& array_array_line_splits(line_split_kind value) {array_array_line_splits_ = value; return *this;} + + size_t indent_size() const override + { + return indent_size_; + } + + basic_json_options& indent_size(size_t value) + { + indent_size_ = value; + return *this; + } + + spaces_option spaces_around_colon() const override + { + return spaces_around_colon_; + } + + basic_json_options& spaces_around_colon(spaces_option value) + { + spaces_around_colon_ = value; + return *this; + } + + spaces_option spaces_around_comma() const override + { + return spaces_around_comma_; + } + + basic_json_options& spaces_around_comma(spaces_option value) + { + spaces_around_comma_ = value; + return *this; + } + + bool pad_inside_object_braces() const override + { + return pad_inside_object_braces_; + } + + basic_json_options& pad_inside_object_braces(bool value) + { + pad_inside_object_braces_ = value; + return *this; + } + + bool pad_inside_array_brackets() const override + { + return pad_inside_array_brackets_; + } + + basic_json_options& pad_inside_array_brackets(bool value) + { + pad_inside_array_brackets_ = value; + return *this; + } + + std::basic_string new_line_chars() const override + { + return new_line_chars_; + } + + basic_json_options& new_line_chars(const std::basic_string& value) + { + new_line_chars_ = value; + return *this; + } + + bool is_nan_to_num() const override + { + return is_nan_to_num_; + } + + bool is_inf_to_num() const override + { + return is_inf_to_num_; + } + + bool is_neginf_to_num() const override + { + return is_neginf_to_num_ || is_inf_to_num_; + } + + bool is_nan_to_str() const override + { + return is_nan_to_str_; + } + + bool is_str_to_nan() const override + { + return is_str_to_nan_; + } + + bool is_inf_to_str() const override + { + return is_inf_to_str_; + } + + bool is_str_to_inf() const override + { + return is_str_to_inf_; + } + + bool is_neginf_to_str() const override + { + return is_neginf_to_str_ || is_inf_to_str_; + } + + bool is_str_to_neginf() const override + { + return is_str_to_neginf_ || is_str_to_inf_; + } + + std::basic_string nan_to_num() const override + { + if (is_nan_to_num_) + { + return nan_to_num_; + } +#if !defined(JSONCONS_NO_DEPRECATED) + else if (!can_read_nan_replacement_) // not string + { + return nan_replacement_; + } +#endif + else + { + return nan_to_num_; // empty string + } + } + + basic_json_options& nan_to_num(const std::basic_string& value) + { + is_nan_to_num_ = true; + nan_to_str_.clear(); + nan_to_num_ = value; + return *this; + } + + std::basic_string inf_to_num() const override + { + if (is_inf_to_num_) + { + return inf_to_num_; + } +#if !defined(JSONCONS_NO_DEPRECATED) + else if (!can_read_pos_inf_replacement_) // not string + { + return pos_inf_replacement_; + } +#endif + else + { + return inf_to_num_; // empty string + } + } + + basic_json_options& inf_to_num(const std::basic_string& value) + { + is_inf_to_num_ = true; + inf_to_str_.clear(); + inf_to_num_ = value; + return *this; + } + + std::basic_string neginf_to_num() const override + { + if (is_neginf_to_num_) + { + return neginf_to_num_; + } + else if (is_inf_to_num_) + { + std::basic_string s; + s.push_back('-'); + s.append(inf_to_num_); + return s; + } +#if !defined(JSONCONS_NO_DEPRECATED) + else if (!can_read_neg_inf_replacement_) // not string + { + return neg_inf_replacement_; + } +#endif + else + { + return neginf_to_num_; // empty string + } + } + + basic_json_options& neginf_to_num(const std::basic_string& value) + { + is_neginf_to_num_ = true; + neginf_to_str_.clear(); + neginf_to_num_ = value; + return *this; + } + + std::basic_string nan_to_str() const override + { + if (is_nan_to_str_) + { + return nan_to_str_; + } +#if !defined(JSONCONS_NO_DEPRECATED) + else if (can_read_nan_replacement_ && nan_replacement_.size() >= 2) // string + { + return nan_replacement_.substr(1,nan_replacement_.size()-2); // Remove quotes + } +#endif + else + { + return nan_to_str_; // empty string + } + } + + basic_json_options& nan_to_str(const std::basic_string& value, bool is_str_to_nan = true) + { + is_nan_to_str_ = true; + is_str_to_nan_ = is_str_to_nan; + nan_to_num_.clear(); + nan_to_str_ = value; + return *this; + } + + std::basic_string inf_to_str() const override + { + if (is_inf_to_str_) + { + return inf_to_str_; + } +#if !defined(JSONCONS_NO_DEPRECATED) + else if (can_read_pos_inf_replacement_ && pos_inf_replacement_.size() >= 2) // string + { + return pos_inf_replacement_.substr(1,pos_inf_replacement_.size()-2); // Strip quotes + } +#endif + else + { + return inf_to_str_; // empty string + } + } + + basic_json_options& inf_to_str(const std::basic_string& value, bool is_inf_to_str = true) + { + is_inf_to_str_ = true; + is_inf_to_str_ = is_inf_to_str; + inf_to_num_.clear(); + inf_to_str_ = value; + return *this; + } + + std::basic_string neginf_to_str() const override + { + if (is_neginf_to_str_) + { + return neginf_to_str_; + } + else if (is_inf_to_str_) + { + std::basic_string s; + s.push_back('-'); + s.append(inf_to_str_); + return s; + } +#if !defined(JSONCONS_NO_DEPRECATED) + else if (can_read_neg_inf_replacement_ && neg_inf_replacement_.size() >= 2) // string + { + return neg_inf_replacement_.substr(1,neg_inf_replacement_.size()-2); // Strip quotes + } +#endif + else + { + return neginf_to_str_; // empty string + } + } + + basic_json_options& neginf_to_str(const std::basic_string& value, bool is_neginf_to_str = true) + { + is_neginf_to_str_ = true; + is_neginf_to_str_ = is_neginf_to_str; + neginf_to_num_.clear(); + neginf_to_str_ = value; + return *this; + } + + bool lossless_number() const override + { + return lossless_number_; + } + + basic_json_options& lossless_number(bool value) + { + lossless_number_ = value; + return *this; + } + + size_t line_length_limit() const override + { + return line_length_limit_; + } + + basic_json_options& line_length_limit(size_t value) + { + line_length_limit_ = value; + return *this; + } + + chars_format floating_point_format() const override + { + return floating_point_format_; + } + + basic_json_options& floating_point_format(chars_format value) + { + floating_point_format_ = value; + return *this; + } + + int precision() const override + { + return precision_; + } + + basic_json_options& precision(int value) + { + precision_ = value; + return *this; + } + + bool escape_all_non_ascii() const override + { + return escape_all_non_ascii_; + } + + basic_json_options& escape_all_non_ascii(bool value) + { + escape_all_non_ascii_ = value; + return *this; + } + + bool escape_solidus() const override + { + return escape_solidus_; + } + + basic_json_options& escape_solidus(bool value) + { + escape_solidus_ = value; + return *this; + } + + size_t max_nesting_depth() const override + { + return max_nesting_depth_; + } + + void max_nesting_depth(size_t value) + { + max_nesting_depth_ = value; + } + +#if !defined(JSONCONS_NO_DEPRECATED) + basic_json_options& big_integer_format(bigint_chars_format value) {bigint_format_ = value; return *this;} + bigint_chars_format bignum_format() const {return bigint_format_;} + basic_json_options& bignum_format(bigint_chars_format value) {bigint_format_ = value; return *this;} + + JSONCONS_DEPRECATED("Instead, use lossless_number()") + bool dec_to_str() const + { + return lossless_number_; + } + + JSONCONS_DEPRECATED("Instead, use lossless_number(bool)") + basic_json_options& dec_to_str(bool value) + { + lossless_number_ = value; + return *this; + } + + JSONCONS_DEPRECATED("Instead, use indent_size()") + size_t indent() const + { + return indent_size(); + } + + JSONCONS_DEPRECATED("Instead, use indent_size(size_t)") + basic_json_options& indent(size_t value) + { + return indent_size(value); + } + + JSONCONS_DEPRECATED("Instead, use is_nan_to_num() or is_nan_to_str()") + bool can_read_nan_replacement() const {return can_read_nan_replacement_;} + + JSONCONS_DEPRECATED("Instead, use is_inf_to_num() or is_inf_to_str()") + bool can_read_pos_inf_replacement() const {return can_read_pos_inf_replacement_;} + + JSONCONS_DEPRECATED("Instead, use is_neginf_to_num() or is_neginf_to_str()") + bool can_read_neg_inf_replacement() const {return can_read_neg_inf_replacement_;} + + bool can_write_nan_replacement() const {return !nan_replacement_.empty();} + + bool can_write_pos_inf_replacement() const {return !pos_inf_replacement_.empty();} + + bool can_write_neg_inf_replacement() const {return !neg_inf_replacement_.empty();} + + JSONCONS_DEPRECATED("Instead, use inf_to_num(const std::basic_string&) or inf_to_str(const std::basic_string&)") + basic_json_options& replace_inf(bool replace) + { + can_read_pos_inf_replacement_ = replace; + can_read_neg_inf_replacement_ = replace; + return *this; + } + + JSONCONS_DEPRECATED("Instead, use inf_to_num(const std::basic_string&) or inf_to_str(const std::basic_string&)") + basic_json_options& replace_pos_inf(bool replace) + { + can_read_pos_inf_replacement_ = replace; + return *this; + } + + JSONCONS_DEPRECATED("Instead, use neginf_to_num(const std::basic_string&) or neginf_to_str(const std::basic_string&)") + basic_json_options& replace_neg_inf(bool replace) + { + can_read_neg_inf_replacement_ = replace; + return *this; + } + + JSONCONS_DEPRECATED("Instead, use nan_to_num() or nan_to_str()") + const string_type& nan_replacement() const + { + return nan_replacement_; + } + + JSONCONS_DEPRECATED("Instead, use nan_to_num(const std::basic_string&) or nan_to_str(const std::basic_string&)") + basic_json_options& nan_replacement(const string_type& value) + { + nan_replacement_ = value; + + can_read_nan_replacement_ = is_string(value); + + return *this; + } + + JSONCONS_DEPRECATED("Instead, use inf_to_num() or inf_to_str()") + const string_type& pos_inf_replacement() const + { + return pos_inf_replacement_; + } + + JSONCONS_DEPRECATED("Instead, use inf_to_num(const std::basic_string&) or inf_to_str(const std::basic_string&)") + basic_json_options& pos_inf_replacement(const string_type& value) + { + pos_inf_replacement_ = value; + can_read_pos_inf_replacement_ = is_string(value); + return *this; + } + + JSONCONS_DEPRECATED("Instead, use neginf_to_num() or neginf_to_str()") + const string_type& neg_inf_replacement() const + { + return neg_inf_replacement_; + } + + JSONCONS_DEPRECATED("Instead, use neginf_to_num(const std::basic_string&) or neginf_to_str(const std::basic_string&)") + basic_json_options& neg_inf_replacement(const string_type& value) + { + neg_inf_replacement_ = value; + can_read_neg_inf_replacement_ = is_string(value); + return *this; + } + + JSONCONS_DEPRECATED("Instead, use object_object_line_splits()") + line_split_kind object_object_split_lines() const {return object_object_line_splits_;} + JSONCONS_DEPRECATED("Instead, use object_object_line_splits(line_split_kind)") + basic_json_options& object_object_split_lines(line_split_kind value) {object_object_line_splits_ = value; return *this;} + + JSONCONS_DEPRECATED("Instead, use array_object_line_splits()") + line_split_kind array_object_split_lines() const {return array_object_line_splits_;} + JSONCONS_DEPRECATED("Instead, use array_object_line_splits(line_split_kind)") + basic_json_options& array_object_split_lines(line_split_kind value) {array_object_line_splits_ = value; return *this;} + + JSONCONS_DEPRECATED("Instead, use object_array_line_splits()") + line_split_kind object_array_split_lines() const {return object_array_line_splits_;} + JSONCONS_DEPRECATED("Instead, use object_array_line_splits(line_split_kind)") + basic_json_options& object_array_split_lines(line_split_kind value) {object_array_line_splits_ = value; return *this;} + + JSONCONS_DEPRECATED("Instead, use array_array_line_splits()") + line_split_kind array_array_split_lines() const {return array_array_line_splits_;} + JSONCONS_DEPRECATED("Instead, use array_array_line_splits(line_split_kind)") + basic_json_options& array_array_split_lines(line_split_kind value) {array_array_line_splits_ = value; return *this;} +#endif +private: + enum class input_state {initial,begin_quote,character,end_quote,escape,error}; + bool is_string(const string_type& s) const + { + input_state state = input_state::initial; + for (CharT c : s) + { + switch (c) + { + case '\t': case ' ': case '\n': case'\r': + break; + case '\\': + state = input_state::escape; + break; + case '\"': + switch (state) + { + case input_state::initial: + state = input_state::begin_quote; + break; + case input_state::begin_quote: + state = input_state::end_quote; + break; + case input_state::character: + state = input_state::end_quote; + break; + case input_state::end_quote: + state = input_state::error; + break; + case input_state::escape: + state = input_state::character; + break; + default: + state = input_state::character; + break; + } + break; + default: + break; + } + + } + return state == input_state::end_quote; + } +}; + +typedef basic_json_options json_options; +typedef basic_json_options wjson_options; + +typedef basic_json_decode_options json_decode_options; +typedef basic_json_decode_options wjson_decode_options; + +typedef basic_json_encode_options json_encode_options; +typedef basic_json_encode_options wjson_encode_options; + +#if !defined(JSONCONS_NO_DEPRECATED) +JSONCONS_DEPRECATED("json_options") typedef json_options output_format; +JSONCONS_DEPRECATED("wjson_options") typedef wjson_options woutput_format; +JSONCONS_DEPRECATED("json_options") typedef json_options serialization_options; +JSONCONS_DEPRECATED("wjson_options") typedef wjson_options wserialization_options; +JSONCONS_DEPRECATED("json_options") typedef json_options json_serializing_options; +JSONCONS_DEPRECATED("wjson_options") typedef wjson_options wjson_serializing_options; +#endif + +} +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_parser.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_parser.hpp index d9a7039..88e3940 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_parser.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_parser.hpp @@ -7,21 +7,19 @@ #ifndef JSONCONS_JSON_PARSER_HPP #define JSONCONS_JSON_PARSER_HPP -#include +#include // std::allocator #include -#include #include -#include -#include #include #include +#include // std::numeric_limits +#include // std::function #include #include +#include #include -#include -#include -#include -#include +#include +#include #define JSONCONS_ILLEGAL_CONTROL_CHARACTER \ case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06:case 0x07:case 0x08:case 0x0b: \ @@ -36,48 +34,72 @@ template class replacement_filter : public basic_json_filter { typedef typename basic_json_content_handler::string_view_type string_view_type; + typedef typename basic_json_options::string_type string_type; - basic_null_json_content_handler default_content_handler_; - basic_json_serializing_options options_; -public: - replacement_filter() - : basic_json_filter(default_content_handler_) - { - } + bool is_str_to_nan_; + bool is_str_to_inf_; + bool is_str_to_neginf_; + string_type nan_to_str_; + string_type inf_to_str_; + string_type neginf_to_str_; - replacement_filter(basic_json_content_handler& handler, const basic_json_serializing_options& options) - : basic_json_filter(handler), options_(options) +public: + replacement_filter() = delete; + + replacement_filter(basic_json_content_handler& handler, + bool is_str_to_nan, + bool is_str_to_inf, + bool is_str_to_neginf, + const string_type& nan_to_str, + const string_type& inf_to_str, + const string_type& neginf_to_str) + : basic_json_filter(handler), + is_str_to_nan_(is_str_to_nan), + is_str_to_inf_(is_str_to_inf), + is_str_to_neginf_(is_str_to_neginf), + nan_to_str_(nan_to_str), + inf_to_str_(inf_to_str), + neginf_to_str_(neginf_to_str) { } - void do_string_value(const string_view_type& s, const serializing_context& context) override + bool do_string_value(const string_view_type& s, + semantic_tag tag, + const ser_context& context) override { - if (options_.can_read_nan_replacement() && s == options_.nan_replacement().substr(1,options_.nan_replacement().length()-2)) - { - this->downstream_handler().double_value(std::nan(""), context); - } - else if (options_.can_read_pos_inf_replacement() && s == options_.pos_inf_replacement().substr(1,options_.pos_inf_replacement().length()-2)) - { - this->downstream_handler().double_value(std::numeric_limits::infinity(), context); - } - else if (options_.can_read_neg_inf_replacement() && s == options_.neg_inf_replacement().substr(1,options_.neg_inf_replacement().length()-2)) + if (tag == semantic_tag::none) { - this->downstream_handler().double_value(-std::numeric_limits::infinity(), context); + if (is_str_to_nan_ && s == nan_to_str_) + { + return this->to_handler().double_value(std::nan(""), tag, context); + } + else if (is_str_to_inf_ && s == inf_to_str_) + { + return this->to_handler().double_value(std::numeric_limits::infinity(), tag, context); + } + else if (is_str_to_neginf_ && s == neginf_to_str_) + { + return this->to_handler().double_value(-std::numeric_limits::infinity(), tag, context); + } + else + { + return this->to_handler().string_value(s, tag, context); + } } else { - this->downstream_handler().string_value(s, context); + return this->to_handler().string_value(s, tag, context); } } - }; } -enum class parse_state : uint8_t +enum class json_parse_state : uint8_t { root, start, + before_done, slash, slash_slash, slash_star, @@ -90,7 +112,7 @@ enum class parse_state : uint8_t expect_value_or_end, expect_value, array, - string_u1, + string, member_name, escape, escape_u1, @@ -122,279 +144,113 @@ enum class parse_state : uint8_t fal, fals, cr, - lf, done }; -template > -class basic_json_parser : private serializing_context +struct default_json_parsing { - static const size_t initial_string_buffer_capacity_ = 1024; - static const size_t initial_number_buffer_capacity_ = 64; - static const int default_initial_stack_capacity_ = 100; - typedef typename basic_json_content_handler::string_view_type string_view_type; + bool operator()(json_errc ec, const ser_context&) noexcept + { + if (ec == json_errc::illegal_comment) + { + return true; // Recover, allow comments + } + else + { + return false; + } + } +}; - detail::replacement_filter replacement_filter_; - basic_null_json_content_handler default_content_handler_; - default_parse_error_handler default_err_handler_; +struct strict_json_parsing +{ + bool operator()(json_errc, const ser_context&) noexcept + { + return false; + } +}; - basic_json_content_handler& handler_; - parse_error_handler& err_handler_; - uint32_t cp_; - uint32_t cp2_; +#if !defined(JSONCONS_NO_DEPRECATED) +JSONCONS_DEPRECATED("instead, use default_json_parsing") typedef default_json_parsing strict_parse_error_handler; +JSONCONS_DEPRECATED("instead, use strict_json_parsing") typedef strict_json_parsing default_parse_error_handler; +#endif +template > +class basic_json_parser : public ser_context +{ + typedef std::basic_string string_type; + typedef typename basic_json_content_handler::string_view_type string_view_type; typedef Allocator allocator_type; typedef typename std::allocator_traits:: template rebind_alloc char_allocator_type; typedef typename std::allocator_traits:: template rebind_alloc numeral_allocator_type; + typedef typename std::allocator_traits:: template rebind_alloc byte_allocator_type; - std::basic_string,char_allocator_type> string_buffer_; - std::basic_string,numeral_allocator_type> number_buffer_; + static const size_t initial_string_buffer_capacity_ = 1024; + static const int default_initial_stack_capacity_ = 100; - bool is_negative_; - uint8_t precision_; - uint8_t decimal_places_; + const basic_json_decode_options& options_; + std::function err_handler_; + int initial_stack_capacity_; + size_t nesting_depth_; + uint32_t cp_; + uint32_t cp2_; size_t line_; size_t column_; - size_t nesting_depth_; - int initial_stack_capacity_; - - size_t max_nesting_depth_; - detail::string_to_double to_double_; const CharT* begin_input_; const CharT* input_end_; const CharT* input_ptr_; + json_parse_state state_; + bool continue_; + bool done_; + + std::basic_string,char_allocator_type> string_buffer_; + jsoncons::detail::string_to_double to_double_; - parse_state state_; - typedef typename std::allocator_traits:: template rebind_alloc parse_state_allocator_type; - std::vector state_stack_; + typedef typename std::allocator_traits:: template rebind_alloc parse_state_allocator_type; + std::vector state_stack_; // Noncopyable and nonmoveable basic_json_parser(const basic_json_parser&) = delete; basic_json_parser& operator=(const basic_json_parser&) = delete; public: - basic_json_parser() - : handler_(default_content_handler_), - err_handler_(default_err_handler_), - cp_(0), - cp2_(0), - is_negative_(false), - precision_(0), - decimal_places_(0), - line_(1), - column_(1), - nesting_depth_(0), - initial_stack_capacity_(default_initial_stack_capacity_), - begin_input_(nullptr), - input_end_(nullptr), - input_ptr_(nullptr), - state_(parse_state::start) - { - string_buffer_.reserve(initial_string_buffer_capacity_); - number_buffer_.reserve(initial_number_buffer_capacity_); - max_nesting_depth_ = (std::numeric_limits::max)(); - - state_stack_.reserve(initial_stack_capacity_); - push_state(parse_state::root); - } - - basic_json_parser(parse_error_handler& err_handler) - : handler_(default_content_handler_), - err_handler_(err_handler), - cp_(0), - cp2_(0), - is_negative_(false), - precision_(0), - decimal_places_(0), - line_(1), - column_(1), - nesting_depth_(0), - initial_stack_capacity_(default_initial_stack_capacity_), - begin_input_(nullptr), - input_end_(nullptr), - input_ptr_(nullptr), - state_(parse_state::start) - { - string_buffer_.reserve(initial_string_buffer_capacity_); - number_buffer_.reserve(initial_number_buffer_capacity_); - max_nesting_depth_ = (std::numeric_limits::max)(); - - state_stack_.reserve(initial_stack_capacity_); - push_state(parse_state::root); - } - - basic_json_parser(basic_json_content_handler& handler) - : handler_(handler), - err_handler_(default_err_handler_), - cp_(0), - cp2_(0), - is_negative_(false), - precision_(0), - decimal_places_(0), - line_(1), - column_(1), - nesting_depth_(0), - initial_stack_capacity_(default_initial_stack_capacity_), - begin_input_(nullptr), - input_end_(nullptr), - input_ptr_(nullptr), - state_(parse_state::start) + : basic_json_parser(basic_json_options::get_default_options(), default_json_parsing()) { - string_buffer_.reserve(initial_string_buffer_capacity_); - number_buffer_.reserve(initial_number_buffer_capacity_); - max_nesting_depth_ = (std::numeric_limits::max)(); - - state_stack_.reserve(initial_stack_capacity_); - push_state(parse_state::root); } - basic_json_parser(basic_json_content_handler& handler, - parse_error_handler& err_handler) - : handler_(handler), - err_handler_(err_handler), - cp_(0), - cp2_(0), - is_negative_(false), - precision_(0), - decimal_places_(0), - line_(1), - column_(1), - nesting_depth_(0), - initial_stack_capacity_(default_initial_stack_capacity_), - begin_input_(nullptr), - input_end_(nullptr), - input_ptr_(nullptr), - state_(parse_state::start) + basic_json_parser(std::function err_handler) + : basic_json_parser(basic_json_options::get_default_options(), err_handler) { - string_buffer_.reserve(initial_string_buffer_capacity_); - number_buffer_.reserve(initial_number_buffer_capacity_); - max_nesting_depth_ = (std::numeric_limits::max)(); - - state_stack_.reserve(initial_stack_capacity_); - push_state(parse_state::root); } - basic_json_parser(const basic_json_serializing_options& options) - : handler_((options.can_read_nan_replacement() || options.can_read_pos_inf_replacement() || options.can_read_neg_inf_replacement()) ? replacement_filter_(default_content_handler_,options) : default_content_handler_), - err_handler_(default_err_handler_), - cp_(0), - cp2_(0), - is_negative_(false), - precision_(0), - decimal_places_(0), - line_(1), - column_(1), - nesting_depth_(0), - initial_stack_capacity_(default_initial_stack_capacity_), - begin_input_(nullptr), - input_end_(nullptr), - input_ptr_(nullptr), - state_(parse_state::start) + basic_json_parser(const basic_json_decode_options& options) + : basic_json_parser(options, default_json_parsing()) { - string_buffer_.reserve(initial_string_buffer_capacity_); - number_buffer_.reserve(initial_number_buffer_capacity_); - max_nesting_depth_ = options.max_nesting_depth(); - - state_stack_.reserve(initial_stack_capacity_); - push_state(parse_state::root); } - basic_json_parser(const basic_json_serializing_options& options, - parse_error_handler& err_handler) - : handler_((options.can_read_nan_replacement() || options.can_read_pos_inf_replacement() || options.can_read_neg_inf_replacement()) ? replacement_filter_(default_content_handler_,options) : default_content_handler_), + basic_json_parser(const basic_json_decode_options& options, + std::function err_handler) + : options_(options), err_handler_(err_handler), - cp_(0), - cp2_(0), - is_negative_(false), - precision_(0), - decimal_places_(0), - line_(1), - column_(1), - nesting_depth_(0), initial_stack_capacity_(default_initial_stack_capacity_), - begin_input_(nullptr), - input_end_(nullptr), - input_ptr_(nullptr), - state_(parse_state::start) - { - string_buffer_.reserve(initial_string_buffer_capacity_); - number_buffer_.reserve(initial_number_buffer_capacity_); - max_nesting_depth_ = options.max_nesting_depth(); - - state_stack_.reserve(initial_stack_capacity_); - push_state(parse_state::root); - } - - basic_json_parser(basic_json_content_handler& handler, - const basic_json_serializing_options& options) - : replacement_filter_(handler,options), - handler_((options.can_read_nan_replacement() || options.can_read_pos_inf_replacement() || options.can_read_neg_inf_replacement()) ? replacement_filter_ : handler), - err_handler_(default_err_handler_), - cp_(0), - cp2_(0), - is_negative_(false), - precision_(0), - decimal_places_(0), - line_(1), - column_(1), nesting_depth_(0), - initial_stack_capacity_(default_initial_stack_capacity_), - begin_input_(nullptr), - input_end_(nullptr), - input_ptr_(nullptr), - state_(parse_state::start) - { - string_buffer_.reserve(initial_string_buffer_capacity_); - number_buffer_.reserve(initial_number_buffer_capacity_); - max_nesting_depth_ = options.max_nesting_depth(); - - state_stack_.reserve(initial_stack_capacity_); - push_state(parse_state::root); - } - - basic_json_parser(basic_json_content_handler& handler, - const basic_json_serializing_options& options, - parse_error_handler& err_handler) - : replacement_filter_(handler,options), - handler_((options.can_read_nan_replacement() || options.can_read_pos_inf_replacement() || options.can_read_neg_inf_replacement()) ? replacement_filter_ : handler), - err_handler_(err_handler), cp_(0), cp2_(0), - is_negative_(false), - precision_(0), - decimal_places_(0), line_(1), column_(1), - nesting_depth_(0), - initial_stack_capacity_(default_initial_stack_capacity_), begin_input_(nullptr), input_end_(nullptr), input_ptr_(nullptr), - state_(parse_state::start) + state_(json_parse_state::start), + continue_(true), + done_(false) { string_buffer_.reserve(initial_string_buffer_capacity_); - number_buffer_.reserve(initial_number_buffer_capacity_); - max_nesting_depth_ = options.max_nesting_depth(); state_stack_.reserve(initial_stack_capacity_); - push_state(parse_state::root); - } - - size_t line_number() const - { - return line_; - } - - size_t column_number() const - { - return column_; - } - - void set_column_number(size_t column) - { - column_ = column; + push_state(json_parse_state::root); } bool source_exhausted() const @@ -407,17 +263,19 @@ class basic_json_parser : private serializing_context } #if !defined(JSONCONS_NO_DEPRECATED) + JSONCONS_DEPRECATED("Instead, use basic_json_options::max_nesting_depth()") size_t max_nesting_depth() const { - return max_nesting_depth_; + return options_.max_nesting_depth(); } + JSONCONS_DEPRECATED("Instead, use basic_json_options::max_nesting_depth(size_t)") void max_nesting_depth(size_t value) { - max_nesting_depth_ = value; + options_.max_nesting_depth() = value; } #endif - parse_state parent() const + json_parse_state parent() const { JSONCONS_ASSERT(state_stack_.size() >= 1); return state_stack_.back(); @@ -425,123 +283,196 @@ class basic_json_parser : private serializing_context bool done() const { - return state_ == parse_state::done; + return done_; } - void skip_whitespace() + bool stopped() const + { + return !continue_; + } + + bool finished() const + { + return !continue_ && state_ != json_parse_state::before_done; + } + + void skip_space() { const CharT* local_input_end = input_end_; - for (;;) + while (input_ptr_ != local_input_end) { - if (JSONCONS_UNLIKELY(input_ptr_ == local_input_end)) - { - return; - } - else if (*input_ptr_ == ' ' || *input_ptr_ == '\t') + switch (*input_ptr_) { - ++input_ptr_; - ++column_; - } - else + case ' ': + case '\t': + ++input_ptr_; + ++column_; + break; + case '\r': + push_state(state_); + ++input_ptr_; + ++column_; + state_ = json_parse_state::cr; + return; + case '\n': + ++input_ptr_; + ++line_; + column_ = 1; + return; + default: + return; + } + } + } + + void skip_whitespace() + { + const CharT* local_input_end = input_end_; + + while (input_ptr_ != local_input_end) + { + switch (state_) { - return; + case json_parse_state::cr: + ++line_; + column_ = 1; + switch (*input_ptr_) + { + case '\n': + ++input_ptr_; + state_ = pop_state(); + break; + default: + state_ = pop_state(); + break; + } + break; + + default: + switch (*input_ptr_) + { + case ' ': + case '\t': + case '\n': + case '\r': + skip_space(); + break; + default: + return; + } + break; } } } - void begin_object(std::error_code& ec) + void begin_object(basic_json_content_handler& handler, std::error_code& ec) { - if (++nesting_depth_ >= max_nesting_depth_) + if (++nesting_depth_ > options_.max_nesting_depth()) { - if (err_handler_.error(json_parser_errc::max_depth_exceeded, *this)) + continue_ = err_handler_(json_errc::max_depth_exceeded, *this); + if (!continue_) { - ec = json_parser_errc::max_depth_exceeded; + ec = json_errc::max_depth_exceeded; return; } } - push_state(parse_state::object); - state_ = parse_state::expect_member_name_or_end; - handler_.begin_object(*this); + push_state(json_parse_state::object); + state_ = json_parse_state::expect_member_name_or_end; + continue_ = handler.begin_object(semantic_tag::none, *this); } - void end_object(std::error_code& ec) + void end_object(basic_json_content_handler& handler, std::error_code& ec) { - JSONCONS_ASSERT(nesting_depth_ >= 1); + if (nesting_depth_ < 1) + { + err_handler_(json_errc::unexpected_right_brace, *this); + ec = json_errc::unexpected_right_brace; + continue_ = false; + return; + } --nesting_depth_; state_ = pop_state(); - if (state_ == parse_state::object) + if (state_ == json_parse_state::object) { - handler_.end_object(*this); + continue_ = handler.end_object(*this); } - else if (state_ == parse_state::array) + else if (state_ == json_parse_state::array) { - err_handler_.fatal_error(json_parser_errc::expected_comma_or_right_bracket, *this); - ec = json_parser_errc::expected_comma_or_right_bracket; + err_handler_(json_errc::expected_comma_or_right_bracket, *this); + ec = json_errc::expected_comma_or_right_bracket; + continue_ = false; return; } else { - err_handler_.fatal_error(json_parser_errc::unexpected_right_brace, *this); - ec = json_parser_errc::unexpected_right_brace; + err_handler_(json_errc::unexpected_right_brace, *this); + ec = json_errc::unexpected_right_brace; + continue_ = false; return; } - if (parent() == parse_state::root) + if (parent() == json_parse_state::root) { - state_ = parse_state::done; - handler_.end_json(); + state_ = json_parse_state::before_done; } else { - state_ = parse_state::expect_comma_or_end; + state_ = json_parse_state::expect_comma_or_end; } } - void begin_array(std::error_code& ec) + void begin_array(basic_json_content_handler& handler, std::error_code& ec) { - if (++nesting_depth_ >= max_nesting_depth_) + if (++nesting_depth_ > options_.max_nesting_depth()) { - if (err_handler_.error(json_parser_errc::max_depth_exceeded, *this)) + continue_ = err_handler_(json_errc::max_depth_exceeded, *this); + if (!continue_) { - ec = json_parser_errc::max_depth_exceeded; + ec = json_errc::max_depth_exceeded; return; } - } - push_state(parse_state::array); - state_ = parse_state::expect_value_or_end; - handler_.begin_array(*this); + push_state(json_parse_state::array); + state_ = json_parse_state::expect_value_or_end; + continue_ = handler.begin_array(semantic_tag::none, *this); } - void end_array(std::error_code& ec) + void end_array(basic_json_content_handler& handler, std::error_code& ec) { - JSONCONS_ASSERT(nesting_depth_ >= 1); + if (nesting_depth_ < 1) + { + err_handler_(json_errc::unexpected_right_bracket, *this); + ec = json_errc::unexpected_right_bracket; + continue_ = false; + return; + } --nesting_depth_; state_ = pop_state(); - if (state_ == parse_state::array) + if (state_ == json_parse_state::array) { - handler_.end_array(*this); + continue_ = handler.end_array(*this); } - else if (state_ == parse_state::object) + else if (state_ == json_parse_state::object) { - err_handler_.fatal_error(json_parser_errc::expected_comma_or_right_brace, *this); - ec = json_parser_errc::expected_comma_or_right_brace; + err_handler_(json_errc::expected_comma_or_right_brace, *this); + ec = json_errc::expected_comma_or_right_brace; + continue_ = false; return; } else { - err_handler_.fatal_error(json_parser_errc::unexpected_right_bracket, *this); - ec = json_parser_errc::unexpected_right_bracket; + err_handler_(json_errc::unexpected_right_bracket, *this); + ec = json_errc::unexpected_right_bracket; + continue_ = false; return; } - if (parent() == parse_state::root) + if (parent() == json_parse_state::root) { - state_ = parse_state::done; - handler_.end_json(); + state_ = json_parse_state::before_done; } else { - state_ = parse_state::expect_comma_or_end; + state_ = json_parse_state::expect_comma_or_end; } } @@ -549,963 +480,1099 @@ class basic_json_parser : private serializing_context { state_stack_.clear(); state_stack_.reserve(initial_stack_capacity_); - push_state(parse_state::root); - state_ = parse_state::start; + push_state(json_parse_state::root); + state_ = json_parse_state::start; + continue_ = true; + done_ = false; line_ = 1; column_ = 1; nesting_depth_ = 0; } + void restart() + { + continue_ = true; + } + void check_done() { std::error_code ec; check_done(ec); if (ec) { - throw parse_error(ec,line_,column_); + throw ser_error(ec,line_,column_); } } void check_done(std::error_code& ec) { - if (state_ != parse_state::done) - { - if (err_handler_.error(json_parser_errc::unexpected_eof, *this)) - { - ec = json_parser_errc::unexpected_eof; - return; - } - } for (; input_ptr_ != input_end_; ++input_ptr_) { CharT curr_char_ = *input_ptr_; switch (curr_char_) { - case '\n': - case '\r': - case '\t': - case ' ': - break; - default: - if (err_handler_.error(json_parser_errc::extra_character, *this)) - { - ec = json_parser_errc::extra_character; - return; - } - break; + case '\n': + case '\r': + case '\t': + case ' ': + break; + default: + continue_ = err_handler_(json_errc::extra_character, *this); + if (!continue_) + { + ec = json_errc::extra_character; + return; + } + break; } } } - void parse_some(std::error_code& ec) + json_parse_state state() const { - const CharT* local_input_end = input_end_; + return state_; + } + + void update(const string_view_type sv) + { + update(sv.data(),sv.length()); + } - while ((input_ptr_ < local_input_end) && (state_ != parse_state::done)) + void update(const CharT* data, size_t length) + { + begin_input_ = data; + input_end_ = data + length; + input_ptr_ = begin_input_; + } + + void parse_some(basic_json_content_handler& handler) + { + std::error_code ec; + parse_some(handler, ec); + if (ec) { - switch (state_) + throw ser_error(ec,line_,column_); + } + } + + void parse_some(basic_json_content_handler& handler, std::error_code& ec) + { + if (options_.is_str_to_nan() || options_.is_str_to_inf() || options_.is_str_to_neginf()) + { + jsoncons::detail::replacement_filter h(handler, + options_.is_str_to_nan(), + options_.is_str_to_inf(), + options_.is_str_to_neginf(), + options_.nan_to_str(), + options_.inf_to_str(), + options_.neginf_to_str()); + parse_some_(h, ec); + } + else + { + parse_some_(handler, ec); + } + } + + void finish_parse(basic_json_content_handler& handler) + { + std::error_code ec; + finish_parse(handler, ec); + if (ec) + { + throw ser_error(ec,line_,column_); + } + } + + void finish_parse(basic_json_content_handler& handler, std::error_code& ec) + { + while (!finished()) + { + parse_some(handler, ec); + } + } + + void parse_some_(basic_json_content_handler& handler, std::error_code& ec) + { + if (state_ == json_parse_state::before_done) + { + handler.flush(); + done_ = true; + state_ = json_parse_state::done; + continue_ = false; + return; + } + const CharT* local_input_end = input_end_; + + if (input_ptr_ == local_input_end && continue_) + { + switch (state_) { - case parse_state::cr: - ++line_; - column_ = 1; - switch (*input_ptr_) - { - case '\n': + case json_parse_state::zero: + case json_parse_state::integer: + end_integer_value(handler, ec); + if (ec) return; + break; + case json_parse_state::fraction2: + end_fraction_value(handler, ec); + if (ec) return; + break; + case json_parse_state::exp3: + end_fraction_value(handler, ec); + if (ec) return; + break; + case json_parse_state::before_done: + handler.flush(); + done_ = true; + state_ = json_parse_state::done; + continue_ = false; + break; + case json_parse_state::done: + continue_ = false; + break; + case json_parse_state::cr: state_ = pop_state(); - ++input_ptr_; break; default: - state_ = pop_state(); + err_handler_(json_errc::unexpected_eof, *this); + ec = json_errc::unexpected_eof; + continue_ = false; + return; + } + } + + while ((input_ptr_ < local_input_end) && continue_) + { + switch (state_) + { + case json_parse_state::before_done: + handler.flush(); + done_ = true; + state_ = json_parse_state::done; + continue_ = false; break; - } - break; - case parse_state::lf: - ++line_; - column_ = 1; - state_ = pop_state(); - break; - case parse_state::start: - { - handler_.begin_json(); + case json_parse_state::cr: + ++line_; + column_ = 1; switch (*input_ptr_) { - JSONCONS_ILLEGAL_CONTROL_CHARACTER: - if (err_handler_.error(json_parser_errc::illegal_control_character, *this)) - { - ec = json_parser_errc::illegal_control_character; - return; - } - break; - case '\r': - push_state(state_); - ++input_ptr_; - ++column_; - state_ = parse_state::cr; - break; - case '\n': - ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::lf; - break; - case ' ':case '\t': - skip_whitespace(); - break; - case '/': + case '\n': ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::slash; - break; - case '{': - begin_object(ec); - if (ec) return; - ++input_ptr_; - ++column_; - break; - case '[': - begin_array(ec); - if (ec) return; - ++input_ptr_; - ++column_; - break; - case '\"': - state_ = parse_state::string_u1; - ++input_ptr_; - ++column_; - break; - case '-': - number_buffer_.clear(); - is_negative_ = true; - precision_ = 0; - ++input_ptr_; - ++column_; - state_ = parse_state::minus; - parse_number(ec); - if (ec) {return;} - break; - case '0': - number_buffer_.clear(); - is_negative_ = false; - precision_ = 1; - number_buffer_.push_back(static_cast(*input_ptr_)); - state_ = parse_state::zero; - ++input_ptr_; - ++column_; - parse_number(ec); - if (ec) {return;} + state_ = pop_state(); break; - case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': - number_buffer_.clear(); - is_negative_ = false; - precision_ = 1; - number_buffer_.push_back(static_cast(*input_ptr_)); - ++input_ptr_; - ++column_; - state_ = parse_state::integer; - parse_number(ec); - if (ec) {return;} - break; - case 'n': - parse_null(ec); - if (ec) {return;} - break; - case 't': - parse_true(ec); - if (ec) {return;} - break; - case 'f': - parse_false(ec); - if (ec) {return;} - break; - case '}': - err_handler_.fatal_error(json_parser_errc::unexpected_right_brace, *this); - ec = json_parser_errc::unexpected_right_brace; - return; - case ']': - err_handler_.fatal_error(json_parser_errc::unexpected_right_bracket, *this); - ec = json_parser_errc::unexpected_right_bracket; - return; default: - err_handler_.fatal_error(json_parser_errc::invalid_json_text, *this); - ec = json_parser_errc::invalid_json_text; - return; + state_ = pop_state(); + break; } - } - break; - - case parse_state::expect_comma_or_end: - { - switch (*input_ptr_) + break; + case json_parse_state::start: { - JSONCONS_ILLEGAL_CONTROL_CHARACTER: - if (err_handler_.error(json_parser_errc::illegal_control_character, *this)) - { - ec = json_parser_errc::illegal_control_character; - return; - } - ++input_ptr_; - ++column_; - break; - case '\r': - ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::cr; - break; - case '\n': - ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::lf; - break; - case ' ':case '\t': - skip_whitespace(); - break; - case '/': - ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::slash; - break; - case '}': - end_object(ec); - if (ec) return; - ++input_ptr_; - ++column_; - break; - case ']': - end_array(ec); - if (ec) return; - ++input_ptr_; - ++column_; - break; - case ',': - begin_member_or_element(ec); - if (ec) return; - ++input_ptr_; - ++column_; - break; - default: - if (parent() == parse_state::array) - { - if (err_handler_.error(json_parser_errc::expected_comma_or_right_bracket, *this)) + switch (*input_ptr_) + { + JSONCONS_ILLEGAL_CONTROL_CHARACTER: + continue_ = err_handler_(json_errc::illegal_control_character, *this); + if (!continue_) { - ec = json_parser_errc::expected_comma_or_right_bracket; + ec = json_errc::illegal_control_character; return; } - } - else if (parent() == parse_state::object) - { - if (err_handler_.error(json_parser_errc::expected_comma_or_right_brace, *this)) + break; + case '\r': + push_state(state_); + ++input_ptr_; + ++column_; + state_ = json_parse_state::cr; + break; + case '\n': + ++input_ptr_; + ++line_; + column_ = 1; + break; + case ' ':case '\t': + skip_space(); + break; + case '/': + ++input_ptr_; + ++column_; + push_state(state_); + state_ = json_parse_state::slash; + break; + case '{': + begin_object(handler, ec); + if (ec) return; + ++input_ptr_; + ++column_; + break; + case '[': + begin_array(handler, ec); + if (ec) return; + ++input_ptr_; + ++column_; + break; + case '\"': + state_ = json_parse_state::string; + ++input_ptr_; + ++column_; + string_buffer_.clear(); + parse_string(handler, ec); + if (ec) return; + break; + case '-': + string_buffer_.clear(); + string_buffer_.push_back('-'); + ++input_ptr_; + ++column_; + state_ = json_parse_state::minus; + parse_number(handler, ec); + if (ec) {return;} + break; + case '0': + string_buffer_.clear(); + string_buffer_.push_back(static_cast(*input_ptr_)); + state_ = json_parse_state::zero; + ++input_ptr_; + ++column_; + parse_number(handler, ec); + if (ec) {return;} + break; + case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': + string_buffer_.clear(); + string_buffer_.push_back(static_cast(*input_ptr_)); + ++input_ptr_; + ++column_; + state_ = json_parse_state::integer; + parse_number(handler, ec); + if (ec) {return;} + break; + case 'n': + parse_null(handler, ec); + if (ec) {return;} + break; + case 't': + parse_true(handler, ec); + if (ec) {return;} + break; + case 'f': + parse_false(handler, ec); + if (ec) {return;} + break; + case '}': + err_handler_(json_errc::unexpected_right_brace, *this); + ec = json_errc::unexpected_right_brace; + continue_ = false; + return; + case ']': + err_handler_(json_errc::unexpected_right_bracket, *this); + ec = json_errc::unexpected_right_bracket; + continue_ = false; + return; + default: + err_handler_(json_errc::invalid_json_text, *this); + ec = json_errc::invalid_json_text; + continue_ = false; + return; + } + } + break; + + case json_parse_state::expect_comma_or_end: + { + switch (*input_ptr_) + { + JSONCONS_ILLEGAL_CONTROL_CHARACTER: + continue_ = err_handler_(json_errc::illegal_control_character, *this); + if (!continue_) { - ec = json_parser_errc::expected_comma_or_right_brace; + ec = json_errc::illegal_control_character; return; } - } - ++input_ptr_; - ++column_; - break; + ++input_ptr_; + ++column_; + break; + case '\r': + ++input_ptr_; + ++column_; + push_state(state_); + state_ = json_parse_state::cr; + break; + case '\n': + ++input_ptr_; + ++line_; + column_ = 1; + break; + case ' ':case '\t': + skip_space(); + break; + case '/': + ++input_ptr_; + ++column_; + push_state(state_); + state_ = json_parse_state::slash; + break; + case '}': + end_object(handler, ec); + if (ec) return; + ++input_ptr_; + ++column_; + break; + case ']': + end_array(handler, ec); + if (ec) return; + ++input_ptr_; + ++column_; + break; + case ',': + begin_member_or_element(ec); + if (ec) return; + ++input_ptr_; + ++column_; + break; + default: + if (parent() == json_parse_state::array) + { + continue_ = err_handler_(json_errc::expected_comma_or_right_bracket, *this); + if (!continue_) + { + ec = json_errc::expected_comma_or_right_bracket; + return; + } + } + else if (parent() == json_parse_state::object) + { + continue_ = err_handler_(json_errc::expected_comma_or_right_brace, *this); + if (!continue_) + { + ec = json_errc::expected_comma_or_right_brace; + return; + } + } + ++input_ptr_; + ++column_; + break; + } } - } - break; - case parse_state::expect_member_name_or_end: - { - switch (*input_ptr_) + break; + case json_parse_state::expect_member_name_or_end: { - JSONCONS_ILLEGAL_CONTROL_CHARACTER: - if (err_handler_.error(json_parser_errc::illegal_control_character, *this)) - { - ec = json_parser_errc::illegal_control_character; - return; - } - ++input_ptr_; - ++column_; - break; - case '\r': - ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::cr; - break; - case '\n': - ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::lf; - break; - case ' ':case '\t': - skip_whitespace(); - break; - case '/': - ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::slash; - break; - case '}': - end_object(ec); - if (ec) return; - ++input_ptr_; - ++column_; - break; - case '\"': - ++input_ptr_; - ++column_; - push_state(parse_state::member_name); - state_ = parse_state::string_u1; - break; - case '\'': - if (err_handler_.error(json_parser_errc::single_quote, *this)) - { - ec = json_parser_errc::single_quote; - return; - } - ++input_ptr_; - ++column_; - break; - default: - if (err_handler_.error(json_parser_errc::expected_name, *this)) - { - ec = json_parser_errc::expected_name; - return; - } - ++input_ptr_; - ++column_; - break; + switch (*input_ptr_) + { + JSONCONS_ILLEGAL_CONTROL_CHARACTER: + continue_ = err_handler_(json_errc::illegal_control_character, *this); + if (!continue_) + { + ec = json_errc::illegal_control_character; + return; + } + ++input_ptr_; + ++column_; + break; + case '\r': + ++input_ptr_; + ++column_; + push_state(state_); + state_ = json_parse_state::cr; + break; + case '\n': + ++input_ptr_; + ++line_; + column_ = 1; + break; + case ' ':case '\t': + skip_space(); + break; + case '/': + ++input_ptr_; + ++column_; + push_state(state_); + state_ = json_parse_state::slash; + break; + case '}': + end_object(handler, ec); + if (ec) return; + ++input_ptr_; + ++column_; + break; + case '\"': + ++input_ptr_; + ++column_; + push_state(json_parse_state::member_name); + state_ = json_parse_state::string; + string_buffer_.clear(); + parse_string(handler, ec); + if (ec) return; + break; + case '\'': + continue_ = err_handler_(json_errc::single_quote, *this); + if (!continue_) + { + ec = json_errc::single_quote; + return; + } + ++input_ptr_; + ++column_; + break; + default: + continue_ = err_handler_(json_errc::expected_name, *this); + if (!continue_) + { + ec = json_errc::expected_name; + return; + } + ++input_ptr_; + ++column_; + break; + } } - } - break; - case parse_state::expect_member_name: - { - switch (*input_ptr_) + break; + case json_parse_state::expect_member_name: { - JSONCONS_ILLEGAL_CONTROL_CHARACTER: - if (err_handler_.error(json_parser_errc::illegal_control_character, *this)) - { - ec = json_parser_errc::illegal_control_character; - return; - } - ++input_ptr_; - ++column_; - break; - case '\r': - ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::cr; - break; - case '\n': - ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::lf; - break; - case ' ':case '\t': - skip_whitespace(); - break; - case '/': - ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::slash; - break; - case '\"': - ++input_ptr_; - ++column_; - push_state(parse_state::member_name); - state_ = parse_state::string_u1; - break; - case '}': - if (err_handler_.error(json_parser_errc::extra_comma, *this)) - { - ec = json_parser_errc::extra_comma; - return; - } - end_object(ec); // Recover - if (ec) return; - ++input_ptr_; - ++column_; - break; - case '\'': - if (err_handler_.error(json_parser_errc::single_quote, *this)) - { - ec = json_parser_errc::single_quote; - return; - } - ++input_ptr_; - ++column_; - break; - default: - if (err_handler_.error(json_parser_errc::expected_name, *this)) - { - ec = json_parser_errc::expected_name; - return; - } - ++input_ptr_; - ++column_; - break; + switch (*input_ptr_) + { + JSONCONS_ILLEGAL_CONTROL_CHARACTER: + continue_ = err_handler_(json_errc::illegal_control_character, *this); + if (!continue_) + { + ec = json_errc::illegal_control_character; + return; + } + ++input_ptr_; + ++column_; + break; + case '\r': + ++input_ptr_; + ++column_; + push_state(state_); + state_ = json_parse_state::cr; + break; + case '\n': + ++input_ptr_; + ++line_; + column_ = 1; + break; + case ' ':case '\t': + skip_space(); + break; + case '/': + ++input_ptr_; + ++column_; + push_state(state_); + state_ = json_parse_state::slash; + break; + case '\"': + ++input_ptr_; + ++column_; + push_state(json_parse_state::member_name); + state_ = json_parse_state::string; + string_buffer_.clear(); + parse_string(handler, ec); + if (ec) return; + break; + case '}': + continue_ = err_handler_(json_errc::extra_comma, *this); + if (!continue_) + { + ec = json_errc::extra_comma; + return; + } + end_object(handler, ec); // Recover + if (ec) return; + ++input_ptr_; + ++column_; + break; + case '\'': + continue_ = err_handler_(json_errc::single_quote, *this); + if (!continue_) + { + ec = json_errc::single_quote; + return; + } + ++input_ptr_; + ++column_; + break; + default: + continue_ = err_handler_(json_errc::expected_name, *this); + if (!continue_) + { + ec = json_errc::expected_name; + return; + } + ++input_ptr_; + ++column_; + break; + } } - } - break; - case parse_state::expect_colon: - { - switch (*input_ptr_) + break; + case json_parse_state::expect_colon: { - JSONCONS_ILLEGAL_CONTROL_CHARACTER: - if (err_handler_.error(json_parser_errc::illegal_control_character, *this)) - { - ec = json_parser_errc::illegal_control_character; - return; - } - ++input_ptr_; - ++column_; - break; - case '\r': - push_state(state_); - state_ = parse_state::cr; - ++input_ptr_; - ++column_; - break; - case '\n': - push_state(state_); - state_ = parse_state::lf; - ++input_ptr_; - ++column_; - break; - case ' ':case '\t': - skip_whitespace(); - break; - case '/': - push_state(state_); - state_ = parse_state::slash; - ++input_ptr_; - ++column_; - break; - case ':': - state_ = parse_state::expect_value; - ++input_ptr_; - ++column_; - break; - default: - if (err_handler_.error(json_parser_errc::expected_colon, *this)) - { - ec = json_parser_errc::expected_colon; - return; - } - ++input_ptr_; - ++column_; - break; + switch (*input_ptr_) + { + JSONCONS_ILLEGAL_CONTROL_CHARACTER: + continue_ = err_handler_(json_errc::illegal_control_character, *this); + if (!continue_) + { + ec = json_errc::illegal_control_character; + return; + } + ++input_ptr_; + ++column_; + break; + case '\r': + push_state(state_); + state_ = json_parse_state::cr; + ++input_ptr_; + ++column_; + break; + case '\n': + ++input_ptr_; + ++line_; + column_ = 1; + break; + case ' ':case '\t': + skip_space(); + break; + case '/': + push_state(state_); + state_ = json_parse_state::slash; + ++input_ptr_; + ++column_; + break; + case ':': + state_ = json_parse_state::expect_value; + ++input_ptr_; + ++column_; + break; + default: + continue_ = err_handler_(json_errc::expected_colon, *this); + if (!continue_) + { + ec = json_errc::expected_colon; + return; + } + ++input_ptr_; + ++column_; + break; + } } - } - break; + break; - case parse_state::expect_value: - { - switch (*input_ptr_) + case json_parse_state::expect_value: { - JSONCONS_ILLEGAL_CONTROL_CHARACTER: - if (err_handler_.error(json_parser_errc::illegal_control_character, *this)) - { - ec = json_parser_errc::illegal_control_character; - return; - } - ++input_ptr_; - ++column_; - break; - case '\r': - push_state(state_); - ++input_ptr_; - ++column_; - state_ = parse_state::cr; - break; - case '\n': - push_state(state_); - ++input_ptr_; - ++column_; - state_ = parse_state::lf; - break; - case ' ':case '\t': - skip_whitespace(); - break; - case '/': - push_state(state_); - ++input_ptr_; - ++column_; - state_ = parse_state::slash; - break; - case '{': - begin_object(ec); - if (ec) return; - ++input_ptr_; - ++column_; - break; - case '[': - begin_array(ec); - if (ec) return; - ++input_ptr_; - ++column_; - break; - case '\"': - ++input_ptr_; - ++column_; - state_ = parse_state::string_u1; - break; - case '-': - number_buffer_.clear(); - is_negative_ = true; - precision_ = 0; - ++input_ptr_; - ++column_; - state_ = parse_state::minus; - parse_number(ec); - if (ec) {return;} - break; - case '0': - number_buffer_.clear(); - is_negative_ = false; - precision_ = 1; - number_buffer_.push_back(static_cast(*input_ptr_)); - ++input_ptr_; - ++column_; - state_ = parse_state::zero; - parse_number(ec); - if (ec) {return;} - break; - case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': - number_buffer_.clear(); - is_negative_ = false; - precision_ = 1; - number_buffer_.push_back(static_cast(*input_ptr_)); - ++input_ptr_; - ++column_; - state_ = parse_state::integer; - parse_number(ec); - if (ec) {return;} - break; - case 'n': - parse_null(ec); - if (ec) {return;} - break; - case 't': - parse_true(ec); - if (ec) {return;} - break; - case 'f': - parse_false(ec); - if (ec) {return;} - break; - case ']': - if (parent() == parse_state::array) - { - if (err_handler_.error(json_parser_errc::extra_comma, *this)) + switch (*input_ptr_) + { + JSONCONS_ILLEGAL_CONTROL_CHARACTER: + continue_ = err_handler_(json_errc::illegal_control_character, *this); + if (!continue_) { - ec = json_parser_errc::extra_comma; + ec = json_errc::illegal_control_character; return; } - end_array(ec); // Recover + ++input_ptr_; + ++column_; + break; + case '\r': + push_state(state_); + ++input_ptr_; + ++column_; + state_ = json_parse_state::cr; + break; + case '\n': + ++input_ptr_; + ++line_; + column_ = 1; + break; + case ' ':case '\t': + skip_space(); + break; + case '/': + push_state(state_); + ++input_ptr_; + ++column_; + state_ = json_parse_state::slash; + break; + case '{': + begin_object(handler, ec); if (ec) return; - } - else - { - if (err_handler_.error(json_parser_errc::expected_value, *this)) + ++input_ptr_; + ++column_; + break; + case '[': + begin_array(handler, ec); + if (ec) return; + ++input_ptr_; + ++column_; + break; + case '\"': + ++input_ptr_; + ++column_; + state_ = json_parse_state::string; + string_buffer_.clear(); + parse_string(handler, ec); + if (ec) return; + break; + case '-': + string_buffer_.clear(); + string_buffer_.push_back('-'); + ++input_ptr_; + ++column_; + state_ = json_parse_state::minus; + parse_number(handler, ec); + if (ec) {return;} + break; + case '0': + string_buffer_.clear(); + string_buffer_.push_back(static_cast(*input_ptr_)); + ++input_ptr_; + ++column_; + state_ = json_parse_state::zero; + parse_number(handler, ec); + if (ec) {return;} + break; + case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': + string_buffer_.clear(); + string_buffer_.push_back(static_cast(*input_ptr_)); + ++input_ptr_; + ++column_; + state_ = json_parse_state::integer; + parse_number(handler, ec); + if (ec) {return;} + break; + case 'n': + parse_null(handler, ec); + if (ec) {return;} + break; + case 't': + parse_true(handler, ec); + if (ec) {return;} + break; + case 'f': + parse_false(handler, ec); + if (ec) {return;} + break; + case ']': + if (parent() == json_parse_state::array) + { + continue_ = err_handler_(json_errc::extra_comma, *this); + if (!continue_) + { + ec = json_errc::extra_comma; + return; + } + end_array(handler, ec); // Recover + if (ec) return; + } + else + { + continue_ = err_handler_(json_errc::expected_value, *this); + if (!continue_) + { + ec = json_errc::expected_value; + return; + } + } + ++input_ptr_; + ++column_; + break; + case '\'': + continue_ = err_handler_(json_errc::single_quote, *this); + if (!continue_) { - ec = json_parser_errc::expected_value; + ec = json_errc::single_quote; return; } + ++input_ptr_; + ++column_; + break; + default: + continue_ = err_handler_(json_errc::expected_value, *this); + if (!continue_) + { + ec = json_errc::expected_value; + return; + } + ++input_ptr_; + ++column_; + break; + } + } + break; + case json_parse_state::expect_value_or_end: + { + switch (*input_ptr_) + { + JSONCONS_ILLEGAL_CONTROL_CHARACTER: + continue_ = err_handler_(json_errc::illegal_control_character, *this); + if (!continue_) + { + ec = json_errc::illegal_control_character; + return; + } + ++input_ptr_; + ++column_; + break; + case '\r': + ++input_ptr_; + ++column_; + push_state(state_); + state_ = json_parse_state::cr; + break; + case '\n': + ++input_ptr_; + ++line_; + column_ = 1; + break; + case ' ':case '\t': + skip_space(); + break; + case '/': + ++input_ptr_; + ++column_; + push_state(state_); + state_ = json_parse_state::slash; + break; + case '{': + begin_object(handler, ec); + if (ec) return; + ++input_ptr_; + ++column_; + break; + case '[': + begin_array(handler, ec); + if (ec) return; + ++input_ptr_; + ++column_; + break; + case ']': + end_array(handler, ec); + if (ec) return; + ++input_ptr_; + ++column_; + break; + case '\"': + ++input_ptr_; + ++column_; + state_ = json_parse_state::string; + string_buffer_.clear(); + parse_string(handler, ec); + if (ec) return; + break; + case '-': + string_buffer_.clear(); + string_buffer_.push_back('-'); + ++input_ptr_; + ++column_; + state_ = json_parse_state::minus; + parse_number(handler, ec); + if (ec) {return;} + break; + case '0': + string_buffer_.clear(); + string_buffer_.push_back(static_cast(*input_ptr_)); + ++input_ptr_; + ++column_; + state_ = json_parse_state::zero; + parse_number(handler, ec); + if (ec) {return;} + break; + case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': + string_buffer_.clear(); + string_buffer_.push_back(static_cast(*input_ptr_)); + ++input_ptr_; + ++column_; + state_ = json_parse_state::integer; + parse_number(handler, ec); + if (ec) {return;} + break; + case 'n': + parse_null(handler, ec); + if (ec) {return;} + break; + case 't': + parse_true(handler, ec); + if (ec) {return;} + break; + case 'f': + parse_false(handler, ec); + if (ec) {return;} + break; + case '\'': + continue_ = err_handler_(json_errc::single_quote, *this); + if (!continue_) + { + ec = json_errc::single_quote; + return; + } + ++input_ptr_; + ++column_; + break; + default: + continue_ = err_handler_(json_errc::expected_value, *this); + if (!continue_) + { + ec = json_errc::expected_value; + return; + } + ++input_ptr_; + ++column_; + break; } + } + break; + case json_parse_state::string: + case json_parse_state::escape: + case json_parse_state::escape_u1: + case json_parse_state::escape_u2: + case json_parse_state::escape_u3: + case json_parse_state::escape_u4: + case json_parse_state::escape_expect_surrogate_pair1: + case json_parse_state::escape_expect_surrogate_pair2: + case json_parse_state::escape_u6: + case json_parse_state::escape_u7: + case json_parse_state::escape_u8: + case json_parse_state::escape_u9: + parse_string(handler, ec); + if (ec) return; + break; + case json_parse_state::minus: + case json_parse_state::zero: + case json_parse_state::integer: + case json_parse_state::fraction1: + case json_parse_state::fraction2: + case json_parse_state::exp1: + case json_parse_state::exp2: + case json_parse_state::exp3: + parse_number(handler, ec); + if (ec) return; + break; + case json_parse_state::t: + switch (*input_ptr_) + { + case 'r': ++input_ptr_; ++column_; - break; - case '\'': - if (err_handler_.error(json_parser_errc::single_quote, *this)) - { - ec = json_parser_errc::single_quote; - return; - } - ++input_ptr_; - ++column_; + state_ = json_parse_state::tr; break; default: - if (err_handler_.error(json_parser_errc::expected_value, *this)) - { - ec = json_parser_errc::expected_value; - return; - } - ++input_ptr_; - ++column_; + err_handler_(json_errc::invalid_value, *this); + ec = json_errc::invalid_value; + continue_ = false; + return; + } + break; + case json_parse_state::tr: + switch (*input_ptr_) + { + case 'u': + state_ = json_parse_state::tru; break; + default: + err_handler_(json_errc::invalid_value, *this); + ec = json_errc::invalid_value; + continue_ = false; + return; } - } - break; - case parse_state::expect_value_or_end: - { + ++input_ptr_; + ++column_; + break; + case json_parse_state::tru: switch (*input_ptr_) { - JSONCONS_ILLEGAL_CONTROL_CHARACTER: - if (err_handler_.error(json_parser_errc::illegal_control_character, *this)) + case 'e': + continue_ = handler.bool_value(true, semantic_tag::none, *this); + if (parent() == json_parse_state::root) { - ec = json_parser_errc::illegal_control_character; - return; + state_ = json_parse_state::before_done; } - ++input_ptr_; - ++column_; - break; - case '\r': - ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::cr; - break; - case '\n': - ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::lf; - break; - case ' ':case '\t': - skip_whitespace(); - break; - case '/': - ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::slash; - break; - case '{': - begin_object(ec); - if (ec) return; - ++input_ptr_; - ++column_; - break; - case '[': - begin_array(ec); - if (ec) return; - ++input_ptr_; - ++column_; - break; - case ']': - end_array(ec); - if (ec) return; - ++input_ptr_; - ++column_; - break; - case '\"': - ++input_ptr_; - ++column_; - state_ = parse_state::string_u1; - break; - case '-': - number_buffer_.clear(); - is_negative_ = true; - precision_ = 0; - ++input_ptr_; - ++column_; - state_ = parse_state::minus; - parse_number(ec); - if (ec) {return;} - break; - case '0': - number_buffer_.clear(); - is_negative_ = false; - precision_ = 1; - number_buffer_.push_back(static_cast(*input_ptr_)); - ++input_ptr_; - ++column_; - state_ = parse_state::zero; - parse_number(ec); - if (ec) {return;} - break; - case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': - number_buffer_.clear(); - is_negative_ = false; - precision_ = 1; - number_buffer_.push_back(static_cast(*input_ptr_)); - ++input_ptr_; - ++column_; - state_ = parse_state::integer; - parse_number(ec); - if (ec) {return;} - break; - case 'n': - parse_null(ec); - if (ec) {return;} - break; - case 't': - parse_true(ec); - if (ec) {return;} - break; - case 'f': - parse_false(ec); - if (ec) {return;} - break; - case '\'': - if (err_handler_.error(json_parser_errc::single_quote, *this)) + else { - ec = json_parser_errc::single_quote; - return; + state_ = json_parse_state::expect_comma_or_end; } - ++input_ptr_; - ++column_; break; default: - if (err_handler_.error(json_parser_errc::expected_value, *this)) - { - ec = json_parser_errc::expected_value; - return; - } - ++input_ptr_; - ++column_; - break; - } + err_handler_(json_errc::invalid_value, *this); + ec = json_errc::invalid_value; + continue_ = false; + return; } - break; - case parse_state::string_u1: - case parse_state::escape: - case parse_state::escape_u1: - case parse_state::escape_u2: - case parse_state::escape_u3: - case parse_state::escape_u4: - case parse_state::escape_expect_surrogate_pair1: - case parse_state::escape_expect_surrogate_pair2: - case parse_state::escape_u6: - case parse_state::escape_u7: - case parse_state::escape_u8: - case parse_state::escape_u9: - parse_string(ec); - if (ec) return; - break; - case parse_state::minus: - case parse_state::zero: - case parse_state::integer: - case parse_state::fraction1: - case parse_state::fraction2: - case parse_state::exp1: - case parse_state::exp2: - case parse_state::exp3: - parse_number(ec); - if (ec) return; - break; - case parse_state::t: - switch (*input_ptr_) - { - case 'r': ++input_ptr_; ++column_; - state_ = parse_state::tr; - break; - default: - err_handler_.error(json_parser_errc::invalid_value, *this); - ec = json_parser_errc::invalid_value; - return; - } - break; - case parse_state::tr: - switch (*input_ptr_) - { - case 'u': - state_ = parse_state::tru; break; - default: - err_handler_.error(json_parser_errc::invalid_value, *this); - ec = json_parser_errc::invalid_value; - return; - } - ++input_ptr_; - ++column_; - break; - case parse_state::tru: - switch (*input_ptr_) - { - case 'e': - handler_.bool_value(true,*this); - if (parent() == parse_state::root) + case json_parse_state::f: + switch (*input_ptr_) { - state_ = parse_state::done; - handler_.end_json(); + case 'a': + ++input_ptr_; + ++column_; + state_ = json_parse_state::fa; + break; + default: + err_handler_(json_errc::invalid_value, *this); + ec = json_errc::invalid_value; + continue_ = false; + return; } - else + break; + case json_parse_state::fa: + switch (*input_ptr_) { - state_ = parse_state::expect_comma_or_end; + case 'l': + state_ = json_parse_state::fal; + break; + default: + err_handler_(json_errc::invalid_value, *this); + ec = json_errc::invalid_value; + continue_ = false; + return; } - break; - default: - err_handler_.error(json_parser_errc::invalid_value, *this); - ec = json_parser_errc::invalid_value; - return; - } - ++input_ptr_; - ++column_; - break; - case parse_state::f: - switch (*input_ptr_) - { - case 'a': ++input_ptr_; ++column_; - state_ = parse_state::fa; - break; - default: - err_handler_.error(json_parser_errc::invalid_value, *this); - ec = json_parser_errc::invalid_value; - return; - } - break; - case parse_state::fa: - switch (*input_ptr_) - { - case 'l': - state_ = parse_state::fal; break; - default: - err_handler_.error(json_parser_errc::invalid_value, *this); - ec = json_parser_errc::invalid_value; - return; - } - ++input_ptr_; - ++column_; - break; - case parse_state::fal: - switch (*input_ptr_) - { - case 's': - state_ = parse_state::fals; - break; - default: - err_handler_.error(json_parser_errc::invalid_value, *this); - ec = json_parser_errc::invalid_value; - return; - } - ++input_ptr_; - ++column_; - break; - case parse_state::fals: - switch (*input_ptr_) - { - case 'e': - handler_.bool_value(false,*this); - if (parent() == parse_state::root) - { - state_ = parse_state::done; - handler_.end_json(); - } - else + case json_parse_state::fal: + switch (*input_ptr_) { - state_ = parse_state::expect_comma_or_end; + case 's': + state_ = json_parse_state::fals; + break; + default: + err_handler_(json_errc::invalid_value, *this); + ec = json_errc::invalid_value; + continue_ = false; + return; } + ++input_ptr_; + ++column_; break; - default: - err_handler_.error(json_parser_errc::invalid_value, *this); - ec = json_parser_errc::invalid_value; - return; - } - ++input_ptr_; - ++column_; - break; - case parse_state::n: - switch (*input_ptr_) - { - case 'u': + case json_parse_state::fals: + switch (*input_ptr_) + { + case 'e': + continue_ = handler.bool_value(false, semantic_tag::none, *this); + if (parent() == json_parse_state::root) + { + state_ = json_parse_state::before_done; + } + else + { + state_ = json_parse_state::expect_comma_or_end; + } + break; + default: + err_handler_(json_errc::invalid_value, *this); + ec = json_errc::invalid_value; + continue_ = false; + return; + } ++input_ptr_; ++column_; - state_ = parse_state::nu; break; - default: - err_handler_.error(json_parser_errc::invalid_value, *this); - ec = json_parser_errc::invalid_value; - return; - } - break; - case parse_state::nu: - switch (*input_ptr_) - { - case 'l': - state_ = parse_state::nul; + case json_parse_state::n: + switch (*input_ptr_) + { + case 'u': + ++input_ptr_; + ++column_; + state_ = json_parse_state::nu; + break; + default: + err_handler_(json_errc::invalid_value, *this); + ec = json_errc::invalid_value; + continue_ = false; + return; + } break; - default: - err_handler_.error(json_parser_errc::invalid_value, *this); - ec = json_parser_errc::invalid_value; - return; - } - ++input_ptr_; - ++column_; - break; - case parse_state::nul: - switch (*input_ptr_) - { - case 'l': - handler_.null_value(*this); - if (parent() == parse_state::root) + case json_parse_state::nu: + switch (*input_ptr_) { - state_ = parse_state::done; - handler_.end_json(); + case 'l': + state_ = json_parse_state::nul; + break; + default: + err_handler_(json_errc::invalid_value, *this); + ec = json_errc::invalid_value; + continue_ = false; + return; } - else + ++input_ptr_; + ++column_; + break; + case json_parse_state::nul: + switch (*input_ptr_) { - state_ = parse_state::expect_comma_or_end; + case 'l': + continue_ = handler.null_value(semantic_tag::none, *this); + if (parent() == json_parse_state::root) + { + state_ = json_parse_state::before_done; + } + else + { + state_ = json_parse_state::expect_comma_or_end; + } + break; + default: + err_handler_(json_errc::invalid_value, *this); + ec = json_errc::invalid_value; + continue_ = false; + return; } + ++input_ptr_; + ++column_; break; - default: - err_handler_.error(json_parser_errc::invalid_value, *this); - ec = json_parser_errc::invalid_value; - return; - } - ++input_ptr_; - ++column_; - break; - case parse_state::slash: + case json_parse_state::slash: { switch (*input_ptr_) { case '*': - state_ = parse_state::slash_star; - if (err_handler_.error(json_parser_errc::illegal_comment, *this)) + state_ = json_parse_state::slash_star; + continue_ = err_handler_(json_errc::illegal_comment, *this); + if (!continue_) { - ec = json_parser_errc::illegal_comment; + ec = json_errc::illegal_comment; return; } break; case '/': - state_ = parse_state::slash_slash; - if (err_handler_.error(json_parser_errc::illegal_comment, *this)) + state_ = json_parse_state::slash_slash; + continue_ = err_handler_(json_errc::illegal_comment, *this); + if (!continue_) { - ec = json_parser_errc::illegal_comment; + ec = json_errc::illegal_comment; return; } break; default: - if (err_handler_.error(json_parser_errc::invalid_json_text, *this)) + continue_ = err_handler_(json_errc::invalid_json_text, *this); + if (!continue_) { - ec = json_parser_errc::invalid_json_text; + ec = json_errc::invalid_json_text; return; } break; } + ++input_ptr_; + ++column_; + break; } - ++input_ptr_; - ++column_; - break; - case parse_state::slash_star: + case json_parse_state::slash_star: { switch (*input_ptr_) { case '\r': push_state(state_); - state_ = parse_state::cr; + state_ = json_parse_state::cr; break; case '\n': - push_state(state_); - state_ = parse_state::lf; + ++line_; + column_ = 1; break; case '*': - state_ = parse_state::slash_star_star; + state_ = json_parse_state::slash_star_star; break; } + ++input_ptr_; + ++column_; + break; } - ++input_ptr_; - ++column_; - break; - case parse_state::slash_slash: + case json_parse_state::slash_slash: { switch (*input_ptr_) { @@ -1519,9 +1586,9 @@ class basic_json_parser : private serializing_context ++input_ptr_; ++column_; } + break; } - break; - case parse_state::slash_star_star: + case json_parse_state::slash_star_star: { switch (*input_ptr_) { @@ -1529,43 +1596,43 @@ class basic_json_parser : private serializing_context state_ = pop_state(); break; default: - state_ = parse_state::slash_star; + state_ = json_parse_state::slash_star; break; } + ++input_ptr_; + ++column_; + break; } - ++input_ptr_; - ++column_; - break; - default: - JSONCONS_ASSERT(false); - break; + default: + JSONCONS_ASSERT(false); + break; } } } - void parse_true(std::error_code& ec) + void parse_true(basic_json_content_handler& handler, std::error_code& ec) { if (JSONCONS_LIKELY(input_end_ - input_ptr_ >= 4)) { if (*(input_ptr_+1) == 'r' && *(input_ptr_+2) == 'u' && *(input_ptr_+3) == 'e') { - handler_.bool_value(true,*this); + continue_ = handler.bool_value(true, semantic_tag::none, *this); input_ptr_ += 4; column_ += 4; - if (parent() == parse_state::root) + if (parent() == json_parse_state::root) { - handler_.end_json(); - state_ = parse_state::done; + state_ = json_parse_state::before_done; } else { - state_ = parse_state::expect_comma_or_end; + state_ = json_parse_state::expect_comma_or_end; } } else { - err_handler_.error(json_parser_errc::invalid_value, *this); - ec = json_parser_errc::invalid_value; + err_handler_(json_errc::invalid_value, *this); + ec = json_errc::invalid_value; + continue_ = false; return; } } @@ -1573,33 +1640,33 @@ class basic_json_parser : private serializing_context { ++input_ptr_; ++column_; - state_ = parse_state::t; + state_ = json_parse_state::t; } } - void parse_null(std::error_code& ec) + void parse_null(basic_json_content_handler& handler, std::error_code& ec) { if (JSONCONS_LIKELY(input_end_ - input_ptr_ >= 4)) { if (*(input_ptr_+1) == 'u' && *(input_ptr_+2) == 'l' && *(input_ptr_+3) == 'l') { - handler_.null_value(*this); + continue_ = handler.null_value(semantic_tag::none, *this); input_ptr_ += 4; column_ += 4; - if (parent() == parse_state::root) + if (parent() == json_parse_state::root) { - handler_.end_json(); - state_ = parse_state::done; + state_ = json_parse_state::before_done; } else { - state_ = parse_state::expect_comma_or_end; + state_ = json_parse_state::expect_comma_or_end; } } else { - err_handler_.error(json_parser_errc::invalid_value, *this); - ec = json_parser_errc::invalid_value; + err_handler_(json_errc::invalid_value, *this); + ec = json_errc::invalid_value; + continue_ = false; return; } } @@ -1607,33 +1674,33 @@ class basic_json_parser : private serializing_context { ++input_ptr_; ++column_; - state_ = parse_state::n; + state_ = json_parse_state::n; } } - void parse_false(std::error_code& ec) + void parse_false(basic_json_content_handler& handler, std::error_code& ec) { if (JSONCONS_LIKELY(input_end_ - input_ptr_ >= 5)) { if (*(input_ptr_+1) == 'a' && *(input_ptr_+2) == 'l' && *(input_ptr_+3) == 's' && *(input_ptr_+4) == 'e') { - handler_.bool_value(false,*this); + continue_ = handler.bool_value(false, semantic_tag::none, *this); input_ptr_ += 5; column_ += 5; - if (parent() == parse_state::root) + if (parent() == json_parse_state::root) { - handler_.end_json(); - state_ = parse_state::done; + state_ = json_parse_state::before_done; } else { - state_ = parse_state::expect_comma_or_end; + state_ = json_parse_state::expect_comma_or_end; } } else { - err_handler_.error(json_parser_errc::invalid_value, *this); - ec = json_parser_errc::invalid_value; + err_handler_(json_errc::invalid_value, *this); + ec = json_errc::invalid_value; + continue_ = false; return; } } @@ -1641,31 +1708,31 @@ class basic_json_parser : private serializing_context { ++input_ptr_; ++column_; - state_ = parse_state::f; + state_ = json_parse_state::f; } } - void parse_number(std::error_code& ec) + void parse_number(basic_json_content_handler& handler, std::error_code& ec) { const CharT* local_input_end = input_end_; switch (state_) { - case parse_state::minus: + case json_parse_state::minus: goto minus_sign; - case parse_state::zero: + case json_parse_state::zero: goto zero; - case parse_state::integer: + case json_parse_state::integer: goto integer; - case parse_state::fraction1: + case json_parse_state::fraction1: goto fraction1; - case parse_state::fraction2: + case json_parse_state::fraction2: goto fraction2; - case parse_state::exp1: + case json_parse_state::exp1: goto exp1; - case parse_state::exp2: + case json_parse_state::exp2: goto exp2; - case parse_state::exp3: + case json_parse_state::exp3: goto exp3; default: JSONCONS_UNREACHABLE(); @@ -1673,96 +1740,85 @@ class basic_json_parser : private serializing_context minus_sign: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::minus; + state_ = json_parse_state::minus; return; } switch (*input_ptr_) { case '0': - number_buffer_.push_back(static_cast(*input_ptr_)); - ++precision_; + string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++column_; goto zero; case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': - number_buffer_.push_back(static_cast(*input_ptr_)); - ++precision_; + string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++column_; goto integer; default: - err_handler_.error(json_parser_errc::expected_value, *this); - ec = json_parser_errc::expected_value; + err_handler_(json_errc::expected_value, *this); + ec = json_errc::expected_value; + continue_ = false; return; } zero: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::zero; + state_ = json_parse_state::zero; return; } switch (*input_ptr_) { case '\r': - end_integer_value(ec); + end_integer_value(handler, ec); if (ec) return; ++input_ptr_; ++column_; push_state(state_); - state_ = parse_state::cr; + state_ = json_parse_state::cr; return; case '\n': - end_integer_value(ec); + end_integer_value(handler, ec); if (ec) return; - push_state(state_); ++input_ptr_; - ++column_; - state_ = parse_state::lf; + ++line_; + column_ = 1; return; case ' ':case '\t': - end_integer_value(ec); + end_integer_value(handler, ec); if (ec) return; - skip_whitespace(); + skip_space(); return; case '/': - end_integer_value(ec); + end_integer_value(handler, ec); if (ec) return; ++input_ptr_; ++column_; push_state(state_); - state_ = parse_state::slash; + state_ = json_parse_state::slash; return; case '}': - end_integer_value(ec); - if (ec) return; - end_object(ec); - ++input_ptr_; - ++column_; + end_integer_value(handler, ec); if (ec) return; + state_ = json_parse_state::expect_comma_or_end; return; case ']': - end_integer_value(ec); - if (ec) return; - end_array(ec); - ++input_ptr_; - ++column_; + end_integer_value(handler, ec); if (ec) return; + state_ = json_parse_state::expect_comma_or_end; return; case '.': - decimal_places_ = 0; - JSONCONS_ASSERT(precision_ == number_buffer_.length()); - number_buffer_.push_back(to_double_.get_decimal_point()); + string_buffer_.push_back(to_double_.get_decimal_point()); ++input_ptr_; ++column_; goto fraction1; case 'e':case 'E': - JSONCONS_ASSERT(precision_ == number_buffer_.length()); - number_buffer_.push_back(static_cast(*input_ptr_)); + string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++column_; goto exp1; case ',': - end_integer_value(ec); + end_integer_value(handler, ec); if (ec) return; begin_member_or_element(ec); if (ec) return; @@ -1770,90 +1826,81 @@ class basic_json_parser : private serializing_context ++column_; return; case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': - err_handler_.error(json_parser_errc::leading_zero, *this); - ec = json_parser_errc::leading_zero; - state_ = parse_state::zero; + err_handler_(json_errc::leading_zero, *this); + ec = json_errc::leading_zero; + continue_ = false; + state_ = json_parse_state::zero; return; default: - err_handler_.error(json_parser_errc::invalid_number, *this); - ec = json_parser_errc::invalid_number; - state_ = parse_state::zero; + err_handler_(json_errc::invalid_number, *this); + ec = json_errc::invalid_number; + continue_ = false; + state_ = json_parse_state::zero; return; } integer: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::integer; + state_ = json_parse_state::integer; return; } switch (*input_ptr_) { case '\r': - end_integer_value(ec); + end_integer_value(handler, ec); if (ec) return; push_state(state_); ++input_ptr_; ++column_; - state_ = parse_state::cr; + state_ = json_parse_state::cr; return; case '\n': - end_integer_value(ec); + end_integer_value(handler, ec); if (ec) return; - push_state(state_); ++input_ptr_; - ++column_; - state_ = parse_state::lf; + ++line_; + column_ = 1; return; case ' ':case '\t': - end_integer_value(ec); + end_integer_value(handler, ec); if (ec) return; - skip_whitespace(); + skip_space(); return; case '/': - end_integer_value(ec); + end_integer_value(handler, ec); if (ec) return; push_state(state_); ++input_ptr_; ++column_; - state_ = parse_state::slash; + state_ = json_parse_state::slash; return; case '}': - end_integer_value(ec); - if (ec) return; - end_object(ec); + end_integer_value(handler, ec); if (ec) return; - ++input_ptr_; - ++column_; + state_ = json_parse_state::expect_comma_or_end; return; case ']': - end_integer_value(ec); + end_integer_value(handler, ec); if (ec) return; - end_array(ec); - if (ec) return; - ++input_ptr_; - ++column_; + state_ = json_parse_state::expect_comma_or_end; return; case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': - number_buffer_.push_back(static_cast(*input_ptr_)); - ++precision_; + string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++column_; goto integer; case '.': - decimal_places_ = 0; - JSONCONS_ASSERT(precision_ == number_buffer_.length()); - number_buffer_.push_back(to_double_.get_decimal_point()); + string_buffer_.push_back(to_double_.get_decimal_point()); ++input_ptr_; ++column_; goto fraction1; case 'e':case 'E': - JSONCONS_ASSERT(precision_ == number_buffer_.length()); - number_buffer_.push_back(static_cast(*input_ptr_)); + string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++column_; goto exp1; case ',': - end_integer_value(ec); + end_integer_value(handler, ec); if (ec) return; begin_member_or_element(ec); if (ec) return; @@ -1861,87 +1908,80 @@ class basic_json_parser : private serializing_context ++column_; return; default: - err_handler_.error(json_parser_errc::invalid_number, *this); - ec = json_parser_errc::invalid_number; - state_ = parse_state::integer; + err_handler_(json_errc::invalid_number, *this); + ec = json_errc::invalid_number; + continue_ = false; + state_ = json_parse_state::integer; return; } fraction1: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::fraction1; + state_ = json_parse_state::fraction1; return; } switch (*input_ptr_) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': - ++precision_; - ++decimal_places_; - number_buffer_.push_back(static_cast(*input_ptr_)); + string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++column_; goto fraction2; default: - err_handler_.error(json_parser_errc::invalid_number, *this); - ec = json_parser_errc::invalid_number; - state_ = parse_state::fraction1; + err_handler_(json_errc::invalid_number, *this); + ec = json_errc::invalid_number; + continue_ = false; + state_ = json_parse_state::fraction1; return; } fraction2: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::fraction2; + state_ = json_parse_state::fraction2; return; } switch (*input_ptr_) { case '\r': - end_fraction_value(chars_format::fixed,ec); + end_fraction_value(handler, ec); if (ec) return; push_state(state_); ++input_ptr_; ++column_; - state_ = parse_state::cr; + state_ = json_parse_state::cr; return; case '\n': - end_fraction_value(chars_format::fixed,ec); + end_fraction_value(handler, ec); if (ec) return; - push_state(state_); ++input_ptr_; - ++column_; - state_ = parse_state::lf; + ++line_; + column_ = 1; return; case ' ':case '\t': - end_fraction_value(chars_format::fixed,ec); + end_fraction_value(handler, ec); if (ec) return; - skip_whitespace(); + skip_space(); return; case '/': - end_fraction_value(chars_format::fixed,ec); + end_fraction_value(handler, ec); if (ec) return; push_state(state_); ++input_ptr_; ++column_; - state_ = parse_state::slash; + state_ = json_parse_state::slash; return; case '}': - end_fraction_value(chars_format::fixed,ec); - if (ec) return; - end_object(ec); + end_fraction_value(handler, ec); if (ec) return; - ++input_ptr_; - ++column_; + state_ = json_parse_state::expect_comma_or_end; return; case ']': - end_fraction_value(chars_format::fixed,ec); + end_fraction_value(handler, ec); if (ec) return; - end_array(ec); - if (ec) return; - ++input_ptr_; - ++column_; + state_ = json_parse_state::expect_comma_or_end; return; case ',': - end_fraction_value(chars_format::fixed,ec); + end_fraction_value(handler, ec); if (ec) return; begin_member_or_element(ec); if (ec) return; @@ -1949,27 +1989,26 @@ class basic_json_parser : private serializing_context ++column_; return; case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': - ++precision_; - ++decimal_places_; - number_buffer_.push_back(static_cast(*input_ptr_)); + string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++column_; goto fraction2; case 'e':case 'E': - number_buffer_.push_back(static_cast(*input_ptr_)); + string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++column_; goto exp1; default: - err_handler_.error(json_parser_errc::invalid_number, *this); - ec = json_parser_errc::invalid_number; - state_ = parse_state::fraction2; + err_handler_(json_errc::invalid_number, *this); + ec = json_errc::invalid_number; + continue_ = false; + state_ = json_parse_state::fraction2; return; } exp1: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::exp1; + state_ = json_parse_state::exp1; return; } switch (*input_ptr_) @@ -1979,96 +2018,91 @@ class basic_json_parser : private serializing_context ++column_; goto exp2; case '-': - number_buffer_.push_back(static_cast(*input_ptr_)); + string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++column_; goto exp2; case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': - number_buffer_.push_back(static_cast(*input_ptr_)); + string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++column_; goto exp3; default: - err_handler_.error(json_parser_errc::expected_value, *this); - ec = json_parser_errc::expected_value; - state_ = parse_state::exp1; + err_handler_(json_errc::expected_value, *this); + ec = json_errc::expected_value; + continue_ = false; + state_ = json_parse_state::exp1; return; } exp2: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::exp2; + state_ = json_parse_state::exp2; return; } switch (*input_ptr_) { case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': - number_buffer_.push_back(static_cast(*input_ptr_)); + string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++column_; goto exp3; default: - err_handler_.error(json_parser_errc::expected_value, *this); - ec = json_parser_errc::expected_value; - state_ = parse_state::exp2; + err_handler_(json_errc::expected_value, *this); + ec = json_errc::expected_value; + continue_ = false; + state_ = json_parse_state::exp2; return; } exp3: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::exp3; + state_ = json_parse_state::exp3; return; } switch (*input_ptr_) { case '\r': - end_fraction_value(chars_format::scientific,ec); + end_fraction_value(handler, ec); if (ec) return; ++input_ptr_; ++column_; push_state(state_); - state_ = parse_state::cr; + state_ = json_parse_state::cr; return; case '\n': - end_fraction_value(chars_format::scientific,ec); + end_fraction_value(handler, ec); if (ec) return; ++input_ptr_; - ++column_; - push_state(state_); - state_ = parse_state::lf; + ++line_; + column_ = 1; return; case ' ':case '\t': - end_fraction_value(chars_format::scientific,ec); + end_fraction_value(handler, ec); if (ec) return; - skip_whitespace(); + skip_space(); return; case '/': - end_fraction_value(chars_format::scientific,ec); + end_fraction_value(handler, ec); if (ec) return; push_state(state_); ++input_ptr_; ++column_; - state_ = parse_state::slash; + state_ = json_parse_state::slash; return; case '}': - end_fraction_value(chars_format::scientific,ec); - if (ec) return; - end_object(ec); + end_fraction_value(handler, ec); if (ec) return; - ++input_ptr_; - ++column_; + state_ = json_parse_state::expect_comma_or_end; return; case ']': - end_fraction_value(chars_format::scientific,ec); + end_fraction_value(handler, ec); if (ec) return; - end_array(ec); - if (ec) return; - ++input_ptr_; - ++column_; + state_ = json_parse_state::expect_comma_or_end; return; case ',': - end_fraction_value(chars_format::scientific,ec); + end_fraction_value(handler, ec); if (ec) return; begin_member_or_element(ec); if (ec) return; @@ -2076,50 +2110,51 @@ class basic_json_parser : private serializing_context ++column_; return; case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9': - number_buffer_.push_back(static_cast(*input_ptr_)); + string_buffer_.push_back(static_cast(*input_ptr_)); ++input_ptr_; ++column_; goto exp3; default: - err_handler_.error(json_parser_errc::invalid_number, *this); - ec = json_parser_errc::invalid_number; - state_ = parse_state::exp3; + err_handler_(json_errc::invalid_number, *this); + ec = json_errc::invalid_number; + continue_ = false; + state_ = json_parse_state::exp3; return; } JSONCONS_UNREACHABLE(); } - void parse_string(std::error_code& ec) + void parse_string(basic_json_content_handler& handler, std::error_code& ec) { const CharT* local_input_end = input_end_; const CharT* sb = input_ptr_; switch (state_) { - case parse_state::string_u1: + case json_parse_state::string: goto string_u1; - case parse_state::escape: + case json_parse_state::escape: goto escape; - case parse_state::escape_u1: + case json_parse_state::escape_u1: goto escape_u1; - case parse_state::escape_u2: + case json_parse_state::escape_u2: goto escape_u2; - case parse_state::escape_u3: + case json_parse_state::escape_u3: goto escape_u3; - case parse_state::escape_u4: + case json_parse_state::escape_u4: goto escape_u4; - case parse_state::escape_expect_surrogate_pair1: + case json_parse_state::escape_expect_surrogate_pair1: goto escape_expect_surrogate_pair1; - case parse_state::escape_expect_surrogate_pair2: + case json_parse_state::escape_expect_surrogate_pair2: goto escape_expect_surrogate_pair2; - case parse_state::escape_u6: + case json_parse_state::escape_u6: goto escape_u6; - case parse_state::escape_u7: + case json_parse_state::escape_u7: goto escape_u7; - case parse_state::escape_u8: + case json_parse_state::escape_u8: goto escape_u8; - case parse_state::escape_u9: + case json_parse_state::escape_u9: goto escape_u9; default: JSONCONS_UNREACHABLE(); @@ -2133,102 +2168,70 @@ class basic_json_parser : private serializing_context JSONCONS_ILLEGAL_CONTROL_CHARACTER: { column_ += (input_ptr_ - sb + 1); - if (err_handler_.error(json_parser_errc::illegal_control_character, *this)) + continue_ = err_handler_(json_errc::illegal_control_character, *this); + if (!continue_) { - ec = json_parser_errc::illegal_control_character; - state_ = parse_state::string_u1; + ec = json_errc::illegal_control_character; + state_ = json_parse_state::string; return; } // recovery - skip - auto result = unicons::validate(sb,input_ptr_); - if (result.ec != unicons::conv_errc()) - { - translate_conv_errc(result.ec,ec); - column_ += (result.it - sb); - return; - } string_buffer_.append(sb,input_ptr_-sb); ++input_ptr_; - state_ = parse_state::string_u1; + state_ = json_parse_state::string; return; } case '\r': { column_ += (input_ptr_ - sb + 1); - if (err_handler_.error(json_parser_errc::illegal_character_in_string, *this)) + continue_ = err_handler_(json_errc::illegal_character_in_string, *this); + if (!continue_) { - ec = json_parser_errc::illegal_character_in_string; - state_ = parse_state::string_u1; + ec = json_errc::illegal_character_in_string; + state_ = json_parse_state::string; return; } // recovery - keep - auto result = unicons::validate(sb,input_ptr_); - if (result.ec != unicons::conv_errc()) - { - translate_conv_errc(result.ec,ec); - column_ += (result.it - sb); - return; - } string_buffer_.append(sb, input_ptr_ - sb + 1); ++input_ptr_; push_state(state_); - state_ = parse_state::cr; + state_ = json_parse_state::cr; return; } case '\n': { - column_ += (input_ptr_ - sb + 1); - if (err_handler_.error(json_parser_errc::illegal_character_in_string, *this)) + ++line_; + column_ = 1; + continue_ = err_handler_(json_errc::illegal_character_in_string, *this); + if (!continue_) { - ec = json_parser_errc::illegal_character_in_string; - state_ = parse_state::string_u1; + ec = json_errc::illegal_character_in_string; + state_ = json_parse_state::string; return; } // recovery - keep - auto result = unicons::validate(sb,input_ptr_); - if (result.ec != unicons::conv_errc()) - { - translate_conv_errc(result.ec,ec); - column_ += (result.it - sb); - return; - } string_buffer_.append(sb, input_ptr_ - sb + 1); ++input_ptr_; - push_state(state_); - state_ = parse_state::lf; return; } case '\t': { column_ += (input_ptr_ - sb + 1); - if (err_handler_.error(json_parser_errc::illegal_character_in_string, *this)) + continue_ = err_handler_(json_errc::illegal_character_in_string, *this); + if (!continue_) { - ec = json_parser_errc::illegal_character_in_string; - state_ = parse_state::string_u1; + ec = json_errc::illegal_character_in_string; + state_ = json_parse_state::string; return; } // recovery - keep - auto result = unicons::validate(sb,input_ptr_); - if (result.ec != unicons::conv_errc()) - { - translate_conv_errc(result.ec,ec); - column_ += (result.it - sb); - return; - } string_buffer_.append(sb, input_ptr_ - sb + 1); ++input_ptr_; - state_ = parse_state::string_u1; + state_ = json_parse_state::string; return; } case '\\': { - auto result = unicons::validate(sb,input_ptr_); - if (result.ec != unicons::conv_errc()) - { - translate_conv_errc(result.ec,ec); - column_ += (result.it - sb); - return; - } string_buffer_.append(sb,input_ptr_-sb); column_ += (input_ptr_ - sb + 1); ++input_ptr_; @@ -2236,23 +2239,15 @@ class basic_json_parser : private serializing_context } case '\"': { - auto result = unicons::validate(sb,input_ptr_); - if (result.ec != unicons::conv_errc()) - { - translate_conv_errc(result.ec,ec); - column_ += (result.it - sb); - return; - } if (string_buffer_.length() == 0) { - end_string_value(sb,input_ptr_-sb, ec); + end_string_value(sb,input_ptr_-sb, handler, ec); if (ec) {return;} } else { string_buffer_.append(sb,input_ptr_-sb); - end_string_value(string_buffer_.data(),string_buffer_.length(), ec); - string_buffer_.clear(); + end_string_value(string_buffer_.data(),string_buffer_.length(), handler, ec); if (ec) {return;} } column_ += (input_ptr_ - sb + 1); @@ -2267,23 +2262,16 @@ class basic_json_parser : private serializing_context // Buffer exhausted { - auto result = unicons::validate(sb,input_ptr_); - if (result.ec != unicons::conv_errc()) - { - translate_conv_errc(result.ec,ec); - column_ += (result.it - sb); - return; - } string_buffer_.append(sb,input_ptr_-sb); column_ += (input_ptr_ - sb + 1); - state_ = parse_state::string_u1; + state_ = json_parse_state::string; return; } escape: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::escape; + state_ = json_parse_state::escape; return; } switch (*input_ptr_) @@ -2334,23 +2322,24 @@ class basic_json_parser : private serializing_context ++column_; goto escape_u1; default: - err_handler_.error(json_parser_errc::illegal_escaped_character, *this); - ec = json_parser_errc::illegal_escaped_character; - state_ = parse_state::escape; + err_handler_(json_errc::illegal_escaped_character, *this); + ec = json_errc::illegal_escaped_character; + continue_ = false; + state_ = json_parse_state::escape; return; } escape_u1: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::escape_u1; + state_ = json_parse_state::escape_u1; return; } { append_codepoint(*input_ptr_,ec); if (ec) { - state_ = parse_state::escape_u1; + state_ = json_parse_state::escape_u1; return; } ++input_ptr_; @@ -2361,14 +2350,14 @@ class basic_json_parser : private serializing_context escape_u2: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::escape_u2; + state_ = json_parse_state::escape_u2; return; } { append_codepoint(*input_ptr_, ec); if (ec) { - state_ = parse_state::escape_u2; + state_ = json_parse_state::escape_u2; return; } ++input_ptr_; @@ -2379,14 +2368,14 @@ class basic_json_parser : private serializing_context escape_u3: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::escape_u3; + state_ = json_parse_state::escape_u3; return; } { append_codepoint(*input_ptr_, ec); if (ec) { - state_ = parse_state::escape_u3; + state_ = json_parse_state::escape_u3; return; } ++input_ptr_; @@ -2397,14 +2386,14 @@ class basic_json_parser : private serializing_context escape_u4: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::escape_u4; + state_ = json_parse_state::escape_u4; return; } { append_codepoint(*input_ptr_, ec); if (ec) { - state_ = parse_state::escape_u4; + state_ = json_parse_state::escape_u4; return; } if (unicons::is_high_surrogate(cp_)) @@ -2418,7 +2407,7 @@ class basic_json_parser : private serializing_context unicons::convert(&cp_, &cp_ + 1, std::back_inserter(string_buffer_)); sb = ++input_ptr_; ++column_; - state_ = parse_state::string_u1; + state_ = json_parse_state::string; return; } } @@ -2426,7 +2415,7 @@ class basic_json_parser : private serializing_context escape_expect_surrogate_pair1: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::escape_expect_surrogate_pair1; + state_ = json_parse_state::escape_expect_surrogate_pair1; return; } { @@ -2438,9 +2427,10 @@ class basic_json_parser : private serializing_context ++column_; goto escape_expect_surrogate_pair2; default: - err_handler_.error(json_parser_errc::expected_codepoint_surrogate_pair, *this); - ec = json_parser_errc::expected_codepoint_surrogate_pair; - state_ = parse_state::escape_expect_surrogate_pair1; + err_handler_(json_errc::expected_codepoint_surrogate_pair, *this); + ec = json_errc::expected_codepoint_surrogate_pair; + continue_ = false; + state_ = json_parse_state::escape_expect_surrogate_pair1; return; } } @@ -2448,7 +2438,7 @@ class basic_json_parser : private serializing_context escape_expect_surrogate_pair2: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::escape_expect_surrogate_pair2; + state_ = json_parse_state::escape_expect_surrogate_pair2; return; } { @@ -2459,9 +2449,10 @@ class basic_json_parser : private serializing_context ++column_; goto escape_u6; default: - err_handler_.error(json_parser_errc::expected_codepoint_surrogate_pair, *this); - ec = json_parser_errc::expected_codepoint_surrogate_pair; - state_ = parse_state::escape_expect_surrogate_pair2; + err_handler_(json_errc::expected_codepoint_surrogate_pair, *this); + ec = json_errc::expected_codepoint_surrogate_pair; + continue_ = false; + state_ = json_parse_state::escape_expect_surrogate_pair2; return; } } @@ -2469,14 +2460,14 @@ class basic_json_parser : private serializing_context escape_u6: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::escape_u6; + state_ = json_parse_state::escape_u6; return; } { append_second_codepoint(*input_ptr_, ec); if (ec) { - state_ = parse_state::escape_u6; + state_ = json_parse_state::escape_u6; return; } } @@ -2487,14 +2478,14 @@ class basic_json_parser : private serializing_context escape_u7: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::escape_u7; + state_ = json_parse_state::escape_u7; return; } { append_second_codepoint(*input_ptr_, ec); if (ec) { - state_ = parse_state::escape_u7; + state_ = json_parse_state::escape_u7; return; } ++input_ptr_; @@ -2505,14 +2496,14 @@ class basic_json_parser : private serializing_context escape_u8: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::escape_u8; + state_ = json_parse_state::escape_u8; return; } { append_second_codepoint(*input_ptr_, ec); if (ec) { - state_ = parse_state::escape_u8; + state_ = json_parse_state::escape_u8; return; } ++input_ptr_; @@ -2523,14 +2514,14 @@ class basic_json_parser : private serializing_context escape_u9: if (JSONCONS_UNLIKELY(input_ptr_ >= local_input_end)) // Buffer exhausted { - state_ = parse_state::escape_u9; + state_ = json_parse_state::escape_u9; return; } { append_second_codepoint(*input_ptr_, ec); if (ec) { - state_ = parse_state::escape_u9; + state_ = json_parse_state::escape_u9; return; } uint32_t cp = 0x10000 + ((cp_ & 0x3FF) << 10) + (cp2_ & 0x3FF); @@ -2550,284 +2541,156 @@ class basic_json_parser : private serializing_context case unicons::conv_errc(): break; case unicons::conv_errc::over_long_utf8_sequence: - if (err_handler_.error(json_parser_errc::over_long_utf8_sequence, *this)) + continue_ = err_handler_(json_errc::over_long_utf8_sequence, *this); + if (!continue_) { - ec = json_parser_errc::over_long_utf8_sequence; + ec = json_errc::over_long_utf8_sequence; return; } break; case unicons::conv_errc::unpaired_high_surrogate: - if (err_handler_.error(json_parser_errc::unpaired_high_surrogate, *this)) + continue_ = err_handler_(json_errc::unpaired_high_surrogate, *this); + if (!continue_) { - ec = json_parser_errc::unpaired_high_surrogate; + ec = json_errc::unpaired_high_surrogate; return; } break; case unicons::conv_errc::expected_continuation_byte: - if (err_handler_.error(json_parser_errc::expected_continuation_byte, *this)) + continue_ = err_handler_(json_errc::expected_continuation_byte, *this); + if (!continue_) { - ec = json_parser_errc::expected_continuation_byte; + ec = json_errc::expected_continuation_byte; return; } break; case unicons::conv_errc::illegal_surrogate_value: - if (err_handler_.error(json_parser_errc::illegal_surrogate_value, *this)) + continue_ = err_handler_(json_errc::illegal_surrogate_value, *this); + if (!continue_) { - ec = json_parser_errc::illegal_surrogate_value; + ec = json_errc::illegal_surrogate_value; return; } break; default: - if (err_handler_.error(json_parser_errc::illegal_codepoint, *this)) + continue_ = err_handler_(json_errc::illegal_codepoint, *this); + if (!continue_) { - ec = json_parser_errc::illegal_codepoint; + ec = json_errc::illegal_codepoint; return; } break; } } - void parse_some() +#if !defined(JSONCONS_NO_DEPRECATED) + + JSONCONS_DEPRECATED("Instead, use finish_parse(basic_json_content_handler&)") + void end_parse(basic_json_content_handler& handler) { std::error_code ec; - parse_some(ec); + finish_parse(handler, ec); if (ec) { - throw parse_error(ec,line_,column_); + throw ser_error(ec,line_,column_); } } - void end_parse() + JSONCONS_DEPRECATED("Instead, use finish_parse(basic_json_content_handler&, std::error_code&)") + void end_parse(basic_json_content_handler& handler, std::error_code& ec) { - std::error_code ec; - end_parse(ec); - if (ec) + while (!finished()) { - throw parse_error(ec,line_,column_); + parse_some(handler, ec); } } - void end_parse(std::error_code& ec) + JSONCONS_DEPRECATED("Instead, use update(const CharT*, size_t)") + void set_source(const CharT* data, size_t length) { - if (parent() == parse_state::root) - { - switch (state_) - { - case parse_state::zero: - case parse_state::integer: - end_integer_value(ec); - if (ec) return; - break; - case parse_state::fraction2: - end_fraction_value(chars_format::fixed,ec); - if (ec) return; - break; - case parse_state::exp3: - end_fraction_value(chars_format::scientific,ec); - if (ec) return; - break; - default: - break; - } - } - if (state_ == parse_state::lf || state_ == parse_state::cr) - { - state_ = pop_state(); - } - if (!(state_ == parse_state::done || state_ == parse_state::start)) - { - if (err_handler_.error(json_parser_errc::unexpected_eof, *this)) - { - ec = json_parser_errc::unexpected_eof; - return; - } - } + begin_input_ = data; + input_end_ = data + length; + input_ptr_ = begin_input_; } +#endif - parse_state state() const + size_t line() const override { - return state_; + return line_; } - void set_source(const CharT* input, size_t length) + size_t column() const override { - begin_input_ = input; - input_end_ = input + length; - input_ptr_ = begin_input_; + return column_; } private: - void end_integer_value(std::error_code& ec) + void end_integer_value(basic_json_content_handler& handler, std::error_code& ec) { - if (is_negative_) + if (string_buffer_[0] == '-') { - end_negative_value(ec); + end_negative_value(handler, ec); } else { - end_positive_value(ec); + end_positive_value(handler, ec); } } - void end_negative_value(std::error_code& ec) + void end_negative_value(basic_json_content_handler& handler, std::error_code& ec) { - static const int64_t min_value = (std::numeric_limits::min)(); - static const int64_t min_value_div_10 = min_value / 10; - - const char* s = number_buffer_.data(); - size_t length = number_buffer_.length(); - int64_t n = 0; - bool overflow = false; - const char* end = s + length; - for (; s < end; ++s) - { - int64_t x = *s - '0'; - if (n < min_value_div_10) - { - overflow = true; - break; - } - n = n * 10; - if (n < min_value + x) - { - overflow = true; - break; - } - - n -= x; - } - - if (!overflow) + auto result = jsoncons::detail::to_integer(string_buffer_.data(), string_buffer_.length()); + if (result.ec == jsoncons::detail::to_integer_errc()) { - handler_.integer_value(n, *this); - - switch (parent()) - { - case parse_state::array: - case parse_state::object: - state_ = parse_state::expect_comma_or_end; - break; - case parse_state::root: - state_ = parse_state::done; - handler_.end_json(); - break; - default: - if (err_handler_.error(json_parser_errc::invalid_json_text, *this)) - { - ec = json_parser_errc::invalid_json_text; - return; - } - break; - } + continue_ = handler.int64_value(result.value, semantic_tag::none, *this); } - else + else // Must be overflow { - end_fraction_value(chars_format::general,ec); + continue_ = handler.string_value(string_buffer_, semantic_tag::bigint, *this); } + after_value(ec); } - void end_positive_value(std::error_code& ec) + void end_positive_value(basic_json_content_handler& handler, std::error_code& ec) { - static const uint64_t max_value = (std::numeric_limits::max)(); - static const uint64_t max_value_div_10 = max_value / 10; - uint64_t n = 0; - bool overflow = false; - const char* s = number_buffer_.data(); - size_t length = number_buffer_.length(); - - const char* end = s + length; - for (; s < end; ++s) - { - uint64_t x = *s - '0'; - if (n > max_value_div_10) - { - overflow = true; - break; - } - n = n * 10; - if (n > max_value - x) - { - overflow = true; - break; - } - - n += x; - } - - if (!overflow) + auto result = jsoncons::detail::to_integer(string_buffer_.data(), string_buffer_.length()); + if (result.ec == jsoncons::detail::to_integer_errc()) { - handler_.uinteger_value(n, *this); - - switch (parent()) - { - case parse_state::array: - case parse_state::object: - state_ = parse_state::expect_comma_or_end; - break; - case parse_state::root: - state_ = parse_state::done; - handler_.end_json(); - break; - default: - if (err_handler_.error(json_parser_errc::invalid_json_text, *this)) - { - ec = json_parser_errc::invalid_json_text; - return; - } - break; - } + continue_ = handler.uint64_value(result.value, semantic_tag::none, *this); } - else + else // Must be overflow { - end_fraction_value(chars_format::general,ec); + continue_ = handler.string_value(string_buffer_, semantic_tag::bigint, *this); } + after_value(ec); } - void end_fraction_value(chars_format format, std::error_code& ec) + void end_fraction_value(basic_json_content_handler& handler, std::error_code& ec) { try { - double d = to_double_(number_buffer_.c_str(), number_buffer_.length()); - if (is_negative_) - d = -d; - - if (precision_ > std::numeric_limits::max_digits10) + if (options_.lossless_number()) { - handler_.double_value(d, number_format(format,std::numeric_limits::max_digits10, decimal_places_), *this); + continue_ = handler.string_value(string_buffer_, semantic_tag::bigdec, *this); } else { - handler_.double_value(d, number_format(format,static_cast(precision_), decimal_places_), *this); + double d = to_double_(string_buffer_.c_str(), string_buffer_.length()); + continue_ = handler.double_value(d, semantic_tag::none, *this); } } catch (...) { - if (err_handler_.error(json_parser_errc::invalid_number, *this)) + continue_ = err_handler_(json_errc::invalid_number, *this); + if (!continue_) { - ec = json_parser_errc::invalid_number; + ec = json_errc::invalid_number; return; } - handler_.null_value(*this); // recovery + continue_ = handler.null_value(semantic_tag::none, *this); // recovery } - switch (parent()) - { - case parse_state::array: - case parse_state::object: - state_ = parse_state::expect_comma_or_end; - break; - case parse_state::root: - state_ = parse_state::done; - handler_.end_json(); - break; - default: - if (err_handler_.error(json_parser_errc::invalid_json_text, *this)) - { - ec = json_parser_errc::invalid_json_text; - return; - } - break; - } + after_value(ec); } void append_codepoint(int c, std::error_code& ec) @@ -2841,9 +2704,10 @@ class basic_json_parser : private serializing_context if (ec) return; break; default: - if (err_handler_.error(json_parser_errc::expected_value, *this)) + continue_ = err_handler_(json_errc::expected_value, *this); + if (!continue_) { - ec = json_parser_errc::expected_value; + ec = json_errc::expected_value; return; } break; @@ -2862,38 +2726,46 @@ class basic_json_parser : private serializing_context if (ec) return; break; default: - if (err_handler_.error(json_parser_errc::expected_value, *this)) + continue_ = err_handler_(json_errc::expected_value, *this); + if (!continue_) { - ec = json_parser_errc::expected_value; + ec = json_errc::expected_value; return; } break; } } - void end_string_value(const CharT* s, size_t length, std::error_code& ec) + void end_string_value(const CharT* s, size_t length, basic_json_content_handler& handler, std::error_code& ec) { + auto result = unicons::validate(s,s+length); + if (result.ec != unicons::conv_errc()) + { + translate_conv_errc(result.ec,ec); + column_ += (result.it - s); + return; + } switch (parent()) { - case parse_state::member_name: - handler_.name(string_view_type(s, length), *this); + case json_parse_state::member_name: + continue_ = handler.name(string_view_type(s, length), *this); state_ = pop_state(); - state_ = parse_state::expect_colon; + state_ = json_parse_state::expect_colon; break; - case parse_state::object: - case parse_state::array: - handler_.string_value(string_view_type(s, length), *this); - state_ = parse_state::expect_comma_or_end; + case json_parse_state::object: + case json_parse_state::array: + continue_ = handler.string_value(string_view_type(s, length), semantic_tag::none, *this); + state_ = json_parse_state::expect_comma_or_end; break; - case parse_state::root: - handler_.string_value(string_view_type(s, length), *this); - state_ = parse_state::done; - handler_.end_json(); + case json_parse_state::root: + continue_ = handler.string_value(string_view_type(s, length), semantic_tag::none, *this); + state_ = json_parse_state::before_done; break; default: - if (err_handler_.error(json_parser_errc::invalid_json_text, *this)) + continue_ = err_handler_(json_errc::invalid_json_text, *this); + if (!continue_) { - ec = json_parser_errc::invalid_json_text; + ec = json_errc::invalid_json_text; return; } break; @@ -2904,33 +2776,56 @@ class basic_json_parser : private serializing_context { switch (parent()) { - case parse_state::object: - state_ = parse_state::expect_member_name; + case json_parse_state::object: + state_ = json_parse_state::expect_member_name; + break; + case json_parse_state::array: + state_ = json_parse_state::expect_value; + break; + case json_parse_state::root: + break; + default: + continue_ = err_handler_(json_errc::invalid_json_text, *this); + if (!continue_) + { + ec = json_errc::invalid_json_text; + return; + } break; - case parse_state::array: - state_ = parse_state::expect_value; + } + } + + void after_value(std::error_code& ec) + { + switch (parent()) + { + case json_parse_state::array: + case json_parse_state::object: + state_ = json_parse_state::expect_comma_or_end; break; - case parse_state::root: + case json_parse_state::root: + state_ = json_parse_state::before_done; break; default: - if (err_handler_.error(json_parser_errc::invalid_json_text, *this)) + continue_ = err_handler_(json_errc::invalid_json_text, *this); + if (!continue_) { - ec = json_parser_errc::invalid_json_text; + ec = json_errc::invalid_json_text; return; } break; } } - void push_state(parse_state state) + void push_state(json_parse_state state) { state_stack_.push_back(state); } - parse_state pop_state() + json_parse_state pop_state() { JSONCONS_ASSERT(!state_stack_.empty()) - parse_state state = state_stack_.back(); + json_parse_state state = state_stack_.back(); state_stack_.pop_back(); return state; } @@ -2952,24 +2847,15 @@ class basic_json_parser : private serializing_context } else { - if (err_handler_.error(json_parser_errc::invalid_hex_escape_sequence, *this)) + continue_ = err_handler_(json_errc::invalid_hex_escape_sequence, *this); + if (!continue_) { - ec = json_parser_errc::invalid_hex_escape_sequence; + ec = json_errc::invalid_hex_escape_sequence; return cp; } } return cp; } - - size_t do_line_number() const override - { - return line_; - } - - size_t do_column_number() const override - { - return column_; - } }; typedef basic_json_parser json_parser; diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_reader.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_reader.hpp index e7c32bd..6574fca 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_reader.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_reader.hpp @@ -7,18 +7,16 @@ #ifndef JSONCONS_JSON_READER_HPP #define JSONCONS_JSON_READER_HPP -#include +#include // std::allocator #include -#include #include -#include -#include #include #include #include +#include // std::move +#include #include #include -#include #include namespace jsoncons { @@ -33,7 +31,7 @@ class json_utf8_other_content_handler_adapter : public json_content_handler private: basic_null_json_content_handler default_content_handler_; basic_json_content_handler& other_handler_; - //parse_error_handler& err_handler_; + //std::function err_handler_; // noncopyable and nonmoveable json_utf8_other_content_handler_adapter(const json_utf8_other_content_handler_adapter&) = delete; @@ -46,7 +44,7 @@ class json_utf8_other_content_handler_adapter : public json_content_handler } json_utf8_other_content_handler_adapter(basic_json_content_handler& other_handler/*, - parse_error_handler& err_handler*/) + std::function err_handler*/) : other_handler_(other_handler)/*, err_handler_(err_handler)*/ { @@ -54,37 +52,32 @@ class json_utf8_other_content_handler_adapter : public json_content_handler private: - void do_begin_json() override + void do_flush() override { - other_handler_.begin_json(); + other_handler_.flush(); } - void do_end_json() override + bool do_begin_object(semantic_tag tag, const ser_context& context) override { - other_handler_.end_json(); + return other_handler_.begin_object(tag, context); } - void do_begin_object(const serializing_context& context) override + bool do_end_object(const ser_context& context) override { - other_handler_.begin_object(context); + return other_handler_.end_object(context); } - void do_end_object(const serializing_context& context) override + bool do_begin_array(semantic_tag tag, const ser_context& context) override { - other_handler_.end_object(context); + return other_handler_.begin_array(tag, context); } - void do_begin_array(const serializing_context& context) override + bool do_end_array(const ser_context& context) override { - other_handler_.begin_array(context); + return other_handler_.end_array(context); } - void do_end_array(const serializing_context& context) override - { - other_handler_.end_array(context); - } - - void do_name(const string_view_type& name, const serializing_context& context) override + bool do_name(const string_view_type& name, const ser_context& context) override { std::basic_string target; auto result = unicons::convert( @@ -92,12 +85,12 @@ class json_utf8_other_content_handler_adapter : public json_content_handler unicons::conv_flags::strict); if (result.ec != unicons::conv_errc()) { - throw parse_error(result.ec,context.line_number(),context.column_number()); + throw ser_error(result.ec,context.line(),context.column()); } - other_handler_.name(target, context); + return other_handler_.name(target, context); } - void do_string_value(const string_view_type& value, const serializing_context& context) override + bool do_string_value(const string_view_type& value, semantic_tag tag, const ser_context& context) override { std::basic_string target; auto result = unicons::convert( @@ -105,51 +98,66 @@ class json_utf8_other_content_handler_adapter : public json_content_handler unicons::conv_flags::strict); if (result.ec != unicons::conv_errc()) { - throw parse_error(result.ec,context.line_number(),context.column_number()); + throw ser_error(result.ec,context.line(),context.column()); } - other_handler_.string_value(target, context); + return other_handler_.string_value(target, tag, context); } - void do_integer_value(int64_t value, const serializing_context& context) override + bool do_int64_value(int64_t value, + semantic_tag tag, + const ser_context& context) override { - other_handler_.integer_value(value, context); + return other_handler_.int64_value(value, tag, context); } - void do_uinteger_value(uint64_t value, const serializing_context& context) override + bool do_uint64_value(uint64_t value, + semantic_tag tag, + const ser_context& context) override { - other_handler_.uinteger_value(value, context); + return other_handler_.uint64_value(value, tag, context); } - void do_double_value(double value, const number_format& fmt, const serializing_context& context) override + bool do_double_value(double value, + semantic_tag tag, + const ser_context& context) override { - other_handler_.double_value(value, fmt, context); + return other_handler_.double_value(value, tag, context); } - void do_bool_value(bool value, const serializing_context& context) override + bool do_bool_value(bool value, semantic_tag tag, const ser_context& context) override { - other_handler_.bool_value(value, context); + return other_handler_.bool_value(value, tag, context); } - void do_null_value(const serializing_context& context) override + bool do_null_value(semantic_tag tag, const ser_context& context) override { - other_handler_.null_value(context); + return other_handler_.null_value(tag, context); } }; -template> +template,class Allocator=std::allocator> class basic_json_reader { - static const size_t default_max_buffer_length = 16384; - +public: typedef CharT char_type; + typedef Src source_type; + typedef basic_string_view string_view_type; typedef Allocator allocator_type; +private: typedef typename std::allocator_traits:: template rebind_alloc char_allocator_type; + static const size_t default_max_buffer_length = 16384; + + basic_null_json_content_handler default_content_handler_; + + basic_json_content_handler& handler_; + basic_json_parser parser_; - std::basic_istream& is_; - bool eof_; + + source_type source_; std::vector buffer_; size_t buffer_length_; + bool eof_; bool begin_; // Noncopyable and nonmoveable @@ -157,97 +165,114 @@ class basic_json_reader basic_json_reader& operator=(const basic_json_reader&) = delete; public: + template + explicit basic_json_reader(Source&& source) + : basic_json_reader(std::forward(source), + default_content_handler_, + basic_json_options::get_default_options(), + default_json_parsing()) + { + } - basic_json_reader(std::basic_istream& is) - : parser_(), - is_(is), - eof_(false), - buffer_length_(default_max_buffer_length), - begin_(true) + template + basic_json_reader(Source&& source, + const basic_json_decode_options& options) + : basic_json_reader(std::forward(source), + default_content_handler_, + options, + default_json_parsing()) { - buffer_.reserve(buffer_length_); } - basic_json_reader(std::basic_istream& is, - parse_error_handler& err_handler) - : parser_(err_handler), - is_(is), - eof_(false), - buffer_length_(default_max_buffer_length), - begin_(true) + template + basic_json_reader(Source&& source, + std::function err_handler) + : basic_json_reader(std::forward(source), + default_content_handler_, + basic_json_options::get_default_options(), + err_handler) { - buffer_.reserve(buffer_length_); } - basic_json_reader(std::basic_istream& is, + template + basic_json_reader(Source&& source, + const basic_json_decode_options& options, + std::function err_handler) + : basic_json_reader(std::forward(source), + default_content_handler_, + options, + err_handler) + { + } + + template + basic_json_reader(Source&& source, basic_json_content_handler& handler) - : parser_(handler), - is_(is), - eof_(false), - buffer_length_(default_max_buffer_length), - begin_(true) + : basic_json_reader(std::forward(source), + handler, + basic_json_options::get_default_options(), + default_json_parsing()) { - buffer_.reserve(buffer_length_); } - basic_json_reader(std::basic_istream& is, + template + basic_json_reader(Source&& source, basic_json_content_handler& handler, - parse_error_handler& err_handler) - : parser_(handler,err_handler), - is_(is), - eof_(false), - buffer_length_(default_max_buffer_length), - begin_(true) + const basic_json_decode_options& options) + : basic_json_reader(std::forward(source), + handler, + options, + default_json_parsing()) { - buffer_.reserve(buffer_length_); } - basic_json_reader(std::basic_istream& is, - const basic_json_serializing_options& options) - : parser_(options), - is_(is), - eof_(false), - buffer_length_(default_max_buffer_length), - begin_(true) + template + basic_json_reader(Source&& source, + basic_json_content_handler& handler, + std::function err_handler) + : basic_json_reader(std::forward(source), + handler, + basic_json_options::get_default_options(), + err_handler) { - buffer_.reserve(buffer_length_); } - basic_json_reader(std::basic_istream& is, - const basic_json_serializing_options& options, - parse_error_handler& err_handler) - : parser_(options,err_handler), - is_(is), - eof_(false), + template + basic_json_reader(Source&& source, + basic_json_content_handler& handler, + const basic_json_decode_options& options, + std::function err_handler, + typename std::enable_if,Source>::value>::type* = 0) + : handler_(handler), + parser_(options,err_handler), + source_(std::forward(source)), buffer_length_(default_max_buffer_length), + eof_(false), begin_(true) { buffer_.reserve(buffer_length_); } - basic_json_reader(std::basic_istream& is, - const basic_json_serializing_options& options, - basic_json_content_handler& handler) - : parser_(handler,options), - is_(is), - eof_(false), - buffer_length_(default_max_buffer_length), - begin_(true) - { - buffer_.reserve(buffer_length_); - } - - basic_json_reader(std::basic_istream& is, + template + basic_json_reader(Source&& source, basic_json_content_handler& handler, - const basic_json_serializing_options& options, - parse_error_handler& err_handler) - : parser_(handler,options,err_handler), - is_(is), + const basic_json_decode_options& options, + std::function err_handler, + typename std::enable_if,Source>::value>::type* = 0) + : handler_(handler), + parser_(options,err_handler), + buffer_length_(0), eof_(false), - buffer_length_(default_max_buffer_length), - begin_(true) + begin_(false) { - buffer_.reserve(buffer_length_); + basic_string_view sv(std::forward(source)); + auto result = unicons::skip_bom(sv.begin(), sv.end()); + if (result.ec != unicons::encoding_errc()) + { + throw ser_error(result.ec,parser_.line(),parser_.column()); + } + size_t offset = result.it - sv.begin(); + parser_.update(sv.data()+offset,sv.size()-offset); } size_t buffer_length() const @@ -261,11 +286,13 @@ class basic_json_reader buffer_.reserve(buffer_length_); } #if !defined(JSONCONS_NO_DEPRECATED) + JSONCONS_DEPRECATED("Instead, use max_nesting_depth() on options") size_t max_nesting_depth() const { return parser_.max_nesting_depth(); } + JSONCONS_DEPRECATED("Instead, use max_nesting_depth(size_t) on options") void max_nesting_depth(size_t depth) { parser_.max_nesting_depth(depth); @@ -277,70 +304,62 @@ class basic_json_reader read_next(ec); if (ec) { - throw parse_error(ec,parser_.line_number(),parser_.column_number()); + throw ser_error(ec,parser_.line(),parser_.column()); } } - void read_buffer(std::error_code& ec) + void read_next(std::error_code& ec) { - buffer_.clear(); - buffer_.resize(buffer_length_); - is_.read(buffer_.data(), buffer_length_); - buffer_.resize(static_cast(is_.gcount())); - if (buffer_.size() == 0) - { - eof_ = true; - } - else if (begin_) + try { - auto result = unicons::skip_bom(buffer_.begin(), buffer_.end()); - if (result.ec != unicons::encoding_errc()) + if (source_.is_error()) { - ec = result.ec; + ec = json_errc::source_error; return; + } + parser_.reset(); + while (!parser_.finished()) + { + if (parser_.source_exhausted()) + { + if (!source_.eof()) + { + read_buffer(ec); + if (ec) return; + } + else + { + eof_ = true; + } + } + parser_.parse_some(handler_, ec); + if (ec) return; } - size_t offset = result.it - buffer_.begin(); - parser_.set_source(buffer_.data()+offset,buffer_.size()-offset); - begin_ = false; - } - else - { - parser_.set_source(buffer_.data(),buffer_.size()); - } - } - - void read_next(std::error_code& ec) - { - parser_.reset(); - while (!eof_ && !parser_.done()) - { - if (parser_.source_exhausted()) + + while (!eof_) { - if (!is_.eof()) + parser_.skip_whitespace(); + if (parser_.source_exhausted()) { - if (is_.fail()) + if (!source_.eof()) + { + read_buffer(ec); + if (ec) return; + } + else { - ec = json_parser_errc::source_error; - return; - } - read_buffer(ec); - if (ec) return; + eof_ = true; + } } else { - eof_ = true; + break; } } - if (!eof_) - { - parser_.parse_some(ec); - if (ec) return; - } } - if (eof_) + catch (const ser_error& e) { - parser_.end_parse(ec); - if (ec) return; + ec = e.code(); } } @@ -350,55 +369,62 @@ class basic_json_reader check_done(ec); if (ec) { - throw parse_error(ec,parser_.line_number(),parser_.column_number()); + throw ser_error(ec,parser_.line(),parser_.column()); } } - size_t line_number() const + size_t line() const { - return parser_.line_number(); + return parser_.line(); } - size_t column_number() const + size_t column() const { - return parser_.column_number(); + return parser_.column(); } void check_done(std::error_code& ec) { - if (eof_) + try { - parser_.check_done(ec); - if (ec) return; - } - else - { - while (!eof_) + if (source_.is_error()) { - if (parser_.source_exhausted()) + ec = json_errc::source_error; + return; + } + if (eof_) + { + parser_.check_done(ec); + if (ec) return; + } + else + { + while (!eof_) { - if (!is_.eof()) + if (parser_.source_exhausted()) { - if (is_.fail()) + if (!source_.eof()) { - ec = json_parser_errc::source_error; - return; - } - read_buffer(ec); - if (ec) return; + read_buffer(ec); + if (ec) return; + } + else + { + eof_ = true; + } } - else + if (!eof_) { - eof_ = true; + parser_.check_done(ec); + if (ec) return; } } - if (!eof_) - { - parser_.check_done(ec); - if (ec) return; - } } } + catch (const ser_error& e) + { + ec = e.code(); + } } bool eof() const @@ -423,21 +449,25 @@ class basic_json_reader #if !defined(JSONCONS_NO_DEPRECATED) + JSONCONS_DEPRECATED("Instead, use buffer_length()") size_t buffer_capacity() const { return buffer_length_; } + JSONCONS_DEPRECATED("Instead, use buffer_length(size_t)") void buffer_capacity(size_t length) { buffer_length_ = length; buffer_.reserve(buffer_length_); } + JSONCONS_DEPRECATED("Instead, use max_nesting_depth()") size_t max_depth() const { return parser_.max_nesting_depth(); } + JSONCONS_DEPRECATED("Instead, use max_nesting_depth(size_t)") void max_depth(size_t depth) { parser_.max_nesting_depth(depth); @@ -445,11 +475,44 @@ class basic_json_reader #endif private: + + void read_buffer(std::error_code& ec) + { + buffer_.clear(); + buffer_.resize(buffer_length_); + size_t count = source_.read(buffer_.data(), buffer_length_); + buffer_.resize(static_cast(count)); + if (buffer_.size() == 0) + { + eof_ = true; + } + else if (begin_) + { + auto result = unicons::skip_bom(buffer_.begin(), buffer_.end()); + if (result.ec != unicons::encoding_errc()) + { + ec = result.ec; + return; + } + size_t offset = result.it - buffer_.begin(); + parser_.update(buffer_.data()+offset,buffer_.size()-offset); + begin_ = false; + } + else + { + parser_.update(buffer_.data(),buffer_.size()); + } + } }; typedef basic_json_reader json_reader; typedef basic_json_reader wjson_reader; +#if !defined(JSONCONS_NO_DEPRECATED) +JSONCONS_DEPRECATED("Instead, use json_reader") typedef json_reader json_string_reader; +JSONCONS_DEPRECATED("Instead, use wjson_reader") typedef wjson_reader wjson_string_reader; +#endif + } #endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_serializer.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_serializer.hpp index d801ea8..2db2635 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_serializer.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_serializer.hpp @@ -7,668 +7,6 @@ #ifndef JSONCONS_JSON_SERIALIZER_HPP #define JSONCONS_JSON_SERIALIZER_HPP -#include -#include -#include -#include -#include -#include -#include // std::numeric_limits -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace jsoncons { - -template> -class basic_json_serializer final : public basic_json_content_handler -{ -public: - using typename basic_json_content_handler::string_view_type; - typedef Writer writer_type; - typedef typename Writer::output_type output_type; - -private: - static const size_t default_buffer_length = 16384; - - enum class structure_type {object, array}; - - class line_split_context - { - structure_type type_; - size_t count_; - line_split_kind split_lines_; - bool indent_before_; - bool unindent_after_; - public: - line_split_context(structure_type type) - : type_(type), count_(0), split_lines_(line_split_kind::same_line), indent_before_(false), unindent_after_(false) - { - } - line_split_context(structure_type type, line_split_kind split_lines, bool indent_once) - : type_(type), count_(0), split_lines_(split_lines), indent_before_(indent_once), unindent_after_(false) - { - } - - size_t count() const - { - return count_; - } - - void increment_count() - { - ++count_; - } - - bool unindent_after() const - { - return unindent_after_; - } - - void unindent_after(bool value) - { - unindent_after_ = value; - } - - bool is_object() const - { - return type_ == structure_type::object; - } - - bool is_array() const - { - return type_ == structure_type::array; - } - - bool is_same_line() const - { - return split_lines_ == line_split_kind::same_line; - } - - bool is_new_line() const - { - return split_lines_ == line_split_kind::new_line; - } - - bool is_multi_line() const - { - return split_lines_ == line_split_kind::multi_line; - } - - bool is_indent_once() const - { - return count_ == 0 ? indent_before_ : false; - } - - }; - basic_json_serializing_options options_; - std::vector stack_; - int indent_; - bool indenting_; - detail::print_double fp_; - Writer writer_; - - // Noncopyable and nonmoveable - basic_json_serializer(const basic_json_serializer&) = delete; - basic_json_serializer& operator=(const basic_json_serializer&) = delete; -public: - basic_json_serializer(output_type& os) - : indent_(0), - indenting_(false), - fp_(options_.precision()), - writer_(os) - { - } - - basic_json_serializer(output_type& os, indenting line_indent) - : indent_(0), - indenting_(line_indent == indenting::indent), - fp_(options_.precision()), - writer_(os) - { - } - - basic_json_serializer(output_type& os, const basic_json_serializing_options& options) - : options_(options), - indent_(0), - indenting_(false), - fp_(options_.precision()), - writer_(os) - { - } - - basic_json_serializer(output_type& os, - const basic_json_serializing_options& options, - indenting line_indent) - : options_(options), - indent_(0), - indenting_(line_indent == indenting::indent), - fp_(options_.precision()), - writer_(os) - { - } - - ~basic_json_serializer() - { - } - - -#if !defined(JSONCONS_NO_DEPRECATED) - - basic_json_serializer(output_type& os, bool pprint) - : indent_(0), - indenting_(pprint), - fp_(options_.precision()), - writer_(os) - { - } - - basic_json_serializer(output_type& os, const basic_json_serializing_options& options, bool pprint) - : options_(options), - indent_(0), - indenting_(pprint), - fp_(options_.precision()), - writer_(os) - { - } -#endif - -private: - void escape_string(const CharT* s, - size_t length, - const basic_json_serializing_options& options, - writer_type& writer) - { - const CharT* begin = s; - const CharT* end = s + length; - for (const CharT* it = begin; it != end; ++it) - { - CharT c = *it; - switch (c) - { - case '\\': - writer.put('\\'); - writer.put('\\'); - break; - case '"': - writer.put('\\'); - writer.put('\"'); - break; - case '\b': - writer.put('\\'); - writer.put('b'); - break; - case '\f': - writer.put('\\'); - writer.put('f'); - break; - case '\n': - writer.put('\\'); - writer.put('n'); - break; - case '\r': - writer.put('\\'); - writer.put('r'); - break; - case '\t': - writer.put('\\'); - writer.put('t'); - break; - default: - if (options.escape_solidus() && c == '/') - { - writer.put('\\'); - writer.put('/'); - } - else if (is_control_character(c) || options.escape_all_non_ascii()) - { - // convert utf8 to codepoint - unicons::sequence_generator g(it,end,unicons::conv_flags::strict); - if (g.done() || g.status() != unicons::conv_errc()) - { - JSONCONS_THROW(json_exception_impl("Invalid codepoint")); - } - uint32_t cp = g.get().codepoint(); - it += (g.get().length() - 1); - if (is_non_ascii_codepoint(cp) || is_control_character(c)) - { - if (cp > 0xFFFF) - { - cp -= 0x10000; - uint32_t first = (cp >> 10) + 0xD800; - uint32_t second = ((cp & 0x03FF) + 0xDC00); - - writer.put('\\'); - writer.put('u'); - writer.put(to_hex_character(first >> 12 & 0x000F)); - writer.put(to_hex_character(first >> 8 & 0x000F)); - writer.put(to_hex_character(first >> 4 & 0x000F)); - writer.put(to_hex_character(first & 0x000F)); - writer.put('\\'); - writer.put('u'); - writer.put(to_hex_character(second >> 12 & 0x000F)); - writer.put(to_hex_character(second >> 8 & 0x000F)); - writer.put(to_hex_character(second >> 4 & 0x000F)); - writer.put(to_hex_character(second & 0x000F)); - } - else - { - writer.put('\\'); - writer.put('u'); - writer.put(to_hex_character(cp >> 12 & 0x000F)); - writer.put(to_hex_character(cp >> 8 & 0x000F)); - writer.put(to_hex_character(cp >> 4 & 0x000F)); - writer.put(to_hex_character(cp & 0x000F)); - } - } - else - { - writer.put(c); - } - } - else - { - writer.put(c); - } - break; - } - } - } - // Implementing methods - void do_begin_json() override - { - } - - void do_end_json() override - { - writer_.flush(); - } - - void do_begin_object(const serializing_context&) override - { - if (!stack_.empty() && stack_.back().is_array()) - { - if (!stack_.empty()) - { - if (stack_.back().count() > 0) - { - writer_. put(','); - } - } - } - - if (indenting_) - { - if (!stack_.empty() && stack_.back().is_object()) - { - stack_.push_back(line_split_context(structure_type::object,options_.object_object_split_lines(), false)); - } - else if (!stack_.empty()) - { - if (options_.array_object_split_lines() != line_split_kind::same_line) - { - stack_.back().unindent_after(true); - stack_.push_back(line_split_context(structure_type::object,options_.array_object_split_lines(), false)); - write_indent1(); - } - else - { - stack_.push_back(line_split_context(structure_type::object,options_.array_object_split_lines(), false)); - } - } - else - { - stack_.push_back(line_split_context(structure_type::object, line_split_kind::multi_line, false)); - } - indent(); - } - else - { - stack_.push_back(line_split_context(structure_type::object)); - } - writer_.put('{'); - } - - void do_end_object(const serializing_context&) override - { - JSONCONS_ASSERT(!stack_.empty()); - if (indenting_) - { - unindent(); - if (stack_.back().unindent_after()) - { - write_indent(); - } - } - stack_.pop_back(); - writer_.put('}'); - - end_value(); - } - - - void do_begin_array(const serializing_context&) override - { - if (!stack_.empty() && stack_.back().is_array()) - { - if (!stack_.empty()) - { - if (stack_.back().count() > 0) - { - writer_. put(','); - } - } - } - if (indenting_) - { - if (!stack_.empty()) - { - if (stack_.back().is_object()) - { - writer_.put('['); - indent(); - if (options_.object_array_split_lines() != line_split_kind::same_line) - { - stack_.push_back(line_split_context(structure_type::array,options_.object_array_split_lines(),true)); - } - else - { - stack_.push_back(line_split_context(structure_type::array,options_.object_array_split_lines(),false)); - } - } - else // array - { - if (options_.array_array_split_lines() == line_split_kind::same_line) - { - if (stack_.back().is_multi_line()) - { - write_indent(); - } - stack_.push_back(line_split_context(structure_type::array,line_split_kind::same_line, false)); - indent(); - } - else if (options_.array_array_split_lines() == line_split_kind::multi_line) - { - write_indent(); - stack_.push_back(line_split_context(structure_type::array,options_.array_array_split_lines(), false)); - indent(); - } - else // new_line - { - write_indent(); - stack_.push_back(line_split_context(structure_type::array,options_.array_array_split_lines(), false)); - indent(); - } - writer_.put('['); - } - } - else - { - stack_.push_back(line_split_context(structure_type::array, line_split_kind::multi_line, false)); - writer_.put('['); - indent(); - } - } - else - { - stack_.push_back(line_split_context(structure_type::array)); - writer_.put('['); - } - } - - void do_end_array(const serializing_context&) override - { - JSONCONS_ASSERT(!stack_.empty()); - if (indenting_) - { - unindent(); - if (stack_.back().unindent_after()) - { - write_indent(); - } - } - stack_.pop_back(); - writer_.put(']'); - end_value(); - } - - void do_name(const string_view_type& name, const serializing_context&) override - { - if (!stack_.empty()) - { - if (stack_.back().count() > 0) - { - writer_. put(','); - } - if (indenting_) - { - if (stack_.back().is_multi_line()) - { - write_indent(); - } - } - } - - writer_.put('\"'); - escape_string(name.data(), name.length(), options_, writer_); - writer_.put('\"'); - writer_.put(':'); - if (indenting_) - { - writer_.put(' '); - } - } - - void do_null_value(const serializing_context&) override - { - if (!stack_.empty() && stack_.back().is_array()) - { - begin_scalar_value(); - } - - auto buf = detail::null_literal(); - writer_.write(buf, 4); - - end_value(); - } - - void do_string_value(const string_view_type& value, const serializing_context&) override - { - if (!stack_.empty() && stack_.back().is_array()) - { - begin_scalar_value(); - } - - writer_. put('\"'); - escape_string(value.data(), value.length(), options_, writer_); - writer_. put('\"'); - - end_value(); - } - - void do_byte_string_value(const uint8_t* data, size_t length, const serializing_context& context) override - { - std::basic_string s; - encode_base64url(data,data+length,s); - do_string_value(s, context); - } - - void do_double_value(double value, const number_format& fmt, const serializing_context&) override - { - if (!stack_.empty() && stack_.back().is_array()) - { - begin_scalar_value(); - } - - if ((std::isnan)(value)) - { - if (options_.can_write_nan_replacement()) - { - writer_.write(options_.nan_replacement()); - } - else - { - writer_.write(detail::null_literal()); - } - } - else if (value == std::numeric_limits::infinity()) - { - if (options_.can_write_pos_inf_replacement()) - { - writer_.write(options_.pos_inf_replacement()); - } - else - { - writer_.write(detail::null_literal()); - } - } - else if (!(std::isfinite)(value)) - { - if (options_.can_write_neg_inf_replacement()) - { - writer_.write(options_.neg_inf_replacement()); - } - else - { - writer_.write(detail::null_literal()); - } - } - else - { - fp_(value, fmt.precision(), writer_); - } - - end_value(); - } - - void do_integer_value(int64_t value, const serializing_context&) override - { - if (!stack_.empty() && stack_.back().is_array()) - { - begin_scalar_value(); - } - detail::print_integer(value, writer_); - end_value(); - } - - void do_uinteger_value(uint64_t value, const serializing_context&) override - { - if (!stack_.empty() && stack_.back().is_array()) - { - begin_scalar_value(); - } - detail::print_uinteger(value, writer_); - end_value(); - } - - void do_bool_value(bool value, const serializing_context&) override - { - if (!stack_.empty() && stack_.back().is_array()) - { - begin_scalar_value(); - } - - if (value) - { - auto buf = detail::true_literal(); - writer_.write(buf,4); - } - else - { - auto buf = detail::false_literal(); - writer_.write(buf,5); - } - - end_value(); - } - - void begin_scalar_value() - { - if (!stack_.empty()) - { - if (stack_.back().count() > 0) - { - writer_. put(','); - } - if (indenting_) - { - if (stack_.back().is_multi_line() || stack_.back().is_indent_once()) - { - write_indent(); - } - } - } - } - - void begin_value() - { - if (!stack_.empty()) - { - if (stack_.back().count() > 0) - { - writer_. put(','); - } - if (indenting_) - { - if (!stack_.back().is_same_line()) - { - write_indent(); - } - } - } - } - - void end_value() - { - if (!stack_.empty()) - { - stack_.back().increment_count(); - } - } - - void indent() - { - indent_ += static_cast(options_.indent()); - } - - void unindent() - { - indent_ -= static_cast(options_.indent()); - } - - void write_indent() - { - if (!stack_.empty()) - { - stack_.back().unindent_after(true); - } - writer_. put('\n'); - for (int i = 0; i < indent_; ++i) - { - writer_. put(' '); - } - } - - void write_indent1() - { - writer_. put('\n'); - for (int i = 0; i < indent_; ++i) - { - writer_. put(' '); - } - } -}; - -typedef basic_json_serializer> json_serializer; -typedef basic_json_serializer> wjson_serializer; - -typedef basic_json_serializer> json_string_serializer; -typedef basic_json_serializer> wjson_string_serializer; - -} #endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_serializing_options.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_serializing_options.hpp deleted file mode 100644 index 7c5be78..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_serializing_options.hpp +++ /dev/null @@ -1,339 +0,0 @@ -// Copyright 2013 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_JSON_SERIALIZING_OPTIONS_HPP -#define JSONCONS_JSON_SERIALIZING_OPTIONS_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace jsoncons { - -enum class indenting {no_indent = 0, indent = 1}; - -#if !defined(JSONCONS_NO_DEPRECATED) -enum class block_options {next_line,same_line}; -#endif - -enum class line_split_kind{same_line,new_line,multi_line}; - -template > -class basic_json_serializing_options -{ -public: - typedef basic_string_view_ext string_view_type; - typedef CharT char_type; - typedef Allocator allocator_type; - typedef typename std::allocator_traits:: template rebind_alloc char_allocator_type; - typedef std::basic_string,char_allocator_type> string_type; -private: - int indent_; - uint8_t precision_; - uint8_t decimal_places_; - bool can_read_nan_replacement_; - bool can_read_pos_inf_replacement_; - bool can_read_neg_inf_replacement_; - string_type nan_replacement_; - string_type pos_inf_replacement_; - string_type neg_inf_replacement_; - bool escape_all_non_ascii_; - bool escape_solidus_; - - line_split_kind object_object_split_lines_; - line_split_kind object_array_split_lines_; - line_split_kind array_array_split_lines_; - line_split_kind array_object_split_lines_; - - chars_format floating_point_format_; - size_t max_nesting_depth_; -public: - static const size_t default_indent = 4; - -// Constructors - - basic_json_serializing_options() - : indent_(default_indent), - precision_(0), - can_read_nan_replacement_(false), - can_read_pos_inf_replacement_(false), - can_read_neg_inf_replacement_(false), - escape_all_non_ascii_(false), - escape_solidus_(false), - object_object_split_lines_(line_split_kind::multi_line), - object_array_split_lines_(line_split_kind::same_line), - array_array_split_lines_(line_split_kind::new_line), - array_object_split_lines_(line_split_kind::multi_line), - max_nesting_depth_((std::numeric_limits::max)()) - { - } - -// Accessors - line_split_kind object_object_split_lines() const {return object_object_split_lines_;} - line_split_kind array_object_split_lines() const {return array_object_split_lines_;} - line_split_kind object_array_split_lines() const {return object_array_split_lines_;} - line_split_kind array_array_split_lines() const {return array_array_split_lines_;} - - basic_json_serializing_options& object_object_split_lines(line_split_kind value) {object_object_split_lines_ = value; return *this;} - basic_json_serializing_options& array_object_split_lines(line_split_kind value) {array_object_split_lines_ = value; return *this;} - basic_json_serializing_options& object_array_split_lines(line_split_kind value) {object_array_split_lines_ = value; return *this;} - basic_json_serializing_options& array_array_split_lines(line_split_kind value) {array_array_split_lines_ = value; return *this;} - -#if !defined(JSONCONS_NO_DEPRECATED) - block_options array_array_block_option() - { - return (array_array_split_lines_ == line_split_kind::same_line) ? block_options::same_line : block_options::next_line; - } - - basic_json_serializing_options& array_array_block_option(block_options value) - { - array_array_split_lines_ = (value == block_options::same_line) ? line_split_kind::same_line : line_split_kind::new_line; - return *this; - } - - block_options array_object_block_option() - { - return (array_object_split_lines_ == line_split_kind::same_line) ? block_options::same_line : block_options::next_line; - } - - basic_json_serializing_options& array_object_block_option(block_options value) - { - array_object_split_lines_ = (value == block_options::same_line) ? line_split_kind::same_line : line_split_kind::new_line; - return *this; - } - - block_options object_array_block_option() - { - return (object_array_split_lines_ == line_split_kind::same_line) ? block_options::same_line : block_options::next_line; - } - - basic_json_serializing_options& object_array_block_option(block_options value) - { - object_array_split_lines_ = (value == block_options::same_line) ? line_split_kind::same_line : line_split_kind::new_line; - return *this; - } - - block_options object_object_block_option() - { - return (object_object_split_lines_ == line_split_kind::same_line) ? block_options::same_line : block_options::next_line; - } - - basic_json_serializing_options& object_object_block_option(block_options value) - { - object_object_split_lines_ = (value == block_options::same_line) ? line_split_kind::same_line : line_split_kind::new_line; - return *this; - } -#endif - - int indent() const - { - return indent_; - } - - basic_json_serializing_options& indent(int value) - { - indent_ = value; - return *this; - } - - chars_format floating_point_format() const - { - return floating_point_format_; - } - - basic_json_serializing_options& floating_point_format(chars_format value) - { - floating_point_format_ = value; - return *this; - } - - uint8_t precision() const - { - return precision_; - } - - basic_json_serializing_options& precision(uint8_t value) - { - precision_ = value; - return *this; - } - - uint8_t decimal_places() const - { - return decimal_places_; - } - - basic_json_serializing_options& decimal_places(uint8_t value) - { - decimal_places_ = value; - return *this; - } - - bool escape_all_non_ascii() const - { - return escape_all_non_ascii_; - } - - basic_json_serializing_options& escape_all_non_ascii(bool value) - { - escape_all_non_ascii_ = value; - return *this; - } - - bool escape_solidus() const - { - return escape_solidus_; - } - - basic_json_serializing_options& escape_solidus(bool value) - { - escape_solidus_ = value; - return *this; - } - - bool can_read_nan_replacement() const {return can_read_nan_replacement_;} - - bool can_read_pos_inf_replacement() const {return can_read_pos_inf_replacement_;} - - bool can_read_neg_inf_replacement() const {return can_read_neg_inf_replacement_;} - - bool can_write_nan_replacement() const {return !nan_replacement_.empty();} - - bool can_write_pos_inf_replacement() const {return !pos_inf_replacement_.empty();} - - bool can_write_neg_inf_replacement() const {return !neg_inf_replacement_.empty();} - - basic_json_serializing_options& replace_inf(bool replace) - { - can_read_pos_inf_replacement_ = replace; - can_read_neg_inf_replacement_ = replace; - return *this; - } - - basic_json_serializing_options& replace_pos_inf(bool replace) - { - can_read_pos_inf_replacement_ = replace; - return *this; - } - - basic_json_serializing_options& replace_neg_inf(bool replace) - { - can_read_neg_inf_replacement_ = replace; - return *this; - } - - const string_type& nan_replacement() const - { - return nan_replacement_; - } - - basic_json_serializing_options& nan_replacement(const string_type& replacement) - { - nan_replacement_ = replacement; - - can_read_nan_replacement_ = is_string(replacement); - - return *this; - } - - const string_type& pos_inf_replacement() const - { - return pos_inf_replacement_; - } - - basic_json_serializing_options& pos_inf_replacement(const string_type& replacement) - { - pos_inf_replacement_ = replacement; - can_read_pos_inf_replacement_ = is_string(replacement); - return *this; - } - - const string_type& neg_inf_replacement() const - { - return neg_inf_replacement_; - } - - basic_json_serializing_options& neg_inf_replacement(const string_type& replacement) - { - neg_inf_replacement_ = replacement; - can_read_neg_inf_replacement_ = is_string(replacement); - return *this; - } - - size_t max_nesting_depth() const - { - return max_nesting_depth_; - } - - void max_nesting_depth(size_t value) - { - max_nesting_depth_ = value; - } -private: - enum class input_state {initial,begin_quote,character,end_quote,escape,error}; - bool is_string(const string_view_type& s) const - { - input_state state = input_state::initial; - for (CharT c : s) - { - switch (c) - { - case '\t': case ' ': case '\n': case'\r': - break; - case '\\': - state = input_state::escape; - break; - case '\"': - switch (state) - { - case input_state::initial: - state = input_state::begin_quote; - break; - case input_state::begin_quote: - state = input_state::end_quote; - break; - case input_state::character: - state = input_state::end_quote; - break; - case input_state::end_quote: - state = input_state::error; - break; - case input_state::escape: - state = input_state::character; - break; - default: - state = input_state::character; - break; - } - default: - break; - } - - } - return state == input_state::end_quote; - } -}; - -typedef basic_json_serializing_options json_serializing_options; -typedef basic_json_serializing_options wjson_serializing_options; - -#if !defined(JSONCONS_NO_DEPRECATED) -typedef basic_json_serializing_options output_format; -typedef basic_json_serializing_options woutput_format; -typedef basic_json_serializing_options serialization_options; -typedef basic_json_serializing_options wserialization_options; -#endif - -} -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_structures.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_structures.hpp deleted file mode 100644 index 74aa150..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_structures.hpp +++ /dev/null @@ -1,1864 +0,0 @@ -// Copyright 2013 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_JSON_STRUCTURES_HPP -#define JSONCONS_JSON_STRUCTURES_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace jsoncons { - -// json_array - -template -class Json_array_base_ -{ -public: - typedef typename Json::allocator_type allocator_type; - -public: - Json_array_base_() - : self_allocator_() - { - } - Json_array_base_(const allocator_type& allocator) - : self_allocator_(allocator) - { - } - - allocator_type get_allocator() const - { - return self_allocator_; - } - - allocator_type self_allocator_; -}; - -// json_array - -template -class json_array: public Json_array_base_ -{ -public: - typedef typename Json::allocator_type allocator_type; - typedef Json value_type; - typedef typename std::allocator_traits:: template rebind_alloc val_allocator_type; - - typedef typename Json::array_storage_type array_storage_type; - - typedef typename array_storage_type::iterator iterator; - typedef typename array_storage_type::const_iterator const_iterator; - - typedef typename std::iterator_traits::reference reference; - typedef typename std::iterator_traits::reference const_reference; - - using Json_array_base_::get_allocator; - - json_array() - : Json_array_base_(), - elements_() - { - } - - explicit json_array(const allocator_type& allocator) - : Json_array_base_(allocator), - elements_(val_allocator_type(allocator)) - { - } - - explicit json_array(size_t n, - const allocator_type& allocator = allocator_type()) - : Json_array_base_(allocator), - elements_(n,Json(),val_allocator_type(allocator)) - { - } - - explicit json_array(size_t n, - const Json& value, - const allocator_type& allocator = allocator_type()) - : Json_array_base_(allocator), - elements_(n,value,val_allocator_type(allocator)) - { - } - - template - json_array(InputIterator begin, InputIterator end, const allocator_type& allocator = allocator_type()) - : Json_array_base_(allocator), - elements_(begin,end,val_allocator_type(allocator)) - { - } - json_array(const json_array& val) - : Json_array_base_(val.get_allocator()), - elements_(val.elements_) - { - } - json_array(const json_array& val, const allocator_type& allocator) - : Json_array_base_(allocator), - elements_(val.elements_,val_allocator_type(allocator)) - { - } - - json_array(json_array&& val) JSONCONS_NOEXCEPT - : Json_array_base_(val.get_allocator()), - elements_(std::move(val.elements_)) - { - } - json_array(json_array&& val, const allocator_type& allocator) - : Json_array_base_(allocator), - elements_(std::move(val.elements_),val_allocator_type(allocator)) - { - } - - json_array(std::initializer_list init) - : Json_array_base_(), - elements_(std::move(init)) - { - } - - json_array(std::initializer_list init, - const allocator_type& allocator) - : Json_array_base_(allocator), - elements_(std::move(init),val_allocator_type(allocator)) - { - } - ~json_array() - { - } - - void swap(json_array& val) - { - elements_.swap(val.elements_); - } - - size_t size() const {return elements_.size();} - - size_t capacity() const {return elements_.capacity();} - - void clear() {elements_.clear();} - - void shrink_to_fit() - { - for (size_t i = 0; i < elements_.size(); ++i) - { - elements_[i].shrink_to_fit(); - } - elements_.shrink_to_fit(); - } - - void reserve(size_t n) {elements_.reserve(n);} - - void resize(size_t n) {elements_.resize(n);} - - void resize(size_t n, const Json& val) {elements_.resize(n,val);} - - void remove_range(size_t from_index, size_t to_index) - { - JSONCONS_ASSERT(from_index <= to_index); - JSONCONS_ASSERT(to_index <= elements_.size()); - elements_.erase(elements_.begin()+from_index,elements_.begin()+to_index); - } - - void erase(const_iterator pos) - { - elements_.erase(pos); - } - - void erase(const_iterator first, const_iterator last) - { - elements_.erase(first,last); - } - - Json& operator[](size_t i) {return elements_[i];} - - const Json& operator[](size_t i) const {return elements_[i];} - - // push_back - - template - typename std::enable_if::value,void>::type - push_back(T&& value) - { - elements_.emplace_back(std::forward(value)); - } - - template - typename std::enable_if::value,void>::type - push_back(T&& value) - { - elements_.emplace_back(std::forward(value),get_allocator()); - } - - template - typename std::enable_if::value,iterator>::type - insert(const_iterator pos, T&& value) - { -#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 9 - // work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54577 - iterator it = elements_.begin() + (pos - elements_.begin()); - return elements_.emplace(it, std::forward(value)); -#else - return elements_.emplace(pos, std::forward(value)); -#endif - } - template - typename std::enable_if::value,iterator>::type - insert(const_iterator pos, T&& value) - { -#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 9 - // work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54577 - iterator it = elements_.begin() + (pos - elements_.begin()); - return elements_.emplace(it, std::forward(value), get_allocator()); -#else - return elements_.emplace(pos, std::forward(value), get_allocator()); -#endif - } - - template - iterator insert(const_iterator pos, InputIt first, InputIt last) - { -#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 9 - // work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54577 - iterator it = elements_.begin() + (pos - elements_.begin()); - return elements_.insert(it, first, last); -#else - return elements_.insert(pos, first, last); -#endif - } - -#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 9 - // work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54577 - template - typename std::enable_if::value,iterator>::type - emplace(const_iterator pos, Args&&... args) - { - iterator it = elements_.begin() + (pos - elements_.begin()); - return elements_.emplace(it, std::forward(args)...); - } -#else - template - typename std::enable_if::value,iterator>::type - emplace(const_iterator pos, Args&&... args) - { - return elements_.emplace(pos, std::forward(args)...); - } -#endif - template - Json& emplace_back(Args&&... args) - { - elements_.emplace_back(std::forward(args)...); - return elements_.back(); - } - - iterator begin() {return elements_.begin();} - - iterator end() {return elements_.end();} - - const_iterator begin() const {return elements_.begin();} - - const_iterator end() const {return elements_.end();} - - bool operator==(const json_array& rhs) const - { - if (size() != rhs.size()) - { - return false; - } - for (size_t i = 0; i < size(); ++i) - { - if (elements_[i] != rhs.elements_[i]) - { - return false; - } - } - return true; - } -private: - array_storage_type elements_; - - json_array& operator=(const json_array&) = delete; -}; - -// json_object - -template -BidirectionalIt last_wins_unique_sequence(BidirectionalIt first, BidirectionalIt last, BinaryPredicate compare) -{ - - if (first == last) - { - return last; - } - - typedef typename BidirectionalIt::value_type value_type; - typedef typename BidirectionalIt::pointer pointer; - std::vector dups; - { - std::vector v(std::distance(first,last)); - auto p = v.begin(); - for (auto it = first; it != last; ++it) - { - *p++ = &(*it); - } - std::sort(v.begin(), v.end(), [&](pointer a, pointer b){return compare(*a,*b)<0;}); - auto it = v.begin(); - auto end = v.end(); - for (auto begin = it+1; begin != end; ++it, ++begin) - { - if (compare(*(*it),*(*begin)) == 0) - { - dups.push_back(*(*it)); - } - } - } - if (dups.size() == 0) - { - return last; - } - - auto it = last; - for (auto p = first; p != last && p != it; ) - { - bool no_dup = true; - if (dups.size() > 0) - { - for (auto q = dups.begin(); no_dup && q != dups.end();) - { - if (compare(*p,*q) == 0) - { - dups.erase(q); - no_dup = false; - } - else - { - ++q; - } - } - } - if (!no_dup) - { - --it; - for (auto r = p; r != it; ++r) - { - *r = std::move(*(r+1)); - } - } - else - { - ++p; - } - } - - return it; -} - -template -class key_value_pair -{ -public: - typedef KeyT key_storage_type; - typedef typename KeyT::value_type char_type; - typedef typename KeyT::allocator_type allocator_type; - typedef typename ValueT::string_view_type string_view_type; - - key_value_pair() - { - } - - key_value_pair(const key_storage_type& name, const ValueT& val) - : key_(name), value_(val) - { - } - - template - key_value_pair(key_storage_type&& name, T&& val) - : key_(std::forward(name)), - value_(std::forward(val)) - { - } - - template - key_value_pair(key_storage_type&& name, - T&& val, - const allocator_type& allocator) - : key_(std::forward(name)), value_(std::forward(val), allocator) - { - } - - key_value_pair(const key_value_pair& member) - : key_(member.key_), value_(member.value_) - { - } - - key_value_pair(key_value_pair&& member) - : key_(std::move(member.key_)), value_(std::move(member.value_)) - { - } - - string_view_type key() const - { - return string_view_type(key_.data(),key_.size()); - } - - ValueT& value() - { - return value_; - } - - const ValueT& value() const - { - return value_; - } - - template - void value(T&& value) - { - value_ = std::forward(value); - } - - void swap(key_value_pair& member) - { - key_.swap(member.key_); - value_.swap(member.value_); - } - - key_value_pair& operator=(const key_value_pair& member) - { - if (this != & member) - { - key_ = member.key_; - value_ = member.value_; - } - return *this; - } - - key_value_pair& operator=(key_value_pair&& member) - { - if (this != &member) - { - key_.swap(member.key_); - value_.swap(member.value_); - } - return *this; - } - - void shrink_to_fit() - { - key_.shrink_to_fit(); - value_.shrink_to_fit(); - } -#if !defined(JSONCONS_NO_DEPRECATED) - const key_storage_type& name() const - { - return key_; - } -#endif -private: - key_storage_type key_; - ValueT value_; -}; - -template -class Json_object_ -{ -public: - typedef typename Json::allocator_type allocator_type; - typedef typename Json::char_type char_type; - typedef typename Json::char_allocator_type char_allocator_type; - typedef KeyT key_storage_type; - typedef typename Json::string_view_type string_view_type; - typedef key_value_pair value_type; - - typedef typename std::allocator_traits:: template rebind_alloc kvp_allocator_type; - typedef typename Json::object_storage_type object_storage_type; - - typedef typename object_storage_type::iterator iterator; - typedef typename object_storage_type::const_iterator const_iterator; - -protected: - allocator_type self_allocator_; - object_storage_type members_; -public: - Json_object_() - : self_allocator_(), members_() - { - } - Json_object_(const allocator_type& allocator) - : self_allocator_(allocator), - members_(kvp_allocator_type(allocator)) - { - } - - Json_object_(const Json_object_& val) - : self_allocator_(val.get_allocator()), members_(val.members_) - { - } - - Json_object_(Json_object_&& val) - : self_allocator_(val.get_allocator()), - members_(std::move(val.members_)) - { - } - - Json_object_(const Json_object_& val, const allocator_type& allocator) : - self_allocator_(allocator), - members_(val.members_,kvp_allocator_type(allocator)) - { - } - - Json_object_(Json_object_&& val,const allocator_type& allocator) : - self_allocator_(allocator), members_(std::move(val.members_),kvp_allocator_type(allocator)) - { - } - - void swap(Json_object_& val) - { - members_.swap(val.members_); - } - - allocator_type get_allocator() const - { - return this->self_allocator_; - } -}; - -// json_object - -template -class json_object -{ -}; - -// Do not preserve order -template -class json_object final : public Json_object_ -{ -public: - using typename Json_object_::allocator_type; - using typename Json_object_::char_type; - using typename Json_object_::char_allocator_type; - using typename Json_object_::key_storage_type; - using typename Json_object_::string_view_type; - using typename Json_object_::value_type; - using typename Json_object_::kvp_allocator_type; - using typename Json_object_::object_storage_type; - using typename Json_object_::iterator; - using typename Json_object_::const_iterator; - using Json_object_::get_allocator; - - json_object() - : Json_object_() - { - } - json_object(const allocator_type& allocator) - : Json_object_(allocator) - { - } - - json_object(const json_object& val) - : Json_object_(val) - { - } - - json_object(json_object&& val) - : Json_object_(std::forward(val)) - { - } - - json_object(const json_object& val, const allocator_type& allocator) - : Json_object_(val,allocator) - { - } - - json_object(json_object&& val,const allocator_type& allocator) - : Json_object_(std::forward(val),allocator) - { - } - - json_object(std::initializer_list> init) - : Json_object_() - { - this->members_.reserve(init.size()); - for (auto& item : init) - { - insert_or_assign(item.first, std::move(item.second)); - } - } - - json_object(std::initializer_list> init, - const allocator_type& allocator) - : Json_object_(allocator) - { - this->members_.reserve(init.size()); - for (auto& item : init) - { - insert_or_assign(item.first, std::move(item.second), allocator); - } - } - - void swap(json_object& val) - { - Json_object_::swap(val); - } - - iterator begin() - { - return this->members_.begin(); - } - - iterator end() - { - return this->members_.end(); - } - - const_iterator begin() const - { - return this->members_.begin(); - } - - const_iterator end() const - { - return this->members_.end(); - } - - size_t size() const {return this->members_.size();} - - size_t capacity() const {return this->members_.capacity();} - - void clear() {this->members_.clear();} - - void shrink_to_fit() - { - for (size_t i = 0; i < this->members_.size(); ++i) - { - this->members_[i].shrink_to_fit(); - } - this->members_.shrink_to_fit(); - } - - void reserve(size_t n) {this->members_.reserve(n);} - - Json& at(size_t i) - { - if (i >= this->members_.size()) - { - JSONCONS_THROW(json_exception_impl("Invalid array subscript")); - } - return this->members_[i].value(); - } - - const Json& at(size_t i) const - { - if (i >= this->members_.size()) - { - JSONCONS_THROW(json_exception_impl("Invalid array subscript")); - } - return this->members_[i].value(); - } - - iterator find(const string_view_type& name) - { - auto it = std::lower_bound(this->members_.begin(),this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - auto result = (it != this->members_.end() && it->key() == name) ? it : this->members_.end(); - return result; - } - - const_iterator find(const string_view_type& name) const - { - auto it = std::lower_bound(this->members_.begin(),this->members_.end(), - name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - auto result = (it != this->members_.end() && it->key() == name) ? it : this->members_.end(); - return result; - } - - void erase(const_iterator pos) - { - this->members_.erase(pos); - } - - void erase(const_iterator first, const_iterator last) - { - this->members_.erase(first,last); - } - - void erase(const string_view_type& name) - { - auto it = std::lower_bound(this->members_.begin(),this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - if (it != this->members_.end() && it->key() == name) - { - this->members_.erase(it); - } - } - - template - void insert(InputIt first, InputIt last, UnaryPredicate pred) - { - size_t count = std::distance(first,last); - this->members_.reserve(this->members_.size() + count); - for (auto s = first; s != last; ++s) - { - this->members_.emplace_back(pred(*s)); - } - std::stable_sort(this->members_.begin(),this->members_.end(), - [](const value_type& a, const value_type& b){return a.key().compare(b.key()) < 0;}); - auto it = std::unique(this->members_.rbegin(), this->members_.rend(), - [](const value_type& a, const value_type& b){ return !(a.key().compare(b.key()));}); - this->members_.erase(this->members_.begin(),it.base()); - } - - // merge - - void merge(const json_object& source) - { - for (auto it = source.begin(); it != source.end(); ++it) - { - try_emplace(it->key(),it->value()); - } - } - - void merge(json_object&& source) - { - auto it = std::make_move_iterator(source.begin()); - auto end = std::make_move_iterator(source.end()); - for (; it != end; ++it) - { - auto pos = std::lower_bound(this->members_.begin(),this->members_.end(), it->key(), - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - if (pos == this->members_.end() ) - { - this->members_.emplace_back(*it); - } - else if (it->key() != pos->key()) - { - this->members_.emplace(pos,*it); - } - } - } - - void merge(iterator hint, const json_object& source) - { - for (auto it = source.begin(); it != source.end(); ++it) - { - hint = try_emplace(hint, it->key(),it->value()); - } - } - - void merge(iterator hint, json_object&& source) - { - auto it = std::make_move_iterator(source.begin()); - auto end = std::make_move_iterator(source.end()); - for (; it != end; ++it) - { - iterator pos; - if (hint != this->members_.end() && hint->key() <= it->key()) - { - pos = std::lower_bound(hint,this->members_.end(), it->key(), - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - else - { - pos = std::lower_bound(this->members_.begin(),this->members_.end(), it->key(), - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - if (pos == this->members_.end() ) - { - this->members_.emplace_back(*it); - hint = this->members_.begin() + (this->members_.size() - 1); - } - else if (it->key() != pos->key()) - { - hint = this->members_.emplace(pos,*it); - } - } - } - - // merge_or_update - - void merge_or_update(const json_object& source) - { - for (auto it = source.begin(); it != source.end(); ++it) - { - insert_or_assign(it->key(),it->value()); - } - } - - void merge_or_update(json_object&& source) - { - auto it = std::make_move_iterator(source.begin()); - auto end = std::make_move_iterator(source.end()); - for (; it != end; ++it) - { - auto pos = std::lower_bound(this->members_.begin(),this->members_.end(), it->key(), - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - if (pos == this->members_.end() ) - { - this->members_.emplace_back(*it); - } - else - { - pos->value(it->value()); - } - } - } - - void merge_or_update(iterator hint, const json_object& source) - { - for (auto it = source.begin(); it != source.end(); ++it) - { - hint = insert_or_assign(hint, it->key(),it->value()); - } - } - - void merge_or_update(iterator hint, json_object&& source) - { - auto it = std::make_move_iterator(source.begin()); - auto end = std::make_move_iterator(source.end()); - for (; it != end; ++it) - { - iterator pos; - if (hint != this->members_.end() && hint->key() <= it->key()) - { - pos = std::lower_bound(hint,this->members_.end(), it->key(), - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - else - { - pos = std::lower_bound(this->members_.begin(),this->members_.end(), it->key(), - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - if (pos == this->members_.end() ) - { - this->members_.emplace_back(*it); - hint = this->members_.begin() + (this->members_.size() - 1); - } - else - { - pos->value(it->value()); - hint = pos; - } - } - } - - // insert_or_assign - - template - typename std::enable_if::value,std::pair>::type - insert_or_assign(const string_view_type& name, T&& value) - { - bool inserted; - auto it = std::lower_bound(this->members_.begin(),this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(name.begin(),name.end()), - std::forward(value)); - inserted = true; - it = this->members_.begin() + this->members_.size() - 1; - } - else if (it->key() == name) - { - it->value(Json(std::forward(value))); - inserted = false; // assigned - } - else - { - it = this->members_.emplace(it, - key_storage_type(name.begin(),name.end()), - std::forward(value)); - inserted = true; - } - return std::make_pair(it,inserted); - } - - template - typename std::enable_if::value,std::pair>::type - insert_or_assign(const string_view_type& name, T&& value) - { - bool inserted; - auto it = std::lower_bound(this->members_.begin(),this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(name.begin(),name.end(), get_allocator()), - std::forward(value),get_allocator()); - inserted = true; - it = this->members_.begin() + this->members_.size() - 1; - } - else if (it->key() == name) - { - it->value(Json(std::forward(value), get_allocator())); - inserted = false; // assigned - } - else - { - it = this->members_.emplace(it, - key_storage_type(name.begin(),name.end(), get_allocator()), - std::forward(value),get_allocator()); - inserted = true; - } - return std::make_pair(it,inserted); - } - - // try_emplace - - template - typename std::enable_if::value,std::pair>::type - try_emplace(const string_view_type& name, Args&&... args) - { - bool inserted; - auto it = std::lower_bound(this->members_.begin(),this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(name.begin(),name.end()), - std::forward(args)...); - it = this->members_.begin() + this->members_.size() - 1; - inserted = true; - } - else if (it->key() == name) - { - inserted = false; - } - else - { - it = this->members_.emplace(it, - key_storage_type(name.begin(),name.end()), - std::forward(args)...); - inserted = true; - } - return std::make_pair(it,inserted); - } - - template - typename std::enable_if::value,std::pair>::type - try_emplace(const string_view_type& name, Args&&... args) - { - bool inserted; - auto it = std::lower_bound(this->members_.begin(),this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(name.begin(),name.end(), get_allocator()), - std::forward(args)...); - it = this->members_.begin() + this->members_.size() - 1; - inserted = true; - } - else if (it->key() == name) - { - inserted = false; - } - else - { - it = this->members_.emplace(it, - key_storage_type(name.begin(),name.end(), get_allocator()), - std::forward(args)...); - inserted = true; - } - return std::make_pair(it,inserted); - } - - template - typename std::enable_if::value,iterator>::type - try_emplace(iterator hint, const string_view_type& name, Args&&... args) - { - iterator it; - if (hint != this->members_.end() && hint->key() <= name) - { - it = std::lower_bound(hint,this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - else - { - it = std::lower_bound(this->members_.begin(),this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(name.begin(),name.end()), - std::forward(args)...); - it = this->members_.begin() + (this->members_.size() - 1); - } - else if (it->key() == name) - { - } - else - { - it = this->members_.emplace(it, - key_storage_type(name.begin(),name.end()), - std::forward(args)...); - } - return it; - } - - template - typename std::enable_if::value,iterator>::type - try_emplace(iterator hint, const string_view_type& name, Args&&... args) - { - iterator it; - if (hint != this->members_.end() && hint->key() <= name) - { - it = std::lower_bound(hint,this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - else - { - it = std::lower_bound(this->members_.begin(),this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(name.begin(),name.end(), get_allocator()), - std::forward(args)...); - it = this->members_.begin() + (this->members_.size() - 1); - } - else if (it->key() == name) - { - } - else - { - it = this->members_.emplace(it, - key_storage_type(name.begin(),name.end(), get_allocator()), - std::forward(args)...); - } - return it; - } - - // set_ - - template - typename std::enable_if::value,void>::type - set_(key_storage_type&& name, T&& value) - { - string_view_type s(name.data(), name.size()); - auto it = std::lower_bound(this->members_.begin(),this->members_.end(), s, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - if (it == this->members_.end()) - { - this->members_.emplace_back(std::forward(name), - std::forward(value)); - } - else if (string_view_type(it->key().data(),it->key().length()) == s) - { - it->value(Json(std::forward(value))); - } - else - { - this->members_.emplace(it, - std::forward(name), - std::forward(value)); - } - } - - template - typename std::enable_if::value,void>::type - set_(key_storage_type&& name, T&& value) - { - string_view_type s(name.data(), name.size()); - auto it = std::lower_bound(this->members_.begin(),this->members_.end(), s, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - if (it == this->members_.end()) - { - this->members_.emplace_back(std::forward(name), - std::forward(value),get_allocator() ); - } - else if (string_view_type(it->key().data(), it->key().length()) == s) - { - it->value(Json(std::forward(value),get_allocator() )); - } - else - { - this->members_.emplace(it, - std::forward(name), - std::forward(value),get_allocator() ); - } - } - - template - typename std::enable_if::value,iterator>::type - insert_or_assign(iterator hint, const string_view_type& name, T&& value) - { - iterator it; - if (hint != this->members_.end() && hint->key() <= name) - { - it = std::lower_bound(hint,this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - else - { - it = std::lower_bound(this->members_.begin(),this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(name.begin(),name.end()), - std::forward(value)); - it = this->members_.begin() + (this->members_.size() - 1); - } - else if (it->key() == name) - { - it->value(Json(std::forward(value))); - } - else - { - it = this->members_.emplace(it, - key_storage_type(name.begin(),name.end()), - std::forward(value)); - } - return it; - } - - template - typename std::enable_if::value,iterator>::type - insert_or_assign(iterator hint, const string_view_type& name, T&& value) - { - iterator it; - if (hint != this->members_.end() && hint->key() <= name) - { - it = std::lower_bound(hint,this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - else - { - it = std::lower_bound(this->members_.begin(),this->members_.end(), name, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(name.begin(),name.end(), get_allocator()), - std::forward(value),get_allocator()); - it = this->members_.begin() + (this->members_.size() - 1); - } - else if (it->key() == name) - { - it->value(Json(std::forward(value),get_allocator())); - } - else - { - it = this->members_.emplace(it, - key_storage_type(name.begin(),name.end(), get_allocator()), - std::forward(value),get_allocator()); - } - return it; - } - - template - typename std::enable_if::value,iterator>::type - set_(iterator hint, key_storage_type&& name, T&& value) - { - string_view_type s(name.data(), name.size()); - iterator it; - if (hint != this->members_.end() && hint->key() <= s) - { - it = std::lower_bound(hint,this->members_.end(), s, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - else - { - it = std::lower_bound(this->members_.begin(),this->members_.end(), s, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - - if (it == this->members_.end()) - { - this->members_.emplace_back(std::forward(name), - std::forward(value)); - it = this->members_.begin() + (this->members_.size() - 1); - } - else if (string_view_type(it->key().data(), it->key().length()) == s) - { - it->value(Json(std::forward(value))); - } - else - { - it = this->members_.emplace(it, - std::forward(name), - std::forward(value)); - } - return it; - } - - template - typename std::enable_if::value,iterator>::type - set_(iterator hint, key_storage_type&& name, T&& value) - { - string_view_type s(name.data(), name.size()); - iterator it; - if (hint != this->members_.end() && hint->key() <= s) - { - it = std::lower_bound(hint,this->members_.end(), s, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - else - { - it = std::lower_bound(this->members_.begin(),this->members_.end(), s, - [](const value_type& a, const string_view_type& k){return a.key().compare(k) < 0;}); - } - - if (it == this->members_.end()) - { - this->members_.emplace_back(std::forward(name), - std::forward(value),get_allocator() ); - it = this->members_.begin() + (this->members_.size() - 1); - } - else if (string_view_type(it->key().data(), it->key().length()) == s) - { - it->value(Json(std::forward(value),get_allocator() )); - } - else - { - it = this->members_.emplace(it, - std::forward(name), - std::forward(value),get_allocator() ); - } - return it; - } - - bool operator==(const json_object& rhs) const - { - if (size() != rhs.size()) - { - return false; - } - for (auto it = this->members_.begin(); it != this->members_.end(); ++it) - { - - auto rhs_it = std::lower_bound(rhs.begin(), rhs.end(), *it, - [](const value_type& a, const value_type& b){return a.key().compare(b.key()) < 0;}); - if (rhs_it == rhs.end() || rhs_it->key() != it->key() || rhs_it->value() != it->value()) - { - return false; - } - } - return true; - } -private: - json_object& operator=(const json_object&) = delete; -}; - -// Preserve order -template -class json_object final : public Json_object_ -{ -public: - using typename Json_object_::allocator_type; - using typename Json_object_::char_type; - using typename Json_object_::char_allocator_type; - using typename Json_object_::key_storage_type; - using typename Json_object_::string_view_type; - using typename Json_object_::value_type; - using typename Json_object_::kvp_allocator_type; - using typename Json_object_::object_storage_type; - using typename Json_object_::iterator; - using typename Json_object_::const_iterator; - using Json_object_::get_allocator; - - json_object() - : Json_object_() - { - } - json_object(const allocator_type& allocator) - : Json_object_(allocator) - { - } - - json_object(const json_object& val) - : Json_object_(val) - { - } - - json_object(json_object&& val) - : Json_object_(std::forward(val)) - { - } - - json_object(const json_object& val, const allocator_type& allocator) - : Json_object_(val,allocator) - { - } - - json_object(json_object&& val,const allocator_type& allocator) - : Json_object_(std::forward(val),allocator) - { - } - - json_object(std::initializer_list init) - : Json_object_() - { - for (const auto& element : init) - { - if (element.size() != 2 || !element[0].is_string()) - { - JSONCONS_THROW(json_exception_impl("Cannot create object from initializer list")); - break; - } - } - for (auto& element : init) - { - insert_or_assign(element[0].as_string_view(), std::move(element[1])); - } - } - - json_object(std::initializer_list init, - const allocator_type& allocator) - : Json_object_(allocator) - { - for (const auto& element : init) - { - if (element.size() != 2 || !element[0].is_string()) - { - JSONCONS_THROW(json_exception_impl("Cannot create object from initializer list")); - break; - } - } - for (auto& element : init) - { - insert_or_assign(element[0].as_string_view(), std::move(element[1])); - } - } - - void swap(json_object& val) - { - Json_object_::swap(val); - } - - iterator begin() - { - return this->members_.begin(); - } - - iterator end() - { - return this->members_.end(); - } - - const_iterator begin() const - { - return this->members_.begin(); - } - - const_iterator end() const - { - return this->members_.end(); - } - - size_t size() const {return this->members_.size();} - - size_t capacity() const {return this->members_.capacity();} - - void clear() {this->members_.clear();} - - void shrink_to_fit() - { - for (size_t i = 0; i < this->members_.size(); ++i) - { - this->members_[i].shrink_to_fit(); - } - this->members_.shrink_to_fit(); - } - - void reserve(size_t n) {this->members_.reserve(n);} - - Json& at(size_t i) - { - if (i >= this->members_.size()) - { - JSONCONS_THROW(json_exception_impl("Invalid array subscript")); - } - return this->members_[i].value(); - } - - const Json& at(size_t i) const - { - if (i >= this->members_.size()) - { - JSONCONS_THROW(json_exception_impl("Invalid array subscript")); - } - return this->members_[i].value(); - } - - iterator find(const string_view_type& name) - { - return std::find_if(this->members_.begin(),this->members_.end(), - [name](const value_type& kv){return kv.key() == name;}); - } - - const_iterator find(const string_view_type& name) const - { - return std::find_if(this->members_.begin(),this->members_.end(), - [name](const value_type& kv){return kv.key() == name;}); - } - - void erase(const_iterator first, const_iterator last) - { - this->members_.erase(first,last); - } - - void erase(const string_view_type& name) - { - auto it = std::find_if(this->members_.begin(),this->members_.end(), - [name](const value_type& kv){return kv.key() == name;}); - if (it != this->members_.end()) - { - this->members_.erase(it); - } - } - - template - void insert(InputIt first, InputIt last, UnaryPredicate pred) - { - size_t count = std::distance(first,last); - this->members_.reserve(this->members_.size() + count); - for (auto s = first; s != last; ++s) - { - this->members_.emplace_back(pred(*s)); - } - auto it = last_wins_unique_sequence(this->members_.begin(), this->members_.end(), - [](const value_type& a, const value_type& b){ return a.key().compare(b.key());}); - this->members_.erase(it,this->members_.end()); - } - - // insert_or_assign - - template - typename std::enable_if::value,std::pair>::type - insert_or_assign(const string_view_type& name, T&& value) - { - bool inserted; - auto it = std::find_if(this->members_.begin(),this->members_.end(), - [name](const value_type& a){return a.key() == name;}); - - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(name.begin(),name.end()), - std::forward(value)); - it = this->members_.begin() + this->members_.size() - 1; - inserted = true; - } - else - { - it->value(Json(std::forward(value))); - inserted = false; // assigned - } - return std::make_pair(it,inserted); - } - - template - typename std::enable_if::value,std::pair>::type - insert_or_assign(const string_view_type& name, T&& value) - { - bool inserted; - auto it = std::find_if(this->members_.begin(),this->members_.end(), - [name](const value_type& a){return a.key() == name;}); - - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(name.begin(),name.end(),get_allocator()), - std::forward(value),get_allocator()); - it = this->members_.begin() + this->members_.size() - 1; - inserted = true; - } - else - { - it->value(Json(std::forward(value),get_allocator())); - inserted = false; // assigned - } - return std::make_pair(it,inserted); - } - - template - typename std::enable_if::value,iterator>::type - insert_or_assign(iterator hint, const string_view_type& key, T&& value) - { - iterator it; - if (hint == this->members_.end()) - { - auto result = insert_or_assign(key, std::forward(value)); - it = result.first; - } - else - { - it = std::find_if(this->members_.begin(),this->members_.end(), - [key](const value_type& a){return a.key() == key;}); - - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(key.begin(),key.end()), - std::forward(value)); - it = this->members_.begin() + this->members_.size() - 1; - } - else - { - it->value(Json(std::forward(value))); - } - } - return it; - } - - template - typename std::enable_if::value,iterator>::type - insert_or_assign(iterator hint, const string_view_type& key, T&& value) - { - iterator it; - if (hint == this->members_.end()) - { - auto result = insert_or_assign(key, std::forward(value)); - it = result.first; - } - else - { - it = std::find_if(this->members_.begin(),this->members_.end(), - [key](const value_type& a){return a.key() == key;}); - - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(key.begin(),key.end(),get_allocator()), - std::forward(value),get_allocator()); - it = this->members_.begin() + this->members_.size() - 1; - } - else - { - it->value(Json(std::forward(value),get_allocator())); - } - } - return it; - } - - // merge - - void merge(const json_object& source) - { - for (auto it = source.begin(); it != source.end(); ++it) - { - try_emplace(it->key(),it->value()); - } - } - - void merge(json_object&& source) - { - auto it = std::make_move_iterator(source.begin()); - auto end = std::make_move_iterator(source.end()); - for (; it != end; ++it) - { - auto pos = std::find_if(this->members_.begin(),this->members_.end(), - [it](const value_type& a){return a.key() == it->key();}); - if (pos == this->members_.end() ) - { - this->members_.emplace_back(*it); - } - } - } - - void merge(iterator hint, const json_object& source) - { - for (auto it = source.begin(); it != source.end(); ++it) - { - hint = try_emplace(hint, it->key(),it->value()); - } - } - - void merge(iterator hint, json_object&& source) - { - auto it = std::make_move_iterator(source.begin()); - auto end = std::make_move_iterator(source.end()); - for (; it != end; ++it) - { - auto pos = std::find_if(this->members_.begin(),this->members_.end(), - [it](const value_type& a){return a.key() == it->key();}); - if (pos == this->members_.end() ) - { - hint = this->members_.emplace(hint,*it); - } - } - } - - // merge_or_update - - void merge_or_update(const json_object& source) - { - for (auto it = source.begin(); it != source.end(); ++it) - { - insert_or_assign(it->key(),it->value()); - } - } - - void merge_or_update(json_object&& source) - { - auto it = std::make_move_iterator(source.begin()); - auto end = std::make_move_iterator(source.end()); - for (; it != end; ++it) - { - auto pos = std::find_if(this->members_.begin(),this->members_.end(), - [it](const value_type& a){return a.key() == it->key();}); - if (pos == this->members_.end() ) - { - this->members_.emplace_back(*it); - } - else - { - pos->value(it->value()); - } - } - } - - void merge_or_update(iterator hint, const json_object& source) - { - for (auto it = source.begin(); it != source.end(); ++it) - { - hint = insert_or_assign(hint, it->key(),it->value()); - } - } - - void merge_or_update(iterator hint, json_object&& source) - { - auto it = std::make_move_iterator(source.begin()); - auto end = std::make_move_iterator(source.end()); - for (; it != end; ++it) - { - auto pos = std::find_if(this->members_.begin(),this->members_.end(), - [it](const value_type& a){return a.key() == it->key();}); - if (pos == this->members_.end() ) - { - hint = this->members_.emplace(hint,*it); - } - else - { - pos->value(it->value()); - hint = pos; - } - } - } - - // try_emplace - template - typename std::enable_if::value,std::pair>::type - try_emplace(const string_view_type& key, Args&&... args) - { - bool inserted; - auto it = std::find_if(this->members_.begin(),this->members_.end(), - [key](const value_type& a){return a.key() == key;}); - - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(key.begin(),key.end()), - std::forward(args)...); - it = this->members_.begin() + this->members_.size() - 1; - inserted = true; - - } - else - { - inserted = false; - } - return std::make_pair(it,inserted); - } - - template - typename std::enable_if::value,std::pair>::type - try_emplace(const string_view_type& key, Args&&... args) - { - bool inserted; - auto it = std::find_if(this->members_.begin(),this->members_.end(), - [key](const value_type& a){return a.key() == key;}); - - if (it == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(key.begin(),key.end(), get_allocator()), - std::forward(args)...); - it = this->members_.begin() + this->members_.size() - 1; - inserted = true; - - } - else - { - inserted = false; - } - return std::make_pair(it,inserted); - } - - template - typename std::enable_if::value,iterator>::type - try_emplace(iterator hint, const string_view_type& key, Args&&... args) - { - auto it = std::find_if(this->members_.begin(),this->members_.end(), - [key](const value_type& a){return a.key() == key;}); - - if (it == this->members_.end()) - { - if (hint == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(key.begin(),key.end()), - std::forward(args)...); - it = this->members_.begin() + (this->members_.size() - 1); - } - else - { - it = this->members_.emplace(hint, - key_storage_type(key.begin(),key.end()), - std::forward(args)...); - } - } - return it; - } - - template - typename std::enable_if::value,iterator>::type - try_emplace(iterator hint, const string_view_type& key, Args&&... args) - { - auto it = std::find_if(this->members_.begin(),this->members_.end(), - [key](const value_type& a){return a.key() == key;}); - - if (it == this->members_.end()) - { - if (hint == this->members_.end()) - { - this->members_.emplace_back(key_storage_type(key.begin(),key.end(), get_allocator()), - std::forward(args)...); - it = this->members_.begin() + (this->members_.size() - 1); - } - else - { - it = this->members_.emplace(hint, - key_storage_type(key.begin(),key.end(), get_allocator()), - std::forward(args)...); - } - } - return it; - } - - // set_ - - template - typename std::enable_if::value,void>::type - set_(key_storage_type&& key, T&& value) - { - string_view_type s(key.data(),key.size()); - auto it = std::find_if(this->members_.begin(),this->members_.end(), - [s](const value_type& a){return a.key().compare(s) == 0;}); - - if (it == this->members_.end()) - { - this->members_.emplace_back(std::forward(key), - std::forward(value)); - } - else - { - it->value(Json(std::forward(value))); - } - } - - template - typename std::enable_if::value,void>::type - set_(key_storage_type&& key, T&& value) - { - string_view_type s(key.data(),key.size()); - auto it = std::find_if(this->members_.begin(),this->members_.end(), - [s](const value_type& a){return a.key().compare(s) == 0;}); - - if (it == this->members_.end()) - { - this->members_.emplace_back(std::forward(key), - std::forward(value),get_allocator()); - } - else - { - it->value(Json(std::forward(value),get_allocator())); - } - } - - template - typename std::enable_if::value,iterator>::type - set_(iterator hint, key_storage_type&& key, T&& value) - { - iterator it = hint; - - if (it == this->members_.end()) - { - this->members_.emplace_back(std::forward(key), - std::forward(value)); - it = this->members_.begin() + (this->members_.size() - 1); - } - else if (it->key() == key) - { - it->value(Json(std::forward(value))); - } - else - { - it = this->members_.emplace(it, - std::forward(key), - std::forward(value)); - } - return it; - } - - template - typename std::enable_if::value,iterator>::type - set_(iterator hint, key_storage_type&& key, T&& value) - { - iterator it = hint; - - if (it == this->members_.end()) - { - this->members_.emplace_back(std::forward(key), - std::forward(value), get_allocator()); - it = this->members_.begin() + (this->members_.size() - 1); - } - else if (it->key() == key) - { - it->value(Json(std::forward(value), get_allocator())); - } - else - { - it = this->members_.emplace(it, - std::forward(key), - std::forward(value), get_allocator()); - } - return it; - } - - bool operator==(const json_object& rhs) const - { - if (size() != rhs.size()) - { - return false; - } - for (auto it = this->members_.begin(); it != this->members_.end(); ++it) - { - auto rhs_it = std::find_if(rhs.begin(),rhs.end(), - [it](const value_type& a){return a.key() == it->key();}); - if (rhs_it == rhs.end() || rhs_it->key() != it->key() || rhs_it->value() != it->value()) - { - return false; - } - } - return true; - } -private: - json_object& operator=(const json_object&) = delete; -}; - -} - -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_type_traits.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_type_traits.hpp index bb796f5..72df5a0 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/json_type_traits.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_type_traits.hpp @@ -12,40 +12,77 @@ #include #include #include -#include #include #include -#include -#include -#include -#include -#include -#include - -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wswitch" -#endif +#include // std::swap +#include // std::numeric_limits +#include // std::enable_if +#include // std::iterator_traits, std::input_iterator_tag +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace jsoncons { -// null_type -struct null_type -{ -}; +template +struct is_basic_json_class : std::false_type +{}; + +#if defined(_MSC_VER) && _MSC_VER < 1916 +template +struct is_basic_json_class::value && + !std::is_void::value && + !std::is_void::value>::type> : std::true_type +{}; +#else +template +struct is_basic_json_class>(),void())> : std::true_type +{}; +#endif + +template +struct is_json_type_traits_declared : public std::false_type +{}; + +#if !defined(JSONCONS_NO_DEPRECATED) +template +using is_json_type_traits_impl = is_json_type_traits_declared; +#endif // json_type_traits +template +struct unimplemented : std::false_type +{}; + template struct json_type_traits { - static const bool is_compatible = false; + typedef typename Json::allocator_type allocator_type; - static bool is(const Json&) + static constexpr bool is_compatible = false; + + static constexpr bool is(const Json&) { return false; } + + static T as(const Json&) + { + static_assert(unimplemented::value, "as not implemented"); + } + + static Json to_json(const T&, allocator_type = allocator_type()) + { + static_assert(unimplemented::value, "to_json not implemented"); + } }; namespace detail { @@ -68,7 +105,18 @@ struct is_compatible_string_type : std::false_type {}; template struct is_compatible_string_type::value && - detail::is_string_like::value && + jsoncons::detail::is_string_like::value && + !is_incompatible::value_type>::value +>::type> : std::true_type {}; + +// is_compatible_string_view_type +template +struct is_compatible_string_view_type : std::false_type {}; + +template +struct is_compatible_string_view_type::value && + jsoncons::detail::is_string_view_like::value && !is_incompatible::value_type>::value >::type> : std::true_type {}; @@ -79,7 +127,7 @@ struct is_compatible_array_type : std::false_type {}; template struct is_compatible_array_type::value && - detail::is_vector_like::value && + jsoncons::detail::is_vector_like::value && !is_incompatible::value_type>::value >::type> : std::true_type {}; @@ -93,13 +141,6 @@ struct is_compatible_object_type::value >::type> : std::true_type {}; -// is_std_array -template -struct is_std_array : std::false_type {}; - -template -struct is_std_array> : std::true_type {}; - template class json_array_input_iterator { @@ -262,7 +303,7 @@ struct json_type_traits::c typedef typename Json::char_type char_type; typedef typename Json::allocator_type allocator_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { return j.is_string(); } @@ -271,9 +312,9 @@ struct json_type_traits::c return j.as_cstring(); } template - static Json to_json(Args&&... args) + static Json to_json(const char_type* s, Args&&... args) { - return Json(typename Json::variant(std::forward(args)...)); + return Json(s, semantic_tag::none, std::forward(args)...); } }; @@ -283,14 +324,14 @@ struct json_type_traits::p typedef typename Json::char_type char_type; typedef typename Json::allocator_type allocator_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { return j.is_string(); } template - static Json to_json(Args&&... args) + static Json to_json(const char_type* s, Args&&... args) { - return Json(typename Json::variant(std::forward(args)...)); + return Json(s, semantic_tag::none, std::forward(args)...); } }; @@ -298,20 +339,20 @@ struct json_type_traits::p template struct json_type_traits::value + typename std::enable_if::value >::type> { typedef typename Json::allocator_type allocator_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { - if (j.is_integer()) + if (j.is_int64()) { - return j.as_integer() >= (std::numeric_limits::min)() && j.as_integer() <= (std::numeric_limits::max)(); + return (j.template as_integer() >= (std::numeric_limits::lowest)()) && (j.template as_integer() <= (std::numeric_limits::max)()); } - else if (j.is_uinteger()) + else if (j.is_uint64()) { - return j.as_uinteger() <= static_cast((std::numeric_limits::max)()); + return j.template as_integer() <= static_cast((std::numeric_limits::max)()); } else { @@ -320,46 +361,44 @@ struct json_type_traits(j.as_integer()); + return j.template as_integer(); } - template - static Json to_json(Args&&... args) + static Json to_json(T val, allocator_type = allocator_type()) { - return Json::from_integer(std::forward(args)...); + return Json(val, semantic_tag::none); } }; template struct json_type_traits::value ->::type > + typename std::enable_if::value>::type> { typedef typename Json::allocator_type allocator_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { - if (j.is_integer()) + if (j.is_int64()) { - return j.as_integer() >= 0 && static_cast(j.as_integer()) <= (std::numeric_limits::max)(); + return j.template as_integer() >= 0 && static_cast(j.template as_integer()) <= (std::numeric_limits::max)(); } - else if (j.is_uinteger()) + else if (j.is_uint64()) { - return j.as_uinteger() <= (std::numeric_limits::max)(); + return j.template as_integer() <= (std::numeric_limits::max)(); } else { return false; } } + static T as(const Json& j) { - return static_cast(j.as_uinteger()); + return j.template as_integer(); } - template - static Json to_json(Args&&... args) + static Json to_json(T val, allocator_type = allocator_type()) { - return Json::from_uinteger(std::forward(args)...); + return Json(val, semantic_tag::none); } }; @@ -370,7 +409,7 @@ struct json_type_traits(j.as_double()); } - template - static Json to_json(Args&&... args) + static Json to_json(T val, allocator_type = allocator_type()) { - return Json::from_floating_point(std::forward(args)...); + return Json(val, semantic_tag::none); } }; template struct json_type_traits { + typedef typename Json::object json_object; typedef typename Json::allocator_type allocator_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { return j.is_object(); } - template - static Json to_json(Args&&... args) + static Json to_json(const json_object& o) { - return Json(typename Json::variant(std::forward(args)...)); + return Json(o,semantic_tag::none); } }; template struct json_type_traits { + typedef typename Json::array json_array; typedef typename Json::allocator_type allocator_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { return j.is_array(); } - template - static Json to_json(Args&&... args) + static Json to_json(const json_array& a) { - return Json(typename Json::variant(std::forward(args)...)); + return Json(a, semantic_tag::none); } }; @@ -422,7 +460,7 @@ struct json_type_traits { typedef typename Json::allocator_type allocator_type; - static bool is(const Json&) JSONCONS_NOEXCEPT + static bool is(const Json&) noexcept { return true; } @@ -430,11 +468,7 @@ struct json_type_traits { return j; } - static Json to_json(const Json& val) - { - return val; - } - static Json to_json(const Json& val, allocator_type) + static Json to_json(const Json& val, allocator_type = allocator_type()) { return val; } @@ -445,7 +479,7 @@ struct json_type_traits { typedef typename Json::allocator_type allocator_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { return j.is_null(); } @@ -454,11 +488,7 @@ struct json_type_traits JSONCONS_ASSERT(j.is_null()); return jsoncons::null_type(); } - static Json to_json(jsoncons::null_type) - { - return Json::null(); - } - static Json to_json(jsoncons::null_type, allocator_type) + static Json to_json(jsoncons::null_type, allocator_type = allocator_type()) { return Json::null(); } @@ -469,7 +499,7 @@ struct json_type_traits { typedef typename Json::allocator_type allocator_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { return j.is_bool(); } @@ -477,10 +507,9 @@ struct json_type_traits { return j.as_bool(); } - template - static Json to_json(Args&&... args) + static Json to_json(bool val, allocator_type = allocator_type()) { - return Json(typename Json::variant(std::forward(args)...)); + return Json(val, semantic_tag::none); } }; @@ -492,7 +521,7 @@ struct json_type_traits - static Json to_json(Args&&... args) + static Json to_json(bool val, allocator_type = allocator_type()) { - return Json(typename Json::variant(std::forward(args)...)); + return Json(val, semantic_tag::none); } }; @@ -512,7 +540,7 @@ struct json_type_traits::reference> { typedef typename Json::allocator_type allocator_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { return j.is_bool(); } @@ -520,22 +548,20 @@ struct json_type_traits::reference> { return j.as_bool(); } - template - static Json to_json(Args&&... args) + static Json to_json(bool val, allocator_type = allocator_type()) { - return Json(typename Json::variant(std::forward(args)...)); + return Json(val, semantic_tag::none); } }; template struct json_type_traits::value && - !detail::is_std_array::value>::type> + typename std::enable_if::value && jsoncons::detail::is_compatible_array_type::value>::type> { typedef typename std::iterator_traits::value_type element_type; typedef typename Json::allocator_type allocator_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { bool result = j.is_array(); if (result) @@ -558,13 +584,13 @@ struct json_type_traits(j.array_range().begin()), - detail::json_array_input_iterator(j.array_range().end())); + T v(jsoncons::detail::json_array_input_iterator(j.array_range().begin()), + jsoncons::detail::json_array_input_iterator(j.array_range().end())); return v; } else { - JSONCONS_THROW(json_exception_impl("Attempt to cast json non-array to array")); + JSONCONS_THROW(json_runtime_error("Attempt to cast json non-array to array")); } } @@ -574,18 +600,24 @@ struct json_type_traits(j.array_range().begin()), - detail::json_array_input_iterator(j.array_range().end())); + T v(jsoncons::detail::json_array_input_iterator(j.array_range().begin()), + jsoncons::detail::json_array_input_iterator(j.array_range().end())); return v; } - else if (j.is_byte_string()) + else if (j.is_byte_string_view()) { T v(j.as_byte_string_view().begin(),j.as_byte_string_view().end()); return v; } + else if (j.is_byte_string()) + { + auto s = j.as_byte_string(); + T v(s.begin(),s.end()); + return v; + } else { - JSONCONS_THROW(json_exception_impl("Attempt to cast json non-array to array")); + JSONCONS_THROW(json_runtime_error("Attempt to cast json non-array to array")); } } @@ -620,52 +652,68 @@ struct json_type_traits struct json_type_traits::value>::type> + typename std::enable_if::value && jsoncons::detail::is_compatible_string_type::value>::type> { - typedef typename std::iterator_traits::value_type element_type; typedef typename Json::allocator_type allocator_type; - typedef typename T::allocator_type string_allocator_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { return j.is_string(); } static T as(const Json& j) { - if (j.is_string()) - { - return j.as_string(string_allocator_type()); - } - else - { - T s; - j.dump(s); - return s; - } + return T(j.as_string()); + } + + static Json to_json(const T& val) + { + return Json(val, semantic_tag::none); + } + + static Json to_json(const T& val, const allocator_type& allocator) + { + return Json(val, semantic_tag::none, allocator); + } +}; + +template +struct json_type_traits::value && jsoncons::detail::is_compatible_string_view_type::value>::type> +{ + typedef typename Json::allocator_type allocator_type; + + static bool is(const Json& j) noexcept + { + return j.is_string_view(); + } + + static T as(const Json& j) + { + return T(j.as_string_view().data(),j.as_string_view().size()); } static Json to_json(const T& val) { - return Json(typename Json::variant(val.data(), val.size())); + return Json(val, semantic_tag::none); } static Json to_json(const T& val, const allocator_type& allocator) { - return Json(typename Json::variant(val.data(),val.size(),allocator)); + return Json(val, semantic_tag::none, allocator); } }; template struct json_type_traits::value>::type + typename std::enable_if::value && jsoncons::detail::is_compatible_object_type::value>::type > { typedef typename T::mapped_type mapped_type; typedef typename T::value_type value_type; typedef typename Json::allocator_type allocator_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { bool result = j.is_object(); for (auto member : j.object_range()) @@ -680,30 +728,20 @@ struct json_type_traits(j.object_range().begin()), - detail::json_object_input_iterator(j.object_range().end())); + T v(jsoncons::detail::json_object_input_iterator(j.object_range().begin()), + jsoncons::detail::json_object_input_iterator(j.object_range().end())); return v; } static Json to_json(const T& val) { - Json j; - j.reserve(val.size()); - for (auto p: val) - { - j.set(p.first, p.second); - } + Json j = typename Json::object(val.begin(), val.end()); return j; } static Json to_json(const T& val, const allocator_type& allocator) { - Json j(allocator); - j.reserve(val.size()); - for (auto p: val) - { - j.set(p.first, p.second); - } + Json j = typename Json::object(val.begin(), val.end(), allocator); return j; } }; @@ -715,7 +753,7 @@ struct json_type_traits> typedef E element_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { bool result = j.is_array() && j.size() == N; if (result) @@ -776,7 +814,7 @@ struct json_tuple_helper using element_type = typename std::tuple_element::type; using next = json_tuple_helper; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { if(j[Pos - 1].template is()) { @@ -804,7 +842,7 @@ struct json_tuple_helper template struct json_tuple_helper<0, Json, Tuple> { - static bool is(const Json&) JSONCONS_NOEXCEPT + static bool is(const Json&) noexcept { return true; } @@ -824,10 +862,10 @@ template struct json_type_traits> { private: - using helper = detail::json_tuple_helper>; + using helper = jsoncons::detail::json_tuple_helper>; public: - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { return helper::is(j); } @@ -851,14 +889,14 @@ template struct json_type_traits> { public: - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { return j.is_array() && j.size() == 2; } static std::pair as(const Json& j) { - return std::make_pair(j[0]. template as(),j[1]. template as()); + return std::make_pair(j[0].template as(),j[1].template as()); } static Json to_json(const std::pair& val) @@ -871,19 +909,86 @@ template struct json_type_traits> { public: - static bool is(const Json& j) JSONCONS_NOEXCEPT + typedef typename Json::allocator_type allocator_type; + + static bool is(const Json& j) noexcept { return j.is_byte_string(); } static basic_byte_string as(const Json& j) + { + return j.template as_byte_string(); + } + + static Json to_json(const basic_byte_string& val, + const allocator_type& allocator = allocator_type()) { - return basic_byte_string(j.as_byte_string_view()); + return Json(val, semantic_tag::none, allocator); + } +}; + +template +struct json_type_traits +{ +public: + static bool is(const Json& j) noexcept + { + return j.is_byte_string_view(); } - static Json to_json(const basic_byte_string& val) + static byte_string_view as(const Json& j) { - return Json(val.data(),val.length()); + return j.as_byte_string_view(); + } + + static Json to_json(const byte_string_view& val) + { + return Json(val); + } +}; +/* +template +struct json_type_traits +{ +public: + static bool is(const Json& j) noexcept + { + return j.is_byte_string(); + } + + static byte_string as(const Json& j) + { + return j.as_byte_string(); + } + + static Json to_json(const byte_string& val) + { + return Json(val); + } +}; +*/ +// basic_bignum + +template +struct json_type_traits> +{ +public: + static bool is(const Json& j) noexcept + { + return j.is_bignum(); + } + + static basic_bignum as(const Json& j) + { + return j.as_bignum(); + } + + static Json to_json(const basic_bignum& val) + { + std::basic_string s; + val.dump(s); + return Json(s,semantic_tag::bigint); } }; @@ -894,7 +999,7 @@ struct json_type_traits> { typedef typename Json::allocator_type allocator_type; - static bool is(const Json& j) JSONCONS_NOEXCEPT + static bool is(const Json& j) noexcept { bool result = j.is_array(); if (result) @@ -924,7 +1029,7 @@ struct json_type_traits> } else { - JSONCONS_THROW(json_exception_impl("Attempt to cast json non-array to array")); + JSONCONS_THROW(json_runtime_error("Attempt to cast json non-array to array")); } } @@ -940,7 +1045,7 @@ struct json_type_traits> j.push_back(*it); } return j; - } + } static Json to_json(const std::valarray& val, const allocator_type& allocator) { @@ -957,11 +1062,6 @@ struct json_type_traits> } }; -} +} // jsoncons -#if defined(__GNUC__) -#pragma GCC diagnostic pop #endif - -#endif - diff --git a/invehicle-apps/3rd-party-libs/jsoncons/json_type_traits_macros.hpp b/invehicle-apps/3rd-party-libs/jsoncons/json_type_traits_macros.hpp new file mode 100644 index 0000000..b05e589 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/json_type_traits_macros.hpp @@ -0,0 +1,407 @@ +// Copyright 2019 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_JSON_TYPE_TRAITS_MACROS_HPP +#define JSONCONS_JSON_TYPE_TRAITS_MACROS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include // std::swap +#include // std::numeric_limits +#include // std::enable_if +#include // std::iterator_traits, std::input_iterator_tag +#include // JSONCONS_EXPAND, JSONCONS_QUOTE +#include +#include +#include +#include +#include +#include +#include +#include + +// This draws on https://github.com/Loki-Astari/ThorsSerializer/blob/master/src/Serialize/Traits.h + +#define JSONCONS_NARGS(...) JSONCONS_NARG_(__VA_ARGS__, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define JSONCONS_NARG_(...) JSONCONS_EXPAND( JSONCONS_ARG_N(__VA_ARGS__) ) +#define JSONCONS_ARG_N(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, N, ...) N + +#define JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) Call(TC, JVal, TVal, Prefix, P2) + +#define JSONCONS_REP_N(Call, TC, JVal, TVal, Prefix, ...) JSONCONS_REP_OF_N(Call, TC, JVal, TVal, Prefix, JSONCONS_NARGS(__VA_ARGS__), __VA_ARGS__) +#define JSONCONS_REP_OF_N(Call, TC, JVal, TVal, Prefix, Count, ...) JSONCONS_REP_OF_N_(Call, TC, JVal, TVal, Prefix, Count, __VA_ARGS__) +#define JSONCONS_REP_OF_N_(Call, TC, JVal, TVal, Prefix, Count, ...) JSONCONS_EXPAND(JSONCONS_REP_OF_ ## Count(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) + +#define JSONCONS_REP_OF_50(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_49(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_49(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_48(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_48(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_47(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_47(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_46(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_46(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_45(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_45(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_44(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_44(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_43(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_43(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_42(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_42(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_41(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_41(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_40(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_40(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_39(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_39(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_38(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_38(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_37(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_37(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_36(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_36(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_35(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_35(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_34(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_34(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_33(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_33(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_32(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_32(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_31(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_31(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_30(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_30(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_29(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_29(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_28(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_28(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_27(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_27(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_26(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_26(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_25(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_25(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_24(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_24(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_23(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_23(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_22(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_22(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_21(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_21(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_20(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_20(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_19(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_19(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_18(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_18(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_17(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_17(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_16(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_16(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_15(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_15(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_14(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_14(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_13(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_13(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_12(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_12(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_11(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_11(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_10(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_10(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_9(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_9(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_8(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_8(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_7(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_7(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_6(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_6(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_5(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_5(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_4(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_4(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_3(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_3(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_2(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_2(Call, TC, JVal, TVal, Prefix, P2, ...) JSONCONS_EXPAND_CALL4(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(JSONCONS_REP_OF_1(Call, TC, JVal, TVal, Prefix, __VA_ARGS__)) +#define JSONCONS_REP_OF_1(Call, TC, JVal, TVal, Prefix, P2) JSONCONS_EXPAND(Call ## _LAST(TC, JVal, TVal, Prefix, P2)) + +#define JSONCONS_IS(TC, JVal, TVal, Prefix, Member) if (!(JVal).contains(JSONCONS_QUOTE(Prefix, Member))) return false; +#define JSONCONS_IS_LAST(TC, JVal, TVal, Prefix, Member) if (!(JVal).contains(JSONCONS_QUOTE(Prefix, Member))) return false; + +#define JSONCONS_TO_JSON(TC, JVal, TVal, Prefix, Member) (JVal).try_emplace(JSONCONS_QUOTE(Prefix, Member), TVal.Member); +#define JSONCONS_TO_JSON_LAST(TC, JVal, TVal, Prefix, Member) (JVal).try_emplace(JSONCONS_QUOTE(Prefix, Member), TVal.Member); + +#define JSONCONS_AS(TC, JVal, TVal, Prefix, Member) if ((JVal).contains(JSONCONS_QUOTE(Prefix, Member))) {val.Member = (JVal).at(JSONCONS_QUOTE(Prefix, Member)).template as();} +#define JSONCONS_AS_LAST(TC, JVal, TVal, Prefix, Member) if ((JVal).contains(JSONCONS_QUOTE(Prefix, Member))) {val.Member = (JVal).at(JSONCONS_QUOTE(Prefix, Member)).template as();} + +#define JSONCONS_MAND_AS(TC, JVal, TVal, Prefix, Member) {val.Member = (JVal).at(JSONCONS_QUOTE(Prefix, Member)).template as();} +#define JSONCONS_MAND_AS_LAST(TC, JVal, TVal, Prefix, Member) {val.Member = (JVal).at(JSONCONS_QUOTE(Prefix, Member)).template as();} + +#define JSONCONS_IS2(TC, JVal, TVal, Prefix, Member) if (!(JVal).contains(JSONCONS_QUOTE(Prefix, Member))) return false; +#define JSONCONS_IS2_LAST(TC, JVal, TVal, Prefix, Member) if (!(JVal).contains(JSONCONS_QUOTE(Prefix, Member))) return false; + +#define JSONCONS_TO_JSON2(TC, JVal, TVal, Prefix, Member) (JVal).try_emplace(JSONCONS_QUOTE(Prefix, Member), TVal.Member() ); +#define JSONCONS_TO_JSON2_LAST(TC, JVal, TVal, Prefix, Member) (JVal).try_emplace(JSONCONS_QUOTE(Prefix, Member), TVal.Member() ); + +#define JSONCONS_AS2(TC, JVal, TVal, Prefix, Member) ((JVal).at(JSONCONS_QUOTE(Prefix, Member))).template asMember())>::type>(), +#define JSONCONS_AS2_LAST(TC, JVal, TVal, Prefix, Member) ((JVal).at(JSONCONS_QUOTE(Prefix, Member))).template asMember())>::type>() + +#define JSONCONS_TYPE_TRAITS_FRIEND \ + template \ + friend struct jsoncons::json_type_traits + +#define JSONCONS_EXPAND_CALL2(Call, Expr, Id) JSONCONS_EXPAND(Call(Expr, Id)) + +#define JSONCONS_TEMPLATE_REP_OF_N(Call, Expr, Pre, App, Count) JSONCONS_TEMPLATE_REP_OF_ ## Count(Call, Expr, Pre, App) + +#define JSONCONS_TEMPLATE_REP_OF_50(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 50) JSONCONS_TEMPLATE_REP_OF_49(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_49(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 49) JSONCONS_TEMPLATE_REP_OF_48(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_48(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 48) JSONCONS_TEMPLATE_REP_OF_47(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_47(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 47) JSONCONS_TEMPLATE_REP_OF_46(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_46(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 46) JSONCONS_TEMPLATE_REP_OF_45(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_45(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 45) JSONCONS_TEMPLATE_REP_OF_44(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_44(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 44) JSONCONS_TEMPLATE_REP_OF_43(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_43(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 43) JSONCONS_TEMPLATE_REP_OF_42(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_42(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 42) JSONCONS_TEMPLATE_REP_OF_41(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_41(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 41) JSONCONS_TEMPLATE_REP_OF_40(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_40(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 40) JSONCONS_TEMPLATE_REP_OF_39(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_39(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 39) JSONCONS_TEMPLATE_REP_OF_38(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_38(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 38) JSONCONS_TEMPLATE_REP_OF_37(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_37(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 37) JSONCONS_TEMPLATE_REP_OF_36(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_36(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 36) JSONCONS_TEMPLATE_REP_OF_35(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_35(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 35) JSONCONS_TEMPLATE_REP_OF_34(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_34(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 34) JSONCONS_TEMPLATE_REP_OF_33(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_33(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 33) JSONCONS_TEMPLATE_REP_OF_32(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_32(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 32) JSONCONS_TEMPLATE_REP_OF_31(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_31(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 31) JSONCONS_TEMPLATE_REP_OF_30(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_30(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 30) JSONCONS_TEMPLATE_REP_OF_29(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_29(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 29) JSONCONS_TEMPLATE_REP_OF_28(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_28(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 28) JSONCONS_TEMPLATE_REP_OF_27(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_27(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 27) JSONCONS_TEMPLATE_REP_OF_26(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_26(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 26) JSONCONS_TEMPLATE_REP_OF_25(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_25(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 25) JSONCONS_TEMPLATE_REP_OF_24(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_24(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 24) JSONCONS_TEMPLATE_REP_OF_23(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_23(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 23) JSONCONS_TEMPLATE_REP_OF_22(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_22(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 22) JSONCONS_TEMPLATE_REP_OF_21(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_21(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 21) JSONCONS_TEMPLATE_REP_OF_20(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_20(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 20) JSONCONS_TEMPLATE_REP_OF_19(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_19(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 19) JSONCONS_TEMPLATE_REP_OF_18(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_18(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 18) JSONCONS_TEMPLATE_REP_OF_17(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_17(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 17) JSONCONS_TEMPLATE_REP_OF_16(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_16(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 16) JSONCONS_TEMPLATE_REP_OF_15(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_15(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 15) JSONCONS_TEMPLATE_REP_OF_14(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_14(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 14) JSONCONS_TEMPLATE_REP_OF_13(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_13(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 13) JSONCONS_TEMPLATE_REP_OF_12(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_12(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 12) JSONCONS_TEMPLATE_REP_OF_11(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_11(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 11) JSONCONS_TEMPLATE_REP_OF_10(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_10(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 10) JSONCONS_TEMPLATE_REP_OF_9(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_9(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 9) JSONCONS_TEMPLATE_REP_OF_8(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_8(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 8) JSONCONS_TEMPLATE_REP_OF_7(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_7(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 7) JSONCONS_TEMPLATE_REP_OF_6(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_6(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 6) JSONCONS_TEMPLATE_REP_OF_5(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_5(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 5) JSONCONS_TEMPLATE_REP_OF_4(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_4(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 4) JSONCONS_TEMPLATE_REP_OF_3(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_3(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 3) JSONCONS_TEMPLATE_REP_OF_2(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_2(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call, Expr, 2) JSONCONS_TEMPLATE_REP_OF_1(Call, Expr, , App) +#define JSONCONS_TEMPLATE_REP_OF_1(Call, Expr, Pre, App) Pre JSONCONS_EXPAND_CALL2(Call ## _LAST, Expr, 1) App +#define JSONCONS_TEMPLATE_REP_OF_0(Call, Expr, Pre, App) + +#define JSONCONS_GENERATE_TEMPLATE_PARAMS(Call, Count) JSONCONS_TEMPLATE_REP_OF_N(Call, , , ,Count) +#define JSONCONS_GENERATE_TEMPLATE_ARGS(Call, Count) JSONCONS_TEMPLATE_REP_OF_N(Call, ,<,>,Count) +#define JSONCONS_GENERATE_TEMPLATE_PARAM(Expr, Id) , typename T ## Id +#define JSONCONS_GENERATE_TEMPLATE_PARAM_LAST(Expr, Id) , typename T ## Id +#define JSONCONS_GENERATE_TEMPLATE_ARG(Expr, Id) T ## Id, +#define JSONCONS_GENERATE_TEMPLATE_ARG_LAST(Ex, Id) T ## Id + +#define JSONCONS_MEMBER_TRAITS_DECL_BASE(CharT,Prefix,NumTemplateParams, ValueType, ...) \ +namespace jsoncons \ +{ \ + template \ + struct json_type_traits::value>::type> \ + { \ + typedef ValueType JSONCONS_GENERATE_TEMPLATE_ARGS(JSONCONS_GENERATE_TEMPLATE_ARG, NumTemplateParams) value_type; \ + typedef typename Json::allocator_type allocator_type; \ + static bool is(const Json& j) noexcept \ + { \ + if (!j.is_object()) return false; \ + JSONCONS_REP_N(JSONCONS_IS, 0, j, void(), Prefix, __VA_ARGS__)\ + return true; \ + } \ + static value_type as(const Json& j) \ + { \ + value_type val{}; \ + JSONCONS_REP_N(JSONCONS_AS, 0, j, val, Prefix, __VA_ARGS__) \ + return val; \ + } \ + static Json to_json(const value_type& val, allocator_type allocator=allocator_type()) \ + { \ + Json j(allocator); \ + JSONCONS_REP_N(JSONCONS_TO_JSON, 0, j, val, Prefix, __VA_ARGS__) \ + return j; \ + } \ + }; \ +} \ + /**/ + +#define JSONCONS_MEMBER_TRAITS_DECL(ValueType, ...) \ + JSONCONS_MEMBER_TRAITS_DECL_BASE(char,,0, ValueType, __VA_ARGS__) \ + JSONCONS_MEMBER_TRAITS_DECL_BASE(wchar_t,L,0, ValueType, __VA_ARGS__) \ + /**/ + +#define JSONCONS_TEMPLATE_MEMBER_TRAITS_DECL(NumTemplateParams, ValueType, ...) \ + JSONCONS_MEMBER_TRAITS_DECL_BASE(char,,NumTemplateParams, ValueType, __VA_ARGS__) \ + JSONCONS_MEMBER_TRAITS_DECL_BASE(wchar_t,L,NumTemplateParams, ValueType, __VA_ARGS__) \ + /**/ + +#define JSONCONS_STRICT_MEMBER_TRAITS_DECL_BASE(CharT,Prefix,NumTemplateParams, ValueType, ...) \ +namespace jsoncons \ +{ \ + template \ + struct json_type_traits::value>::type> \ + { \ + typedef ValueType JSONCONS_GENERATE_TEMPLATE_ARGS(JSONCONS_GENERATE_TEMPLATE_ARG, NumTemplateParams) value_type; \ + typedef typename Json::allocator_type allocator_type; \ + static bool is(const Json& j) noexcept \ + { \ + if (!j.is_object()) return false; \ + JSONCONS_REP_N(JSONCONS_IS, 0, j, void(), Prefix, __VA_ARGS__)\ + return true; \ + } \ + static value_type as(const Json& j) \ + { \ + value_type val{}; \ + JSONCONS_REP_N(JSONCONS_MAND_AS, 0, j, val, Prefix, __VA_ARGS__) \ + return val; \ + } \ + static Json to_json(const value_type& val, allocator_type allocator=allocator_type()) \ + { \ + Json j(allocator); \ + JSONCONS_REP_N(JSONCONS_TO_JSON, 0, j, val, Prefix, __VA_ARGS__) \ + return j; \ + } \ + }; \ +} \ + /**/ + +#define JSONCONS_STRICT_MEMBER_TRAITS_DECL(ValueType, ...) \ + JSONCONS_STRICT_MEMBER_TRAITS_DECL_BASE(char,,0,ValueType,__VA_ARGS__) \ + JSONCONS_STRICT_MEMBER_TRAITS_DECL_BASE(wchar_t,L,0,ValueType,__VA_ARGS__) \ + /**/ + +#define JSONCONS_TEMPLATE_STRICT_MEMBER_TRAITS_DECL(NumTemplateParams, ValueType, ...) \ + JSONCONS_STRICT_MEMBER_TRAITS_DECL_BASE(char,,NumTemplateParams,ValueType,__VA_ARGS__) \ + JSONCONS_STRICT_MEMBER_TRAITS_DECL_BASE(wchar_t,L,NumTemplateParams,ValueType,__VA_ARGS__) \ + /**/ + +#define JSONCONS_GETTER_CTOR_TRAITS_DECL_BASE(CharT,Prefix,NumTemplateParams, ValueType, ...) \ +namespace jsoncons \ +{ \ + template \ + struct json_type_traits::value>::type> \ + { \ + typedef ValueType JSONCONS_GENERATE_TEMPLATE_ARGS(JSONCONS_GENERATE_TEMPLATE_ARG, NumTemplateParams) value_type; \ + typedef typename Json::allocator_type allocator_type; \ + static bool is(const Json& j) noexcept \ + { \ + if (!j.is_object()) return false; \ + JSONCONS_REP_N(JSONCONS_IS2, 0, j, void(), Prefix, __VA_ARGS__)\ + return true; \ + } \ + static value_type as(const Json& j) \ + { \ + return value_type ( JSONCONS_REP_N(JSONCONS_AS2, 0, j, void(), Prefix, __VA_ARGS__) ); \ + } \ + static Json to_json(const value_type& val, allocator_type allocator=allocator_type()) \ + { \ + Json j(allocator); \ + JSONCONS_REP_N(JSONCONS_TO_JSON2, 0, j, val, Prefix, __VA_ARGS__) \ + return j; \ + } \ + }; \ +} \ + /**/ + +#define JSONCONS_GETTER_CTOR_TRAITS_DECL(ValueType, ...) \ +JSONCONS_GETTER_CTOR_TRAITS_DECL_BASE(char,,0, ValueType, __VA_ARGS__) \ +JSONCONS_GETTER_CTOR_TRAITS_DECL_BASE(wchar_t,L,0, ValueType, __VA_ARGS__) \ + /**/ + +#define JSONCONS_TEMPLATE_GETTER_CTOR_TRAITS_DECL(NumTemplateParams, ValueType, ...) \ +JSONCONS_GETTER_CTOR_TRAITS_DECL_BASE(char,,NumTemplateParams, ValueType, __VA_ARGS__) \ +JSONCONS_GETTER_CTOR_TRAITS_DECL_BASE(wchar_t,L,NumTemplateParams, ValueType, __VA_ARGS__) \ + /**/ + +#define JSONCONS_ENUM_PAIR(TC, JVal, TVal, Prefix, Member) {value_type::Member, JSONCONS_QUOTE(Prefix,Member)}, +#define JSONCONS_ENUM_PAIR_LAST(TC, JVal, TVal, Prefix, Member) {value_type::Member, JSONCONS_QUOTE(Prefix,Member)} + +#define JSONCONS_ENUM_TRAITS_DECL_BASE(CharT,Prefix,EnumType, ...) \ +namespace jsoncons \ +{ \ + template \ + struct json_type_traits::value>::type> \ + { \ + static_assert(std::is_enum::value, # EnumType " must be an enum"); \ + typedef EnumType value_type; \ + typedef std::basic_string string_type; \ + typedef basic_string_view string_view_type; \ + typedef typename Json::allocator_type allocator_type; \ + typedef std::pair mapped_type; \ + \ + static std::pair get_values() \ + { \ + static const mapped_type v[] = { \ + JSONCONS_REP_N(JSONCONS_ENUM_PAIR, 0, void(), void(), Prefix, __VA_ARGS__)\ + };\ + return std::make_pair(v,v+JSONCONS_NARGS(__VA_ARGS__)); \ + } \ + \ + static bool is(const Json& j) noexcept \ + { \ + if (!j.is_string()) return false; \ + auto first = get_values().first; \ + auto last = get_values().second; \ + const string_view_type s = j.template as(); \ + if (s.empty() && std::find_if(first, last, \ + [](const mapped_type& item) -> bool \ + { return item.first == value_type(); }) == last) \ + { \ + return true; \ + } \ + auto it = std::find_if(first, last, \ + [&](const mapped_type& item) -> bool \ + { return item.second == s; }); \ + return it != last; \ + } \ + static value_type as(const Json& j) \ + { \ + if (!j.is_string()) \ + { \ + JSONCONS_THROW(json_runtime_error("Not an enum")); \ + } \ + const string_view_type s = j.template as(); \ + auto first = get_values().first; \ + auto last = get_values().second; \ + if (s.empty() && std::find_if(first, last, \ + [](const mapped_type& item) -> bool \ + { return item.first == value_type(); }) == last) \ + { \ + return value_type(); \ + } \ + auto it = std::find_if(first, last, \ + [&](const mapped_type& item) -> bool \ + { return item.second == s; }); \ + if (it == last) \ + { \ + if (s.empty()) \ + { \ + return value_type(); \ + } \ + else \ + { \ + JSONCONS_THROW(json_runtime_error("Not an enum")); \ + } \ + } \ + return it->first; \ + } \ + static Json to_json(value_type val, allocator_type allocator=allocator_type()) \ + { \ + static constexpr CharT empty_string[] = {0}; \ + auto first = get_values().first; \ + auto last = get_values().second; \ + auto it = std::find_if(first, last, \ + [val](const mapped_type& item) -> bool \ + { return item.first == val; }); \ + if (it == last) \ + { \ + if (val == value_type()) \ + { \ + return Json(empty_string); \ + } \ + else \ + { \ + JSONCONS_THROW(json_runtime_error("Not an enum")); \ + } \ + } \ + return Json(it->second,allocator); \ + } \ + }; \ +} \ + /**/ + +#define JSONCONS_ENUM_TRAITS_DECL(EnumType, ...) \ + JSONCONS_ENUM_TRAITS_DECL_BASE(char,,EnumType,__VA_ARGS__) \ + JSONCONS_ENUM_TRAITS_DECL_BASE(wchar_t,L,EnumType,__VA_ARGS__) \ + /**/ + +#if !defined(JSONCONS_NO_DEPRECATED) +#define JSONCONS_TYPE_TRAITS_DECL JSONCONS_MEMBER_TRAITS_DECL +#define JSONCONS_NONDEFAULT_MEMBER_TRAITS_DECL JSONCONS_STRICT_MEMBER_TRAITS_DECL +#endif + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/jsoncons_config.hpp b/invehicle-apps/3rd-party-libs/jsoncons/jsoncons_config.hpp deleted file mode 100644 index 59c6b65..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/jsoncons_config.hpp +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2013 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_JSONCONS_CONFIG_HPP -#define JSONCONS_JSONCONS_CONFIG_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // std::numeric_limits - -// Uncomment the following line to suppress deprecated names (recommended for new code) -//#define JSONCONS_NO_DEPRECATED - -// The definitions below follow the definitions in compiler_support_p.h, https://github.com/01org/tinycbor -// MIT license - -#if defined(__GNUC__) || defined(__clang__) -#define JSONCONS_LIKELY(x) __builtin_expect(!!(x), 1) -#define JSONCONS_UNLIKELY(x) __builtin_expect(!!(x), 0) -#define JSONCONS_UNREACHABLE() __builtin_unreachable() -#elif defined(_MSC_VER) -#define JSONCONS_LIKELY(x) x -#define JSONCONS_UNLIKELY(x) x -#define JSONCONS_UNREACHABLE() __assume(0) -#else -#define JSONCONS_LIKELY(x) x -#define JSONCONS_UNLIKELY(x) x -#define JSONCONS_UNREACHABLE() do {} while (0) -#endif - -namespace jsoncons -{ - -#if _MSC_VER > 1800 // _MSC_VER == 1800 -> MS Visual Studio 2013 -#else -#define JSONCONS_NO_CONSTEXPR -#endif - -#define JSONCONS_NO_TO_CHARS - -#if defined(_MSC_VER) -#if _MSC_VER >= 1900 -#define JSONCONS_HAS_USER_DEFINED_LITERALS -#endif -#else -#define JSONCONS_HAS_USER_DEFINED_LITERALS -#endif - -//#define JSONCONS_HAS_STRING_VIEW - -#if defined(ANDROID) || defined(__ANDROID__) -#define JSONCONS_HAS_STRTOLD_L -#define JSONCONS_NO_LOCALECONV -#endif - -#if defined (__clang__) -#if defined(_GLIBCXX_USE_NOEXCEPT) -#define JSONCONS_NOEXCEPT _GLIBCXX_USE_NOEXCEPT -#else -#define JSONCONS_NOEXCEPT noexcept -#endif -#elif defined(__GNUC__) -#define JSONCONS_NOEXCEPT _GLIBCXX_USE_NOEXCEPT -#elif defined(_MSC_VER) -#if _MSC_VER >= 1900 -#define JSONCONS_NOEXCEPT noexcept -#else -#define JSONCONS_NOEXCEPT -#endif -#else -#define JSONCONS_NOEXCEPT -#endif - -#if defined(_MSC_VER) -#define JSONCONS_HAS_MSC__STRTOD_L -#define JSONCONS_HAS__ECVT_S -#define JSONCONS_HAS_FOPEN_S -#if _MSC_VER >= 1900 -#define JSONCONS_ALIGNOF alignof -#else -#define JSONCONS_ALIGNOF __alignof -#endif -#else -#define JSONCONS_ALIGNOF alignof -#endif - -#define JSONCONS_DEFINE_LITERAL( name, lit ) \ -template< class Ch > Ch const* name(); \ -template<> inline char const * name() { return lit; } \ -template<> inline wchar_t const* name() { return L ## lit; } - -} - -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/jsoncons_utilities.hpp b/invehicle-apps/3rd-party-libs/jsoncons/jsoncons_utilities.hpp deleted file mode 100644 index 28a9eb7..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/jsoncons_utilities.hpp +++ /dev/null @@ -1,954 +0,0 @@ -// Copyright 2013 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_JSONCONSUTILITIES_HPP -#define JSONCONS_JSONCONSUTILITIES_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if !defined(JSONCONS_NO_TO_CHARS) -#include -#endif -#include - -namespace jsoncons -{ - -#if !defined(JSONCONS_HAS_STRING_VIEW) -template > -class Basic_string_view_ -{ -private: - const CharT* data_; - size_t length_; -public: - typedef CharT value_type; - typedef const CharT& const_reference; - typedef Traits traits_type; - typedef std::size_t size_type; - static const size_type npos = size_type(-1); - typedef const CharT* const_iterator; - typedef const CharT* iterator; - typedef std::reverse_iterator const_reverse_iterator; - - Basic_string_view_() - : data_(nullptr), length_(0) - { - } - Basic_string_view_(const CharT* data, size_t length) - : data_(data), length_(length) - { - } - Basic_string_view_(const CharT* data) - : data_(data), length_(Traits::length(data)) - { - } - Basic_string_view_(const Basic_string_view_& other) = default; - - template - Basic_string_view_(const std::basic_string& s) - : data_(s.data()), length_(s.length()) - { - } - - template - explicit operator std::basic_string() const - { - return std::basic_string(data_,length_); - } - - // iterator support - const_iterator begin() const JSONCONS_NOEXCEPT - { - return data_; - } - const_iterator end() const JSONCONS_NOEXCEPT - { - return data_ + length_; - } - const_iterator cbegin() const JSONCONS_NOEXCEPT - { - return data_; - } - const_iterator cend() const JSONCONS_NOEXCEPT - { - return data_ + length_; - } - const_reverse_iterator rbegin() const JSONCONS_NOEXCEPT - { - return const_reverse_iterator(end()); - } - const_reverse_iterator rend() const JSONCONS_NOEXCEPT - { - return const_reverse_iterator(begin()); - } - const_reverse_iterator crbegin() const JSONCONS_NOEXCEPT - { - return const_reverse_iterator(end()); - } - const_reverse_iterator crend() const JSONCONS_NOEXCEPT - { - return const_reverse_iterator(begin()); - } - - // capacity - - size_t size() const - { - return length_; - } - - size_t length() const - { - return length_; - } - size_type max_size() const JSONCONS_NOEXCEPT - { - return length_; - } - bool empty() const JSONCONS_NOEXCEPT - { - return length_ == 0; - } - - // element access - - const_reference operator[](size_type pos) const - { - return data_[pos]; - } - - const_reference at(size_t pos) const - { - if (pos >= length_) - { - JSONCONS_THROW(json_exception_impl("pos exceeds length")); - } - return data_[pos]; - } - - const_reference front() const - { - return data_[0]; - } - const_reference back() const - { - return data_[length_-1]; - } - - const CharT* data() const - { - return data_; - } - - // string operations - - Basic_string_view_ substr(size_type pos, size_type n=npos) const - { - if (pos > length_) - { - JSONCONS_THROW(json_exception_impl("pos exceeds size")); - } - if (n == npos || pos + n > length_) - { - n = length_ - pos; - } - return Basic_string_view_(data_ + pos, n); - } - - int compare(Basic_string_view_ s) const - { - const int rc = Traits::compare(data_, s.data_, (std::min)(length_, s.length_)); - return rc != 0 ? rc : (length_ == s.length_ ? 0 : length_ < s.length_ ? -1 : 1); - } - - int compare(const CharT* data) const - { - const size_t length = Traits::length(data); - const int rc = Traits::compare(data_, data, (std::min)(length_, length)); - return rc != 0 ? rc : (length_ == length? 0 : length_ < length? -1 : 1); - } - - template - int compare(const std::basic_string& s) const - { - const int rc = Traits::compare(data_, s.data(), (std::min)(length_, s.length())); - return rc != 0 ? rc : (length_ == s.length() ? 0 : length_ < s.length() ? -1 : 1); - } - - size_type find(Basic_string_view_ s, size_type pos = 0) const JSONCONS_NOEXCEPT - { - if (pos > length_) - { - return npos; - } - if (s.length_ == 0) - { - return pos; - } - const_iterator it = std::search(cbegin() + pos, cend(), - s.cbegin(), s.cend(), Traits::eq); - return it == cend() ? npos : std::distance(cbegin(), it); - } - size_type find(CharT ch, size_type pos = 0) const JSONCONS_NOEXCEPT - { - return find(Basic_string_view_(&ch, 1), pos); - } - size_type find(const CharT* s, size_type pos, size_type n) const JSONCONS_NOEXCEPT - { - return find(Basic_string_view_(s, n), pos); - } - size_type find(const CharT* s, size_type pos = 0) const JSONCONS_NOEXCEPT - { - return find(Basic_string_view_(s), pos); - } - - size_type rfind(Basic_string_view_ s, size_type pos = npos) const JSONCONS_NOEXCEPT - { - if (length_ < s.length_) - { - return npos; - } - if (pos > length_ - s.length_) - { - pos = length_ - s.length_; - } - if (s.length_ == 0) - { - return pos; - } - for (const CharT* p = data_ + pos; true; --p) - { - if (Traits::compare(p, s.data_, s.length_) == 0) - { - return p - data_; - } - if (p == data_) - { - return npos; - } - }; - } - size_type rfind(CharT ch, size_type pos = npos) const JSONCONS_NOEXCEPT - { - return rfind(Basic_string_view_(&ch, 1), pos); - } - size_type rfind(const CharT* s, size_type pos, size_type n) const JSONCONS_NOEXCEPT - { - return rfind(Basic_string_view_(s, n), pos); - } - size_type rfind(const CharT* s, size_type pos = npos) const JSONCONS_NOEXCEPT - { - return rfind(Basic_string_view_(s), pos); - } - - size_type find_first_of(Basic_string_view_ s, size_type pos = 0) const JSONCONS_NOEXCEPT - { - if (pos >= length_ || s.length_ == 0) - { - return npos; - } - const_iterator it = std::find_first_of - (cbegin() + pos, cend(), s.cbegin(), s.cend(), Traits::eq); - return it == cend() ? npos : std::distance (cbegin(), it); - } - size_type find_first_of(CharT ch, size_type pos = 0) const JSONCONS_NOEXCEPT - { - return find_first_of(Basic_string_view_(&ch, 1), pos); - } - size_type find_first_of(const CharT* s, size_type pos, size_type n) const JSONCONS_NOEXCEPT - { - return find_first_of(Basic_string_view_(s, n), pos); - } - size_type find_first_of(const CharT* s, size_type pos = 0) const JSONCONS_NOEXCEPT - { - return find_first_of(Basic_string_view_(s), pos); - } - - size_type find_last_of(Basic_string_view_ s, size_type pos = npos) const JSONCONS_NOEXCEPT - { - if (s.length_ == 0) - { - return npos; - } - if (pos >= length_) - { - pos = 0; - } - else - { - pos = length_ - (pos+1); - } - const_reverse_iterator it = std::find_first_of - (crbegin() + pos, crend(), s.cbegin(), s.cend(), Traits::eq); - return it == crend() ? npos : (length_ - 1 - std::distance(crbegin(), it)); - } - size_type find_last_of(CharT ch, size_type pos = npos) const JSONCONS_NOEXCEPT - { - return find_last_of(Basic_string_view_(&ch, 1), pos); - } - size_type find_last_of(const CharT* s, size_type pos, size_type n) const JSONCONS_NOEXCEPT - { - return find_last_of(Basic_string_view_(s, n), pos); - } - size_type find_last_of(const CharT* s, size_type pos = npos) const JSONCONS_NOEXCEPT - { - return find_last_of(Basic_string_view_(s), pos); - } - - size_type find_first_not_of(Basic_string_view_ s, size_type pos = 0) const JSONCONS_NOEXCEPT - { - if (pos >= length_) - return npos; - if (s.length_ == 0) - return pos; - - const_iterator it = cend(); - for (auto p = cbegin()+pos; p != cend(); ++p) - { - if (Traits::find(s.data_, s.length_, *p) == 0) - { - it = p; - break; - } - } - return it == cend() ? npos : std::distance (cbegin(), it); - } - size_type find_first_not_of(CharT ch, size_type pos = 0) const JSONCONS_NOEXCEPT - { - return find_first_not_of(Basic_string_view_(&ch, 1), pos); - } - size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const JSONCONS_NOEXCEPT - { - return find_first_not_of(Basic_string_view_(s, n), pos); - } - size_type find_first_not_of(const CharT* s, size_type pos = 0) const JSONCONS_NOEXCEPT - { - return find_first_not_of(Basic_string_view_(s), pos); - } - - size_type find_last_not_of(Basic_string_view_ s, size_type pos = npos) const JSONCONS_NOEXCEPT - { - if (pos >= length_) - { - pos = length_ - 1; - } - if (s.length_ == 0) - { - return pos; - } - pos = length_ - (pos+1); - - const_iterator it = crend(); - for (auto p = crbegin()+pos; p != crend(); ++p) - { - if (Traits::find(s.data_, s.length_, *p) == 0) - { - it = p; - break; - } - } - return it == crend() ? npos : (length_ - 1 - std::distance(crbegin(), it)); - } - size_type find_last_not_of(CharT ch, size_type pos = npos) const JSONCONS_NOEXCEPT - { - return find_last_not_of(Basic_string_view_(&ch, 1), pos); - } - size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const JSONCONS_NOEXCEPT - { - return find_last_not_of(Basic_string_view_(s, n), pos); - } - size_type find_last_not_of(const CharT* s, size_type pos = npos) const JSONCONS_NOEXCEPT - { - return find_last_not_of(Basic_string_view_(s), pos); - } - - friend std::basic_ostream& operator<<(std::basic_ostream& os, const Basic_string_view_& sv) - { - os.write(sv.data_,sv.length_); - return os; - } -}; - -// == -template -bool operator==(const Basic_string_view_& lhs, - const Basic_string_view_& rhs) -{ - return lhs.compare(rhs) == 0; -} -template -bool operator==(const Basic_string_view_& lhs, - const std::basic_string& rhs) -{ - return lhs.compare(rhs) == 0; -} -template -bool operator==(const std::basic_string& lhs, - const Basic_string_view_& rhs) -{ - return rhs.compare(lhs) == 0; -} -template -bool operator==(const Basic_string_view_& lhs, - const CharT* rhs) -{ - return lhs.compare(rhs) == 0; -} -template -bool operator==(const CharT* lhs, - const Basic_string_view_& rhs) -{ - return rhs.compare(lhs) == 0; -} - -// != -template -bool operator!=(const Basic_string_view_& lhs, - const Basic_string_view_& rhs) -{ - return lhs.compare(rhs) != 0; -} -template -bool operator!=(const Basic_string_view_& lhs, - const std::basic_string& rhs) -{ - return lhs.compare(rhs) != 0; -} -template -bool operator!=(const std::basic_string& lhs, - const Basic_string_view_& rhs) -{ - return rhs.compare(lhs) != 0; -} -template -bool operator!=(const Basic_string_view_& lhs, - const CharT* rhs) -{ - return lhs.compare(rhs) != 0; -} -template -bool operator!=(const CharT* lhs, - const Basic_string_view_& rhs) -{ - return rhs.compare(lhs) != 0; -} - -// <= -template -bool operator<=(const Basic_string_view_& lhs, - const Basic_string_view_& rhs) -{ - return lhs.compare(rhs) <= 0; -} -template -bool operator<=(const Basic_string_view_& lhs, - const std::basic_string& rhs) -{ - return lhs.compare(rhs) <= 0; -} -template -bool operator<=(const std::basic_string& lhs, - const Basic_string_view_& rhs) -{ - return rhs.compare(lhs) >= 0; -} - -// < -template -bool operator<(const Basic_string_view_& lhs, - const Basic_string_view_& rhs) -{ - return lhs.compare(rhs) < 0; -} -template -bool operator<(const Basic_string_view_& lhs, - const std::basic_string& rhs) -{ - return lhs.compare(rhs) < 0; -} -template -bool operator<(const std::basic_string& lhs, - const Basic_string_view_& rhs) -{ - return rhs.compare(lhs) > 0; -} - -// >= -template -bool operator>=(const Basic_string_view_& lhs, - const Basic_string_view_& rhs) -{ - return lhs.compare(rhs) >= 0; -} -template -bool operator>=(const Basic_string_view_& lhs, - const std::basic_string& rhs) -{ - return lhs.compare(rhs) >= 0; -} -template -bool operator>=(const std::basic_string& lhs, - const Basic_string_view_& rhs) -{ - return rhs.compare(lhs) <= 0; -} - -// > -template -bool operator>(const Basic_string_view_& lhs, - const Basic_string_view_& rhs) -{ - return lhs.compare(rhs) > 0; -} -template -bool operator>(const Basic_string_view_& lhs, - const std::basic_string& rhs) -{ - return lhs.compare(rhs) > 0; -} -template -bool operator>(const std::basic_string& lhs, - const Basic_string_view_& rhs) -{ - return rhs.compare(lhs) < 0; -} -#endif - -#if !defined(JSONCONS_HAS_STRING_VIEW) -template > -using basic_string_view_ext = Basic_string_view_; -#else -#include -template > -using basic_string_view_ext = std::basic_string_view; -#endif - -#if !defined(JSONCONS_NO_TO_CHARS) -using chars_format = std::chars_format; -#else -enum class chars_format : uint8_t {fixed=1,scientific=2,hex=4,general=fixed|scientific}; -#endif - -// number_format - -class number_format -{ - chars_format format_; - uint8_t precision_; - uint8_t decimal_places_; -public: - number_format() - : format_(chars_format::general), precision_(0), decimal_places_(0) - { - } - - number_format(uint8_t precision, uint8_t decimal_places) - : format_(chars_format::general), precision_(precision), decimal_places_(decimal_places) - { - } - - number_format(chars_format format, uint8_t precision, uint8_t decimal_places) - : format_(format), precision_(precision), decimal_places_(decimal_places) - { - } - - number_format(chars_format format) - : format_(format), precision_(0), decimal_places_(0) - { - } - - number_format(const number_format&) = default; - number_format(number_format&&) = default; - number_format& operator=(const number_format& e) = default; - number_format& operator=(number_format&& e) = default; - - uint8_t precision() const - { - return precision_; - } - - uint8_t decimal_places() const - { - return decimal_places_; - } - - chars_format floating_point_format() const - { - return format_; - } -}; - -// byte_string_view -class byte_string_view -{ - const uint8_t* data_; - size_t length_; -public: - typedef const uint8_t* const_iterator; - typedef const uint8_t* iterator; - typedef std::size_t size_type; - - byte_string_view(const uint8_t* data, size_t length) - : data_(data), length_(length) - { - } - - const uint8_t* data() const - { - return data_; - } - - size_t length() const - { - return length_; - } - - size_t size() const - { - return length_; - } - - // iterator support - const_iterator begin() const JSONCONS_NOEXCEPT - { - return data_; - } - const_iterator end() const JSONCONS_NOEXCEPT - { - return data_ + length_; - } - - uint8_t operator[](size_type pos) const - { - return data_[pos]; - } - - friend bool operator==(const byte_string_view& lhs, const byte_string_view& rhs) - { - if (lhs.length() != rhs.length()) - { - return false; - } - for (size_t i = 0; i < lhs.length(); ++i) - { - if (lhs[i] != rhs[i]) - { - return false; - } - } - return true; - } - - friend bool operator!=(const byte_string_view& lhs, const byte_string_view& rhs) - { - return !(lhs == rhs); - } - - template - friend std::basic_ostream& operator<<(std::basic_ostream& os, const byte_string_view& o) - { - std::basic_ostringstream ss; - ss.flags(std::ios::hex | std::ios::showbase); - for (auto b : o) - { - ss << (int)b; - } - os << ss.str(); - return os; - } -}; - -// basic_byte_string -template > -class basic_byte_string -{ - std::vector data_; -public: - typedef typename std::vector::const_iterator const_iterator; - typedef typename std::vector::const_iterator iterator; - typedef std::size_t size_type; - - basic_byte_string() = default; - - explicit basic_byte_string(const Allocator& alloc) - : data_(alloc) - { - } - - basic_byte_string(std::initializer_list init) - : data_(std::move(init)) - { - } - - basic_byte_string(std::initializer_list init, const Allocator& alloc) - : data_(std::move(init), alloc) - { - } - - explicit basic_byte_string(const byte_string_view& v) - : data_(v.begin(),v.end()) - { - } - - basic_byte_string(const byte_string_view& v, const Allocator& alloc) - : data_(v.begin(),v.end(),alloc) - { - } - - basic_byte_string(const char* s) - { - while (*s) - { - data_.push_back(*s++); - } - } - - basic_byte_string(const uint8_t* data, size_t length) - { - data_.insert(data,data+length); - } - - basic_byte_string(const basic_byte_string& s) = default; - - basic_byte_string(basic_byte_string&& s) = default; - - basic_byte_string& operator=(const basic_byte_string& s) = default; - - basic_byte_string& operator=(basic_byte_string&& s) = default; - - operator byte_string_view() const JSONCONS_NOEXCEPT - { - return byte_string_view(data(),length()); - } - - void push_back(uint8_t b) - { - data_.push_back(b); - } - - void assign(const uint8_t* s, size_t count) - { - data_.clear(); - data_.insert(s, s+count); - } - - void append(const uint8_t* s, size_t count) - { - data_.insert(s, s+count); - } - - void clear() - { - data_.clear(); - } - - uint8_t operator[](size_type pos) const - { - return data_[pos]; - } - - // iterator support - const_iterator begin() const JSONCONS_NOEXCEPT - { - return data_.begin(); - } - const_iterator end() const JSONCONS_NOEXCEPT - { - return data_.end(); - } - - const uint8_t* data() const - { - return data_.data(); - } - - size_t size() const - { - return data_.size(); - } - - size_t length() const - { - return data_.size(); - } - - friend bool operator==(const basic_byte_string& lhs, const basic_byte_string& rhs) - { - return byte_string_view(lhs) == byte_string_view(rhs); - } - - friend bool operator!=(const basic_byte_string& lhs, const basic_byte_string& rhs) - { - return byte_string_view(lhs) != byte_string_view(rhs); - } - - template - friend std::basic_ostream& operator<<(std::basic_ostream& os, const basic_byte_string& o) - { - os << byte_string_view(o); - return os; - } -}; - -typedef basic_byte_string> byte_string; - -static const std::string base64_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/" - "="; -static const std::string base64url_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789-_" - "\0"; - -inline -static bool is_base64(uint8_t c) -{ - return isalnum(c) || c == '+' || c == '/'; -} - -template -void encode_base64(InputIt first, InputIt last, const std::string& alphabet, std::basic_string& result) -{ - unsigned char a3[3]; - unsigned char a4[4]; - unsigned char fill = alphabet.back(); - int i = 0; - int j = 0; - - while (first != last) - { - a3[i++] = *first++; - if (i == 3) - { - a4[0] = (a3[0] & 0xfc) >> 2; - a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); - a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); - a4[3] = a3[2] & 0x3f; - - for (i = 0; i < 4; i++) - { - result.push_back(alphabet[a4[i]]); - } - i = 0; - } - } - - if (i > 0) - { - for (j = i; j < 3; ++j) - { - a3[j] = 0; - } - - a4[0] = (a3[0] & 0xfc) >> 2; - a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); - a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); - - for (j = 0; j < i + 1; ++j) - { - result.push_back(alphabet[a4[j]]); - } - - if (fill != 0) - { - while (i++ < 3) - { - result.push_back(fill); - } - } - } -} - -template -void encode_base64url(InputIt first, InputIt last, std::basic_string& result) -{ - return encode_base64(first,last,base64url_alphabet,result); -} - -template -void encode_base64(InputIt first, InputIt last, std::basic_string& result) -{ - encode_base64(first,last,base64_alphabet,result); -} - -inline -std::string decode_base64(const std::string& base64_string) -{ - std::string result; - uint8_t a4[4], a3[3]; - uint8_t i = 0; - uint8_t j = 0; - - auto first = base64_string.begin(); - auto last = base64_string.end(); - - while (first != last && *first != '=') - { - JSONCONS_ASSERT(is_base64(*first)); - - a4[i++] = *first++; - if (i == 4) - { - for (i = 0; i < 4; ++i) - { - a4[i] = static_cast(base64_alphabet.find(a4[i])); - } - - a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4); - a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2); - a3[2] = ((a4[2] & 0x3) << 6) + a4[3]; - - for (i = 0; i < 3; i++) - { - result.push_back(a3[i]); - } - i = 0; - } - } - - if (i > 0) - { - for (j = 0; j < i; ++j) - { - a4[j] = static_cast(base64_alphabet.find(a4[j])); - } - - a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4); - a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2); - - for (j = 0; j < i - 1; ++j) - { - result.push_back(a3[j]); - } - } - - return result; -} - -} - -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/parse_error_handler.hpp b/invehicle-apps/3rd-party-libs/jsoncons/parse_error_handler.hpp index cd79e0f..dad619b 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/parse_error_handler.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/parse_error_handler.hpp @@ -7,141 +7,7 @@ #ifndef JSONCONS_PARSE_ERROR_HANDLER_HPP #define JSONCONS_PARSE_ERROR_HANDLER_HPP -#include -#include -#include -#include +#include -namespace jsoncons { - -class parse_error : public std::exception, public virtual json_exception -{ -public: - parse_error() - : line_number_(0), - column_number_(0) - { - } - parse_error(std::error_code ec, - size_t line, - size_t column) - : error_code_(ec), - line_number_(line), - column_number_(column) - { - } - parse_error(const parse_error& other) - : error_code_(other.error_code_), - line_number_(other.line_number_), - column_number_(other.column_number_) - { - } - - const char* what() const JSONCONS_NOEXCEPT override - { - try - { - std::ostringstream os; - os << error_code_.message() << " at line " << line_number_ << " and column " << column_number_; - const_cast(buffer_) = os.str(); - return buffer_.c_str(); - } - catch (...) - { - return ""; - } - } - - const std::error_code code() const - { - return error_code_; - } - - size_t line_number() const - { - return line_number_; - } - - size_t column_number() const - { - return column_number_; - } - - parse_error& operator=(const parse_error& e) - { - error_code_ = e.error_code_; - line_number_ = e.line_number_; - column_number_ = e.column_number_; - return *this; - } -private: - std::error_code error_code_; - std::string buffer_; - size_t line_number_; - size_t column_number_; -}; - -#if !defined(JSONCONS_NO_DEPRECATED) -typedef parse_error json_parse_exception; -typedef parse_error parse_exception; #endif -class parse_error_handler -{ -public: - virtual ~parse_error_handler() - { - } - - bool error(std::error_code ec, - const serializing_context& context) JSONCONS_NOEXCEPT - { - return do_error(ec,context); - } - - void fatal_error(std::error_code ec, - const serializing_context& context) JSONCONS_NOEXCEPT - { - do_fatal_error(ec,context); - } - -private: - virtual bool do_error(std::error_code, - const serializing_context& context) JSONCONS_NOEXCEPT = 0; - - virtual void do_fatal_error(std::error_code, - const serializing_context&) JSONCONS_NOEXCEPT - { - } -}; - -class default_parse_error_handler : public parse_error_handler -{ -private: - bool do_error(std::error_code code, - const serializing_context&) JSONCONS_NOEXCEPT override - { - static const std::error_code illegal_comment = make_error_code(json_parser_errc::illegal_comment); - - if (code == illegal_comment) - { - return false; - } - else - { - return true; - } - } -}; - -class strict_parse_error_handler : public parse_error_handler -{ -private: - bool do_error(std::error_code, const serializing_context&) JSONCONS_NOEXCEPT override - { - return true; - } -}; - -} -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/pretty_print.hpp b/invehicle-apps/3rd-party-libs/jsoncons/pretty_print.hpp new file mode 100644 index 0000000..4ddf20e --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/pretty_print.hpp @@ -0,0 +1,89 @@ +// Copyright 2013 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_PRETTY_PRINT_HPP +#define JSONCONS_PRETTY_PRINT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace jsoncons { + +template +class json_printable +{ +public: + typedef typename Json::char_type char_type; + + json_printable(const Json& j, indenting line_indent) + : j_(&j), indenting_(line_indent) + { + } + + json_printable(const Json& j, + const basic_json_options& options, + indenting line_indent) + : j_(&j), options_(options), indenting_(line_indent) + { + } + + void dump(std::basic_ostream& os) const + { + j_->dump(os, options_, indenting_); + } + + friend std::basic_ostream& operator<<(std::basic_ostream& os, const json_printable& pr) + { + pr.dump(os); + return os; + } + + const Json *j_; + basic_json_options options_; + indenting indenting_; +private: + json_printable(); +}; + +template +json_printable print(const Json& j) +{ + return json_printable(j, indenting::no_indent); +} + +template +json_printable print(const Json& j, + const basic_json_options& options) +{ + return json_printable(j, options, indenting::no_indent); +} + +template +json_printable pretty_print(const Json& j) +{ + return json_printable(j, indenting::indent); +} + +template +json_printable pretty_print(const Json& j, + const basic_json_options& options) +{ + return json_printable(j, options, indenting::indent); +} + +} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/result.hpp b/invehicle-apps/3rd-party-libs/jsoncons/result.hpp new file mode 100644 index 0000000..d53341f --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/result.hpp @@ -0,0 +1,284 @@ +// 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_RESULT_HPP +#define JSONCONS_RESULT_HPP + +#include +#include +#include +#include +#include +#include +#include // std::addressof +#include // std::memcpy +#include +#include + +namespace jsoncons { + +// stream_result + +template +class stream_result +{ +public: + typedef CharT value_type; + typedef std::basic_ostream output_type; + +private: + static const size_t default_buffer_length = 16384; + + std::basic_ostream* os_; + std::vector buffer_; + CharT * begin_buffer_; + const CharT* end_buffer_; + CharT* p_; + + // Noncopyable + stream_result(const stream_result&) = delete; + stream_result& operator=(const stream_result&) = delete; + +public: + stream_result(stream_result&&) = default; + + stream_result(std::basic_ostream& os) + : os_(std::addressof(os)), buffer_(default_buffer_length), begin_buffer_(buffer_.data()), end_buffer_(begin_buffer_+buffer_.size()), p_(begin_buffer_) + { + } + stream_result(std::basic_ostream& os, size_t buflen) + : os_(std::addressof(os)), buffer_(buflen), begin_buffer_(buffer_.data()), end_buffer_(begin_buffer_+buffer_.size()), p_(begin_buffer_) + { + } + ~stream_result() + { + os_->write(begin_buffer_, buffer_length()); + os_->flush(); + } + + stream_result& operator=(stream_result&&) = default; + + void flush() + { + os_->write(begin_buffer_, buffer_length()); + os_->flush(); + p_ = buffer_.data(); + } + + void append(const CharT* s, size_t length) + { + size_t diff = end_buffer_ - p_; + if (diff >= length) + { + std::memcpy(p_, s, length*sizeof(CharT)); + p_ += length; + } + else + { + os_->write(begin_buffer_, buffer_length()); + os_->write(s,length); + p_ = begin_buffer_; + } + } + + void push_back(CharT ch) + { + if (p_ < end_buffer_) + { + *p_++ = ch; + } + else + { + os_->write(begin_buffer_, buffer_length()); + p_ = begin_buffer_; + push_back(ch); + } + } +private: + + size_t buffer_length() const + { + return p_ - begin_buffer_; + } +}; + +// binary_stream_result + +class binary_stream_result +{ +public: + typedef uint8_t value_type; + typedef std::basic_ostream output_type; +private: + static const size_t default_buffer_length = 16384; + + std::basic_ostream* os_; + std::vector buffer_; + uint8_t * begin_buffer_; + const uint8_t* end_buffer_; + uint8_t* p_; + + // Noncopyable + binary_stream_result(const binary_stream_result&) = delete; + binary_stream_result& operator=(const binary_stream_result&) = delete; + +public: + binary_stream_result(binary_stream_result&&) = default; + + binary_stream_result(std::basic_ostream& os) + : os_(std::addressof(os)), + buffer_(default_buffer_length), + begin_buffer_(buffer_.data()), + end_buffer_(begin_buffer_+buffer_.size()), + p_(begin_buffer_) + { + } + binary_stream_result(std::basic_ostream& os, size_t buflen) + : os_(std::addressof(os)), + buffer_(buflen), + begin_buffer_(buffer_.data()), + end_buffer_(begin_buffer_+buffer_.size()), + p_(begin_buffer_) + { + } + ~binary_stream_result() + { + os_->write((char*)begin_buffer_, buffer_length()); + os_->flush(); + } + + binary_stream_result& operator=(binary_stream_result&&) = default; + + void flush() + { + os_->write((char*)begin_buffer_, buffer_length()); + p_ = buffer_.data(); + } + + void append(const uint8_t* s, size_t length) + { + size_t diff = end_buffer_ - p_; + if (diff >= length) + { + std::memcpy(p_, s, length*sizeof(uint8_t)); + p_ += length; + } + else + { + os_->write((char*)begin_buffer_, buffer_length()); + os_->write((const char*)s,length); + p_ = begin_buffer_; + } + } + + void push_back(uint8_t ch) + { + if (p_ < end_buffer_) + { + *p_++ = ch; + } + else + { + os_->write((char*)begin_buffer_, buffer_length()); + p_ = begin_buffer_; + push_back(ch); + } + } +private: + + size_t buffer_length() const + { + return p_ - begin_buffer_; + } +}; + +// string_result + +template +class string_result +{ +public: + typedef typename StringT::value_type value_type; + typedef StringT output_type; +private: + output_type* s_; + + // Noncopyable + string_result(const string_result&) = delete; + string_result& operator=(const string_result&) = delete; +public: + string_result(string_result&& val) + : s_(nullptr) + { + std::swap(s_,val.s_); + } + + string_result(output_type& s) + : s_(std::addressof(s)) + { + } + + string_result& operator=(string_result&& val) + { + std::swap(s_, val.s_); + } + + void flush() + { + } + + void append(const value_type* s, size_t length) + { + s_->insert(s_->end(), s, s+length); + } + + void push_back(value_type ch) + { + s_->push_back(ch); + } +}; + +// bytes_result + +class bytes_result +{ +public: + typedef uint8_t value_type; + typedef std::vector output_type; +private: + output_type& s_; + + // Noncopyable + bytes_result(const bytes_result&) = delete; + bytes_result& operator=(const bytes_result&) = delete; +public: + bytes_result(bytes_result&&) = default; + + bytes_result(output_type& s) + : s_(s) + { + } + + bytes_result& operator=(bytes_result&&) = default; + + void flush() + { + } + + void append(const uint8_t* s, size_t length) + { + s_.insert(s_.end(), s, s+length); + } + + void push_back(uint8_t ch) + { + s_.push_back(ch); + } +}; + +} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/ser_context.hpp b/invehicle-apps/3rd-party-libs/jsoncons/ser_context.hpp new file mode 100644 index 0000000..2032f31 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/ser_context.hpp @@ -0,0 +1,52 @@ +/// Copyright 2013-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_SER_CONTEXT_HPP +#define JSONCONS_SER_CONTEXT_HPP + +namespace jsoncons { + +class ser_context +{ +public: + virtual ~ser_context() = default; + + virtual size_t line() const = 0; + + virtual size_t column() const = 0; + +#if !defined(JSONCONS_NO_DEPRECATED) + JSONCONS_DEPRECATED("Instead, use line()") + size_t line_number() const + { + return line(); + } + + JSONCONS_DEPRECATED("Instead, use column()") + size_t column_number() const + { + return column(); + } +#endif +}; + +class null_ser_context : public ser_context +{ +private: + size_t line() const override { return 0; } + + size_t column() const override { return 0; } +}; + +#if !defined(JSONCONS_NO_DEPRECATED) +JSONCONS_DEPRECATED("Instead, use ser_context") typedef ser_context parsing_context; +JSONCONS_DEPRECATED("Instead, use ser_context") typedef ser_context serializing_context; +JSONCONS_DEPRECATED("Instead, use null_ser_context") typedef null_ser_context null_parsing_context; +JSONCONS_DEPRECATED("Instead, use null_ser_context") typedef null_ser_context null_serializing_context; +#endif + +} +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/serialization_traits.hpp b/invehicle-apps/3rd-party-libs/jsoncons/serialization_traits.hpp deleted file mode 100644 index 1c2159f..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/serialization_traits.hpp +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright 2017 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_SERIALIZATION_TRAITS_HPP -#define JSONCONS_SERIALIZATION_TRAITS_HPP - -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wswitch" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace jsoncons { - -// serialization_traits - -template -struct serialization_traits -{ - template - static void encode(const T&, basic_json_content_handler&) - { - } -}; - -// dump - -template -void dump(const T& val, basic_json_content_handler& handler) -{ - handler.begin_json(); - serialization_traits::encode(val,handler); - handler.end_json(); -} - -#if !defined(JSONCONS_NO_DEPRECATED) -template -void dump_body(const T& val, basic_json_content_handler& handler) -{ - dump_fragment(val,handler); -} -#endif - -template -void dump_fragment(const T& val, basic_json_content_handler& handler) -{ - serialization_traits::encode(val,handler); -} - -template -void dump(const T& val, std::basic_ostream& os) -{ - basic_json_serializer serializer(os); - dump(val, serializer); -} - -template -void dump(const T& val, const basic_json_serializing_options& options, - std::basic_ostream& os) -{ - basic_json_serializer serializer(os, options); - dump(val, serializer); -} - -template -void dump(const T& val, std::basic_ostream& os, bool pprint) -{ - basic_json_serializer serializer(os, pprint); - dump(val, serializer); -} - -template -void dump(const T& val, const basic_json_serializing_options& options, - std::basic_ostream& os, bool pprint) -{ - basic_json_serializer serializer(os, options, pprint); - dump(val, serializer); -} - -// integer - -template -struct serialization_traits::value ->::type> -{ - template - static void encode(T val, basic_json_content_handler& handler) - { - handler.integer_value(val); - } -}; - -// uinteger - -template -struct serialization_traits::value ->::type> -{ - template - static void encode(T val, basic_json_content_handler& handler) - { - handler.uinteger_value(val); - } -}; - -// double - -template -struct serialization_traits::value ->::type> -{ - template - static void encode(T val, basic_json_content_handler& handler) - { - handler.double_value(val); - } -}; - -// bool - -template<> -struct serialization_traits -{ - template - static void encode(bool val, basic_json_content_handler& handler) - { - handler.bool_value(val); - } -}; - -// string - -template -struct serialization_traits::value ->::type> -{ - template - static void encode(const T& val, basic_json_content_handler& handler) - { - handler.string_value(val); - } -}; - -/*template<> -struct serialization_traits::const_pointer_type> -{ - template - static void encode(typename type_wrapper::const_pointer_type val, basic_json_content_handler& handler) - { - handler.string_value(val); - } -};*/ - -// sequence container (except string and array) - -template -struct serialization_traits::value ->::type> -{ - typedef typename std::iterator_traits::value_type value_type; - - template - static void encode(const T& val, basic_json_content_handler& handler) - { - handler.begin_array(); - for (auto it = std::begin(val); it != std::end(val); ++it) - { - serialization_traits::encode(*it,handler); - } - handler.end_array(); - } -}; - -// std::array - -template -struct serialization_traits> -{ - typedef typename std::array::value_type value_type; -public: - - template - static void encode(const std::array& val, basic_json_content_handler& handler) - { - handler.begin_array(); - for (auto it = std::begin(val); it != std::end(val); ++it) - { - serialization_traits::encode(*it,handler); - } - handler.end_array(); - } -}; - -// associative container - -template -struct serialization_traits::value ->::type> -{ - typedef typename T::mapped_type mapped_type; - typedef typename T::value_type value_type; - - template - static void encode(const T& val, basic_json_content_handler& handler) - { - handler.begin_object(); - for (auto it = std::begin(val); it != std::end(val); ++it) - { - handler.name(it->first); - serialization_traits::encode(it->second,handler); - } - handler.end_object(); - } -}; - -namespace detail { namespace streaming { - -template -struct tuple_helper -{ - using element_type = typename std::tuple_element::value - Pos, Tuple>::type; - using next = tuple_helper; - - template - static void encode(const Tuple& tuple, basic_json_content_handler& handler) - { - serialization_traits::encode(std::get::value - Pos>(tuple),handler); - next::encode(tuple, handler); - } -}; - -template -struct tuple_helper<0, Tuple> -{ - template - static void encode(const Tuple&, basic_json_content_handler&) - { - } -}; - -}} - -template -struct serialization_traits> -{ -private: - using helper = detail::streaming::tuple_helper>; - -public: - template - static void encode(const std::tuple& value, basic_json_content_handler& handler) - { - handler.begin_array(); - helper::encode(value, handler); - handler.end_array(); - } -}; - -template -struct serialization_traits> -{ -public: - - template - static void encode(const std::pair& value, basic_json_content_handler& handler) - { - handler.begin_array(); - serialization_traits::encode(value.first, handler); - serialization_traits::encode(value.second, handler); - handler.end_array(); - } -}; - -#if !defined(JSONCONS_NO_DEPRECATED) -template -struct serialization_traits> -{ -public: - - template - static void encode(std::shared_ptr p, basic_json_content_handler& handler) - { - serialization_traits::encode(*p, handler); - } -}; -#endif - -} - -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - -#endif - - diff --git a/invehicle-apps/3rd-party-libs/jsoncons/serializing_context.hpp b/invehicle-apps/3rd-party-libs/jsoncons/serializing_context.hpp deleted file mode 100644 index 77af770..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/serializing_context.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/// Copyright 2013-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_SERIALIZING_CONTEXT_HPP -#define JSONCONS_SERIALIZING_CONTEXT_HPP - -namespace jsoncons { - -class serializing_context -{ -public: - virtual ~serializing_context() = default; - - size_t line_number() const - { - return do_line_number(); - } - size_t column_number() const - { - return do_column_number(); - } - -private: - virtual size_t do_line_number() const = 0; - virtual size_t do_column_number() const = 0; -}; - -class null_serializing_context : public serializing_context -{ -private: - size_t do_line_number() const override { return 0; } - - size_t do_column_number() const override { return 0; } -}; - -#if !defined(JSONCONS_NO_DEPRECATED) -typedef serializing_context serializing_context; -#endif - -} -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/source.hpp b/invehicle-apps/3rd-party-libs/jsoncons/source.hpp new file mode 100644 index 0000000..f1feec5 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/source.hpp @@ -0,0 +1,746 @@ +// 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_SOURCE_HPP +#define JSONCONS_SOURCE_HPP + +#include +#include +#include +#include +#include // std::addressof +#include // std::memcpy +#include +#include // std::enable_if +#include +#include // jsoncons::byte_traits + +namespace jsoncons { + +template +class basic_null_istream : public std::basic_istream +{ + class null_buffer : public std::basic_streambuf + { + public: + using typename std::basic_streambuf::int_type; + using typename std::basic_streambuf::traits_type; + + null_buffer() = default; + null_buffer(const null_buffer&) = default; + null_buffer& operator=(const null_buffer&) = default; + + int_type overflow( int_type ch = traits_type::eof() ) override + { + return ch; + } + } nb_; +public: + basic_null_istream() + : std::basic_istream(&nb_) + { + } + basic_null_istream(basic_null_istream&&) = default; + + basic_null_istream& operator=(basic_null_istream&&) = default; +}; + +// text sources + +template +class stream_source +{ +public: + typedef CharT value_type; + typedef std::char_traits traits_type; +private: + basic_null_istream null_is_; + std::basic_istream* is_; + std::basic_streambuf* sbuf_; + size_t position_; + + // Noncopyable + stream_source(const stream_source&) = delete; + stream_source& operator=(const stream_source&) = delete; +public: + stream_source() + : is_(&null_is_), sbuf_(null_is_.rdbuf()), position_(0) + { + } + + stream_source(std::basic_istream& is) + : is_(std::addressof(is)), sbuf_(is.rdbuf()), position_(0) + { + } + + stream_source(stream_source&& other) + { + std::swap(is_,other.is_); + std::swap(sbuf_,other.sbuf_); + std::swap(position_,other.position_); + } + + ~stream_source() + { + } + + stream_source& operator=(stream_source&& other) + { + std::swap(is_,other.is_); + std::swap(sbuf_,other.sbuf_); + std::swap(position_,other.position_); + return *this; + } + + bool eof() const + { + return is_->eof(); + } + + bool is_error() const + { + return is_->bad(); + } + + size_t position() const + { + return position_; + } + + size_t get(value_type& c) + { + try + { + int val = sbuf_->sbumpc(); + if (!(val == traits_type::eof())) + { + c = (value_type)val; + ++position_; + return 1; + } + else + { + is_->clear(is_->rdstate() | std::ios::eofbit); + return 0; + } + } + catch (const std::exception&) + { + is_->clear(is_->rdstate() | std::ios::badbit | std::ios::eofbit); + return 0; + } + } + + int get() + { + try + { + int c = sbuf_->sbumpc(); + if (c == traits_type::eof()) + { + is_->clear(is_->rdstate() | std::ios::eofbit); + } + else + { + ++position_; + } + return c; + } + catch (const std::exception&) + { + is_->clear(is_->rdstate() | std::ios::badbit | std::ios::eofbit); + return traits_type::eof(); + } + } + + void ignore(size_t count) + { + try + { + for (size_t i = 0; i < count; ++i) + { + int c = sbuf_->sbumpc(); + if (c == traits_type::eof()) + { + is_->clear(is_->rdstate() | std::ios::eofbit); + return; + } + else + { + ++position_; + } + } + } + catch (const std::exception&) + { + is_->clear(is_->rdstate() | std::ios::badbit | std::ios::eofbit); + } + } + + int peek() + { + try + { + int c = sbuf_->sgetc(); + if (c == traits_type::eof()) + { + is_->clear(is_->rdstate() | std::ios::eofbit); + } + return c; + } + catch (const std::exception&) + { + is_->clear(is_->rdstate() | std::ios::badbit); + return traits_type::eof(); + } + } + + size_t read(value_type* p, size_t length) + { + try + { + std::streamsize count = sbuf_->sgetn(p, length); // never negative + if (static_cast(count) < length) + { + is_->clear(is_->rdstate() | std::ios::eofbit); + } + position_ += length; + return static_cast(count); + } + catch (const std::exception&) + { + is_->clear(is_->rdstate() | std::ios::badbit | std::ios::eofbit); + return 0; + } + } + + template + typename std::enable_if::value,size_t>::type + read(OutputIt p, size_t length) + { + size_t count = 0; + try + { + for (count = 0; count < length; ++count) + { + int c = sbuf_->sbumpc(); + if (c == traits_type::eof()) + { + is_->clear(is_->rdstate() | std::ios::eofbit); + return count; + } + else + { + ++position_; + } + *p++ = (value_type)c; + } + return count; + } + catch (const std::exception&) + { + is_->clear(is_->rdstate() | std::ios::badbit | std::ios::eofbit); + return count; + } + } +}; + +// string_source + +template +struct is_string_sourceable : std::false_type {}; + +template +struct is_string_sourceable::value>::type> : std::true_type {}; + +template +class string_source +{ +public: + typedef CharT value_type; + typedef std::char_traits traits_type; + typedef jsoncons::basic_string_view string_view_type; +private: + const value_type* data_; + const value_type* input_ptr_; + const value_type* input_end_; + bool eof_; + + // Noncopyable + string_source(const string_source&) = delete; + string_source& operator=(const string_source&) = delete; +public: + string_source() + : data_(nullptr), input_ptr_(nullptr), input_end_(nullptr), eof_(true) + { + } + + template + string_source(const Source& s, + typename std::enable_if::type>::value>::type* = 0) + : data_(s.data()), input_ptr_(s.data()), input_end_(s.data()+s.size()), eof_(s.size() == 0) + { + } + + string_source(const value_type* data, size_t size) + : data_(data), input_ptr_(data), input_end_(data+size), eof_(size == 0) + { + } + + string_source(string_source&& val) + : data_(nullptr), input_ptr_(nullptr), input_end_(nullptr), eof_(true) + { + std::swap(data_,val.data_); + std::swap(input_ptr_,val.input_ptr_); + std::swap(input_end_,val.input_end_); + std::swap(eof_,val.eof_); + } + + string_source& operator=(string_source&& val) + { + std::swap(data_,val.data_); + std::swap(input_ptr_,val.input_ptr_); + std::swap(input_end_,val.input_end_); + std::swap(eof_,val.eof_); + return *this; + } + + bool eof() const + { + return eof_; + } + + bool is_error() const + { + return false; + } + + size_t position() const + { + return (input_ptr_ - data_)/sizeof(value_type) + 1; + } + + size_t get(value_type& c) + { + if (input_ptr_ < input_end_) + { + c = *input_ptr_++; + return 1; + } + else + { + eof_ = true; + input_ptr_ = input_end_; + return 0; + } + } + + int get() + { + if (input_ptr_ < input_end_) + { + return *input_ptr_++; + } + else + { + eof_ = true; + input_ptr_ = input_end_; + return traits_type::eof(); + } + } + + void ignore(size_t count) + { + size_t len; + if ((size_t)(input_end_ - input_ptr_) < count) + { + len = input_end_ - input_ptr_; + eof_ = true; + } + else + { + len = count; + } + input_ptr_ += len; + } + + int peek() + { + return input_ptr_ < input_end_ ? *input_ptr_ : traits_type::eof(); + } + + size_t read(value_type* p, size_t length) + { + size_t len; + if ((size_t)(input_end_ - input_ptr_) < length) + { + len = input_end_ - input_ptr_; + eof_ = true; + } + else + { + len = length; + } + std::memcpy(p, input_ptr_, len*sizeof(value_type)); + input_ptr_ += len; + return len; + } + + template + typename std::enable_if::value,size_t>::type + read(OutputIt d_first, size_t count) + { + size_t len; + if ((size_t)(input_end_ - input_ptr_) < count) + { + len = input_end_ - input_ptr_; + eof_ = true; + } + else + { + len = count; + } + for (size_t i = 0; i < len; ++i) + { + *d_first++ = *input_ptr_++; + } + return len; + } +}; + +// binary sources + +class binary_stream_source +{ +public: + typedef uint8_t value_type; + typedef byte_traits traits_type; +private: + basic_null_istream null_is_; + std::istream* is_; + std::streambuf* sbuf_; + size_t position_; + + // Noncopyable + binary_stream_source(const binary_stream_source&) = delete; + binary_stream_source& operator=(const binary_stream_source&) = delete; +public: + binary_stream_source() + : is_(&null_is_), sbuf_(null_is_.rdbuf()), position_(0) + { + } + + binary_stream_source(std::istream& is) + : is_(std::addressof(is)), sbuf_(is.rdbuf()), position_(0) + { + } + + binary_stream_source(binary_stream_source&& other) + { + std::swap(is_,other.is_); + std::swap(sbuf_,other.sbuf_); + std::swap(position_,other.position_); + } + + ~binary_stream_source() + { + } + + binary_stream_source& operator=(binary_stream_source&& other) + { + std::swap(is_,other.is_); + std::swap(sbuf_,other.sbuf_); + std::swap(position_,other.position_); + return *this; + } + + bool eof() const + { + return is_->eof(); + } + + bool is_error() const + { + return is_->bad(); + } + + size_t position() const + { + return position_; + } + + size_t get(value_type& c) + { + try + { + int val = sbuf_->sbumpc(); + if (!(val == traits_type::eof())) + { + c = (value_type)val; + ++position_; + return 1; + } + else + { + is_->clear(is_->rdstate() | std::ios::eofbit); + return 0; + } + } + catch (const std::exception&) + { + is_->clear(is_->rdstate() | std::ios::badbit | std::ios::eofbit); + return 0; + } + } + + int get() + { + try + { + int c = sbuf_->sbumpc(); + if (c == traits_type::eof()) + { + is_->clear(is_->rdstate() | std::ios::eofbit); + } + else + { + ++position_; + } + return c; + } + catch (const std::exception&) + { + is_->clear(is_->rdstate() | std::ios::badbit | std::ios::eofbit); + return traits_type::eof(); + } + } + + void ignore(size_t count) + { + try + { + for (size_t i = 0; i < count; ++i) + { + int c = sbuf_->sbumpc(); + if (c == traits_type::eof()) + { + is_->clear(is_->rdstate() | std::ios::eofbit); + return; + } + else + { + ++position_; + } + } + } + catch (const std::exception&) + { + is_->clear(is_->rdstate() | std::ios::badbit | std::ios::eofbit); + } + } + + int peek() + { + try + { + int c = sbuf_->sgetc(); + if (c == traits_type::eof()) + { + is_->clear(is_->rdstate() | std::ios::eofbit); + } + return c; + } + catch (const std::exception&) + { + is_->clear(is_->rdstate() | std::ios::badbit); + return traits_type::eof(); + } + } + + template + size_t read(OutputIt p, size_t length) + { + size_t count = 0; + try + { + for (count = 0; count < length; ++count) + { + int c = sbuf_->sbumpc(); + if (c == traits_type::eof()) + { + is_->clear(is_->rdstate() | std::ios::eofbit); + return count; + } + else + { + ++position_; + } + *p++ = (value_type)c; + } + return count; + } + catch (const std::exception&) + { + is_->clear(is_->rdstate() | std::ios::badbit | std::ios::eofbit); + return count; + } + } +}; + +template +struct is_bytes_sourceable : std::false_type {}; + +template +struct is_bytes_sourceable::value>::type> : std::true_type {}; + +class bytes_source +{ +public: + typedef uint8_t value_type; + typedef byte_traits traits_type; +private: + const value_type* data_; + const value_type* input_ptr_; + const value_type* input_end_; + bool eof_; + + // Noncopyable + bytes_source(const bytes_source&) = delete; + bytes_source& operator=(const bytes_source&) = delete; +public: + bytes_source() + : data_(nullptr), input_ptr_(nullptr), input_end_(nullptr), eof_(true) + { + } + + template + bytes_source(const Source& s, + typename std::enable_if::type>::value>::type* = 0) + : data_(s.data()), + input_ptr_(s.data()), + input_end_(s.data()+s.size()), + eof_(s.size() == 0) + { + } + + bytes_source(const value_type* data, size_t size) + : data_(data), + input_ptr_(data), + input_end_(data+size), + eof_(size == 0) + { + } + + bytes_source(bytes_source&&) = default; + + bytes_source& operator=(bytes_source&&) = default; + + bool eof() const + { + return eof_; + } + + bool is_error() const + { + return false; + } + + size_t position() const + { + return input_ptr_ - data_ + 1; + } + + size_t get(value_type& c) + { + if (input_ptr_ < input_end_) + { + c = *input_ptr_++; + return 1; + } + else + { + eof_ = true; + input_ptr_ = input_end_; + return 0; + } + } + + int get() + { + if (input_ptr_ < input_end_) + { + return *input_ptr_++; + } + else + { + eof_ = true; + input_ptr_ = input_end_; + return traits_type::eof(); + } + } + + void ignore(size_t count) + { + size_t len; + if ((size_t)(input_end_ - input_ptr_) < count) + { + len = input_end_ - input_ptr_; + eof_ = true; + } + else + { + len = count; + } + input_ptr_ += len; + } + + int peek() + { + return input_ptr_ < input_end_ ? *input_ptr_ : traits_type::eof(); + } + + size_t read(value_type* p, size_t length) + { + size_t len; + if ((size_t)(input_end_ - input_ptr_) < length) + { + len = input_end_ - input_ptr_; + eof_ = true; + } + else + { + len = length; + } + std::memcpy(p, input_ptr_, len); + input_ptr_ += len; + return len; + } + + template + typename std::enable_if::value,size_t>::type + read(OutputIt d_first, size_t count) + { + size_t len; + if ((size_t)(input_end_ - input_ptr_) < count) + { + len = input_end_ - input_ptr_; + eof_ = true; + } + else + { + len = count; + } + for (size_t i = 0; i < len; ++i) + { + *d_first++ = *input_ptr_++; + } + return len; + } +}; + +} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/staj_iterator.hpp b/invehicle-apps/3rd-party-libs/jsoncons/staj_iterator.hpp new file mode 100644 index 0000000..0920d22 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/staj_iterator.hpp @@ -0,0 +1,482 @@ +// 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_STAJ_ITERATOR_HPP +#define JSONCONS_STAJ_ITERATOR_HPP + +#include // placement new +#include +#include +#include +#include +#include +#include // std::input_iterator_tag +#include +#include + +namespace jsoncons { + +template> +class basic_staj_array_iterator +{ + typedef CharT char_type; + + basic_staj_reader* reader_; + unsigned char memory_[sizeof(T)]; + T* valuep_; +public: + typedef T value_type; + typedef std::ptrdiff_t difference_type; + typedef T* pointer; + typedef T& reference; + typedef std::input_iterator_tag iterator_category; + + basic_staj_array_iterator() noexcept + : reader_(nullptr), valuep_(nullptr) + { + } + + basic_staj_array_iterator(basic_staj_reader& reader) + : reader_(std::addressof(reader)), valuep_(nullptr) + { + if (reader_->current().event_type() == staj_event_type::begin_array) + { + next(); + } + else + { + reader_ = nullptr; + } + } + + basic_staj_array_iterator(basic_staj_reader& reader, + std::error_code& ec) + : reader_(std::addressof(reader)), valuep_(nullptr) + { + if (reader_->current().event_type() == staj_event_type::begin_array) + { + next(ec); + if (ec) + { + reader_ = nullptr; + } + } + else + { + reader_ = nullptr; + } + } + + basic_staj_array_iterator(const basic_staj_array_iterator& other) + : reader_(other.reader_), valuep_(nullptr) + { + if (other.valuep_) + { + valuep_ = ::new(memory_)T(*other.valuep_); + } + } + + basic_staj_array_iterator(basic_staj_array_iterator&& other) + : reader_(other.reader_), valuep_(nullptr) + { + if (other.valuep_) + { + valuep_ = ::new(memory_)T(std::move(*other.valuep_)); + } + } + + ~basic_staj_array_iterator() + { + if (valuep_) + { + valuep_->~T(); + } + } + + basic_staj_array_iterator& operator=(const basic_staj_array_iterator& other) + { + reader_ = other.reader_; + if (other.valuep_) + { + valuep_ = ::new(memory_)T(*other.valuep_); + } + else + { + valuep_ = nullptr; + } + return *this; + } + + basic_staj_array_iterator& operator=(basic_staj_array_iterator&& other) + { + reader_ = other.reader_; + if (other.valuep_) + { + valuep_ = ::new(memory_)T(std::move(*other.valuep_)); + } + else + { + valuep_ = nullptr; + } + return *this; + } + + const T& operator*() const + { + return *valuep_; + } + + const T* operator->() const + { + return valuep_; + } + + basic_staj_array_iterator& operator++() + { + next(); + return *this; + } + + basic_staj_array_iterator& increment(std::error_code& ec) + { + next(ec); + if (ec) + { + reader_ = nullptr; + } + return *this; + } + + basic_staj_array_iterator operator++(int) // postfix increment + { + basic_staj_array_iterator temp(*this); + next(); + return temp; + } + + friend bool operator==(const basic_staj_array_iterator& a, const basic_staj_array_iterator& b) + { + return (!a.reader_ && !b.reader_) + || (!a.reader_ && b.done()) + || (!b.reader_ && a.done()); + } + + friend bool operator!=(const basic_staj_array_iterator& a, const basic_staj_array_iterator& b) + { + return !(a == b); + } + +private: + + bool done() const + { + return reader_->done() || reader_->current().event_type() == staj_event_type::end_array; + } + + void next(); + + void next(std::error_code& ec); +}; + +template +basic_staj_array_iterator begin(basic_staj_array_iterator iter) noexcept +{ + return iter; +} + +template +basic_staj_array_iterator end(const basic_staj_array_iterator&) noexcept +{ + return basic_staj_array_iterator(); +} + +template +class basic_staj_object_iterator +{ +public: + typedef CharT char_type; + typedef std::basic_string key_type; + typedef std::pair value_type; + typedef std::ptrdiff_t difference_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::input_iterator_tag iterator_category; + +private: + unsigned char memory_[sizeof(value_type)]; + basic_staj_reader* reader_; + value_type* kvp_; +public: + + basic_staj_object_iterator() noexcept + : reader_(nullptr), kvp_(nullptr) + { + } + + basic_staj_object_iterator(basic_staj_reader& reader) + : reader_(std::addressof(reader)), kvp_(nullptr) + { + if (reader_->current().event_type() == staj_event_type::begin_object) + { + next(); + } + else + { + reader_ = nullptr; + } + } + + basic_staj_object_iterator(basic_staj_reader& reader, + std::error_code& ec) + : reader_(std::addressof(reader)), kvp_(nullptr) + { + if (reader_->current().event_type() == staj_event_type::begin_object) + { + next(ec); + if (ec) + { + reader_ = nullptr; + } + } + else + { + reader_ = nullptr; + } + } + + basic_staj_object_iterator(const basic_staj_object_iterator& other) + : reader_(other.reader_), kvp_(nullptr) + { + if (other.kvp_) + { + kvp_ = ::new(memory_)value_type(*other.kvp_); + } + } + + basic_staj_object_iterator(basic_staj_object_iterator&& other) + : reader_(other.reader_), kvp_(nullptr) + { + if (other.kvp_) + { + kvp_ = ::new(memory_)value_type(std::move(*other.kvp_)); + } + } + + ~basic_staj_object_iterator() + { + if (kvp_) + { + kvp_->~value_type(); + } + } + + basic_staj_object_iterator& operator=(const basic_staj_object_iterator& other) + { + reader_ = other.reader_; + if (other.kvp_) + { + kvp_ = ::new(memory_)value_type(*other.kvp_); + } + else + { + kvp_ = nullptr; + } + return *this; + } + + basic_staj_object_iterator& operator=(basic_staj_object_iterator&& other) + { + reader_ = other.reader_; + if (other.kvp_) + { + kvp_ = ::new(memory_)value_type(std::move(*other.kvp_)); + } + else + { + kvp_ = nullptr; + } + return *this; + } + + const value_type& operator*() const + { + return *kvp_; + } + + const value_type* operator->() const + { + return kvp_; + } + + basic_staj_object_iterator& operator++() + { + next(); + return *this; + } + + basic_staj_object_iterator& increment(std::error_code& ec) + { + next(ec); + if (ec) + { + reader_ = nullptr; + } + return *this; + } + + basic_staj_object_iterator operator++(int) // postfix increment + { + basic_staj_object_iterator temp(*this); + next(); + return temp; + } + + friend bool operator==(const basic_staj_object_iterator& a, const basic_staj_object_iterator& b) + { + return (!a.reader_ && !b.reader_) + || (!a.reader_ && b.done()) + || (!b.reader_ && a.done()); + } + + friend bool operator!=(const basic_staj_object_iterator& a, const basic_staj_object_iterator& b) + { + return !(a == b); + } + +private: + + bool done() const + { + return reader_->done() || reader_->current().event_type() == staj_event_type::end_object; + } + + + void next(); + + void next(std::error_code& ec); + +}; + +template +basic_staj_object_iterator begin(basic_staj_object_iterator iter) noexcept +{ + return iter; +} + +template +basic_staj_object_iterator end(const basic_staj_object_iterator&) noexcept +{ + return basic_staj_object_iterator(); +} + +template +using staj_array_iterator = basic_staj_array_iterator; + +template +using wstaj_array_iterator = basic_staj_array_iterator; + +template +using staj_object_iterator = basic_staj_object_iterator; + +template +using wstaj_object_iterator = basic_staj_object_iterator; + +} + +#include + +namespace jsoncons { + +template +void basic_staj_array_iterator::next() +{ + if (!done()) + { + reader_->next(); + if (!done()) + { + if (valuep_) + { + valuep_->~T(); + } + valuep_ = ::new(memory_)T(read_from(Json(), *reader_)); + } + } +} + +template +void basic_staj_array_iterator::next(std::error_code& ec) +{ + if (!done()) + { + reader_->next(ec); + if (ec) + { + return; + } + if (!done()) + { + if (valuep_) + { + valuep_->~T(); + } + valuep_ = ::new(memory_)T(read_from(Json(), *reader_, ec)); + } + } +} + +template +void basic_staj_object_iterator::next() +{ + reader_->next(); + if (!done()) + { + JSONCONS_ASSERT(reader_->current().event_type() == staj_event_type::name); + key_type key = reader_->current(). template get(); + reader_->next(); + if (!done()) + { + if (kvp_) + { + kvp_->~value_type(); + } + kvp_ = ::new(memory_)value_type(std::move(key),read_from(Json(), *reader_)); + } + } +} + +template +void basic_staj_object_iterator::next(std::error_code& ec) +{ + reader_->next(ec); + if (ec) + { + return; + } + if (!done()) + { + JSONCONS_ASSERT(reader_->current().event_type() == staj_event_type::name); + auto key = reader_->current(). template get(); + reader_->next(ec); + if (ec) + { + return; + } + if (!done()) + { + if (kvp_) + { + kvp_->~value_type(); + } + kvp_ = ::new(memory_)value_type(std::move(key),read_from(Json(), *reader_, ec)); + } + } +} + +} + +#endif + diff --git a/invehicle-apps/3rd-party-libs/jsoncons/staj_reader.hpp b/invehicle-apps/3rd-party-libs/jsoncons/staj_reader.hpp new file mode 100644 index 0000000..504e062 --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons/staj_reader.hpp @@ -0,0 +1,665 @@ +// 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_STAJ_READER_HPP +#define JSONCONS_STAJ_READER_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 + +namespace jsoncons { + +enum class staj_event_type +{ + begin_array, + end_array, + begin_object, + end_object, + name, + string_value, + byte_string_value, + null_value, + bool_value, + int64_value, + uint64_value, + double_value +}; + +inline +std::ostream& operator<<(std::ostream& os, staj_event_type tag) +{ + switch (tag) + { + case staj_event_type::begin_array: + { + os << "begin_array"; + break; + } + case staj_event_type::end_array: + { + os << "end_array"; + break; + } + case staj_event_type::begin_object: + { + os << "begin_object"; + break; + } + case staj_event_type::end_object: + { + os << "end_object"; + break; + } + case staj_event_type::name: + { + os << "name"; + break; + } + case staj_event_type::string_value: + { + os << "string_value"; + break; + } + case staj_event_type::byte_string_value: + { + os << "byte_string_value"; + break; + } + case staj_event_type::null_value: + { + os << "null_value"; + break; + } + case staj_event_type::bool_value: + { + os << "bool_value"; + break; + } + case staj_event_type::int64_value: + { + os << "int64_value"; + break; + } + case staj_event_type::uint64_value: + { + os << "uint64_value"; + break; + } + case staj_event_type::double_value: + { + os << "double_value"; + break; + } + } + return os; +} + +JSONCONS_STRING_LITERAL(null,'n','u','l','l') +JSONCONS_STRING_LITERAL(true,'t','r','u','e') +JSONCONS_STRING_LITERAL(false,'f','a','l','s','e') + +template +class basic_staj_event +{ + staj_event_type event_type_; + semantic_tag tag_; + union + { + bool bool_value_; + int64_t int64_value_; + uint64_t uint64_value_; + double double_value_; + const CharT* string_data_; + const uint8_t* byte_string_data_; + } value_; + size_t length_; +public: + typedef basic_string_view string_view_type; + + basic_staj_event(staj_event_type event_type, semantic_tag tag = semantic_tag::none) + : event_type_(event_type), tag_(tag), length_(0) + { + } + + basic_staj_event(null_type, semantic_tag tag) + : event_type_(staj_event_type::null_value), tag_(tag), length_(0) + { + } + + basic_staj_event(bool value, semantic_tag tag) + : event_type_(staj_event_type::bool_value), tag_(tag), length_(0) + { + value_.bool_value_ = value; + } + + basic_staj_event(int64_t value, semantic_tag tag) + : event_type_(staj_event_type::int64_value), tag_(tag), length_(0) + { + value_.int64_value_ = value; + } + + basic_staj_event(uint64_t value, semantic_tag tag) + : event_type_(staj_event_type::uint64_value), tag_(tag), length_(0) + { + value_.uint64_value_ = value; + } + + basic_staj_event(double value, semantic_tag tag) + : event_type_(staj_event_type::double_value), tag_(tag), length_(0) + { + value_.double_value_ = value; + } + + basic_staj_event(const string_view_type& s, + staj_event_type event_type, + semantic_tag tag = semantic_tag::none) + : event_type_(event_type), tag_(tag), length_(s.length()) + { + value_.string_data_ = s.data(); + } + + basic_staj_event(const byte_string_view& s, + staj_event_type event_type, + semantic_tag tag = semantic_tag::none) + : event_type_(event_type), tag_(tag), length_(s.length()) + { + value_.byte_string_data_ = s.data(); + } + + template + typename std::enable_if::value && std::is_same::value, T>::type + get() const + { + T s; + switch (event_type_) + { + case staj_event_type::name: + case staj_event_type::string_value: + s = T(value_.string_data_, length_); + break; + case staj_event_type::int64_value: + { + jsoncons::string_result result(s); + jsoncons::detail::print_integer(value_.int64_value_, result); + break; + } + case staj_event_type::uint64_value: + { + jsoncons::string_result result(s); + jsoncons::detail::print_uinteger(value_.uint64_value_, result); + break; + } + case staj_event_type::double_value: + { + jsoncons::string_result result(s); + jsoncons::detail::print_double f{ floating_point_options() }; + f(value_.double_value_, result); + break; + } + case staj_event_type::bool_value: + { + jsoncons::string_result result(s); + if (value_.bool_value_) + { + result.append(true_literal().data(),true_literal().size()); + } + else + { + result.append(false_literal().data(),false_literal().size()); + } + break; + } + case staj_event_type::null_value: + { + jsoncons::string_result result(s); + result.append(null_literal().data(),null_literal().size()); + break; + } + default: + JSONCONS_THROW(json_runtime_error("Not a string")); + } + return s; + } + + template + typename std::enable_if::value && std::is_same::value, T>::type + get() const + { + T s; + switch (event_type_) + { + case staj_event_type::name: + case staj_event_type::string_value: + s = T(value_.string_data_, length_); + break; + default: + JSONCONS_THROW(json_runtime_error("Not a string")); + } + return s; + } + + template + typename std::enable_if::value, T>::type + get() const + { + T s; + switch (event_type_) + { + case staj_event_type::byte_string_value: + s = T(value_.byte_string_data_, length_); + break; + default: + JSONCONS_THROW(json_runtime_error("Not a byte_string")); + } + return s; + } + + template + typename std::enable_if::value, T>::type + get() const + { + return static_cast(as_int64()); + } + + template + typename std::enable_if::value, T>::type + get() const + { + return static_cast(as_uint64()); + } + + template + typename std::enable_if::value, T>::type + get() const + { + return static_cast(as_double()); + } + + template> + typename std::enable_if>::value, T>::type + get() const + { + return as_bignum(); + } + + template + typename std::enable_if::value, T>::type + get() const + { + return as_bool(); + } + +#if !defined(JSONCONS_NO_DEPRECATED) + template + JSONCONS_DEPRECATED("Instead, use get()") + T as() const + { + return get(); + } + semantic_tag get_semantic_tag() const noexcept { return tag_; } +#endif + + staj_event_type event_type() const noexcept { return event_type_; } + + semantic_tag tag() const noexcept { return tag_; } +private: + + int64_t as_int64() const + { + int64_t value = 0; + switch (event_type_) + { + case staj_event_type::name: + case staj_event_type::string_value: + { + auto result = jsoncons::detail::to_integer(value_.string_data_, length_); + if (result.ec != jsoncons::detail::to_integer_errc()) + { + JSONCONS_THROW(json_runtime_error(make_error_code(result.ec).message())); + } + value = result.value; + break; + } + case staj_event_type::double_value: + value = static_cast(value_.double_value_); + break; + case staj_event_type::int64_value: + value = value_.int64_value_; + break; + case staj_event_type::uint64_value: + value = static_cast(value_.uint64_value_); + break; + case staj_event_type::bool_value: + value = value_.bool_value_ ? 1 : 0; + break; + default: + JSONCONS_THROW(json_runtime_error("Not an integer")); + } + return value; + } + + uint64_t as_uint64() const + { + uint64_t value = 0; + switch (event_type_) + { + case staj_event_type::name: + case staj_event_type::string_value: + { + auto result = jsoncons::detail::to_integer(value_.string_data_, length_); + if (result.ec != jsoncons::detail::to_integer_errc()) + { + JSONCONS_THROW(json_runtime_error(make_error_code(result.ec).message())); + } + value = result.value; + break; + } + case staj_event_type::double_value: + value = static_cast(value_.double_value_); + break; + case staj_event_type::int64_value: + value = static_cast(value_.int64_value_); + break; + case staj_event_type::uint64_value: + value = value_.uint64_value_; + break; + case staj_event_type::bool_value: + value = value_.bool_value_ ? 1 : 0; + break; + default: + JSONCONS_THROW(json_runtime_error("Not an unsigned integer")); + } + return value; + } + + double as_double() const + { + switch (event_type_) + { + case staj_event_type::name: + case staj_event_type::string_value: + { + std::string target; + auto result = unicons::convert( + value_.string_data_, value_.string_data_ + length_, std::back_inserter(target), unicons::conv_flags::strict); + if (result.ec != unicons::conv_errc()) + { + JSONCONS_THROW(json_runtime_error("Not a double")); + } + jsoncons::detail::string_to_double f; + return f(target.data(), target.length()); + } + case staj_event_type::double_value: + return value_.double_value_; + case staj_event_type::int64_value: + return static_cast(value_.int64_value_); + case staj_event_type::uint64_value: + return static_cast(value_.uint64_value_); + default: + JSONCONS_THROW(json_runtime_error("Not a double")); + } + } + + bool as_bool() const + { + switch (event_type_) + { + case staj_event_type::bool_value: + return value_.bool_value_; + case staj_event_type::double_value: + return value_.double_value_ != 0.0; + case staj_event_type::int64_value: + return value_.int64_value_ != 0; + case staj_event_type::uint64_value: + return value_.uint64_value_ != 0; + default: + JSONCONS_THROW(json_runtime_error("Not a bool")); + } + } + + template > + basic_bignum as_bignum() const + { + switch (event_type_) + { + case staj_event_type::string_value: + if (!jsoncons::detail::is_integer(value_.string_data_, length_)) + { + JSONCONS_THROW(json_runtime_error("Not a bignum")); + } + return basic_bignum(value_.string_data_, length_); + case staj_event_type::double_value: + return basic_bignum(value_.double_value_); + case staj_event_type::int64_value: + return basic_bignum(value_.int64_value_); + case staj_event_type::uint64_value: + return basic_bignum(value_.uint64_value_); + case staj_event_type::bool_value: + return basic_bignum(value_.bool_value_ ? 1 : 0); + default: + JSONCONS_THROW(json_runtime_error("Not a bignum")); + } + } + +}; + +// basic_staj_event_handler + +template +class basic_staj_event_handler final : public basic_json_content_handler +{ +public: + using typename basic_json_content_handler::string_view_type; +private: + std::function&, const ser_context&)> filter_; + basic_staj_event event_; +public: + basic_staj_event_handler() + : filter_(accept), event_(staj_event_type::null_value) + { + } + + basic_staj_event_handler(std::function&, const ser_context&)> filter) + : filter_(filter), event_(staj_event_type::null_value) + { + } + + const basic_staj_event& event() const + { + return event_; + } +private: + static bool accept(const basic_staj_event&, const ser_context&) + { + return true; + } + + bool do_begin_object(semantic_tag tag, const ser_context& context) override + { + event_ = basic_staj_event(staj_event_type::begin_object, tag); + return !filter_(event_, context); + } + + bool do_end_object(const ser_context& context) override + { + event_ = basic_staj_event(staj_event_type::end_object); + return !filter_(event_, context); + } + + bool do_begin_array(semantic_tag tag, const ser_context& context) override + { + event_ = basic_staj_event(staj_event_type::begin_array, tag); + return !filter_(event_, context); + } + + bool do_end_array(const ser_context& context) override + { + event_ = basic_staj_event(staj_event_type::end_array); + return !filter_(event_, context); + } + + bool do_name(const string_view_type& name, const ser_context& context) override + { + event_ = basic_staj_event(name, staj_event_type::name); + return !filter_(event_, context); + } + + bool do_null_value(semantic_tag tag, const ser_context& context) override + { + event_ = basic_staj_event(staj_event_type::null_value, tag); + return !filter_(event_, context); + } + + bool do_bool_value(bool value, semantic_tag tag, const ser_context& context) override + { + event_ = basic_staj_event(value, tag); + return !filter_(event_, context); + } + + bool do_string_value(const string_view_type& s, semantic_tag tag, const ser_context& context) override + { + event_ = basic_staj_event(s, staj_event_type::string_value, tag); + return !filter_(event_, context); + } + + bool do_byte_string_value(const byte_string_view& s, + semantic_tag tag, + const ser_context& context) override + { + event_ = basic_staj_event(s, staj_event_type::byte_string_value, tag); + return !filter_(event_, context); + } + + bool do_int64_value(int64_t value, + semantic_tag tag, + const ser_context& context) override + { + event_ = basic_staj_event(value, tag); + return !filter_(event_, context); + } + + bool do_uint64_value(uint64_t value, + semantic_tag tag, + const ser_context& context) override + { + event_ = basic_staj_event(value, tag); + return !filter_(event_, context); + } + + bool do_double_value(double value, + semantic_tag tag, + const ser_context& context) override + { + event_ = basic_staj_event(value, tag); + return !filter_(event_, context); + } + + void do_flush() override + { + } +}; + +template +bool staj_to_saj_event(const basic_staj_event& ev, + basic_json_content_handler& handler, + const ser_context& context) +{ + switch (ev.event_type()) + { + case staj_event_type::begin_array: + return handler.begin_array(ev.tag(), context); + case staj_event_type::end_array: + return handler.end_array(context); + case staj_event_type::begin_object: + return handler.begin_object(ev.tag(), context); + case staj_event_type::end_object: + return handler.end_object(context); + case staj_event_type::name: + return handler.name(ev.template get>(), context); + case staj_event_type::string_value: + return handler.string_value(ev.template get>(), ev.tag(), context); + case staj_event_type::byte_string_value: + return handler.byte_string_value(ev.template get(), ev.tag(), context); + case staj_event_type::null_value: + return handler.null_value(ev.tag(), context); + case staj_event_type::bool_value: + return handler.bool_value(ev.template get(), ev.tag(), context); + case staj_event_type::int64_value: + return handler.int64_value(ev.template get(), ev.tag(), context); + case staj_event_type::uint64_value: + return handler.uint64_value(ev.template get(), ev.tag(), context); + case staj_event_type::double_value: + return handler.double_value(ev.template get(), ev.tag(), context); + default: + return false; + } +} + +// basic_staj_reader + + template +class basic_staj_reader +{ +public: + virtual ~basic_staj_reader() = default; + + virtual bool done() const = 0; + + virtual const basic_staj_event& current() const = 0; + + virtual void read_to(basic_json_content_handler& handler) = 0; + + virtual void read_to(basic_json_content_handler& handler, + std::error_code& ec) = 0; + + virtual void next() = 0; + + virtual void next(std::error_code& ec) = 0; + + virtual const ser_context& context() const = 0; +}; + +typedef basic_staj_event staj_event; +typedef basic_staj_event wstaj_event; + +typedef basic_staj_reader staj_reader; +typedef basic_staj_reader wstaj_reader; + +#if !defined(JSONCONS_NO_DEPRECATED) + +JSONCONS_DEPRECATED("Instead, use staj_event_type") typedef staj_event_type stream_event_type; + +template +using basic_stream_event = basic_staj_event; + +template +using basic_stream_reader = basic_staj_reader; + +JSONCONS_DEPRECATED("Instead, use staj_event") typedef basic_staj_event stream_event; +JSONCONS_DEPRECATED("Instead, use wstaj_event") typedef basic_staj_event wstream_event; + +JSONCONS_DEPRECATED("Instead, use staj_reader") typedef basic_staj_reader stream_reader; +JSONCONS_DEPRECATED("Instead, use wstaj_reader") typedef basic_staj_reader wstream_reader; + +#endif + +} + +#endif + diff --git a/invehicle-apps/3rd-party-libs/jsoncons/detail/unicode_traits.hpp b/invehicle-apps/3rd-party-libs/jsoncons/unicode_traits.hpp similarity index 96% rename from invehicle-apps/3rd-party-libs/jsoncons/detail/unicode_traits.hpp rename to invehicle-apps/3rd-party-libs/jsoncons/unicode_traits.hpp index affbb9b..56bc9e7 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons/detail/unicode_traits.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons/unicode_traits.hpp @@ -13,8 +13,18 @@ * Unicode Standard." */ -#ifndef UNICONS_UNICODE_TRAITS_HPP -#define UNICONS_UNICODE_TRAITS_HPP +#ifndef JSONCONS_UNICONS_UNICODE_TRAITS_HPP +#define JSONCONS_UNICONS_UNICODE_TRAITS_HPP + +#if defined(__clang__) +# define UNICONS_FALLTHROUGH [[clang::fallthrough]] +#elif defined(__GNUC__) && ((__GNUC__ >= 7)) +# define UNICONS_FALLTHROUGH __attribute__((fallthrough)) +#elif defined (__GNUC__) +# define UNICONS_FALLTHROUGH // FALLTHRU +#else +# define UNICONS_FALLTHROUGH +#endif #if defined (__clang__) #if defined(_GLIBCXX_USE_NOEXCEPT) @@ -39,7 +49,7 @@ #include #include -namespace unicons { +namespace jsoncons { namespace unicons { /* * Magic values subtracted from a buffer value during UTF8 conversion. @@ -229,20 +239,6 @@ std::error_code make_error_code(encoding_errc result) { return std::error_code(static_cast(result),encoding_error_category()); } -} - -namespace std { - template<> - struct is_error_code_enum : public true_type - { - }; - template<> - struct is_error_code_enum : public true_type - { - }; -} - -namespace unicons { // utf8 @@ -260,11 +256,11 @@ is_legal_utf8(Iterator first, size_t length) case 4: if (((a = (*--srcptr))& 0xC0) != 0x80) return conv_errc::expected_continuation_byte; - // FALLTHRU + UNICONS_FALLTHROUGH; case 3: if (((a = (*--srcptr))& 0xC0) != 0x80) return conv_errc::expected_continuation_byte; - // FALLTHRU + UNICONS_FALLTHROUGH; case 2: if (((a = (*--srcptr))& 0xC0) != 0x80) return conv_errc::expected_continuation_byte; @@ -279,11 +275,11 @@ is_legal_utf8(Iterator first, size_t length) default: if (a < 0x80) return conv_errc::source_illegal; } - // FALLTHRU + UNICONS_FALLTHROUGH; case 1: if (static_cast(*first) >= 0x80 && static_cast(*first) < 0xC2) return conv_errc::source_illegal; - // FALLTHRU + break; } if (static_cast(*first) > 0xF4) return conv_errc::source_illegal; @@ -373,8 +369,11 @@ convert(InputIt first, InputIt last, OutputIt target, conv_flags flags=conv_flag switch (length) { case 4: *target++ = (static_cast(*first++)); + UNICONS_FALLTHROUGH; case 3: *target++ = (static_cast(*first++)); + UNICONS_FALLTHROUGH; case 2: *target++ = (static_cast(*first++)); + UNICONS_FALLTHROUGH; case 1: *target++ = (static_cast(*first++)); } } @@ -473,13 +472,31 @@ convert(InputIt first, InputIt last, /* * The cases all fall through. See "Note A" below. */ - switch (extra_bytes_to_read) { - case 5: ch += static_cast(*first++); ch <<= 6; - case 4: ch += static_cast(*first++); ch <<= 6; - case 3: ch += static_cast(*first++); ch <<= 6; - case 2: ch += static_cast(*first++); ch <<= 6; - case 1: ch += static_cast(*first++); ch <<= 6; - case 0: ch += static_cast(*first++); + switch (extra_bytes_to_read) + { + case 5: + ch += static_cast(*first++); + ch <<= 6; + UNICONS_FALLTHROUGH; + case 4: + ch += static_cast(*first++); + ch <<= 6; + UNICONS_FALLTHROUGH; + case 3: + ch += static_cast(*first++); + ch <<= 6; + UNICONS_FALLTHROUGH; + case 2: + ch += static_cast(*first++); + ch <<= 6; + UNICONS_FALLTHROUGH; + case 1: + ch += static_cast(*first++); + ch <<= 6; + UNICONS_FALLTHROUGH; + case 0: + ch += static_cast(*first++); + break; } ch -= offsets_from_utf8[extra_bytes_to_read]; @@ -743,13 +760,13 @@ convert(InputIt first, InputIt last, switch (bytes_to_write) { case 4: byte4 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6; - // FALLTHRU + UNICONS_FALLTHROUGH; case 3: byte3 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6; - // FALLTHRU + UNICONS_FALLTHROUGH; case 2: byte2 = (uint8_t)((ch | byteMark) & byteMask); ch >>= 6; - // FALLTHRU + UNICONS_FALLTHROUGH; case 1: byte1 = (uint8_t) (ch | first_byte_mark[bytes_to_write]); } @@ -983,13 +1000,13 @@ class sequence break; case 4: ch += static_cast(*it++); ch <<= 6; - // FALLTHRU + UNICONS_FALLTHROUGH; case 3: ch += static_cast(*it++); ch <<= 6; - // FALLTHRU + UNICONS_FALLTHROUGH; case 2: ch += static_cast(*it++); ch <<= 6; - // FALLTHRU + UNICONS_FALLTHROUGH; case 1: ch += static_cast(*it++); ch -= offsets_from_utf8[length_ - 1]; @@ -1457,6 +1474,18 @@ skip_bom(Iterator first, Iterator last) UNICONS_NOEXCEPT } } +} // unicons +} // jsoncons + +namespace std { + template<> + struct is_error_code_enum : public true_type + { + }; + template<> + struct is_error_code_enum : public true_type + { + }; } #endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons/version.hpp b/invehicle-apps/3rd-party-libs/jsoncons/version.hpp deleted file mode 100644 index 19a2888..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons/version.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2017 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_VERSION_HPP -#define JSONCONS_VERSION_HPP - -#include - -namespace jsoncons { - -struct versioning_info -{ - versioning_info(unsigned int major, - unsigned int minor, - unsigned int patch) - : major_(major), - minor_(minor), - patch_(patch) - {} - - unsigned int const major_; - unsigned int const minor_; - unsigned int const patch_; - - friend std::ostream& operator<<(std::ostream& os, const versioning_info& ver) - { - os << ver.major_ << '.' - << ver.minor_ << '.' - << ver.patch_; - return os; - } - - versioning_info(const versioning_info&) = default; - versioning_info() = delete; - versioning_info& operator=(const versioning_info&) = delete; -}; - -inline -versioning_info version() -{ - static versioning_info ver(0, 105, 0); - return ver; -} - -} - -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/json_query.hpp b/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/json_query.hpp index 8356d56..fb3ed83 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/json_query.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/json_query.hpp @@ -1,24 +1,89 @@ -// Copyright 2013 Daniel Parker +// Copyright 2013 Daniel Parkerpath_single_quoted // 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_JSONPATH_JSONQUERY_HPP -#define JSONCONS_JSONPATH_JSONQUERY_HPP +#ifndef JSONCONS_JSONPATH_JSON_QUERY_HPP +#define JSONCONS_JSONPATH_JSON_QUERY_HPP +#include // std::array #include -#include #include -#include -#include #include +#include // std::is_const +#include // std::numeric_limits +#include // std::move +#include +#include // std::set +#include // std::make_move_iterator #include -#include "jsonpath_filter.hpp" -#include "jsonpath_error_category.hpp" +#include +#include +#include namespace jsoncons { namespace jsonpath { +struct array_slice +{ + size_t start_; + bool is_start_positive; + size_t end_; + bool is_end_positive; + bool is_end_defined; + size_t step_; + bool is_step_positive; + + array_slice() + : start_(0), is_start_positive(true), + end_(0), is_end_positive(true), is_end_defined(false), + step_(1), is_step_positive(true) + { + } + + array_slice(size_t start, bool is_start_positive, + size_t end, bool is_end_positive, bool is_end_defined, + size_t step, bool is_step_positive) + : start_(start), is_start_positive(is_start_positive), + end_(end), is_end_positive(is_end_positive), is_end_defined(is_end_defined), + step_(step), is_step_positive(is_step_positive) + { + } + + size_t get_start(size_t size) const + { + return is_start_positive ? start_ : size - start_; + } + + size_t get_end(size_t size) const + { + if (is_end_defined) + { + return is_end_positive ? end_ : size - end_; + } + else + { + return size; + } + } + + size_t step() const + { + return step_; + } + + array_slice(const array_slice&) = default; + + array_slice& operator=(const array_slice&) = default; +}; + +// work around for std::make_unique not being available until C++14 +template +std::unique_ptr make_unique_ptr(Args&&... args) +{ + return std::unique_ptr(new T(std::forward(args)...)); +} + enum class result_type {value,path}; template @@ -26,14 +91,14 @@ Json json_query(const Json& root, const typename Json::string_view_type& path, r { if (result_t == result_type::value) { - detail::jsonpath_evaluator> evaluator; - evaluator.evaluate(root,path.data(),path.length()); + jsoncons::jsonpath::detail::jsonpath_evaluator> evaluator; + evaluator.evaluate(root, path); return evaluator.get_values(); } else { - detail::jsonpath_evaluator> evaluator; - evaluator.evaluate(root,path.data(),path.length()); + jsoncons::jsonpath::detail::jsonpath_evaluator> evaluator; + evaluator.evaluate(root, path); return evaluator.get_normalized_paths(); } } @@ -41,8 +106,8 @@ Json json_query(const Json& root, const typename Json::string_view_type& path, r template void json_replace(Json& root, const typename Json::string_view_type& path, T&& new_value) { - detail::jsonpath_evaluator> evaluator; - evaluator.evaluate(root,path.data(),path.length()); + jsoncons::jsonpath::detail::jsonpath_evaluator> evaluator; + evaluator.evaluate(root, path); evaluator.replace(std::forward(new_value)); } @@ -75,7 +140,7 @@ bool try_string_to_index(const CharT *s, size_t length, size_t* value, bool* pos CharT c = s[i]; switch (c) { - case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': + case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': { size_t x = c - '0'; if (n > max_value_div_10) @@ -89,11 +154,11 @@ bool try_string_to_index(const CharT *s, size_t length, size_t* value, bool* pos } n += x; + break; } - break; - default: - return false; - break; + default: + return false; + break; } } *value = n; @@ -104,76 +169,166 @@ bool try_string_to_index(const CharT *s, size_t length, size_t* value, bool* pos return false; } } - + enum class path_state { start, - cr, - lf, - expect_dot_or_left_bracket, - expect_unquoted_name_or_left_bracket, + dot_or_left_bracket, + name_or_left_bracket, + name, unquoted_name, - left_bracket_single_quoted_string, - left_bracket_double_quoted_string, - left_bracket, - left_bracket_start, - left_bracket_end, - left_bracket_end2, - left_bracket_step, - left_bracket_step2, - expect_comma_or_right_bracket, - dot + unquoted_name2, + single_quoted_name, + double_quoted_name, + bracketed_unquoted_name, + bracketed_single_quoted_name, + bracketed_double_quoted_name, + bracketed_name_or_path, + bracketed_wildcard_or_path, + wildcard_or_rpath_or_slice_or_filter, + slice_end_or_end_step, + slice_end, + slice_step, + slice_step2, + comma_or_right_bracket, + path_or_function_name, + function, + arg_or_right_paren, + path_argument, + unquoted_arg, + single_quoted_arg, + double_quoted_arg, + more_args_or_right_paren, + dot, + path, + path2, + path_single_quoted, + path_double_quoted +}; + +struct state_item +{ + path_state state; + bool is_recursive_descent; + bool is_union; + + state_item() + : state(path_state::start), is_recursive_descent(false), is_union(false) + { + } + + explicit state_item(path_state state) + : state(state), is_recursive_descent(false), is_union(false) + { + } + + state_item(path_state state, const state_item& parent) + : state(state), + is_recursive_descent(parent.is_recursive_descent), + is_union(parent.is_union) + { + } + + state_item(const state_item&) = default; + state_item& operator=(const state_item&) = default; }; +JSONCONS_STRING_LITERAL(length, 'l', 'e', 'n', 'g', 't', 'h') + template> -class jsonpath_evaluator : private serializing_context + class JsonReference, + class PathCons> +class jsonpath_evaluator : public ser_context { -private: typedef typename Json::char_type char_type; typedef typename Json::char_traits_type char_traits_type; typedef std::basic_string string_type; typedef typename Json::string_view_type string_view_type; typedef JsonReference reference; using pointer = typename std::conditional::type>::value,typename Json::const_pointer,typename Json::pointer>::type; + typedef typename Json::const_pointer const_pointer; + struct node_type { + string_type path; + pointer val_ptr; + node_type() = default; node_type(const string_type& p, const pointer& valp) - : skip_contained_object(false),path(p),val_ptr(valp) + : path(p),val_ptr(valp) { } node_type(string_type&& p, pointer&& valp) - : skip_contained_object(false),path(std::move(p)),val_ptr(valp) + : path(std::move(p)),val_ptr(valp) { } node_type(const node_type&) = default; - node_type(node_type&&) = default; + node_type(node_type&& other) + : path(std::move(other.path)), val_ptr(other.val_ptr) + { + + } + node_type& operator=(const node_type&) = default; + node_type& operator=(node_type&& other) + { + path.swap(other.path); + val_ptr = other.val_ptr; + } - bool skip_contained_object; - string_type path; - pointer val_ptr; }; typedef std::vector node_set; - static string_view_type length_literal() + struct node_less { - static const char_type data[] = {'l','e','n','g','t','h'}; - return string_view_type{data,sizeof(data)/sizeof(char_type)}; - } + bool operator()(const node_type& a, const node_type& b) const + { + return *(a.val_ptr) < *(b.val_ptr); + } + }; - class selector + class selector_base { public: - virtual ~selector() + virtual ~selector_base() + { + } + virtual void select(jsonpath_evaluator& evaluator, + const string_type& path, reference val, node_set& nodes) = 0; + + virtual bool is_filter() const { + return false; } - virtual void select(node_type& node, const string_type& path, reference val, - node_set& nodes, std::vector>& temp_json_values) = 0; }; - class expr_selector final : public selector + class path_selector final : public selector_base + { + private: + std::basic_string path_; + public: + path_selector(const std::basic_string& path) + : path_(path) + { + } + + void select(jsonpath_evaluator&, + const string_type& path, reference val, + node_set& nodes) override + { + std::error_code ec; + jsonpath_evaluator e; + e.evaluate(val, path_, ec); + if (!ec) + { + for (auto ptr : e.get_pointers()) + { + nodes.emplace_back(PathCons()(path,path_),ptr); + } + } + } + }; + + class expr_selector final : public selector_base { private: jsonpath_filter_expr result_; @@ -183,13 +338,14 @@ class jsonpath_evaluator : private serializing_context { } - void select(node_type& node, const string_type& path, reference val, - node_set& nodes, std::vector>& temp_json_values) override + void select(jsonpath_evaluator& evaluator, + const string_type& path, reference val, + node_set& nodes) override { auto index = result_.eval(val); if (index.template is()) { - size_t start = index. template as(); + size_t start = index.template as(); if (val.is_array() && start < val.size()) { nodes.emplace_back(PathCons()(path,start),std::addressof(val[start])); @@ -197,13 +353,13 @@ class jsonpath_evaluator : private serializing_context } else if (index.is_string()) { - name_selector selector(index.as_string_view(),true); - selector.select(node, path, val, nodes, temp_json_values); + name_selector selector(index.as_string_view()); + selector.select(evaluator, path, val, nodes); } } }; - class filter_selector final : public selector + class filter_selector final : public selector_base { private: jsonpath_filter_expr result_; @@ -213,12 +369,19 @@ class jsonpath_evaluator : private serializing_context { } - void select(node_type& node, const string_type& path, reference val, - node_set& nodes, std::vector>&) override + bool is_filter() const override { + return true; + } + + void select(jsonpath_evaluator&, + const string_type& path, reference val, + node_set& nodes) override + { + //std::cout << "filter_selector select "; if (val.is_array()) { - node.skip_contained_object =true; + //std::cout << "from array \n"; for (size_t i = 0; i < val.size(); ++i) { if (result_.exists(val[i])) @@ -229,110 +392,91 @@ class jsonpath_evaluator : private serializing_context } else if (val.is_object()) { - if (!node.skip_contained_object) - { - if (result_.exists(val)) - { - nodes.emplace_back(path, std::addressof(val)); - } - } - else + //std::cout << "from object \n"; + if (result_.exists(val)) { - node.skip_contained_object = false; + nodes.emplace_back(path, std::addressof(val)); } } } }; - class name_selector final : public selector + class name_selector final : public selector_base { private: string_type name_; - bool positive_start_; public: - name_selector(const string_view_type& name, bool positive_start) - : name_(name), positive_start_(positive_start) + name_selector(const string_view_type& name) + : name_(name) { } - void select(node_type& node, const string_type& path, reference val, - node_set& nodes, - std::vector>& temp_json_values) override + void select(jsonpath_evaluator& evaluator, + const string_type& path, reference val, + node_set& nodes) override { - if (val.is_object() && val.count(name_) > 0) + bool is_start_positive = true; + + if (val.is_object() && val.contains(name_)) { nodes.emplace_back(PathCons()(path,name_),std::addressof(val.at(name_))); } else if (val.is_array()) { size_t pos = 0; - if (try_string_to_index(name_.data(), name_.size(), &pos, &positive_start_)) + if (try_string_to_index(name_.data(), name_.size(), &pos, &is_start_positive)) { - size_t index = positive_start_ ? pos : val.size() - pos; + size_t index = is_start_positive ? pos : val.size() - pos; if (index < val.size()) { nodes.emplace_back(PathCons()(path,index),std::addressof(val[index])); } } - else if (name_ == length_literal() && val.size() > 0) + else if (name_ == length_literal() && val.size() > 0) { - auto temp = std::make_shared(val.size()); - temp_json_values.push_back(temp); - nodes.emplace_back(PathCons()(path,name_),temp.get()); + pointer ptr = evaluator.create_temp(val.size()); + nodes.emplace_back(PathCons()(path, name_), ptr); } } else if (val.is_string()) { size_t pos = 0; string_view_type sv = val.as_string_view(); - if (try_string_to_index(name_.data(), name_.size(), &pos, &positive_start_)) + if (try_string_to_index(name_.data(), name_.size(), &pos, &is_start_positive)) { - size_t index = positive_start_ ? pos : sv.size() - pos; + size_t index = is_start_positive ? pos : sv.size() - pos; auto sequence = unicons::sequence_at(sv.data(), sv.data() + sv.size(), index); if (sequence.length() > 0) { - auto temp = std::make_shared(sequence.begin(),sequence.length()); - temp_json_values.push_back(temp); - nodes.emplace_back(PathCons()(path,index),temp.get()); + pointer ptr = evaluator.create_temp(sequence.begin(),sequence.length()); + nodes.emplace_back(PathCons()(path, index), ptr); } } - else if (name_ == length_literal() && sv.size() > 0) + else if (name_ == length_literal() && sv.size() > 0) { size_t count = unicons::u32_length(sv.begin(),sv.end()); - auto temp = std::make_shared(count); - temp_json_values.push_back(temp); - nodes.emplace_back(PathCons()(path,name_),temp.get()); + pointer ptr = evaluator.create_temp(count); + nodes.emplace_back(PathCons()(path, name_), ptr); } } } }; - class array_slice_selector final : public selector + class array_slice_selector final : public selector_base { private: - size_t start_; - bool positive_start_; - size_t end_; - bool positive_end_; - bool undefined_end_; - size_t step_; - bool positive_step_; + array_slice slice_; public: - array_slice_selector(size_t start, bool positive_start, - size_t end, bool positive_end, - size_t step, bool positive_step, - bool undefined_end) - : start_(start), positive_start_(positive_start), - end_(end), positive_end_(positive_end),undefined_end_(undefined_end), - step_(step), positive_step_(positive_step) + array_slice_selector(const array_slice& slice) + : slice_(slice) { } - void select(node_type& node, const string_type& path, reference val, - node_set& nodes, - std::vector>&) override + void select(jsonpath_evaluator&, + const string_type& path, reference val, + node_set& nodes) override { - if (positive_step_) + if (slice_.is_step_positive) { end_array_slice1(path, val, nodes); } @@ -346,17 +490,9 @@ class jsonpath_evaluator : private serializing_context { if (val.is_array()) { - size_t start = positive_start_ ? start_ : val.size() - start_; - size_t end; - if (!undefined_end_) - { - end = positive_end_ ? end_ : val.size() - end_; - } - else - { - end = val.size(); - } - for (size_t j = start; j < end; j += step_) + size_t start = slice_.get_start(val.size()); + size_t end = slice_.get_end(val.size()); + for (size_t j = start; j < end; j += slice_.step()) { if (j < val.size()) { @@ -370,21 +506,13 @@ class jsonpath_evaluator : private serializing_context { if (val.is_array()) { - size_t start = positive_start_ ? start_ : val.size() - start_; - size_t end; - if (!undefined_end_) - { - end = positive_end_ ? end_ : val.size() - end_; - } - else - { - end = val.size(); - } + size_t start = slice_.get_start(val.size()); + size_t end = slice_.get_end(val.size()); - size_t j = end + step_ - 1; - while (j > (start+step_-1)) + size_t j = end + slice_.step() - 1; + while (j > (start+slice_.step()-1)) { - j -= step_; + j -= slice_.step(); if (j < val.size()) { nodes.emplace_back(PathCons()(path,j),std::addressof(val[j])); @@ -394,42 +522,47 @@ class jsonpath_evaluator : private serializing_context } }; - default_parse_error_handler default_err_handler_; - parse_error_handler *err_handler_; - path_state state_; - string_type buffer_; - size_t start_; - bool positive_start_; - size_t end_; - bool positive_end_; - bool undefined_end_; - size_t step_; - bool positive_step_; - bool recursive_descent_; + function_table functions_; + node_set nodes_; std::vector stack_; - std::vector> temp_json_values_; size_t line_; size_t column_; const char_type* begin_input_; const char_type* end_input_; const char_type* p_; - std::vector> selectors_; + std::vector> selectors_; + std::vector> temp_json_values_; + + typedef std::vector argument_type; + std::vector function_stack_; + std::vector state_stack_; public: jsonpath_evaluator() - : err_handler_(&default_err_handler_), - state_(path_state::start), - start_(0), positive_start_(true), - end_(0), positive_end_(true), undefined_end_(false), - step_(0), positive_step_(true), - recursive_descent_(false), - line_(0), column_(0), + : line_(1), column_(1), begin_input_(nullptr), end_input_(nullptr), p_(nullptr) { } + jsonpath_evaluator(size_t line, size_t column) + : line_(line), column_(column), + begin_input_(nullptr), end_input_(nullptr), + p_(nullptr) + { + } + + size_t line() const + { + return line_; + } + + size_t column() const + { + return column_; + } + Json get_values() const { Json result = typename Json::array(); @@ -445,6 +578,50 @@ class jsonpath_evaluator : private serializing_context return result; } + std::vector get_pointers() const + { + std::vector result; + + if (stack_.size() > 0) + { + result.reserve(stack_.back().size()); + for (const auto& p : stack_.back()) + { + result.push_back(p.val_ptr); + } + } + return result; + } + + void call_function(const string_type& function_name, std::error_code& ec) + { + auto f = functions_.get(function_name, ec); + if (ec) + { + return; + } + auto result = f(function_stack_, ec); + if (ec) + { + return; + } + + string_type s = {'$'}; + node_set v; + pointer ptr = create_temp(std::move(result)); + v.emplace_back(s,ptr); + stack_.push_back(v); + } + + template + pointer create_temp(Args&& ... args) + { + auto temp = make_unique_ptr(std::forward(args)...); + pointer ptr = temp.get(); + temp_json_values_.emplace_back(std::move(temp)); + return ptr; + } + Json get_normalized_paths() const { Json result = typename Json::array(); @@ -472,479 +649,1035 @@ class jsonpath_evaluator : private serializing_context } void evaluate(reference root, const string_view_type& path) - { - evaluate(root,path.data(),path.length()); - } - void evaluate(reference root, const char_type* path) - { - evaluate(root,path,char_traits_type::length(path)); - } - - void evaluate(reference root, - const char_type* path, - size_t length) { std::error_code ec; - evaluate(root, path, length, ec); + evaluate(root, path.data(), path.length(), ec); if (ec) { - throw parse_error(ec,line_,column_); + throw jsonpath_error(ec, line_, column_); } } + void evaluate(reference root, const string_view_type& path, std::error_code& ec) + { + try + { + evaluate(root, path.data(), path.length(), ec); + } + catch (...) + { + ec = jsonpath_errc::unidentified_error; + } + } + void evaluate(reference root, const char_type* path, size_t length, std::error_code& ec) { - path_state pre_line_break_state = path_state::start; + state_stack_.emplace_back(path_state::start); + + string_type function_name; + string_type buffer; begin_input_ = path; end_input_ = path + length; p_ = begin_input_; - line_ = 1; - column_ = 1; - state_ = path_state::start; - - recursive_descent_ = false; + string_type s = {'$'}; + node_set v; + v.emplace_back(std::move(s),std::addressof(root)); + stack_.push_back(v); - clear_index(); + array_slice slice; while (p_ < end_input_) { - switch (state_) + switch (state_stack_.back().state) { - case path_state::cr: - ++line_; - column_ = 1; - switch (*p_) + case path_state::start: { - case '\n': - state_ = pre_line_break_state; - ++p_; - ++column_; - break; - default: - state_ = pre_line_break_state; + switch (*p_) + { + case ' ':case '\t':case '\r':case '\n': + advance_past_space_character(); + break; + case '$': + { + state_stack_.emplace_back(path_state::dot_or_left_bracket, state_stack_.back()); + ++p_; + ++column_; + break; + } + default: + { + switch (*p_) + { + case '.': + case '[': + ec = jsonpath_errc::expected_root; + return; + default: // might be function, validate name later + state_stack_.emplace_back(path_state::dot_or_left_bracket, state_stack_.back()); + state_stack_.emplace_back(path_state::path_or_function_name, state_stack_.back()); + break; + } + break; + } + + return; + }; break; } - break; - case path_state::lf: - ++line_; - column_ = 1; - state_ = pre_line_break_state; - break; - case path_state::start: - switch (*p_) - { - case ' ':case '\t': + case path_state::path_or_function_name: + switch (*p_) + { + case ' ':case '\t':case '\r':case '\n': + { + selectors_.push_back(make_unique_ptr(buffer)); + apply_selectors(); + buffer.clear(); + state_stack_.pop_back(); + advance_past_space_character(); + break; + } + case '(': + state_stack_.back().state = path_state::arg_or_right_paren; + function_name = std::move(buffer); + buffer.clear(); + ++p_; + ++column_; + break; + case '[': + { + if (buffer.size() > 0) + { + selectors_.push_back(make_unique_ptr(buffer)); + apply_selectors(); + buffer.clear(); + } + slice.start_ = 0; + + state_stack_.back().state = path_state::wildcard_or_rpath_or_slice_or_filter; + ++p_; + ++column_; + break; + } + case '.': + { + if (buffer.size() > 0) + { + selectors_.push_back(make_unique_ptr(buffer)); + apply_selectors(); + buffer.clear(); + } + state_stack_.back().state = path_state::dot; + ++p_; + ++column_; + break; + } + case '*': + { + end_all(); + transfer_nodes(); + state_stack_.back().state = path_state::dot; + ++p_; + ++column_; + break; + } + case '\'': + { + buffer.clear(); + state_stack_.back().state = path_state::single_quoted_name; + ++p_; + ++column_; + break; + } + case '\"': + { + buffer.clear(); + state_stack_.back().state = path_state::double_quoted_name; + ++p_; + ++column_; + break; + } + default: + buffer.push_back(*p_); + ++p_; + ++column_; + break; + } break; - case '$': - case '@': + case path_state::arg_or_right_paren: + switch (*p_) { - string_type s; - s.push_back('$'); - node_set v; - v.emplace_back(std::move(s),std::addressof(root)); - stack_.push_back(v); + case ' ':case '\t':case '\r':case '\n': + advance_past_space_character(); + break; + case '$': + buffer.clear(); + buffer.push_back(*p_); + state_stack_.emplace_back(path_state::path_argument, state_stack_.back()); + ++p_; + ++column_; + break; + case '\'': + buffer.clear(); + buffer.push_back('\"'); + state_stack_.back().state = path_state::more_args_or_right_paren; + state_stack_.emplace_back(path_state::single_quoted_arg, state_stack_.back()); + ++p_; + ++column_; + break; + case '\"': + buffer.clear(); + buffer.push_back('\"'); + state_stack_.back().state = path_state::more_args_or_right_paren; + state_stack_.emplace_back(path_state::double_quoted_arg, state_stack_.back()); + ++p_; + ++column_; + break; + case ')': + { + jsonpath_evaluator evaluator; + evaluator.evaluate(root, buffer, ec); + if (ec) + { + return; + } + function_stack_.push_back(evaluator.get_pointers()); - state_ = path_state::expect_dot_or_left_bracket; + call_function(function_name, ec); + if (ec) + { + return; + } + state_stack_.pop_back(); + ++p_; + ++column_; + break; + } + default: + buffer.clear(); + state_stack_.back().state = path_state::more_args_or_right_paren; + state_stack_.emplace_back(path_state::unquoted_arg, state_stack_.back()); + ++p_; + ++column_; + break; } break; - default: - err_handler_->fatal_error(jsonpath_parser_errc::expected_root, *this); - ec = jsonpath_parser_errc::expected_root; - return; - }; - ++p_; - ++column_; - break; - case path_state::dot: - switch (*p_) - { - case '.': - recursive_descent_ = true; + case path_state::path_argument: + switch (*p_) + { + case ',': + { + jsonpath_evaluator evaluator; + evaluator.evaluate(root, buffer, ec); + if (ec) + { + return; + } + function_stack_.push_back(evaluator.get_pointers()); + state_stack_.pop_back(); + ++p_; + ++column_; + break; + } + case ')': + { + state_stack_.pop_back(); + break; + } + default: + buffer.push_back(*p_); // path_argument + ++p_; + ++column_; + break; + } + break; + case path_state::unquoted_arg: + switch (*p_) + { + case ',': + try + { + auto val = Json::parse(buffer); + auto temp = create_temp(val); + function_stack_.push_back(std::vector{temp}); + } + catch (const ser_error&) + { + ec = jsonpath_errc::argument_parse_error; + return; + } + buffer.clear(); + //state_ = path_state::arg_or_right_paren; + state_stack_.pop_back(); + break; + case ')': + { + try + { + auto val = Json::parse(buffer); + auto temp = create_temp(val); + function_stack_.push_back(std::vector{temp}); + } + catch (const ser_error&) + { + ec = jsonpath_errc::argument_parse_error; + return; + } + call_function(function_name, ec); + if (ec) + { + return; + } + state_stack_.pop_back(); + break; + } + default: + buffer.push_back(*p_); + break; + } ++p_; ++column_; - state_ = path_state::expect_unquoted_name_or_left_bracket; break; - default: - state_ = path_state::expect_unquoted_name_or_left_bracket; - break; - } - break; - case path_state::expect_unquoted_name_or_left_bracket: - switch (*p_) - { - case '.': - err_handler_->fatal_error(jsonpath_parser_errc::expected_name, *this); - ec = jsonpath_parser_errc::expected_name; - return; - case '*': - end_all(); - transfer_nodes(); - state_ = path_state::expect_dot_or_left_bracket; + case path_state::single_quoted_arg: + switch (*p_) + { + case '\'': + buffer.push_back('\"'); + state_stack_.pop_back(); + break; + case '\"': + buffer.push_back('\\'); + buffer.push_back('\"'); + state_stack_.pop_back(); + break; + default: + buffer.push_back(*p_); + break; + } ++p_; ++column_; break; - case '[': - state_ = path_state::left_bracket; + case path_state::double_quoted_arg: + switch (*p_) + { + case '\"': + buffer.push_back('\"'); + state_stack_.pop_back(); + break; + default: + buffer.push_back(*p_); + break; + } ++p_; ++column_; break; - default: - buffer_.clear(); - state_ = path_state::unquoted_name; + case path_state::more_args_or_right_paren: + switch (*p_) + { + case ' ':case '\t':case '\r':case '\n': + advance_past_space_character(); + break; + case ',': + try + { + auto val = Json::parse(buffer); + auto temp = create_temp(val); + function_stack_.push_back(std::vector{temp}); + } + catch (const ser_error&) + { + ec = jsonpath_errc::argument_parse_error; + return; + } + buffer.clear(); + //state_ = path_state::arg_or_right_paren; + state_stack_.pop_back(); + ++p_; + ++column_; + break; + case ')': + { + try + { + auto val = Json::parse(buffer); + auto temp = create_temp(val); + function_stack_.push_back(std::vector{temp}); + } + catch (const ser_error&) + { + ec = jsonpath_errc::argument_parse_error; + return; + } + call_function(function_name, ec); + if (ec) + { + return; + } + state_stack_.pop_back(); + ++p_; + ++column_; + break; + } + default: + ec = jsonpath_errc::invalid_filter_unsupported_operator; + return; + } break; - } - break; - case path_state::expect_dot_or_left_bracket: - switch (*p_) - { - case ' ':case '\t': + case path_state::dot: + switch (*p_) + { + case '.': + state_stack_.back().is_recursive_descent = true; + ++p_; + ++column_; + state_stack_.back().state = path_state::name_or_left_bracket; + break; + default: + state_stack_.back().state = path_state::name; + break; + } break; - case '.': - state_ = path_state::dot; + case path_state::name_or_left_bracket: + switch (*p_) + { + case ' ':case '\t':case '\r':case '\n': + advance_past_space_character(); + break; + case '[': // [ can follow .. + state_stack_.back().state = path_state::wildcard_or_rpath_or_slice_or_filter; + ++p_; + ++column_; + break; + default: + buffer.clear(); + state_stack_.back().state = path_state::name; + break; + } break; - case '[': - state_ = path_state::left_bracket; + case path_state::name: + switch (*p_) + { + case ' ':case '\t':case '\r':case '\n': + advance_past_space_character(); + break; + case '*': + end_all(); + transfer_nodes(); + state_stack_.pop_back(); + ++p_; + ++column_; + break; + case '\'': + state_stack_.back().state = path_state::single_quoted_name; + ++p_; + ++column_; + break; + case '\"': + state_stack_.back().state = path_state::double_quoted_name; + ++p_; + ++column_; + break; + case '[': + case '.': + ec = jsonpath_errc::expected_name; + return; + default: + buffer.clear(); + state_stack_.back().state = path_state::unquoted_name; + break; + } break; - default: - err_handler_->fatal_error(jsonpath_parser_errc::expected_separator, *this); - ec = jsonpath_parser_errc::expected_separator; - return; - }; - ++p_; - ++column_; - break; - case path_state::expect_comma_or_right_bracket: - switch (*p_) - { - case ',': - state_ = path_state::left_bracket; + case path_state::dot_or_left_bracket: + switch (*p_) + { + case ' ':case '\t':case '\r':case '\n': + advance_past_space_character(); + break; + case '.': + state_stack_.emplace_back(path_state::dot, state_stack_.back()); + ++p_; + ++column_; + break; + case '[': + state_stack_.emplace_back(path_state::wildcard_or_rpath_or_slice_or_filter, state_stack_.back()); + ++p_; + ++column_; + break; + default: + ec = jsonpath_errc::expected_separator; + return; + }; break; - case ']': - apply_selectors(); - state_ = path_state::expect_dot_or_left_bracket; + case path_state::unquoted_name: + switch (*p_) + { + case '[': + case '.': + case ' ':case '\t': + case '\r': + case '\n': + state_stack_.back().state = path_state::unquoted_name2; + break; + default: + buffer.push_back(*p_); + ++p_; + ++column_; + break; + }; break; - case ' ':case '\t': + case path_state::unquoted_name2: + switch (*p_) + { + case ' ':case '\t':case '\r':case '\n': + advance_past_space_character(); + break; + case '[': + selectors_.push_back(make_unique_ptr(buffer)); + apply_selectors(); + buffer.clear(); + slice.start_ = 0; + state_stack_.pop_back(); + break; + case '.': + selectors_.push_back(make_unique_ptr(buffer)); + apply_selectors(); + buffer.clear(); + state_stack_.pop_back(); + break; + default: + ec = jsonpath_errc::expected_name; + return; + }; break; - default: - err_handler_->fatal_error(jsonpath_parser_errc::expected_right_bracket, *this); - ec = jsonpath_parser_errc::expected_right_bracket; - return; - } - ++p_; - ++column_; - break; - case path_state::left_bracket: - switch (*p_) - { - case ' ':case '\t': + case path_state::single_quoted_name: + switch (*p_) + { + case '\'': + selectors_.push_back(make_unique_ptr(buffer)); + apply_selectors(); + buffer.clear(); + state_stack_.pop_back(); + break; + case '\\': + if (p_+1 < end_input_) + { + ++p_; + ++column_; + buffer.push_back(*p_); + } + else + { + ec = jsonpath_errc::unexpected_end_of_input; + return; + } + break; + default: + buffer.push_back(*p_); + break; + }; + ++p_; + ++column_; + break; + case path_state::double_quoted_name: + switch (*p_) + { + case '\"': + selectors_.push_back(make_unique_ptr(buffer)); + apply_selectors(); + buffer.clear(); + state_stack_.pop_back(); + break; + case '\\': + if (p_+1 < end_input_) + { + ++p_; + ++column_; + buffer.push_back(*p_); + } + else + { + ec = jsonpath_errc::unexpected_end_of_input; + return; + } + break; + default: + buffer.push_back(*p_); + break; + }; ++p_; ++column_; break; - case '(': + case path_state::comma_or_right_bracket: + switch (*p_) { - jsonpath_filter_parser parser(line_,column_); - auto result = parser.parse(root, p_,end_input_,&p_); - line_ = parser.line(); - column_ = parser.column(); - selectors_.push_back(std::make_shared(result)); - state_ = path_state::expect_comma_or_right_bracket; + case ' ':case '\t':case '\r':case '\n': + advance_past_space_character(); + break; + case ',': + state_stack_.back().is_union = true; + state_stack_.back().state = path_state::wildcard_or_rpath_or_slice_or_filter; + ++p_; + ++column_; + break; + case ']': + apply_selectors(); + state_stack_.pop_back(); + ++p_; + ++column_; + break; + default: + ec = jsonpath_errc::expected_right_bracket; + return; } break; - case '?': + case path_state::wildcard_or_rpath_or_slice_or_filter: + switch (*p_) { - jsonpath_filter_parser parser(line_,column_); - auto result = parser.parse(root,p_,end_input_,&p_); - line_ = parser.line(); - column_ = parser.column(); - selectors_.push_back(std::make_shared(result)); - state_ = path_state::expect_comma_or_right_bracket; + case ' ':case '\t':case '\r':case '\n': + advance_past_space_character(); + break; + case '(': + { + jsonpath_filter_parser parser(line_,column_); + auto result = parser.parse(root, p_,end_input_,&p_); + line_ = parser.line(); + column_ = parser.column(); + selectors_.push_back(make_unique_ptr(result)); + state_stack_.back().state = path_state::comma_or_right_bracket; + break; + } + case '?': + { + jsonpath_filter_parser parser(line_,column_); + auto result = parser.parse(root,p_,end_input_,&p_); + line_ = parser.line(); + column_ = parser.column(); + selectors_.push_back(make_unique_ptr(result)); + state_stack_.back().state = path_state::comma_or_right_bracket; + break; + } + case ':': + slice = array_slice(); + buffer.clear(); + state_stack_.back().state = path_state::comma_or_right_bracket; + state_stack_.emplace_back(path_state::slice_end_or_end_step, state_stack_.back()); + ++p_; + ++column_; + break; + case '*': + state_stack_.back().state = path_state::comma_or_right_bracket; + state_stack_.emplace_back(path_state::bracketed_wildcard_or_path, state_stack_.back()); + ++p_; + ++column_; + break; + case '\'': + state_stack_.back().state = path_state::comma_or_right_bracket; + state_stack_.emplace_back(path_state::bracketed_single_quoted_name, state_stack_.back()); + ++p_; + ++column_; + break; + case '\"': + state_stack_.back().state = path_state::comma_or_right_bracket; + state_stack_.emplace_back(path_state::bracketed_double_quoted_name, state_stack_.back()); + ++p_; + ++column_; + break; + default: + slice = array_slice(); + buffer.clear(); + buffer.push_back(*p_); + state_stack_.back().state = path_state::comma_or_right_bracket; + state_stack_.emplace_back(path_state::bracketed_unquoted_name, state_stack_.back()); + ++p_; + ++column_; + break; } - break; - case ':': - clear_index(); - state_ = path_state::left_bracket_end; - ++p_; - ++column_; break; - case '*': - end_all(); - state_ = path_state::expect_comma_or_right_bracket; - ++p_; - ++column_; + case path_state::bracketed_unquoted_name: + switch (*p_) + { + case ':': + if (!try_string_to_index(buffer.data(), buffer.size(), &slice.start_, &slice.is_start_positive)) + { + ec = jsonpath_errc::expected_slice_start; + return; + } + state_stack_.back().state = path_state::slice_end_or_end_step; + ++p_; + ++column_; + break; + case '.': + case '[': + case ',': + case ']': + state_stack_.back().state = path_state::bracketed_name_or_path; + break; + default: + buffer.push_back(*p_); + ++p_; + ++column_; + break; + } break; - case '\'': - state_ = path_state::left_bracket_single_quoted_string; + case path_state::bracketed_name_or_path: + switch (*p_) + { + case ' ':case '\t':case '\r':case '\n': + advance_past_space_character(); + break; + case '.': + buffer.push_back(*p_); + state_stack_.back().state = path_state::path; + ++p_; + ++column_; + break; + case '[': + buffer.push_back(*p_); + state_stack_.back().state = path_state::path2; + ++p_; + ++column_; + break; + case ',': + case ']': + if (!buffer.empty()) + { + selectors_.push_back(make_unique_ptr(buffer)); + buffer.clear(); + } + state_stack_.pop_back(); + break; + default: + ec = jsonpath_errc::expected_right_bracket; + return; + } + break; + case path_state::bracketed_wildcard_or_path: + switch (*p_) + { + case ' ':case '\t':case '\r':case '\n': + advance_past_space_character(); + break; + case '.': + buffer.push_back('*'); + buffer.push_back(*p_); + state_stack_.back().state = path_state::path; + ++p_; + ++column_; + break; + case '[': + buffer.push_back('*'); + buffer.push_back(*p_); + state_stack_.back().state = path_state::path2; + ++p_; + ++column_; + break; + case ',': + case ']': + end_all(); + state_stack_.pop_back(); + break; + default: + ec = jsonpath_errc::expected_right_bracket; + return; + } + break; + case path_state::path: + switch (*p_) + { + case '\'': + buffer.push_back(*p_); + state_stack_.emplace_back(path_state::path_single_quoted, state_stack_.back()); + ++p_; + ++column_; + break; + case '\"': + buffer.push_back(*p_); + state_stack_.emplace_back(path_state::path_double_quoted, state_stack_.back()); + ++p_; + ++column_; + break; + case ',': + case ']': + if (!buffer.empty()) + { + selectors_.push_back(make_unique_ptr(buffer)); + buffer.clear(); + } + state_stack_.pop_back(); + break; + default: + buffer.push_back(*p_); + ++p_; + ++column_; + break; + } + break; + case path_state::path_double_quoted: + switch (*p_) + { + case '\"': + buffer.push_back(*p_); + state_stack_.pop_back(); + break; + case '\\': + if (p_+1 < end_input_) + { + ++p_; + ++column_; + buffer.push_back(*p_); + } + else + { + ec = jsonpath_errc::unexpected_end_of_input; + return; + } + break; + default: + buffer.push_back(*p_); + break; + } ++p_; ++column_; break; - case '\"': - state_ = path_state::left_bracket_double_quoted_string; + case path_state::path_single_quoted: + switch (*p_) + { + case '\'': + buffer.push_back(*p_); + state_stack_.pop_back(); + break; + case '\\': + if (p_+1 < end_input_) + { + ++p_; + ++column_; + buffer.push_back(*p_); + } + else + { + ec = jsonpath_errc::unexpected_end_of_input; + return; + } + break; + default: + buffer.push_back(*p_); + break; + } ++p_; ++column_; break; - default: - clear_index(); - buffer_.push_back(*p_); - state_ = path_state::left_bracket_start; + case path_state::path2: + switch (*p_) + { + case ']': + buffer.push_back(*p_); + state_stack_.back().state = path_state::path; + break; + default: + buffer.push_back(*p_); + break; + } ++p_; ++column_; break; - } - break; - case path_state::left_bracket_start: - switch (*p_) - { - case ':': - if (!try_string_to_index(buffer_.data(), buffer_.size(), &start_, &positive_start_)) + case path_state::slice_end_or_end_step: + switch (*p_) { - err_handler_->fatal_error(jsonpath_parser_errc::expected_index, *this); - ec = jsonpath_parser_errc::expected_index; - return; + case '-': + slice.is_end_positive = false; + state_stack_.back().state = path_state::slice_end; + ++p_; + ++column_; + break; + case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': + slice.is_end_defined = true; + slice.end_ = static_cast(*p_-'0'); + state_stack_.back().state = path_state::slice_end; + ++p_; + ++column_; + break; + case ':': + slice.step_ = 0; + state_stack_.back().state = path_state::slice_step; + ++p_; + ++column_; + break; + case ',': + case ']': + selectors_.push_back(make_unique_ptr(slice)); + state_stack_.pop_back(); + break; + default: + ec = jsonpath_errc::expected_minus_or_digit_or_colon_or_comma_or_right_bracket; + return; } - state_ = path_state::left_bracket_end; - break; - case ',': - selectors_.push_back(std::make_shared(buffer_,positive_start_)); - buffer_.clear(); - state_ = path_state::left_bracket; - break; - case ']': - selectors_.push_back(std::make_shared(buffer_,positive_start_)); - buffer_.clear(); - apply_selectors(); - state_ = path_state::expect_dot_or_left_bracket; - break; - default: - buffer_.push_back(*p_); - break; - } - ++p_; - ++column_; - break; - case path_state::left_bracket_end: - switch (*p_) - { - case '-': - positive_end_ = false; - state_ = path_state::left_bracket_end2; - break; - case ':': - step_ = 0; - state_ = path_state::left_bracket_step; - break; - case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': - undefined_end_ = false; - end_ = static_cast(*p_-'0'); - state_ = path_state::left_bracket_end2; break; - case ',': - selectors_.push_back(std::make_shared(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_)); - state_ = path_state::left_bracket; - break; - case ']': - selectors_.push_back(std::make_shared(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_)); - apply_selectors(); - state_ = path_state::expect_dot_or_left_bracket; - break; - } - ++p_; - ++column_; - break; - case path_state::left_bracket_end2: - switch (*p_) - { - case ':': - step_ = 0; - state_ = path_state::left_bracket_step; - break; - case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': - undefined_end_ = false; - end_ = end_*10 + static_cast(*p_-'0'); - break; - case ',': - selectors_.push_back(std::make_shared(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_)); - state_ = path_state::left_bracket; - break; - case ']': - selectors_.push_back(std::make_shared(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_)); - apply_selectors(); - state_ = path_state::expect_dot_or_left_bracket; - break; - } - ++p_; - ++column_; - break; - case path_state::left_bracket_step: - switch (*p_) - { - case '-': - positive_step_ = false; - state_ = path_state::left_bracket_step2; - break; - case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': - step_ = static_cast(*p_-'0'); - state_ = path_state::left_bracket_step2; - break; - case ',': - selectors_.push_back(std::make_shared(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_)); - state_ = path_state::left_bracket; - break; - case ']': - selectors_.push_back(std::make_shared(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_)); - apply_selectors(); - state_ = path_state::expect_dot_or_left_bracket; - break; - } - ++p_; - ++column_; - break; - case path_state::left_bracket_step2: - switch (*p_) - { - case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': - step_ = step_*10 + static_cast(*p_-'0'); - break; - case ',': - selectors_.push_back(std::make_shared(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_)); - state_ = path_state::left_bracket; - break; - case ']': - selectors_.push_back(std::make_shared(start_,positive_start_,end_,positive_end_,step_,positive_step_,undefined_end_)); - apply_selectors(); - state_ = path_state::expect_dot_or_left_bracket; - break; - } - ++p_; - ++column_; - break; - case path_state::unquoted_name: - switch (*p_) - { - case '[': - apply_unquoted_string(buffer_); - transfer_nodes(); - start_ = 0; - state_ = path_state::left_bracket; - break; - case '.': - apply_unquoted_string(buffer_); - transfer_nodes(); - state_ = path_state::dot; - break; - case ' ':case '\t': - apply_unquoted_string(buffer_); - transfer_nodes(); - state_ = path_state::expect_dot_or_left_bracket; - break; - case '\r': - apply_unquoted_string(buffer_); - transfer_nodes(); - pre_line_break_state = path_state::expect_dot_or_left_bracket; - state_= path_state::cr; - break; - case '\n': - apply_unquoted_string(buffer_); - transfer_nodes(); - pre_line_break_state = path_state::expect_dot_or_left_bracket; - state_= path_state::lf; - break; - default: - buffer_.push_back(*p_); - break; - }; - ++p_; - ++column_; - break; - case path_state::left_bracket_single_quoted_string: - switch (*p_) - { - case '\'': - selectors_.push_back(std::make_shared(buffer_,positive_start_)); - buffer_.clear(); - state_ = path_state::expect_comma_or_right_bracket; + case path_state::slice_end: + switch (*p_) + { + case ':': + slice.step_ = 0; + state_stack_.back().state = path_state::slice_step; + ++p_; + ++column_; + break; + case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': + slice.is_end_defined = true; + slice.end_ = slice.end_*10 + static_cast(*p_-'0'); + ++p_; + ++column_; + break; + case ',': + case ']': + if (!slice.is_end_defined) + { + ec = jsonpath_errc::expected_slice_end; + return; + } + selectors_.push_back(make_unique_ptr(slice)); + state_stack_.pop_back(); + break; + default: + ec = jsonpath_errc::expected_digit_or_colon_or_comma_or_right_bracket; + return; + } break; - case '\\': - buffer_.push_back(*p_); - if (p_+1 < end_input_) + case path_state::slice_step: + switch (*p_) { - ++p_; - ++column_; - buffer_.push_back(*p_); + case '-': + slice.is_step_positive = false; + slice.step_ = 0; + state_stack_.back().state = path_state::slice_step2; + ++p_; + ++column_; + break; + default: + slice.step_ = 0; + state_stack_.back().state = path_state::slice_step2; + break; } break; - default: - buffer_.push_back(*p_); + case path_state::slice_step2: + switch (*p_) + { + case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': + slice.step_ = slice.step_*10 + static_cast(*p_-'0'); + ++p_; + ++column_; + break; + case ',': + case ']': + if (slice.step_ == 0) + { + ec = jsonpath_errc::expected_slice_step; + return; + } + selectors_.push_back(make_unique_ptr(slice)); + state_stack_.pop_back(); + break; + default: + ec = jsonpath_errc::expected_minus_or_digit_or_comma_or_right_bracket; + return; + } break; - }; - ++p_; - ++column_; - break; - case path_state::left_bracket_double_quoted_string: - switch (*p_) - { - case '\"': - selectors_.push_back(std::make_shared(buffer_,positive_start_)); - buffer_.clear(); - state_ = path_state::expect_comma_or_right_bracket; + case path_state::bracketed_single_quoted_name: + switch (*p_) + { + case '\'': + state_stack_.back().state = path_state::bracketed_name_or_path; + break; + case '\\': + if (p_+1 < end_input_) + { + ++p_; + ++column_; + buffer.push_back(*p_); + } + else + { + ec = jsonpath_errc::unexpected_end_of_input; + return; + } + break; + default: + buffer.push_back(*p_); + break; + }; + ++p_; + ++column_; break; - case '\\': - buffer_.push_back(*p_); - if (p_+1 < end_input_) + case path_state::bracketed_double_quoted_name: + switch (*p_) { - ++p_; - ++column_; - buffer_.push_back(*p_); - } + case '\"': + state_stack_.back().state = path_state::bracketed_name_or_path; + break; + case '\\': + if (p_+1 < end_input_) + { + ++p_; + ++column_; + buffer.push_back(*p_); + } + else + { + ec = jsonpath_errc::unexpected_end_of_input; + return; + } + break; + default: + buffer.push_back(*p_); + break; + }; + ++p_; + ++column_; break; default: - buffer_.push_back(*p_); + ++p_; + ++column_; break; - }; - ++p_; - ++column_; - break; - default: - ++p_; - ++column_; - break; } } - switch (state_) + + switch (state_stack_.back().state) { - case path_state::unquoted_name: + case path_state::unquoted_name: + case path_state::unquoted_name2: { - apply_unquoted_string(buffer_); - transfer_nodes(); + selectors_.push_back(make_unique_ptr(buffer)); + apply_selectors(); + buffer.clear(); + state_stack_.pop_back(); // unquoted_name + break; } - break; - default: - break; + default: + break; } - } - void clear_index() - { - buffer_.clear(); - start_ = 0; - positive_start_ = true; - end_ = 0; - positive_end_ = true; - undefined_end_ = true; - step_ = 1; - positive_step_ = true; + if (state_stack_.size() > 2) + { + ec = jsonpath_errc::unexpected_end_of_input; + return; + } + + JSONCONS_ASSERT(state_stack_.size() == 2); + state_stack_.pop_back(); + + JSONCONS_ASSERT(state_stack_.back().state == path_state::start); + state_stack_.pop_back(); } void end_all() { - for (size_t i = 0; i < stack_.back().size(); ++i) + for (const auto& node : stack_.back()) { - const auto& path = stack_.back()[i].path; - pointer p = stack_.back()[i].val_ptr; + const auto& path = node.path; + pointer p = node.val_ptr; if (p->is_array()) { @@ -962,131 +1695,63 @@ class jsonpath_evaluator : private serializing_context } } - start_ = 0; - } - - void apply_unquoted_string(const string_view_type& name) - { - if (name.length() > 0) - { - for (size_t i = 0; i < stack_.back().size(); ++i) - { - apply_unquoted_string(stack_.back()[i].path, *(stack_.back()[i].val_ptr), name); - } - } - buffer_.clear(); - } - - void apply_unquoted_string(const string_type& path, reference val, const string_view_type& name) - { - if (val.is_object()) - { - if (val.count(name) > 0) - { - nodes_.emplace_back(PathCons()(path,name),std::addressof(val.at(name))); - } - if (recursive_descent_) - { - for (auto it = val.object_range().begin(); it != val.object_range().end(); ++it) - { - if (it->value().is_object() || it->value().is_array()) - { - apply_unquoted_string(path, it->value(), name); - } - } - } - } - else if (val.is_array()) - { - size_t pos = 0; - if (try_string_to_index(name.data(),name.size(),&pos, &positive_start_)) - { - size_t index = positive_start_ ? pos : val.size() - pos; - if (index < val.size()) - { - nodes_.emplace_back(PathCons()(path,index),std::addressof(val[index])); - } - } - else if (name == length_literal() && val.size() > 0) - { - auto temp = std::make_shared(val.size()); - temp_json_values_.push_back(temp); - nodes_.emplace_back(PathCons()(path,name),temp.get()); - } - if (recursive_descent_) - { - for (auto it = val.array_range().begin(); it != val.array_range().end(); ++it) - { - if (it->is_object() || it->is_array()) - { - apply_unquoted_string(path, *it, name); - } - } - } - } - else if (val.is_string()) - { - string_view_type sv = val.as_string_view(); - size_t pos = 0; - if (try_string_to_index(name.data(),name.size(),&pos, &positive_start_)) - { - auto sequence = unicons::sequence_at(sv.data(), sv.data() + sv.size(), pos); - if (sequence.length() > 0) - { - auto temp = std::make_shared(sequence.begin(),sequence.length()); - temp_json_values_.push_back(temp); - nodes_.emplace_back(PathCons()(path,pos),temp.get()); - } - } - else if (name == length_literal() && sv.size() > 0) - { - size_t count = unicons::u32_length(sv.begin(),sv.end()); - auto temp = std::make_shared(count); - temp_json_values_.push_back(temp); - nodes_.emplace_back(PathCons()(path,name),temp.get()); - } - } } void apply_selectors() { + //std::cout << "apply_selectors count: " << selectors_.size() << "\n"; if (selectors_.size() > 0) { - for (size_t i = 0; i < stack_.back().size(); ++i) + for (auto& node : stack_.back()) { - node_type& node = stack_.back()[i]; - apply_selectors(node, node.path, *(node.val_ptr)); + //std::cout << "apply selector to:\n" << pretty_print(*(node.val_ptr)) << "\n"; + for (auto& selector : selectors_) + { + apply_selector(node.path, *(node.val_ptr), *selector, true); + } } selectors_.clear(); } transfer_nodes(); } - void apply_selectors(node_type& node, const string_type& path, reference val) + void apply_selector(const string_type& path, reference val, selector_base& selector, bool process) { - for (const auto& selector : selectors_) + if (process) { - selector->select(node, path, val, nodes_, temp_json_values_); + selector.select(*this, path, val, nodes_); } - if (recursive_descent_) + //std::cout << "*it: " << val << "\n"; + //std::cout << "apply_selectors 1 done\n"; + if (state_stack_.back().is_recursive_descent) { + //std::cout << "is_recursive_descent\n"; if (val.is_object()) { + //std::cout << "is_object\n"; for (auto& nvp : val.object_range()) { - if (nvp.value().is_object() || nvp.value().is_array()) + if (nvp.value().is_array() || nvp.value().is_object()) { - apply_selectors(node,PathCons()(path,nvp.key()),nvp.value()); - } + apply_selector(PathCons()(path,nvp.key()), nvp.value(), selector, true); + } } } else if (val.is_array()) { - for (auto& elem : val.array_range()) + //std::cout << "is_array\n"; + auto first = val.array_range().begin(); + auto last = val.array_range().end(); + for (auto it = first; it != last; ++it) { - if (elem.is_object() || elem.is_array()) + if (it->is_array()) { - apply_selectors(node,path, elem); + apply_selector(PathCons()(path,it - first), *it,selector, true); + //std::cout << "*it: " << *it << "\n"; + } + else if (it->is_object()) + { + apply_selector(PathCons()(path,it - first), *it, selector, !selector.is_filter()); } } } @@ -1095,21 +1760,44 @@ class jsonpath_evaluator : private serializing_context void transfer_nodes() { - stack_.push_back(nodes_); + if (state_stack_.back().is_union) + { + std::set temp(nodes_.begin(), nodes_.end()); + stack_.push_back(std::vector(temp.begin(),temp.end())); + } + else + { + stack_.push_back(std::move(nodes_)); + } nodes_.clear(); - recursive_descent_ = false; + state_stack_.back().is_recursive_descent = false; + state_stack_.back().is_union = false; } - size_t do_line_number() const override + void advance_past_space_character() { - return line_; - } - - size_t do_column_number() const override - { - return column_; + switch (*p_) + { + case ' ':case '\t': + ++p_; + ++column_; + break; + case '\r': + if (p_+1 < end_input_ && *(p_+1) == '\n') + ++p_; + ++line_; + column_ = 1; + ++p_; + break; + case '\n': + ++line_; + column_ = 1; + ++p_; + break; + default: + break; + } } - }; } diff --git a/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/jsonpath_error.hpp b/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/jsonpath_error.hpp new file mode 100644 index 0000000..31ab90a --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/jsonpath_error.hpp @@ -0,0 +1,208 @@ +/// Copyright 2013 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_JSONPATH_JSONPATH_ERROR_HPP +#define JSONCONS_JSONPATH_JSONPATH_ERROR_HPP + +#include +#include + +namespace jsoncons { namespace jsonpath { + +class jsonpath_error : public std::system_error, public virtual json_exception +{ + std::string buffer_; + size_t line_number_; + size_t column_number_; +public: + jsonpath_error(std::error_code ec) + : std::system_error(ec), line_number_(0), column_number_(0) + { + } + jsonpath_error(std::error_code ec, size_t position) + : std::system_error(ec), line_number_(0), column_number_(position) + { + } + jsonpath_error(std::error_code ec, size_t line, size_t column) + : std::system_error(ec), line_number_(line), column_number_(column) + { + } + jsonpath_error(const jsonpath_error& other) = default; + + jsonpath_error(jsonpath_error&& other) = default; + + const char* what() const noexcept override + { + try + { + std::ostringstream os; + os << std::system_error::what(); + if (line_number_ != 0 && column_number_ != 0) + { + os << " at line " << line_number_ << " and column " << column_number_; + } + else if (column_number_ != 0) + { + os << " at position " << column_number_; + } + const_cast(buffer_) = os.str(); + return buffer_.c_str(); + } + catch (...) + { + return std::system_error::what(); + } + } + + size_t line() const noexcept + { + return line_number_; + } + + size_t column() const noexcept + { + return column_number_; + } +#if !defined(JSONCONS_NO_DEPRECATED) + JSONCONS_DEPRECATED("Instead, use line()") + size_t line_number() const noexcept + { + return line(); + } + + JSONCONS_DEPRECATED("Instead, use column()") + size_t column_number() const noexcept + { + return column(); + } +#endif +}; + +enum class jsonpath_errc +{ + ok = 0, + expected_root, + expected_current_node, + expected_right_bracket, + expected_name, + expected_separator, + invalid_filter, + invalid_filter_expected_slash, + invalid_filter_unbalanced_paren, + invalid_filter_unsupported_operator, + invalid_filter_expected_right_brace, + invalid_filter_expected_primary, + expected_slice_start, + expected_slice_end, + expected_slice_step, + expected_left_bracket_token, + expected_minus_or_digit_or_colon_or_comma_or_right_bracket, + expected_digit_or_colon_or_comma_or_right_bracket, + expected_minus_or_digit_or_comma_or_right_bracket, + expected_digit_or_comma_or_right_bracket, + unexpected_operator, + invalid_function_name, + invalid_argument, + function_name_not_found, + parse_error_in_filter, + argument_parse_error, + unidentified_error, + unexpected_end_of_input +}; + +class jsonpath_error_category_impl + : public std::error_category +{ +public: + const char* name() const noexcept override + { + return "jsoncons/jsonpath"; + } + std::string message(int ev) const override + { + switch (static_cast(ev)) + { + case jsonpath_errc::expected_root: + return "Expected $"; + case jsonpath_errc::expected_current_node: + return "Expected @"; + case jsonpath_errc::expected_right_bracket: + return "Expected ]"; + case jsonpath_errc::expected_name: + return "Expected a name following a dot"; + case jsonpath_errc::expected_slice_start: + return "Expected slice start"; + case jsonpath_errc::expected_slice_end: + return "Expected slice end"; + case jsonpath_errc::expected_slice_step: + return "Expected slice step"; + case jsonpath_errc::expected_separator: + return "Expected dot or left bracket separator"; + case jsonpath_errc::invalid_filter: + return "Invalid path filter"; + case jsonpath_errc::invalid_filter_expected_slash: + return "Invalid path filter, expected '/'"; + case jsonpath_errc::invalid_filter_unbalanced_paren: + return "Invalid path filter, unbalanced parenthesis"; + case jsonpath_errc::invalid_filter_unsupported_operator: + return "Unsupported operator"; + case jsonpath_errc::invalid_filter_expected_right_brace: + return "Invalid path filter, expected right brace }"; + case jsonpath_errc::invalid_filter_expected_primary: + return "Invalid path filter, expected primary expression."; + case jsonpath_errc::expected_left_bracket_token: + return "Expected ?,',\",0-9,*"; + case jsonpath_errc::expected_minus_or_digit_or_colon_or_comma_or_right_bracket: + return "Expected - or 0-9 or : or , or ]"; + case jsonpath_errc::expected_minus_or_digit_or_comma_or_right_bracket: + return "Expected - or 0-9 or , or ]"; + case jsonpath_errc::expected_digit_or_comma_or_right_bracket: + return "Expected - or 0-9 or , or ]"; + case jsonpath_errc::expected_digit_or_colon_or_comma_or_right_bracket: + return "Expected 0-9 or : or , or ]"; + case jsonpath_errc::invalid_function_name: + return "Invalid function name"; + case jsonpath_errc::invalid_argument: + return "Invalid argument type"; + case jsonpath_errc::function_name_not_found: + return "Function name not found"; + case jsonpath_errc::parse_error_in_filter: + return "Could not parse JSON expression in a JSONPath filter"; + case jsonpath_errc::argument_parse_error: + return "Could not parse JSON expression passed to JSONPath function"; + case jsonpath_errc::unidentified_error: + return "Unidentified error"; + case jsonpath_errc::unexpected_end_of_input: + return "Unexpected end of jsonpath input"; + default: + return "Unknown jsonpath parser error"; + } + } +}; + +inline +const std::error_category& jsonpath_error_category() +{ + static jsonpath_error_category_impl instance; + return instance; +} + +inline +std::error_code make_error_code(jsonpath_errc result) +{ + return std::error_code(static_cast(result),jsonpath_error_category()); +} + +}} + +namespace std { + template<> + struct is_error_code_enum : public true_type + { + }; +} + +#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/jsonpath_error_category.hpp b/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/jsonpath_error_category.hpp deleted file mode 100644 index 62aa588..0000000 --- a/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/jsonpath_error_category.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/// Copyright 2013 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_JSONPATH_JSONPATH_ERROR_CATEGORY_HPP -#define JSONCONS_JSONPATH_JSONPATH_ERROR_CATEGORY_HPP - -#include -#include - -namespace jsoncons { namespace jsonpath { - -enum class jsonpath_parser_errc -{ - ok = 0, - expected_root = 1, - expected_right_bracket = 2, - expected_name = 3, - expected_separator = 4, - invalid_filter = 5, - invalid_filter_expected_slash = 6, - invalid_filter_unbalanced_paren = 7, - invalid_filter_unsupported_operator = 8, - invalid_filter_expected_right_brace = 9, - invalid_filter_expected_primary = 10, - expected_index = 11, - expected_left_bracket_token = 12, - unexpected_operator = 13 -}; - -class jsonpath_error_category_impl - : public std::error_category -{ -public: - virtual const char* name() const JSONCONS_NOEXCEPT - { - return "jsonpath"; - } - virtual std::string message(int ev) const - { - switch (static_cast(ev)) - { - case jsonpath_parser_errc::expected_root: - return "Expected $"; - case jsonpath_parser_errc::expected_right_bracket: - return "Expected ]"; - case jsonpath_parser_errc::expected_name: - return "Expected a name following a dot"; - case jsonpath_parser_errc::expected_index: - return "Expected index"; - case jsonpath_parser_errc::expected_separator: - return "Expected dot or left bracket separator"; - case jsonpath_parser_errc::invalid_filter: - return "Invalid path filter"; - case jsonpath_parser_errc::invalid_filter_expected_slash: - return "Invalid path filter, expected '/'"; - case jsonpath_parser_errc::invalid_filter_unbalanced_paren: - return "Invalid path filter, unbalanced parenthesis"; - case jsonpath_parser_errc::invalid_filter_unsupported_operator: - return "Unsupported operator"; - case jsonpath_parser_errc::invalid_filter_expected_right_brace: - return "Invalid path filter, expected right brace }"; - case jsonpath_parser_errc::invalid_filter_expected_primary: - return "Invalid path filter, expected primary expression."; - case jsonpath_parser_errc::expected_left_bracket_token: - return "Expected ?,',\",0-9,*"; - default: - return "Unknown jsonpath parser error"; - } - } -}; - -inline -const std::error_category& jsonpath_error_category() -{ - static jsonpath_error_category_impl instance; - return instance; -} - -inline -std::error_code make_error_code(jsonpath_parser_errc result) -{ - return std::error_code(static_cast(result),jsonpath_error_category()); -} - -}} - -namespace std { - template<> - struct is_error_code_enum : public true_type - { - }; -} - -#endif diff --git a/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/jsonpath_filter.hpp b/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/jsonpath_filter.hpp index c3af2ed..9d8cdc2 100644 --- a/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/jsonpath_filter.hpp +++ b/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/jsonpath_filter.hpp @@ -6,44 +6,40 @@ #ifndef JSONCONS_JSONPATH_FILTER_HPP #define JSONCONS_JSONPATH_FILTER_HPP - + #include -#include -#include +#include // std::map #include -#include -#include #include #include #include #include +#include // std::numeric_limits #include -#include "jsonpath_error_category.hpp" +#include namespace jsoncons { namespace jsonpath { namespace detail { -JSONCONS_DEFINE_LITERAL(eqtilde_literal,"=~") -JSONCONS_DEFINE_LITERAL(star_literal,"*") -JSONCONS_DEFINE_LITERAL(forwardslash_literal,"/") -JSONCONS_DEFINE_LITERAL(plus_literal,"+") -JSONCONS_DEFINE_LITERAL(minus_literal,"-") -JSONCONS_DEFINE_LITERAL(lt_literal,"<") -JSONCONS_DEFINE_LITERAL(lte_literal,"<=") -JSONCONS_DEFINE_LITERAL(gt_literal,">") -JSONCONS_DEFINE_LITERAL(gte_literal,">=") -JSONCONS_DEFINE_LITERAL(eq_literal,"==") -JSONCONS_DEFINE_LITERAL(ne_literal,"!=") -JSONCONS_DEFINE_LITERAL(ampamp_literal,"&&") -JSONCONS_DEFINE_LITERAL(pipepipe_literal,"||") -JSONCONS_DEFINE_LITERAL(max_literal,"max") -JSONCONS_DEFINE_LITERAL(min_literal,"min") +JSONCONS_STRING_LITERAL(eqtilde,'=','~') +JSONCONS_STRING_LITERAL(star,'*') +JSONCONS_STRING_LITERAL(forwardslash,'/') +JSONCONS_STRING_LITERAL(plus,'+') +JSONCONS_STRING_LITERAL(minus,'-') +JSONCONS_STRING_LITERAL(lt,'<') +JSONCONS_STRING_LITERAL(lte,'<','=') +JSONCONS_STRING_LITERAL(gt,'>') +JSONCONS_STRING_LITERAL(gte,'>','=') +JSONCONS_STRING_LITERAL(eq,'=','=') +JSONCONS_STRING_LITERAL(ne,'!', '=') +JSONCONS_STRING_LITERAL(ampamp,'&','&') +JSONCONS_STRING_LITERAL(pipepipe,'|','|') template struct PathConstructor { typedef typename Json::char_type char_type; typedef typename Json::string_view_type string_view_type; - typedef typename Json::string_type string_type; + typedef std::basic_string string_type; string_type operator()(const string_type& path, size_t index) const { @@ -82,8 +78,8 @@ template struct VoidPathConstructor { typedef typename Json::char_type char_type; + typedef std::basic_string string_type; typedef typename Json::string_view_type string_view_type; - typedef typename Json::string_type string_type; string_type operator()(const string_type&, size_t) const { @@ -101,11 +97,16 @@ template class jsonpath_evaluator; +enum class filter_path_mode +{ + path, + root_path, + current_path +}; + enum class filter_state { start, - cr, - lf, expect_right_round_bracket, expect_oper_or_right_round_bracket, expect_path_or_value_or_unary_op, @@ -117,7 +118,12 @@ enum class filter_state path, value, oper, - function_argument, + expect_arg, + path_argument, + unquoted_argument, + single_quoted_argument, + double_quoted_argument, + expect_more_args_or_right_round_bracket, done }; @@ -134,130 +140,129 @@ template class term { public: - typedef typename Json::string_type string_type; typedef typename Json::char_type char_type; + typedef std::basic_string string_type; virtual ~term() {} - virtual void initialize(const Json&) - { - } + virtual void initialize(const Json&) = 0; + virtual bool accept_single_node() const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } - virtual Json evaluate_single_node() const + virtual Json get_single_node() const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool exclaim() const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool eq_term(const term&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool eq(const Json&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool ne_term(const term&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool ne(const Json&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool regex_term(const term&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool regex2(const string_type&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool ampamp_term(const term&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool ampamp(const Json&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool pipepipe_term(const term&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool pipepipe(const Json&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool lt_term(const term&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool lt(const Json&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool gt_term(const term&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual bool gt(const Json&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual Json minus_term(const term&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual Json minus(const Json&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual Json left_minus(const Json&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual Json unary_minus() const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual Json plus_term(const term&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual Json plus(const Json&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual Json mult_term(const term&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual Json mult(const Json&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual Json div_term(const term&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual Json div(const Json&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } virtual Json left_div(const Json&) const { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,1,1); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator); } }; @@ -271,56 +276,35 @@ struct operator_properties operator_type op; }; -template -struct function_properties -{ - typedef std::function&)> function_type; - - size_t precedence_level; - bool is_right_associative; - bool is_aggregate; - function_type op; -}; - template class token { +public: + typedef std::function&)> unary_operator_type; + typedef std::function&, const term&)> operator_type; +private: token_type type_; size_t precedence_level_; bool is_right_associative_; - bool is_aggregate_; std::shared_ptr> operand_ptr_; - std::function&)> unary_operator_; - std::function&, const term&)> operator_; + unary_operator_type unary_operator_; + operator_type operator_; public: - typedef std::function&)> unary_operator_type; - typedef std::function&, const term&)> operator_type; - - Json operator()(const term& a) - { - return unary_operator_(a); - } - - Json operator()(const term& a, const term& b) - { - return operator_(a,b); - } token(token_type type) - : type_(type),precedence_level_(0),is_right_associative_(false),is_aggregate_(false) + : type_(type),precedence_level_(0),is_right_associative_(false) { } token(token_type type, std::shared_ptr> term_ptr) - : type_(type),precedence_level_(0),is_right_associative_(false),is_aggregate_(false),operand_ptr_(term_ptr) + : type_(type),precedence_level_(0),is_right_associative_(false),operand_ptr_(term_ptr) { } token(size_t precedence_level, bool is_right_associative, - std::function&)> unary_operator) + unary_operator_type unary_operator) : type_(token_type::unary_operator), precedence_level_(precedence_level), is_right_associative_(is_right_associative), - is_aggregate_(false), unary_operator_(unary_operator) { } @@ -328,23 +312,28 @@ class token : type_(token_type::binary_operator), precedence_level_(properties.precedence_level), is_right_associative_(properties.is_right_associative), - is_aggregate_(false), operator_(properties.op) { } - token(const function_properties& properties) - : type_(token_type::unary_operator), - precedence_level_(properties.precedence_level), - is_right_associative_(properties.is_right_associative), - is_aggregate_(properties.is_aggregate), - unary_operator_(properties.op) + + token(const token& t) = default; + + token_type type() const { + return type_; + } + + Json operator()(const term& a) + { + return unary_operator_(a); + } + + Json operator()(const term& a, const term& b) + { + return operator_(a,b); } - token(const token& t) = default; - //token(token&& t) = default; token& operator=(const token& val) = default; - //token& operator=(token&& val) = default; bool is_operator() const { @@ -386,22 +375,17 @@ class token return is_right_associative_; } - bool is_aggregate() const - { - return is_aggregate_; - } - const term& operand() { JSONCONS_ASSERT(type_ == token_type::operand && operand_ptr_ != nullptr); return *operand_ptr_; } - void initialize(const Json& context_node) + void initialize(const Json& current_node) { if (operand_ptr_.get() != nullptr) { - operand_ptr_->initialize(context_node); + operand_ptr_->initialize(current_node); } } }; @@ -422,15 +406,15 @@ template bool lt(const Json& lhs, const Json& rhs) { bool result = false; - if (lhs. template is() && rhs. template is()) + if (lhs.template is() && rhs.template is()) { - result = lhs. template as() < rhs. template as(); + result = lhs.template as() < rhs.template as(); } - else if (lhs. template is() && rhs. template is()) + else if (lhs.template is() && rhs.template is()) { - result = lhs. template as() < rhs. template as(); + result = lhs.template as() < rhs.template as(); } - else if ((lhs.is_number() && rhs.is_double()) || (lhs.is_double() && rhs.is_number())) + else if (lhs.is_number() && rhs.is_number()) { result = lhs.as_double() < rhs.as_double(); } @@ -451,17 +435,17 @@ template Json plus(const Json& lhs, const Json& rhs) { Json result = Json(jsoncons::null_type()); - if (lhs.is_integer() && rhs.is_integer()) + if (lhs.is_int64() && rhs.is_int64()) { - result = Json(((lhs.as_integer() + rhs.as_integer()))); + result = Json(((lhs.template as() + rhs.template as()))); } - else if ((lhs.is_number() && rhs.is_double()) || (lhs.is_double() && rhs.is_number())) + else if (lhs.is_uint64() && rhs.is_uint64()) { - result = Json((lhs.as_double() + rhs.as_double())); + result = Json((lhs.template as() + rhs.template as())); } - else if (lhs.is_uinteger() && rhs.is_uinteger()) + else if ((lhs.is_number() && rhs.is_number())) { - result = Json((lhs.as_uinteger() + rhs.as_uinteger())); + result = Json((lhs.as_double() + rhs.as_double())); } return result; } @@ -470,17 +454,17 @@ template Json mult(const Json& lhs, const Json& rhs) { Json result = Json(jsoncons::null_type()); - if (lhs.is_integer() && rhs.is_integer()) + if (lhs.is_int64() && rhs.is_int64()) { - result = Json(((lhs.as_integer() * rhs.as_integer()))); + result = Json(((lhs.template as() * rhs.template as()))); } - else if ((lhs.is_number() && rhs.is_double()) || (lhs.is_double() && rhs.is_number())) + else if (lhs.is_uint64() && rhs.is_uint64()) { - result = Json((lhs.as_double() * rhs.as_double())); + result = Json((lhs.template as() * rhs.template as())); } - else if (lhs.is_uinteger() && rhs.is_uinteger()) + else if ((lhs.is_number() && rhs.is_number())) { - result = Json((lhs.as_uinteger() * rhs.as_uinteger())); + result = Json((lhs.as_double() * rhs.as_double())); } return result; } @@ -489,17 +473,17 @@ template Json div(const Json& lhs, const Json& rhs) { Json result = Json(jsoncons::null_type()); - if (lhs.is_integer() && rhs.is_integer()) + if (lhs.is_int64() && rhs.is_int64()) { - result = Json((double)(lhs.as_integer() / (double)rhs.as_integer())); + result = Json((double)(lhs.template as() / (double)rhs.template as())); } - else if ((lhs.is_number() && rhs.is_double()) || (lhs.is_double() && rhs.is_number())) + else if (lhs.is_uint64() && rhs.is_uint64()) { - result = Json((lhs.as_double() / rhs.as_double())); + result = Json((double)(lhs.template as() / (double)rhs.template as())); } - else if (lhs.is_uinteger() && rhs.is_uinteger()) + else if ((lhs.is_number() && rhs.is_number())) { - result = Json((double)(lhs.as_uinteger() / (double)rhs.as_uinteger())); + result = Json((lhs.as_double() / rhs.as_double())); } return result; } @@ -508,9 +492,9 @@ template Json unary_minus(const Json& lhs) { Json result = Json::null(); - if (lhs.is_integer()) + if (lhs.is_int64()) { - result = -lhs.as_integer(); + result = -lhs.template as(); } else if (lhs.is_double()) { @@ -523,17 +507,17 @@ template Json minus(const Json& lhs, const Json& rhs) { Json result = Json::null(); - if (lhs.is_integer() && rhs.is_integer()) + if (lhs.is_int64() && rhs.is_int64()) { - result = ((lhs.as_integer() - rhs.as_integer())); + result = ((lhs.template as() - rhs.template as())); } - else if ((lhs.is_number() && rhs.is_double()) || (lhs.is_double() && rhs.is_number())) + else if (lhs.is_uint64() && rhs.is_uint64() && lt(rhs,lhs)) { - result = (lhs.as_double() - rhs.as_double()); + result = (lhs.template as() - rhs.template as()); } - else if (lhs.is_uinteger() && rhs.is_uinteger() && lt(rhs,lhs)) + else if ((lhs.is_number() && rhs.is_number())) { - result = (lhs.as_uinteger() - rhs.as_uinteger()); + result = (lhs.as_double() - rhs.as_double()); } return result; } @@ -543,18 +527,25 @@ class value_term final : public term { Json value_; public: - template - value_term(const T& val) + value_term(const Json& val) : value_(val) { } + value_term(Json&& val) + : value_(std::move(val)) + { + } + + void initialize(const Json&) override + { + } bool accept_single_node() const override { return value_.as_bool(); } - Json evaluate_single_node() const override + Json get_single_node() const override { return value_; } @@ -678,7 +669,7 @@ template class regex_term final : public term { typedef typename Json::char_type char_type; - typedef typename Json::string_type string_type; + typedef std::basic_string string_type; const std::basic_regex pattern_; public: regex_term(const string_type& pattern, std::regex::flag_type flags) @@ -686,6 +677,10 @@ class regex_term final : public term { } + void initialize(const Json&) override + { + } + bool regex2(const string_type& subject) const override { return std::regex_match(subject, pattern_); @@ -695,20 +690,23 @@ class regex_term final : public term template class path_term final : public term { - typedef typename Json::string_type string_type; + typedef typename Json::char_type char_type; + typedef std::basic_string string_type; string_type path_; + size_t line_; + size_t column_; Json nodes_; public: - path_term(const string_type& path) - : path_(path) + path_term(const string_type& path, size_t line, size_t column) + : path_(path), line_(line), column_(column) { } - void initialize(const Json& context_node) override + void initialize(const Json& current_node) override { - jsonpath_evaluator> evaluator; - evaluator.evaluate(context_node,path_); + jsonpath_evaluator> evaluator(line_,column_); + evaluator.evaluate(current_node, path_); nodes_ = evaluator.get_values(); } @@ -717,7 +715,7 @@ class path_term final : public term return nodes_.size() != 0; } - Json evaluate_single_node() const override + Json get_single_node() const override { return nodes_.size() == 1 ? nodes_[0] : nodes_; } @@ -984,7 +982,7 @@ token evaluate(const Json& context, std::vector>& tokens) auto rhs = stack.back(); stack.pop_back(); Json val = t(rhs.operand()); - stack.push_back(token(token_type::operand,std::make_shared>(val))); + stack.push_back(token(token_type::operand,std::make_shared>(std::move(val)))); } else if (t.is_binary_operator()) { @@ -993,12 +991,12 @@ token evaluate(const Json& context, std::vector>& tokens) auto lhs = stack.back(); stack.pop_back(); Json val = t(lhs.operand(), rhs.operand()); - stack.push_back(token(token_type::operand,std::make_shared>(val))); + stack.push_back(token(token_type::operand,std::make_shared>(std::move(val)))); } } if (stack.size() != 1) { - JSONCONS_THROW(json_exception_impl("Invalid state")); + JSONCONS_THROW(json_runtime_error("Invalid state")); } return stack.back(); @@ -1009,135 +1007,65 @@ class jsonpath_filter_expr { public: std::vector> tokens_; - size_t line_; - size_t column_; public: - - jsonpath_filter_expr(const std::vector>& tokens, size_t line, size_t column) - : tokens_(tokens), line_(line), column_(column) + jsonpath_filter_expr() { } - Json eval(const Json& context_node) + jsonpath_filter_expr(const std::vector>& tokens) + : tokens_(tokens) { - try - { - auto t = evaluate(context_node,tokens_); - - return t.operand().evaluate_single_node(); + } - } - catch (const parse_error& e) - { - throw parse_error(e.code(),line_,column_); - } + Json eval(const Json& current_node) + { + auto t = evaluate(current_node, tokens_); + return t.operand().get_single_node(); } - bool exists(const Json& context_node) + bool exists(const Json& current_node) { - try - { - auto t = evaluate(context_node,tokens_); - return t.operand().accept_single_node(); - } - catch (const parse_error& e) - { - throw parse_error(e.code(),line_,column_); - } + auto t = evaluate(current_node,tokens_); + return t.operand().accept_single_node(); } }; template class jsonpath_filter_parser { - typedef typename Json::string_type string_type; - typedef typename Json::string_view_type string_view_type; typedef typename Json::char_type char_type; + typedef std::basic_string string_type; + typedef typename Json::string_view_type string_view_type; std::vector> output_stack_; std::vector> operator_stack_; std::vector state_stack_; + std::vector path_mode_stack_; size_t line_; size_t column_; static const operator_properties op_properties_[]; - class function_table - { - typedef std::map> function_dictionary; - - const function_dictionary functions_ = - { - { - max_literal(),{1,true,true,[](const term& term) - { - Json a = term.evaluate_single_node(); - - double v = std::numeric_limits::lowest(); - for (const auto& elem : a.array_range()) - { - double x = elem. template as(); - if (x > v) - { - v = x; - } - } - return v; - } - } - }, - { - min_literal(),{1,true,true,[](const term& term) - { - Json a = term.evaluate_single_node(); - - double v = (std::numeric_limits::max)(); - for (const auto& elem : a.array_range()) - { - double x = elem. template as(); - if (x < v) - { - v = x; - } - } - return v; - } - } - } - }; - - public: - - typename function_dictionary::const_iterator find(const string_type& key) const - { - return functions_.find(key); - } - typename function_dictionary::const_iterator end() const - { - return functions_.end(); - } - }; - class binary_operator_table { typedef std::map> binary_operator_map; const binary_operator_map operators = { - {eqtilde_literal(),{2,false,[](const term& a, const term& b) {return Json(a.regex_term(b)); }}}, - {star_literal(),{3,false,[](const term& a, const term& b) {return a.mult_term(b); }}}, - {forwardslash_literal(),{3,false,[](const term& a, const term& b) {return a.div_term(b); }}}, - {plus_literal(),{4,false,[](const term& a, const term& b) {return a.plus_term(b); }}}, - {minus_literal(),{4,false,[](const term& a, const term& b) {return a.minus_term(b); }}}, - {lt_literal(),{5,false,[](const term& a, const term& b) {return Json(a.lt_term(b)); }}}, - {lte_literal(),{5,false,[](const term& a, const term& b) {return Json(a.lt_term(b) || a.eq_term(b)); }}}, - {gt_literal(),{5,false,[](const term& a, const term& b) {return Json(a.gt_term(b)); }}}, - {gte_literal(),{5,false,[](const term& a, const term& b) {return Json(a.gt_term(b) || a.eq_term(b)); }}}, - {eq_literal(),{6,false,[](const term& a, const term& b) {return Json(a.eq_term(b)); }}}, - {ne_literal(),{6,false,[](const term& a, const term& b) {return Json(a.ne_term(b)); }}}, - {ampamp_literal(),{7,false,[](const term& a, const term& b) {return Json(a.ampamp_term(b)); }}}, - {pipepipe_literal(),{8,false,[](const term& a, const term& b) {return Json(a.pipepipe_term(b)); }}} + {eqtilde_literal(),{2,false,[](const term& a, const term& b) -> Json {return Json(a.regex_term(b)); }}}, + {star_literal(),{3,false,[](const term& a, const term& b) -> Json {return a.mult_term(b); }}}, + {forwardslash_literal(),{3,false,[](const term& a, const term& b) -> Json {return a.div_term(b); }}}, + {plus_literal(),{4,false,[](const term& a, const term& b) -> Json {return a.plus_term(b); }}}, + {minus_literal(),{4,false,[](const term& a, const term& b) -> Json {return a.minus_term(b); }}}, + {lt_literal(),{5,false,[](const term& a, const term& b) -> Json {return Json(a.lt_term(b)); }}}, + {lte_literal(),{5,false,[](const term& a, const term& b) -> Json {return Json(a.lt_term(b) || a.eq_term(b)); }}}, + {gt_literal(),{5,false,[](const term& a, const term& b) -> Json {return Json(a.gt_term(b)); }}}, + {gte_literal(),{5,false,[](const term& a, const term& b) -> Json {return Json(a.gt_term(b) || a.eq_term(b)); }}}, + {eq_literal(),{6,false,[](const term& a, const term& b) -> Json {return Json(a.eq_term(b)); }}}, + {ne_literal(),{6,false,[](const term& a, const term& b) -> Json {return Json(a.ne_term(b)); }}}, + {ampamp_literal(),{7,false,[](const term& a, const term& b) -> Json {return Json(a.ampamp_term(b)); }}}, + {pipepipe_literal(),{8,false,[](const term& a, const term& b) -> Json {return Json(a.pipepipe_term(b)); }}} }; public: @@ -1151,7 +1079,6 @@ class jsonpath_filter_parser } }; - function_table functions_; binary_operator_table binary_operators_; public: @@ -1174,11 +1101,6 @@ class jsonpath_filter_parser return column_; } - jsonpath_filter_expr parse(const Json& root, const char_type* p, size_t length, const char_type** end_ptr) - { - return parse(root, p,p+length, end_ptr); - } - void push_state(filter_state state) { state_stack_.push_back(state); @@ -1186,65 +1108,68 @@ class jsonpath_filter_parser filter_state pop_state() { - if (state_stack_.empty()) - { - JSONCONS_THROW(json_exception_impl("Invalid state")); - } + JSONCONS_ASSERT(!state_stack_.empty()) filter_state state = state_stack_.back(); state_stack_.pop_back(); return state; } - void add_token(token token) + void push_token(token token) { - if (token.is_operand()) - { - output_stack_.push_back(token); - } - else if (token.is_lparen()) - { - operator_stack_.push_back(token); - } - else if (token.is_rparen()) - { - auto it = operator_stack_.rbegin(); - while (it != operator_stack_.rend() && !it->is_lparen()) - { - output_stack_.push_back(*it); - ++it; - } - if (it == operator_stack_.rend()) - { - JSONCONS_THROW(json_exception_impl("Unbalanced parenthesis")); - } - operator_stack_.erase(it.base(),operator_stack_.end()); - operator_stack_.pop_back(); - } - else if (token.is_operator()) + switch (token.type()) { - if (operator_stack_.empty() || operator_stack_.back().is_lparen()) - { - operator_stack_.push_back(token); - } - else if (token.precedence_level() < operator_stack_.back().precedence_level() - || (token.precedence_level() == operator_stack_.back().precedence_level() && token.is_right_associative())) - { + case token_type::operand: + output_stack_.push_back(token); + break; + case token_type::lparen: operator_stack_.push_back(token); - } - else + break; + case token_type::rparen: + { + auto it = operator_stack_.rbegin(); + while (it != operator_stack_.rend() && !it->is_lparen()) + { + output_stack_.push_back(*it); + ++it; + } + if (it == operator_stack_.rend()) + { + JSONCONS_THROW(json_runtime_error("Unbalanced parenthesis")); + } + operator_stack_.erase(it.base(),operator_stack_.end()); + operator_stack_.pop_back(); + break; + } + case token_type::unary_operator: + case token_type::binary_operator: { - auto it = operator_stack_.rbegin(); - while (it != operator_stack_.rend() && it->is_operator() - && (token.precedence_level() > it->precedence_level() - || (token.precedence_level() == it->precedence_level() && token.is_right_associative()))) + if (operator_stack_.empty() || operator_stack_.back().is_lparen()) + { + operator_stack_.push_back(token); + } + else if (token.precedence_level() < operator_stack_.back().precedence_level() + || (token.precedence_level() == operator_stack_.back().precedence_level() && token.is_right_associative())) { - output_stack_.push_back(*it); - ++it; + operator_stack_.push_back(token); } + else + { + auto it = operator_stack_.rbegin(); + while (it != operator_stack_.rend() && it->is_operator() + && (token.precedence_level() > it->precedence_level() + || (token.precedence_level() == it->precedence_level() && token.is_right_associative()))) + { + output_stack_.push_back(*it); + ++it; + } - operator_stack_.erase(it.base(),operator_stack_.end()); - operator_stack_.push_back(token); + operator_stack_.erase(it.base(),operator_stack_.end()); + operator_stack_.push_back(token); + } + break; } + default: + break; } } @@ -1255,6 +1180,8 @@ class jsonpath_filter_parser state_stack_.clear(); string_type buffer; + size_t buffer_line = 1; + size_t buffer_column = 1; int depth = 0; filter_state state = filter_state::start; @@ -1262,106 +1189,205 @@ class jsonpath_filter_parser { switch (state) { - case filter_state::cr: - ++line_; - column_ = 1; - switch (*p) + case filter_state::start: + switch (*p) + { + case '\r': + if (p+1 < end_expr && *(p+1) == '\n') + ++p; + ++line_; + column_ = 1; + ++p; + break; + case '\n': + ++line_; + column_ = 1; + ++p; + break; + case '(': + state = filter_state::expect_path_or_value_or_unary_op; + ++depth; + push_token(token(token_type::lparen)); + break; + case ')': + state = filter_state::expect_path_or_value_or_unary_op; + push_token(token(token_type::rparen)); + if (--depth == 0) + { + state = filter_state::done; + } + break; + } + ++p; + ++column_; + break; + + case filter_state::expect_arg: { - case '\n': - state = pop_state(); + switch (*p) + { + case ' ':case '\t': + break; + case '\r': + if (p+1 < end_expr && *(p+1) == '\n') + ++p; + ++line_; + column_ = 1; + ++p; + break; + case '\n': + ++line_; + column_ = 1; + ++p; + break; + case '$': + buffer.push_back(*p); + path_mode_stack_.back() = filter_path_mode::root_path; + state = filter_state::path_argument; + break; + case '@': + buffer.push_back('$'); + path_mode_stack_.back() = filter_path_mode::current_path; + state = filter_state::path_argument; + break; + // Maybe error from here down + case '\'': + buffer.push_back('\"'); + state = filter_state::single_quoted_argument; + break; + case '\"': + buffer.push_back('\"'); + state = filter_state::double_quoted_argument; + break; + default: + buffer.push_back(*p); + state = filter_state::unquoted_argument; + break; + } ++p; ++column_; break; - default: - state = pop_state(); - break; } - break; - case filter_state::lf: - ++line_; - column_ = 1; - state = pop_state(); - break; - case filter_state::start: - switch (*p) + + case filter_state::path_argument: { - case '\r': - push_state(state); - state = filter_state::cr; + switch (*p) + { + case '\r': + if (p+1 < end_expr && *(p+1) == '\n') + ++p; + ++line_; + column_ = 1; + ++p; + break; + case '\n': + ++line_; + column_ = 1; + ++p; + break; + case ' ':case '\t': + break; + case ',': + buffer.push_back(*p); + state = filter_state::expect_arg; + break; + case ')': + { + buffer.push_back(*p); + state = filter_state::path; + break; + } + default: + buffer.push_back(*p); + break; + } + ++p; + ++column_; break; - case '\n': - push_state(state); - state = filter_state::lf; + } + case filter_state::single_quoted_argument: + { + switch (*p) + { + case '\'': + buffer.push_back('\"'); + state = filter_state::expect_more_args_or_right_round_bracket; + break; + default: + buffer.push_back(*p); + break; + } + ++p; + ++column_; break; - case '(': - state = filter_state::expect_path_or_value_or_unary_op; - ++depth; - add_token(token(token_type::lparen)); + } + case filter_state::double_quoted_argument: + { + switch (*p) + { + case '\"': + buffer.push_back('\"'); + state = filter_state::expect_more_args_or_right_round_bracket; + break; + default: + buffer.push_back(*p); + break; + } + ++p; + ++column_; break; - case ')': - state = filter_state::expect_path_or_value_or_unary_op; - add_token(token(token_type::rparen)); - if (--depth == 0) + } + case filter_state::unquoted_argument: + { + switch (*p) { - state = filter_state::done; + case ',': + buffer.push_back(*p); + state = filter_state::expect_arg; + break; + case ')': + { + buffer.push_back(*p); + state = filter_state::path; + break; + } + default: + buffer.push_back(*p); + break; } + ++p; + ++column_; break; } - ++p; - ++column_; - break; - case filter_state::function_argument: + case filter_state::expect_more_args_or_right_round_bracket: { switch (*p) { - case '\r': - push_state(state); - state = filter_state::cr; - break; - case '\n': - push_state(state); - state = filter_state::lf; - break; - case ' ':case '\t': - break; - case ')': - if (buffer.length() > 0) + case ' ': + case '\t': + break; + case ',': + buffer.push_back(*p); + state = filter_state::expect_arg; + break; + case ')': { - if (operator_stack_.back().is_aggregate()) - { - try - { - // path, parse against root, get value - jsonpath_evaluator> evaluator; - evaluator.evaluate(root,buffer.data(),buffer.length()); - auto result = evaluator.get_values(); - add_token(token(token_type::operand,std::make_shared>(result))); - } - catch (const parse_error& e) - { - throw parse_error(e.code(),line_,column_); - } - } - else - { - add_token(token(token_type::operand,std::make_shared>(buffer))); - } - buffer.clear(); - state = filter_state::expect_oper_or_right_round_bracket; + buffer.push_back(*p); + state = filter_state::path; + break; } - break; - default: - buffer.push_back(*p); - break; + default: + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator, line_, column_); } ++p; ++column_; + break; } - break; + case filter_state::oper: switch (*p) { - case '~': + case '~': { buffer.push_back(*p); ++p; @@ -1369,16 +1395,17 @@ class jsonpath_filter_parser auto it = binary_operators_.find(buffer); if (it == binary_operators_.end()) { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator, line_, column_); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator, line_, column_); } buffer.clear(); - add_token(token(it->second)); + buffer_line = buffer_column = 1; + push_token(token(it->second)); state = filter_state::expect_regex; + break; } - break; - case '=': - case '&': - case '|': + case '=': + case '&': + case '|': { buffer.push_back(*p); ++p; @@ -1386,123 +1413,123 @@ class jsonpath_filter_parser auto it = binary_operators_.find(buffer); if (it == binary_operators_.end()) { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator, line_, column_); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator, line_, column_); } buffer.clear(); - add_token(token(it->second)); + buffer_line = buffer_column = 1; + push_token(token(it->second)); state = filter_state::expect_path_or_value_or_unary_op; + break; } - break; - default: + default: { auto it = binary_operators_.find(buffer); if (it == binary_operators_.end()) { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator, line_, column_); + throw jsonpath_error(jsonpath_errc::invalid_filter_unsupported_operator, line_, column_); } buffer.clear(); - add_token(token(it->second)); + buffer_line = buffer_column = 1; + push_token(token(it->second)); state = filter_state::expect_path_or_value_or_unary_op; + break; } - break; } break; case filter_state::unquoted_text: { switch (*p) { - case ' ':case '\t': - if (buffer.length() > 0) - { - try + case ' ':case '\t': + if (buffer.length() > 0) { - auto val = Json::parse(buffer); - add_token(token(token_type::operand,std::make_shared>(val))); - } - catch (const parse_error& e) - { - throw parse_error(e.code(),line_,column_); + try + { + auto val = Json::parse(buffer); + push_token(token(token_type::operand,std::make_shared>(std::move(val)))); + } + catch (const ser_error&) + { + throw jsonpath_error(jsonpath_errc::parse_error_in_filter,line_,column_); + } + buffer.clear(); + buffer_line = buffer_column = 1; } - buffer.clear(); - } - ++p; - ++column_; - break; - case '(': - { - auto it = functions_.find(buffer); - if (it == functions_.end()) + ++p; + ++column_; + break; + case '(': { - throw parse_error(jsonpath_parser_errc::invalid_filter_unsupported_operator,line_,column_); + buffer.push_back(*p); + path_mode_stack_.push_back(filter_path_mode::path); + state = filter_state::expect_arg; + ++p; + ++column_; + break; } - add_token(token(it->second)); - state = filter_state::function_argument; - buffer.clear(); - ++p; - ++column_; - break; - } - case '<': - case '>': - case '!': - case '=': - case '&': - case '|': - case '+': - case '-': - case '*': - case '/': - { + case '<': + case '>': + case '!': + case '=': + case '&': + case '|': + case '+': + case '-': + case '*': + case '/': + { + if (buffer.length() > 0) + { + try + { + auto val = Json::parse(buffer); + push_token(token(token_type::operand,std::make_shared>(std::move(val)))); + } + catch (const ser_error&) + { + throw jsonpath_error(jsonpath_errc::parse_error_in_filter,line_,column_); + } + buffer.clear(); + buffer_line = buffer_column = 1; + } + buffer.push_back(*p); + state = filter_state::oper; + ++p; + ++column_; + } + break; + case ')': if (buffer.length() > 0) { try { auto val = Json::parse(buffer); - add_token(token(token_type::operand,std::make_shared>(val))); + push_token(token(token_type::operand,std::make_shared>(std::move(val)))); } - catch (const parse_error& e) + catch (const ser_error&) { - throw parse_error(e.code(),line_,column_); + throw jsonpath_error(jsonpath_errc::parse_error_in_filter,line_,column_); } buffer.clear(); + buffer_line = buffer_column = 1; } - buffer.push_back(*p); - state = filter_state::oper; - ++p; - ++column_; - } - break; - case ')': - if (buffer.length() > 0) - { - try + push_token(token(token_type::rparen)); + if (--depth == 0) { - auto val = Json::parse(buffer); - add_token(token(token_type::operand,std::make_shared>(val))); + state = filter_state::done; } - catch (const parse_error& e) + else { - throw parse_error(e.code(),line_,column_); + state = filter_state::expect_path_or_value_or_unary_op; } - buffer.clear(); - } - add_token(token(token_type::rparen)); - if (--depth == 0) - { - state = filter_state::done; - } - else - { - state = filter_state::expect_path_or_value_or_unary_op; - } - ++p; - ++column_; - break; - default: - buffer.push_back(*p); - ++p; - ++column_; - break; + ++p; + ++column_; + break; + default: + buffer.push_back(*p); + ++p; + ++column_; + break; } } break; @@ -1510,36 +1537,37 @@ class jsonpath_filter_parser { switch (*p) { - case '\\': - buffer.push_back(*p); - if (p+1 < end_expr) - { - ++p; - ++column_; + case '\\': buffer.push_back(*p); - } - break; - case '\'': - buffer.push_back('\"'); - //if (buffer.length() > 0) - { - try + if (p+1 < end_expr) { - auto val = Json::parse(buffer); - add_token(token(token_type::operand,std::make_shared>(val))); + ++p; + ++column_; + buffer.push_back(*p); } - catch (const parse_error& e) + break; + case '\'': + buffer.push_back('\"'); + //if (buffer.length() > 0) { - throw parse_error(e.code(),line_,column_); + try + { + auto val = Json::parse(buffer); + push_token(token(token_type::operand,std::make_shared>(std::move(val)))); + } + catch (const ser_error&) + { + throw jsonpath_error(jsonpath_errc::parse_error_in_filter,line_,column_); + } + buffer.clear(); + buffer_line = buffer_column = 1; } - buffer.clear(); - } - state = filter_state::expect_path_or_value_or_unary_op; - break; + state = filter_state::expect_path_or_value_or_unary_op; + break; - default: - buffer.push_back(*p); - break; + default: + buffer.push_back(*p); + break; } } ++p; @@ -1549,36 +1577,34 @@ class jsonpath_filter_parser { switch (*p) { - case '\\': - buffer.push_back(*p); - if (p+1 < end_expr) - { - ++p; - ++column_; + case '\\': + buffer.push_back(*p); + if (p+1 < end_expr) + { + ++p; + ++column_; + buffer.push_back(*p); + } + break; + case '\"': buffer.push_back(*p); - } - break; - case '\"': - buffer.push_back(*p); - //if (buffer.length() > 0) - { try { auto val = Json::parse(buffer); - add_token(token(token_type::operand,std::make_shared>(val))); + push_token(token(token_type::operand,std::make_shared>(std::move(val)))); } - catch (const parse_error& e) + catch (const ser_error&) { - throw parse_error(e.code(),line_,column_); + throw jsonpath_error(jsonpath_errc::parse_error_in_filter,line_,column_); } buffer.clear(); - } - state = filter_state::expect_path_or_value_or_unary_op; - break; + buffer_line = buffer_column = 1; + state = filter_state::expect_path_or_value_or_unary_op; + break; - default: - buffer.push_back(*p); - break; + default: + buffer.push_back(*p); + break; } } ++p; @@ -1587,149 +1613,159 @@ class jsonpath_filter_parser case filter_state::expect_path_or_value_or_unary_op: switch (*p) { - case '\r': - push_state(state); - state = filter_state::cr; - ++p; - break; - case '\n': - push_state(state); - state = filter_state::lf; - ++p; - break; - case ' ':case '\t': - ++p; - ++column_; - break; - case '!': - { - std::function&)> f = [](const term& b) {return Json(b.exclaim());}; - add_token(token(1, true, f)); - ++p; - ++column_; - break; - } - case '-': - { - std::function&)> f = [](const term& b) {return b.unary_minus();}; - add_token(token(1, true, f)); - ++p; - ++column_; - break; - } - case '@': - buffer.push_back(*p); - state = filter_state::path; - ++p; - ++column_; - break; - case '\'': - buffer.push_back('\"'); - state = filter_state::single_quoted_text; - ++p; - ++column_; - break; - case '\"': - buffer.push_back(*p); - state = filter_state::double_quoted_text; - ++p; - ++column_; - break; - case '(': - ++depth; - add_token(token(token_type::lparen)); - ++p; - ++column_; - break; - case ')': - add_token(token(token_type::rparen)); - if (--depth == 0) + case '\r': + if (p+1 < end_expr && *(p+1) == '\n') + ++p; + ++line_; + column_ = 1; + ++p; + break; + case '\n': + ++line_; + column_ = 1; + ++p; + break; + case ' ':case '\t': + ++p; + ++column_; + break; + case '!': { - state = filter_state::done; + std::function&)> f = [](const term& b) {return Json(b.exclaim());}; + push_token(token(1, true, f)); + ++p; + ++column_; + break; } - ++p; - ++column_; - break; - default: - // don't increment - state = filter_state::unquoted_text; - break; + case '-': + { + std::function&)> f = [](const term& b) {return b.unary_minus();}; + push_token(token(1, true, f)); + ++p; + ++column_; + break; + } + case '@': + buffer_line = line_; + buffer_column = column_; + buffer.push_back('$'); + state = filter_state::path; + ++p; + ++column_; + break; + case '\'': + buffer.push_back('\"'); + state = filter_state::single_quoted_text; + ++p; + ++column_; + break; + case '\"': + buffer.push_back(*p); + state = filter_state::double_quoted_text; + ++p; + ++column_; + break; + case '(': + ++depth; + push_token(token(token_type::lparen)); + ++p; + ++column_; + break; + case ')': + push_token(token(token_type::rparen)); + if (--depth == 0) + { + state = filter_state::done; + } + ++p; + ++column_; + break; + default: + // don't increment + state = filter_state::unquoted_text; + break; }; break; case filter_state::expect_oper_or_right_round_bracket: switch (*p) { - case '\r': - push_state(state); - state = filter_state::cr; - ++p; - break; - case '\n': - push_state(state); - state = filter_state::lf; - ++p; - break; - case ' ':case '\t': - ++p; - ++column_; - break; - case ')': - add_token(token(token_type::rparen)); - if (--depth == 0) - { - state = filter_state::done; - ++p; // fix - } - break; - case '<': - case '>': - case '!': - case '=': - case '&': - case '|': - case '+': - case '-': - case '*': - case '/': - { - buffer.push_back(*p); - state = filter_state::oper; + case '\r': + if (p+1 < end_expr && *(p+1) == '\n') + ++p; + ++line_; + column_ = 1; + ++p; + break; + case '\n': + ++line_; + column_ = 1; + ++p; + break; + case ' ':case '\t': ++p; ++column_; - } - break; - default: - throw parse_error(jsonpath_parser_errc::invalid_filter,line_,column_); - break; + break; + case ')': + push_token(token(token_type::rparen)); + if (--depth == 0) + { + state = filter_state::done; + ++p; // fix + } + break; + case '<': + case '>': + case '!': + case '=': + case '&': + case '|': + case '+': + case '-': + case '*': + case '/': + { + buffer.push_back(*p); + state = filter_state::oper; + ++p; + ++column_; + } + break; + default: + throw jsonpath_error(jsonpath_errc::invalid_filter,line_,column_); + break; }; break; case filter_state::expect_right_round_bracket: switch (*p) { - case '\r': - push_state(state); - state = filter_state::cr; - break; - case '\n': - push_state(state); - state = filter_state::lf; - break; - case ' ':case '\t': - break; - case ')': - add_token(token(token_type::rparen)); - if (--depth == 0) - { - state = filter_state::done; - } - else - { - state = filter_state::expect_oper_or_right_round_bracket; - } - break; - default: - throw parse_error(jsonpath_parser_errc::invalid_filter,line_,column_); - break; + case '\r': + if (p+1 < end_expr && *(p+1) == '\n') + ++p; + ++line_; + column_ = 1; + ++p; + break; + case '\n': + ++line_; + column_ = 1; + ++p; + break; + case ' ':case '\t': + break; + case ')': + push_token(token(token_type::rparen)); + if (--depth == 0) + { + state = filter_state::done; + } + else + { + state = filter_state::expect_oper_or_right_round_bracket; + } + break; + default: + throw jsonpath_error(jsonpath_errc::invalid_filter,line_,column_); + break; }; ++p; ++column_; @@ -1737,136 +1773,180 @@ class jsonpath_filter_parser case filter_state::path: switch (*p) { - case '<': - case '>': - case '!': - case '=': - case '&': - case '|': - case '+': - case '-': - case '*': - case '/': - { - if (buffer.length() > 0) + case '<': + case '>': + case '!': + case '=': + case '&': + case '|': + case '+': + case '-': + case '*': + case '/': { - add_token(token(token_type::operand,std::make_shared>(buffer))); + if (!path_mode_stack_.empty()) + { + if (path_mode_stack_[0] == filter_path_mode::root_path) + { + jsonpath_evaluator> evaluator(buffer_line,buffer_column); + evaluator.evaluate(root, buffer); + auto result = evaluator.get_values(); + if (result.size() > 0) + { + push_token(token(token_type::operand,std::make_shared>(std::move(result[0])))); + } + } + else + { + push_token(token(token_type::operand,std::make_shared>(buffer, buffer_line, buffer_column))); + } + path_mode_stack_.pop_back(); + } + else + { + push_token(token(token_type::operand,std::make_shared>(buffer, buffer_line, buffer_column))); + } buffer.clear(); + buffer_line = buffer_column = 1; + buffer.push_back(*p); + ++p; + ++column_; + state = filter_state::oper; + } + break; + case ')': + if (!path_mode_stack_.empty()) + { + if (path_mode_stack_[0] == filter_path_mode::root_path) + { + jsonpath_evaluator> evaluator(buffer_line,buffer_column); + evaluator.evaluate(root, buffer); + auto result = evaluator.get_values(); + if (result.size() > 0) + { + push_token(token(token_type::operand,std::make_shared>(std::move(result[0])))); + } + push_token(token(token_type::rparen)); + } + else + { + push_token(token(token_type::operand,std::make_shared>(buffer, buffer_line, buffer_column))); + } + path_mode_stack_.pop_back(); + } + else + { + push_token(token(token_type::operand,std::make_shared>(buffer, buffer_line, buffer_column))); + push_token(token(token_type::rparen)); + } + buffer.clear(); + buffer_line = buffer_column = 1; + if (--depth == 0) + { + state = filter_state::done; } + else + { + state = filter_state::expect_path_or_value_or_unary_op; + } + ++p; + ++column_; + break; + default: buffer.push_back(*p); ++p; ++column_; - state = filter_state::oper; - } + break; + }; break; - case ')': - if (buffer.length() > 0) - { - add_token(token(token_type::operand,std::make_shared>(buffer))); - add_token(token(token_type::rparen)); - buffer.clear(); - } - if (--depth == 0) - { - state = filter_state::done; - } - else + case filter_state::expect_regex: + switch (*p) { - state = filter_state::expect_path_or_value_or_unary_op; - } - ++p; - ++column_; - break; - default: - buffer.push_back(*p); + case '\r': + if (p+1 < end_expr && *(p+1) == '\n') + ++p; + ++line_; + column_ = 1; + ++p; + break; + case '\n': + ++line_; + column_ = 1; + ++p; + break; + case ' ':case '\t': + break; + case '/': + state = filter_state::regex; + break; + default: + throw jsonpath_error(jsonpath_errc::invalid_filter_expected_slash,line_,column_); + break; + }; ++p; ++column_; break; - }; - break; - case filter_state::expect_regex: - switch (*p) - { - case '\r': - push_state(state); - state = filter_state::cr; - break; - case '\n': - push_state(state); - state = filter_state::lf; - break; - case ' ':case '\t': - break; - case '/': - state = filter_state::regex; - break; - default: - throw parse_error(jsonpath_parser_errc::invalid_filter_expected_slash,line_,column_); - break; - }; - ++p; - ++column_; - break; - case filter_state::regex: + case filter_state::regex: { switch (*p) { - case '/': - //if (buffer.length() > 0) - { - std::regex::flag_type flags = std::regex_constants::ECMAScript; - if (p+1 < end_expr && *(p+1) == 'i') + case '/': + //if (buffer.length() > 0) { - ++p; - ++column_; - flags |= std::regex_constants::icase; + std::regex::flag_type flags = std::regex_constants::ECMAScript; + if (p+1 < end_expr && *(p+1) == 'i') + { + ++p; + ++column_; + flags |= std::regex_constants::icase; + } + push_token(token(token_type::operand,std::make_shared>(buffer,flags))); + buffer.clear(); + buffer_line = buffer_column = 1; } - add_token(token(token_type::operand,std::make_shared>(buffer,flags))); - buffer.clear(); - } - state = filter_state::expect_path_or_value_or_unary_op; - break; + state = filter_state::expect_path_or_value_or_unary_op; + break; - default: - buffer.push_back(*p); - break; + default: + buffer.push_back(*p); + break; } + ++p; + ++column_; + break; } - ++p; - ++column_; - break; - default: - ++p; - ++column_; - break; + default: + ++p; + ++column_; + break; } } if (depth != 0) { - throw parse_error(jsonpath_parser_errc::invalid_filter_unbalanced_paren,line_,column_); + throw jsonpath_error(jsonpath_errc::invalid_filter_unbalanced_paren,line_,column_); } *end_ptr = p; - return jsonpath_filter_expr(output_stack_,line_,column_); + return jsonpath_filter_expr(output_stack_); } }; template const operator_properties jsonpath_filter_parser::op_properties_[] = { - {2,false,[](const term& a, const term& b) {return Json(a.regex_term(b));}}, - {3,false,[](const term& a, const term& b) {return a.mult_term(b);}}, - {3,false,[](const term& a, const term& b) {return a.div_term(b);}}, - {4,false,[](const term& a, const term& b) {return a.plus_term(b);}}, - {4,false,[](const term& a, const term& b) {return a.minus_term(b);}}, - {5,false,[](const term& a, const term& b) {return Json(a.lt_term(b));}}, - {5,false,[](const term& a, const term& b) {return Json(a.lt_term(b) || a.eq_term(b));}}, - {5,false,[](const term& a, const term& b) {return Json(a.gt_term(b));}}, - {5,false,[](const term& a, const term& b) {return Json(a.gt_term(b) || a.eq_term(b));}}, - {6,false,[](const term& a, const term& b) {return Json(a.eq_term(b)); }}, - {6,false,[](const term& a, const term& b) {return Json(a.ne_term(b)); }}, - {7,false,[](const term& a, const term& b) {return Json(a.ampamp_term(b));}}, - {8,false,[](const term& a, const term& b) {return Json(a.pipepipe_term(b));}} + {2,false,[](const term& a, const term& b) -> Json {return Json(a.regex_term(b));}}, + {3,false,[](const term& a, const term& b) -> Json {return a.mult_term(b);}}, + {3,false,[](const term& a, const term& b) -> Json {return a.div_term(b);}}, + {4,false,[](const term& a, const term& b) -> Json {return a.plus_term(b);}}, + {4,false,[](const term& a, const term& b) -> Json {return a.minus_term(b);}}, + {5,false,[](const term& a, const term& b) -> Json {return Json(a.lt_term(b));}}, + {5,false,[](const term& a, const term& b) -> Json {return Json(a.lt_term(b) || a.eq_term(b));}}, + {5,false,[](const term& a, const term& b) -> Json {return Json(a.gt_term(b));}}, + {5,false,[](const term& a, const term& b) -> Json {return Json(a.gt_term(b) || a.eq_term(b));}}, + {6,false,[](const term& a, const term& b) -> Json {return Json(a.eq_term(b)); }}, + {6,false,[](const term& a, const term& b) -> Json {return Json(a.ne_term(b)); }}, + {7,false,[](const term& a, const term& b) -> Json {return Json(a.ampamp_term(b));}}, + {8,false,[](const term& a, const term& b) -> Json {return Json(a.pipepipe_term(b));}} }; }}} diff --git a/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/jsonpath_function.hpp b/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/jsonpath_function.hpp new file mode 100644 index 0000000..9f97f3e --- /dev/null +++ b/invehicle-apps/3rd-party-libs/jsoncons_ext/jsonpath/jsonpath_function.hpp @@ -0,0 +1,225 @@ +// Copyright 2013 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_JSONPATH_JSONPATH_FUNCTION_HPP +#define JSONCONS_JSONPATH_JSONPATH_FUNCTION_HPP + +#include // std::basic_string +#include // std::vector +#include // std::unordered_map +#include // std::numeric_limits +#include // std::move +#include + +namespace jsoncons { namespace jsonpath { + +JSONCONS_STRING_LITERAL(keys,'k','e','y','s') +JSONCONS_STRING_LITERAL(avg,'a','v','g') +JSONCONS_STRING_LITERAL(max,'m','a','x') +JSONCONS_STRING_LITERAL(min,'m','i','n') +JSONCONS_STRING_LITERAL(sum,'s','u','m') +JSONCONS_STRING_LITERAL(prod,'p','r','o','d') +JSONCONS_STRING_LITERAL(count,'c','o','u','n','t') +JSONCONS_STRING_LITERAL(tokenize,'t','o','k','e','n','i','z','e') + +template +class function_table +{ +public: + typedef typename Json::char_type char_type; + typedef typename Json::char_traits_type char_traits_type; + typedef std::basic_string string_type; + typedef typename Json::string_view_type string_view_type; + typedef JsonPointer pointer; + typedef std::vector argument_type; + typedef std::function&, std::error_code&)> function_type; + typedef std::unordered_map function_dictionary; +private: + const function_dictionary functions_ = + { + { + keys_literal(),[](const std::vector& args, std::error_code& ec) -> Json + { + Json j = typename Json::array(); + if (args.size() != 1) + { + ec = jsonpath_errc::invalid_argument; + return j; + } + if (args[0].size() != 1 && !args[0][0]->is_object()) + { + return j; + } + pointer arg = args[0][0]; + for (const auto& kv : arg->object_range()) + { + j.emplace_back(kv.key()); + } + + return j; + } + }, + { + max_literal(),[](const std::vector& args, std::error_code& ec) -> Json + { + if (args.size() != 1) + { + ec = jsonpath_errc::invalid_argument; + return Json(); + } + const auto& arg = args[0]; + double v = std::numeric_limits::lowest(); + for (auto& node : arg) + { + double x = node->template as(); + if (x > v) + { + v = x; + } + } + return Json(v); + } + }, + { + min_literal(),[](const std::vector& args, std::error_code& ec) -> Json + { + if (args.size() != 1) + { + ec = jsonpath_errc::invalid_argument; + return Json(); + } + const auto& arg = args[0]; + double v = (std::numeric_limits::max)(); + for (const auto& node : arg) + { + double x = node->template as(); + if (x < v) + { + v = x; + } + } + return Json(v); + } + }, + { + avg_literal(),[](const std::vector& args, std::error_code& ec) -> Json + { + if (args.size() != 1) + { + ec = jsonpath_errc::invalid_argument; + return Json(); + } + const auto& arg = args[0]; + double v = 0.0; + for (const auto& node : arg) + { + v += node->template as(); + } + return arg.size() > 0 ? Json(v/arg.size()) : Json(null_type()); + } + }, + { + sum_literal(),[](const std::vector& args, std::error_code& ec) -> Json + { + if (args.size() != 1) + { + ec = jsonpath_errc::invalid_argument; + return Json(); + } + const auto& arg = args[0]; + double v = 0.0; + for (const auto& node : arg) + { + v += node->template as(); + } + return Json(v); + } + }, + { + count_literal(),[](const std::vector& args, std::error_code& ec) -> Json + { + if (args.size() != 1) + { + ec = jsonpath_errc::invalid_argument; + return Json(); + } + const auto& arg = args[0]; + size_t count = 0; + while (count < arg.size()) + { + ++count; + } + return Json(count); + } + }, + { + prod_literal(),[](const std::vector& args, std::error_code& ec) -> Json + { + if (args.size() != 1) + { + ec = jsonpath_errc::invalid_argument; + return Json(); + } + const auto& arg = args[0]; + double v = 0.0; + for (const auto& node : arg) + { + double x = node->template as(); + v == 0.0 && x != 0.0 + ? (v = x) + : (v *= x); + + } + return Json(v); + } + } +#if !(defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ < 9)) +// GCC 4.8 has broken regex support: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53631 + ,{ + tokenize_literal(),[](const std::vector& args, std::error_code& ec) -> Json + { + if (args.size() != 2) + { + ec = jsonpath_errc::invalid_argument; + return Json(); + } + string_type arg1 = args[0][0]->as_string(); + string_type arg2 = args[1][0]->as_string(); + + std::regex::flag_type flags = std::regex_constants::ECMAScript; + std::basic_regex pieces_regex(arg2, flags); + + std::regex_token_iterator rit ( arg1.begin(), arg1.end(), pieces_regex, -1); + std::regex_token_iterator rend; + + Json j = typename Json::array(); + while (rit!=rend) + { + j.push_back(rit->str()); + ++rit; + } + return j; + } + } +#endif + }; +public: + function_type get(const string_type& name, std::error_code& ec) const + { + auto it = functions_.find(name); + if (it == functions_.end()) + { + //std::cout << "Function name " << name << " not found\n"; + ec = jsonpath_errc::function_name_not_found; + return nullptr; + } + return it->second; + } +}; + +}} + +#endif diff --git a/invehicle-apps/examples/demo-certificates/CA.key b/invehicle-apps/examples/demo-certificates/CA.key deleted file mode 100644 index 1b76563..0000000 --- a/invehicle-apps/examples/demo-certificates/CA.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEArHvEPTUuDauZ9ZP/Rivz/vCTw5IrW4MM4V8f//DIx0zx9mfQ -HQwpKDTNZ9oO9NHagAqDmolAdZcFEo8vEeCmSaGeoBlIiNy/NVRBIAIxNT0I5nkD -MAcDxd5ICV4OgnaR77p/NgWtTZlz4GAFbV1FraUyOLrK1EOtRsI0i51opbhwUV86 -N09ZR59OBQCMLVeeUqSeTT0lLxwNKiHZFhgRl8JBr94GjvUMKVGQBDixPUO6Y7tt -X0ua2ZwoH9+Gx6kgS0eO2lIp2Dg72ZPpxsy9KoZzNxK3EQcu2FbbpoqerpLua/fC -scOjIoYFjjoYYY0duONDeRzG2rIe3BwwANieDQIDAQABAoIBAEVOnjXyDoVTtNOn -GmY59xsz1Ew7icyFxkExFgyj1imvU3KtmERzxH3xabAXQPdC88eLcgJAsHQPsOwa -ONG4MVlY5gJy5mCIQxTMvDZ+awN3eQITEiLUTsHNZajN8Iqf1lg72i387fxGcvdv -3f5qAjuaK6n79NCCOTg7hR2srIYaA7fUVZxWvybQRjz8WAn26O1ingWzYy9gYNjM -j1pL4BB38M7NYkYUkrDqJEKcIvYAT/TzdqHUWw2fDVyx+zKDBwjGzs8njiX+wBSs -XjVsvJHkNY76BOZrcmaHZmcSXPrOi+kirhZ77vu9oI5NsCbg/PeF66OZ6dmpZKR1 -dz3/6gkCgYEA0xhYzZp5hVdPrNjE3N6ltDVwD8rAqASI0+kbVwg/B5ZLbwXdBS9O -YoZOxEuPpkNpFQI/iePhgpxnaAn3SrC2sJW/5waMyKeDFjL955be2wM9yCFC5jdR -mOhALaHRWTZgyy01p72E2UJuxqtA/VY3wmuc57RPF4bNhXk0VNBDHicCgYEA0Sy8 -pS8UIHMMXhprCXCm4cU2d8JDeYrl0Du+KSyEJkCdDdINv8yUUiF++7yzVQgD7EaF -0+pdCkeRYm7r6RCvMGL6d8P/45iFpfAw6w13xR6f1achJSshnrToTNwF5NkfHasR -IJm9cUdiE76JDcdo1u6Zt4DbKfS6o6JOiQLm9qsCgYBryASfhf4CHSBrSorJk0zc -BGThS06u+xG50U3KVEWKZCzD1SSSnyLQn27cPxBrfgPLXEiA6T+dZqpNrrj7A9tj -sjI3jVqYoR8HWKXXd2r2PGNxKbp0vU4GWp9aLUMs39zwIHdC3DtWitrwyUP3lewG -cte8Xo37nzKUsdwMagG7BQKBgCUhDMdBaRAte8eEZvWBAo5WxElTuUhsyEhDIokK -dtaXZ4lZfMlL1hQSEAk9QJPaXV/mUMEB+8vkUkEnsUZoiMBNAWqa5uQOYcLHtNc0 -R8s8mWCCTxba5hfWwtlJwN4TUDui7uJbh84Avr8Edi109P4Z0j1JaR20bCC5obke -Q8MLAoGAaymxiePVolj+aG7HHQWJgFyEYQdpYPOrfVpdax4Bm62NswV3z2tVfd40 -1LyBQgHf/+hTJuUiE127PIfDRNHfQa5Xsf4zfBZ2tMss/YzrmNZ0YSyAavz6A7lF -lDoVvMsJrkY9N6eh0q9nUBcIt4FWpYlxtpVpIbd6g+QoddT6Gxo= ------END RSA PRIVATE KEY----- diff --git a/invehicle-apps/examples/demo-certificates/CA.pem b/invehicle-apps/examples/demo-certificates/CA.pem index 9935655..573d22c 100644 --- a/invehicle-apps/examples/demo-certificates/CA.pem +++ b/invehicle-apps/examples/demo-certificates/CA.pem @@ -1,22 +1,22 @@ -----BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIJAODr2wPyLenpMA0GCSqGSIb3DQEBCwUAMHQxCzAJBgNV -BAYTAkRFMRMwEQYDVQQIDApTb21lLVN0YXRlMRAwDgYDVQQKDAdFY2xpcHNlMQ4w -DAYDVQQLDAVLdWtzYTESMBAGA1UEAwwJbG9jYWxob3N0MRowGAYJKoZIhvcNAQkB -Fgt5eHpAeHl6LmNvbTAeFw0xODA5MTExMzMzMTFaFw0yMTA3MDExMzMzMTFaMHQx -CzAJBgNVBAYTAkRFMRMwEQYDVQQIDApTb21lLVN0YXRlMRAwDgYDVQQKDAdFY2xp -cHNlMQ4wDAYDVQQLDAVLdWtzYTESMBAGA1UEAwwJbG9jYWxob3N0MRowGAYJKoZI -hvcNAQkBFgt5eHpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBALuvexkuQW4V9LFeKnzyr5ygsNd5uzeFBdJXEz6/I1EoiZd3Y0W6YoKkrocV -O/KbrmlgnLvURQ7X2IqS8f9+BVh5VpCSF1JRKjkMrZ+j7oA8JA/fGb8QY4kujEPT -8QLZ/sXA4U0Tp6xzU18vPrXZCBm5lhdxggntFZzeiT8kLa2/+pO1GQECBCjxM18n -A1sciHXLR4ChR940RefG4e/6vDK3AVt+08BcqzWRhEi1CoUKugmSgJQzaqonPnSn -iLrMDCbUZXfwTF8ShUt8b28Y4+Nux+lAaqWhwDfl1emB2SgEvNhUucY8gbJJ69kS -7ZWkzll4eVcRrkRIEkFH8/chfHECAwEAAaNQME4wHQYDVR0OBBYEFA1c54uyl9PD -B/vPLA/ci9Un5bSUMB8GA1UdIwQYMBaAFA1c54uyl9PDB/vPLA/ci9Un5bSUMAwG -A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFgf2AOEnVsmWOxF8JLo/Wm0 -MhzFS6dTSd4dCeXqieRM6tVz+I+ZfeM+KhMHEYX/0vtbwHxEIYlecxyDX6CfgDIl -q74dHkRrmb9Gq/R57EKsBL8RdCAV3zpvXC7j3OdOFFAxmMB/Jzu9Sdt3MzATcsck -aAWqUr0t+Yu66SU12SRxOadZ8kF+fG+E9JBXEx2KmBGlN8DhuSHlCobubZiLp1iy -axDTXHBJWsuJ0uUMaB/pHXb7TLfgzuaL8Js4u+iP+LIj4XsX+CCplzv2bvCrAwGt -1lb1Gj4ZCpLBb2goBNw72dE27Pjmsj9WEgqK/zDkfDiH98kRiZKGi8If7LzN/2w= +MIIDjTCCAnWgAwIBAgIJAKFM6muNnoa6MA0GCSqGSIb3DQEBCwUAMEMxCzAJBgNV +BAYTAkRFMQswCQYDVQQIDAJCVzEMMAoGA1UEBwwDU3R1MQswCQYDVQQKDAJSQjEM +MAoGA1UECwwDQ0FQMB4XDTE5MDEyMjE2MzE0NloXDTIxMTExMTE2MzE0NlowQzEL +MAkGA1UEBhMCREUxCzAJBgNVBAgMAkJXMQwwCgYDVQQHDANTdHUxCzAJBgNVBAoM +AlJCMQwwCgYDVQQLDANDQVAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCse8Q9NS4Nq5n1k/9GK/P+8JPDkitbgwzhXx//8MjHTPH2Z9AdDCkoNM1n2g70 +0dqACoOaiUB1lwUSjy8R4KZJoZ6gGUiI3L81VEEgAjE1PQjmeQMwBwPF3kgJXg6C +dpHvun82Ba1NmXPgYAVtXUWtpTI4usrUQ61GwjSLnWiluHBRXzo3T1lHn04FAIwt +V55SpJ5NPSUvHA0qIdkWGBGXwkGv3gaO9QwpUZAEOLE9Q7pju21fS5rZnCgf34bH +qSBLR47aUinYODvZk+nGzL0qhnM3ErcRBy7YVtumip6uku5r98Kxw6MihgWOOhhh +jR2440N5HMbash7cHDAA2J4NAgMBAAGjgYMwgYAwHQYDVR0OBBYEFE1BWCMpuM4h +hywPphcP1ehrMbfNMB8GA1UdIwQYMBaAFE1BWCMpuM4hhywPphcP1ehrMbfNMAwG +A1UdEwQFMAMBAf8wMAYDVR0RBCkwJ4IOKi5teWRvbWFpbi5jb22CCWxvY2FsaG9z +dIcErBEAAYcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAGtu4PhnkJJzGEhS8RNdP +eRIo8HFVuUaNM9LHHKquHpqloLp+eueINY/rsJPRgyCShDGZ44HpFIOhOqbOMAHz +UhG7jvLuYB7uxewbgfSX/nEG58GzI0u3tmrBmihmqJ7oE6w6CFxKNuqA0RK884PN +eTi+/XiKfcRNAUtEFjYSpO44GB6aerkF4jdoKSHnJn37vFQfWFbW01brCKthWB5k +DyPV4lcq648Sn5Bkz4n7zQKvw4PyVTgIfm3Kv6MtAL5X3nRu/9JQgqYmZJ+ZUoP+ +EuyMmNq56xW38p90ORE5FYAPFBJwQYMYMlltD2pHbSHEl345GRNvqnyjiFNETpx8 +LQ== -----END CERTIFICATE----- diff --git a/invehicle-apps/examples/demo-certificates/Client.key b/invehicle-apps/examples/demo-certificates/Client.key index b490eff..1352db2 100644 --- a/invehicle-apps/examples/demo-certificates/Client.key +++ b/invehicle-apps/examples/demo-certificates/Client.key @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAzhvjqCkSOIG/EkktKbn9J/zaN/FS7mnm/8ZKwt7NBOFzX5LF -tXunBmHnsTZlB+U9DlLxs2XenkvBsBi5qVk1ezZIdomcCZtWDVB3gY+r6x/WslCQ -GMRTpm829KWqWph2GhwpOFR1TrHpvKNMY3XWSrCfQWHEvzzR5JZN0/0PEcAIeK9X -NgM3SLfAW9aCpzpxHhM/USyrOwIOD8MVnWyAKxmg5TVDGrW6nB0zTs3bVxXQVgcr -W3PANvcQ4DFqIhCc7yivrlogHA62RkD5TADacKMBsZWIOd496VGo7dduXCudIBgQ -7PIE4BUoGze6cB2n0nq712b4x8pNGdl9l+WBwwIDAQABAoIBAEJHf68s/foD50Dn -HUnk0H8Sdc41oZifn7QyvQnrgfyGz4Y1ebTBvdV0mIBJYLXoRvkbPTSWlr9K109c -tB+8W1FzBFxyJiaEuGhxruyQGhXzWCRheeUtBUVpUD/eImkdzCTbV3oQ1uRmnCaY -UNFPLIk6QQxSd2WUFl8u4npAT59CEObNSlYHcqezVyKnxZUvEqfWESN4YxsRcB5W -jM+itv02M/aMIOaKMx/pqoiCVXD4uqgS237ug7df1eGdUxGk4wH7dAOEGMEcR1Xw -YwabzG4dMjkvoF9Xs1RnBtJYDBhBbM38j98wGzNVd5c8VEymt6szce9T9kQeFby1 -tpHcLhECgYEA7VMQvm2fP9AIOb9Gb8uldkCWUIYarmIdP+BbtsL415YDOYRfSrq5 -IHyJdmBkD1MzM+eEoPW/krjKwWJiIgCaeNNy3KDAbEAQXLqd+Vw3nQIbDFrNXT7E -fs2AJfc+TM5xv4k1kJmrg0ghDL4RtnYhTuVlOrTNPKAL2UquLH6iYdsCgYEA3lP7 -jo0RFCk7R7bG//tQeOePs0pN/93ITloUn2myMkIoL179BIasi2yLKzyngTjIogis -sj4IAlLNH26cdlB4pceyAqI4AA44rLniUq7G6EHlInX3Hyycej7bwtDoRrU42b70 -HcRN7GKuMGsbQkRct/ERHiCAFdL6LnCP6mZyqDkCgYEAx9V58986iPES/A0jsl84 -JCqeZ4+ER/I1zuOMVog2INIgRP5BfxtbZw92cEcZ+g2Ev9/iveYwOcuAbvX4y8jW -SYdC4KQ7YutO28YH30DXU03CmNScuDdyHZPMpCtcOjBbd3yBrhC3awQBUEl7gLhX -s6dVZel4J+RcFcvcfXrkIKECgYEA16KE/kH8Kp3DDU9Nu8G4z0toqPCMrnohaT0d -e3A8kVpxN2Dd7qHggGoKoSj3HfJBRkc7mLVpdzdwE+hogKiUG9aP5NYJkqQ4e+7e -gGtcKLCg2Mepo+bU7gxBgba1Ur86IJeAlc5r9bXQVM3NZnx/oTiC7cF/+arjVF+A -dkxfMKECgYAk3JTo1jPBuqTErw3mMo7BKflVchdN7cFD3T7LDovuJv+ItMwCqtv2 -yDmK5/8FGeJeGcHEsvetjO2JgTubb7i4ubu0zSiATO24abYymkaAntAAQD59DQh5 -cr5rO9XcIz8yzaIogp9QwYUab2WxuSOhJJHHbTs60KRxRHfHjtuUIw== +MIIEpQIBAAKCAQEAzKCKyzYnCDFazKUG7JRGbLKLYphzT+E1NGd4K/MFPmNazTTF +0LoIZf11b6gMLOocq3D+ALwflW5BThuizU/3vpio3kFqalCI9Fnwn3kO5JXDQ0SQ +CgGj7UF/ZNAlU2zurkbhl2C6Kr8IE8/LU9m3gtG47Hw/fFZOlgYGcDsEdkOrAW8U +fNsOx0uWK2K1Ri8dAmSxeh3ScNu4kfvxoQwRU9uLHceE/07Lyk1LgkMhcEwLiruo +fO9e6O4F1FQW95Mnd7V8gVwxkfNsy+JtzLyUOZfslz4XyAgSjKOGxu5mTS7FD8Pp +473hJtFr5vF6V6NTQ85bbeo7E89FSNLfxrCNBwIDAQABAoIBAQDAFBr0sbpl2F5R +Jr+fJ3gL5HUuccgcPVxB+rY1GwPbEkxTv6vISDhF9GteCjKTnpaW35OugOhszngC +p7JkYyI9CPPK3UDU1xAXvq0+JNaz/1ixNhS3L97+gLLioPfIncJWWTa9cBCQu40L +e8xywzWdWNvrMJ4vSpyt+q3kf6GqmB4hAXLJNeiXe3XwUt8d0CNkyOsUIuK/bqif +Pgyz2aaD+q0fiyvVcQn7pPDVW9vwsng+Ypq/haKpj2pLLIH3oRWzJj6ckYpU54rs +Q4HYJnt03e52BO6CEFtYKOdRS4aiLew46fPytPAOe32elKOodO+JZ0TZxQ0dDQ/e +aEice/5hAoGBAP8QFmMzxyBwcqjm9Zf+PFCFvKbwXD+ybeqLcoOsnTf/RaqTIIFF +daL5Mlk0vhuGuZFhvDCzsrttEwS/gRaBfRASqP1gyFDVSq6O6xV4Tf3t/fBa2HjN +eNVLSzyEcWFhNUZEDgZtgBKr6/Ok5TzYkNvJ+gppMAW9hA3iNdWyMNfZAoGBAM1h +A8jWDef5kMmYyE0K5U1z5Cg2dCayRZbFZmp1rQB5U1T+K9LTwOBBjwOJu2HLHhIw +Rt09dnTDXUf2wlF3WNN9AIEldEOmtEd5Gs7SjchPPbjOGQyiqMBDBEhAy5pkPp08 +qHXXCBJUZao4ImLYKjYqbUNOec+5V6Ny/0CKg1/fAoGBAO8VLlcIttOyc9fcvkMd +vX2hDofQ8DeI0j0zP0Er8ScHMk9EoAhsimsceVRi+vwkWhdrbJKeLqA/Cr+9novx +DsCdLShsqvgSJnHfZ351iW3HwuukzBrYRzZv4HM2lmy4SM63hgoCZDWcT4zPeU2C +lq5e8fEGTkxjK8Az1VCdOelpAoGBAI9m7f2NeKhA2Zfp1fH1aaZrBSQO4YsjbvOX +Yatz/xgVntn5nx/WOxZasEEIKo5eBOEuVEymXc+pmbhl08iOTLde0LtcK5IRFE/T +f6Rp4BW9PpuLTHJGIQ4dvR+2HnPvCsk/UWD2g+xIgbQY/emGhfLMLP6SDPu9rjOy +WAf4r0KBAoGAPssbYOLcBBEBjVB4qM1OQP9lruDj/efXSOZRn94RPWYnOZoQtqaA +JTFeNK0SdGYGlUub7NEMEbOys+PVdd10io5KgxEkFAW56LGk3cOJELFGmO2VQVlR +pYLfeRzUnz0uxPWlRJhhXUHIKh2FuWyYturgkiDYSX1uCSCCCAsy5PA= -----END RSA PRIVATE KEY----- diff --git a/invehicle-apps/examples/demo-certificates/Client.pem b/invehicle-apps/examples/demo-certificates/Client.pem index 5f96263..a9475ee 100644 --- a/invehicle-apps/examples/demo-certificates/Client.pem +++ b/invehicle-apps/examples/demo-certificates/Client.pem @@ -1,21 +1,21 @@ -----BEGIN CERTIFICATE----- -MIIDZDCCAkwCCQDCqMcXkze/5zANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJE -RTETMBEGA1UECAwKU29tZS1TdGF0ZTEQMA4GA1UECgwHRWNsaXBzZTEOMAwGA1UE -CwwFS3Vrc2ExEjAQBgNVBAMMCWxvY2FsaG9zdDEaMBgGCSqGSIb3DQEJARYLeXh6 -QHh5ei5jb20wHhcNMTgwOTExMTMzNTMyWhcNMjEwNzAxMTMzNTMyWjB0MQswCQYD -VQQGEwJERTETMBEGA1UECAwKU29tZS1TdGF0ZTEQMA4GA1UECgwHRWNsaXBzZTEO -MAwGA1UECwwFa3Vrc2ExEjAQBgNVBAMMCWxvY2FsaG9zdDEaMBgGCSqGSIb3DQEJ -ARYLeHl6QHh5ei5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDO -G+OoKRI4gb8SSS0puf0n/No38VLuaeb/xkrC3s0E4XNfksW1e6cGYeexNmUH5T0O -UvGzZd6eS8GwGLmpWTV7Nkh2iZwJm1YNUHeBj6vrH9ayUJAYxFOmbzb0papamHYa -HCk4VHVOsem8o0xjddZKsJ9BYcS/PNHklk3T/Q8RwAh4r1c2AzdIt8Bb1oKnOnEe -Ez9RLKs7Ag4PwxWdbIArGaDlNUMatbqcHTNOzdtXFdBWBytbc8A29xDgMWoiEJzv -KK+uWiAcDrZGQPlMANpwowGxlYg53j3pUajt125cK50gGBDs8gTgFSgbN7pwHafS -ervXZvjHyk0Z2X2X5YHDAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFqwNSU/JLqs -nOg6+q9NShHBcL5vDOC4Zo4SlokKC/CWStUrrwLYZXrrUt3aABI4IJNI6O7bK/Wo -YtVgpdJGXEue4YA383Tt7klnx7xZ6DJOwxdlqox9GvgDhNr9LxXrWRZEdA8iWCRt -go4ChYJ/hZ8Kd0W3c5LWFpZCsJf85ABYztE9EuDBDYda72GckgE6sBPkC7qOAMoo -I1VNiEw8QpDfWyuyRs4FmiFROLyNrRCeehOu88VB+69r10JVWd5GI8c4JnG05GEL -pZMdcWIMg9nkqit59mxNO6IMIdW21JjuUeV2qAJiLNfOQAYSt0b61LTg99ZJ3Um9 -HHvLcFUpVis= +MIIDZjCCAk6gAwIBAgIJAORHnA+7AlXvMA0GCSqGSIb3DQEBCwUAMEMxCzAJBgNV +BAYTAkRFMQswCQYDVQQIDAJCVzEMMAoGA1UEBwwDU3R1MQswCQYDVQQKDAJSQjEM +MAoGA1UECwwDQ0FQMB4XDTE5MDEyMjE2MzM1MFoXDTIxMTExMTE2MzM1MFowQzEL +MAkGA1UEBhMCREUxCzAJBgNVBAgMAkJXMQwwCgYDVQQHDANTdHUxCzAJBgNVBAoM +AlJCMQwwCgYDVQQLDANDQVAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDMoIrLNicIMVrMpQbslEZssotimHNP4TU0Z3gr8wU+Y1rNNMXQughl/XVvqAws +6hyrcP4AvB+VbkFOG6LNT/e+mKjeQWpqUIj0WfCfeQ7klcNDRJAKAaPtQX9k0CVT +bO6uRuGXYLoqvwgTz8tT2beC0bjsfD98Vk6WBgZwOwR2Q6sBbxR82w7HS5YrYrVG +Lx0CZLF6HdJw27iR+/GhDBFT24sdx4T/TsvKTUuCQyFwTAuKu6h8717o7gXUVBb3 +kyd3tXyBXDGR82zL4m3MvJQ5l+yXPhfICBKMo4bG7mZNLsUPw+njveEm0Wvm8XpX +o1NDzltt6jsTz0VI0t/GsI0HAgMBAAGjXTBbMB8GA1UdIwQYMBaAFE1BWCMpuM4h +hywPphcP1ehrMbfNMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgTwMCAGA1UdEQQZMBeC +CWxvY2FsaG9zdIcErBEAAYcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAOtEP7G9F +YjcxatlObss14lvH2khV59mLreX9j0+wv7EC6DBUqVlJtNQm71IdHQlRxgWEafHq +zOTtBNiZeA6P9FZd2jjWp8h5Mzy02SsfTsF0CDTbekMYngdcuxZDAjjUwLPqgKlq +jfQv78imxnKsjk+7mO5OHHAvZ7mll+3tpjBOUMnNNQNIYhSj1eyJhvw29c+0Pwt2 +G3LfaXDt0vXdJuJ7d2qcyzUkT8rwKlZAF93lCbDNPxfhPqNF7Aa+49gu+d0vnOLp +xFNDPVkHO9V5yvAKd2KRPgUsZBKAsBIY30Wd8SZB1n2wdAnNYamIhnIqF9KQ1lsw +Ef1AD20z09b5uQ== -----END CERTIFICATE----- diff --git a/invehicle-apps/examples/demo-certificates/json.private.key b/invehicle-apps/examples/demo-certificates/json.private.key new file mode 100644 index 0000000..194cda9 --- /dev/null +++ b/invehicle-apps/examples/demo-certificates/json.private.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKAIBAAKCAgEAr6a1eCaSHq6KOgK8QgyeJIg+wjtUe8kRcHfnofUEu1aDFR+I +w5R8o26+/B0Nnmcs+VUWvPfbuhRZZcjoJWeV/3W9pcCZAZpIFW0WoMKXK9K4+/PD +5do4GP/C9qSlyd02Lr0pvyjAICR70E2HFj5FrtcapjSn2Gr1q+XVkg3wE/JA+QQ2 +wqiCtt3RYXikwsezSZn38lX5AqOdMYNV90r0WLry95l1DhG1sUJ6Mdk/DymHVezO +m3Iij2bIzsu0PM4HtgHrfNPndln9E47M/yYKOYxIUQ7uQH5UfMnWlXSXBb0zMgYz ++/LvArg8vJYbzA8hzw8kEf2SN4hyT3Pn2Ov+cAfHvcXopBOGaZk+3ltFruwbIimq +zyFTNnWxd1SYoUrAJ8HtCjq/tAFXvHtF5rzxWpXnHUHSqtQiMzD+YzGv0zyN3E97 +ZxnVIRxiKLxrUiTwJyAKGb2sc/r4I1+84zl4/PsRZCXaDSDhLBOc6aHyO/kqcqKy +yEd8EwASyhgfn9PutdznhJ+I069Wugm3Z/nA32nnocCoQr2j27i9x8cDSClQaE+a +oESl4LagdrEALPdLwBPs/KEqJLjNknOwsz8vI7wCDC9KXXvKom63nvSEVVax3iWD +fGdUK9qUANebYVqPYgzGRz6W6S3ksUOIFG5gqd9HHH3/ELar7hksQ6NFyHcCAwEA +AQKCAgAxKPFFDVZ769GX5sgVnD5ubwtRhRViB6Yv2f8kHtUSMWZCdS7rvhUcEJS3 +LtJu8OVvatcQUDZY3/UdPZtrTJB4jNVlHIA2KJ3gEUXx/EQe6b0IFvNO00I8DOjd +6rrTwmu1rQ+QBrGuzUcxx2D1YrxR8LXuqnIHafgUAiFB3VDB5F021G0XEd5zm6VM +KF3Efeu5v7PbSSCGEpCeGOnoajv00W3KylIue9pkH/zfErRJZBAShlJUwx7VD6lH +508sbWVPFT55Ez2GrCzeWmsZReY6sP5UYV9hAXpX6o16CsVxv8AiUgYej6FBG5s0 +FLb2541IzC4GMvfHPxLvFbtfxLzS2t6fEkFka/S7OJtwQYI1IeOcFXBkrHNv5Yae +LfcVOOGA01Rpg66h+4opzLkGlHe8018MadehfywHLt448Zv3OsmmusLDRLezAl4x +tIq58SEV1j5a3kEgu+aq8X8XG9ynNhxru4UktHmcYmK6+DzGf9ZuNW+NvWl7Z7tG +zGSQoJsklACGSiH06nrU4gfD457RgmEtzCYN4X0c2MNpLOOqwTwktudSP7d6NeUJ +NGcQbkdkTLhVlF6rRPpQ5JzXBqNakYcwKdxLLIrzY/sB952QfwPxJ8EISapN+LSn +PPZNiO0sjo0is3DRQ36rZd6o6DhN8IAN509J/aF7zf+fo4AzIQKCAQEA5nZVJmqQ +vlKqhss7KyPyVrvPCBuqOfGYKjrs+HQlGbd7cPYYqo4eYijRJcIf2xNm+Q0oRoZF +n16mJw4jskQbHKOtXtX96bZYpdEUJngCbeFfabKTvX0A8yGUvCceengeXUq8L6WP +Bg/IV2ESvUkHsQY0LAYfySEyvJap3dmlmjQI3iaP1u2ZA30TSAWMbfNDv8CeLB62 +Z/5DrwlNKxSd6M/YO2TeoPGRlvkcZxyOVPQH8JM/KRZxkVGRtqIEHwgS80gZjHa0 +hGc7EgSdAwCiBhaFgbxskS+6LGGA+zgOJOCrV6Z41ZsHvDQxPqw4OXsNp4YM6nS5 +ii/KSbC6xIX+aQKCAQEAwx2EaceCDJTe9Y0qspiAifkakAItLrpofaxc6F1/PBPm +DxHz4PmX7695CpwZiv50FfHFSr3DfRiLWfn2+rReLMx9USb1r9BK4HS3/Aa0dYBL +Dq/wkXNEScBo108xfG6ASLLzcTXNKanvXI6Ag3e67kXvhkD6KByBK9wru5uv9Szp +W3gKYUPX7uAbwqmm6KKwOHoHKaDiSdNI2O99euXu0wK6EzRfXhACAX03Cn4VpBqN +LUBOY5zKd6jOiTmCYvk94YR3/q+GV1rrNxfq7vsWX7PEyHti3wLBwHjmSHMlN9Js +StwRuxX/lkIA8lK1HVkzP+e3WUuEBNOL9xKcVqRz3wKCAQABSXvkQQgZ6ABHzG7C +KOs7jMT1OKJUvIKrCbU1FgD3Cc1IrjcpDK4iwjOY0GK5KHyUu3wUGL/eyfqHkU6l +ujeki012kB9g5MHN+0LvjBAHaRDNWE/26PHOacuY2WcULAOPZdFzOqt3zzLBOiuO +nw/J70zvSgF3cBYGc5jzQjnoiI3cH78B5kXKfTJUXqOQIaGpOnwnpuxB3GuoWJbz +vKO9HxwICOItZ+v2OeHsuX4Z/1rj/w6FPjjYJOp5aKI5QiRI84gg/rC3ZJQx35C4 +6ZH+ErYgKVs53Fhf0xOTU5bQoeiTDrzyBHGgnXIA9ZlCyOskml0MGibHHMk2bCQ+ +4LixAoIBAQCy+RljuiiVh9z4WnQG/JIzfTcbT5PIYB7G4Fscnd6+6fXGbw5ImEoB +BvE9hTB86ajsFCiHxYdS8Tep4frlvpr/9tcgoF8O1T5Jo2a8nB3eBj9TCpndoWDL +Ud4ZWcAnxmiPxu49Mz+s7v7r5J8HeMUUGTx75pBQSM1HwR6waT++4mJvj63dyFCD +AjkUl2/NxqVkOLLnQXcwhsk0jIGKQO2PytmKEilEa+SbHxNk4YDSVbSYBHujLcge +eM5y2zi5tqxHd65mBPVynahSkfLjIZhFUu23hE6OB8ZX2c5KOKy0BqVlCXaOKMCY +QJUDslAFyrOS8+af1wATOUUS7pRPeWv7AoIBAHGyU/vs4r96j2FnCGX6z4paD2ne +iD3gGFdP9At4eDBxIXoQ0f36qKqSnzgSoljJEXjde/2xNQWh6L0WXPyKMEnUiIeL +9Ns5nuug19uCIeq1VDvEp90iT7vgF0gnzyWNGSYPlTyTDH32Lu6+JbymdqFbp/yi +Hhux0gx6MHyWijCgH0AazYa66iRB+vfsQq1hH/E0SkhWv/sE0pn/uB5Ea0XQvlSe +g4V9rqAubYg7yMkXIl61yJDB28gtnZuiaAhwFUUwnT7OJggbQJJ4muKCiiZ9BfV8 ++lTwbZJ8sVntJUvxiITTvQw9Q2FDu2iWf23EQn1uPqmYJvm9+GymZgS57bg= +-----END RSA PRIVATE KEY----- diff --git a/invehicle-apps/examples/demo-certificates/jwt.pub.key b/invehicle-apps/examples/demo-certificates/jwt.pub.key index c6bbd08..211c54c 100644 --- a/invehicle-apps/examples/demo-certificates/jwt.pub.key +++ b/invehicle-apps/examples/demo-certificates/jwt.pub.key @@ -1,6 +1,14 @@ -----BEGIN PUBLIC KEY----- -MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd -UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs -HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D -o2kQ+X5xK9cipRgEKwIDAQAB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAr6a1eCaSHq6KOgK8Qgye +JIg+wjtUe8kRcHfnofUEu1aDFR+Iw5R8o26+/B0Nnmcs+VUWvPfbuhRZZcjoJWeV +/3W9pcCZAZpIFW0WoMKXK9K4+/PD5do4GP/C9qSlyd02Lr0pvyjAICR70E2HFj5F +rtcapjSn2Gr1q+XVkg3wE/JA+QQ2wqiCtt3RYXikwsezSZn38lX5AqOdMYNV90r0 +WLry95l1DhG1sUJ6Mdk/DymHVezOm3Iij2bIzsu0PM4HtgHrfNPndln9E47M/yYK +OYxIUQ7uQH5UfMnWlXSXBb0zMgYz+/LvArg8vJYbzA8hzw8kEf2SN4hyT3Pn2Ov+ +cAfHvcXopBOGaZk+3ltFruwbIimqzyFTNnWxd1SYoUrAJ8HtCjq/tAFXvHtF5rzx +WpXnHUHSqtQiMzD+YzGv0zyN3E97ZxnVIRxiKLxrUiTwJyAKGb2sc/r4I1+84zl4 +/PsRZCXaDSDhLBOc6aHyO/kqcqKyyEd8EwASyhgfn9PutdznhJ+I069Wugm3Z/nA +32nnocCoQr2j27i9x8cDSClQaE+aoESl4LagdrEALPdLwBPs/KEqJLjNknOwsz8v +I7wCDC9KXXvKom63nvSEVVax3iWDfGdUK9qUANebYVqPYgzGRz6W6S3ksUOIFG5g +qd9HHH3/ELar7hksQ6NFyHcCAwEAAQ== -----END PUBLIC KEY----- diff --git a/invehicle-apps/kuksa-cloud-dashboard/src/main.cpp b/invehicle-apps/kuksa-cloud-dashboard/src/main.cpp index d8a3de4..de6df03 100755 --- a/invehicle-apps/kuksa-cloud-dashboard/src/main.cpp +++ b/invehicle-apps/kuksa-cloud-dashboard/src/main.cpp @@ -11,15 +11,17 @@ * Robert Bosch GmbH - initial API and functionality * ***************************************************************************** */ + +#include #include #include #include #include +#include #include #include "client_wss.hpp" #include "honoMqtt.hpp" #include "emailHTTP.hpp" -#include // delay between sending each signals in microseconds #define SENDDELAY 50000 diff --git a/invehicle-apps/kuksa-cloud-mechanic/src/main.cpp b/invehicle-apps/kuksa-cloud-mechanic/src/main.cpp index e728737..a3ca32a 100755 --- a/invehicle-apps/kuksa-cloud-mechanic/src/main.cpp +++ b/invehicle-apps/kuksa-cloud-mechanic/src/main.cpp @@ -11,6 +11,8 @@ * Robert Bosch GmbH - initial API and functionality * ***************************************************************************** */ + +#include #include #include #include @@ -18,7 +20,6 @@ #include #include "client_wss.hpp" #include "honoMqtt.hpp" -#include using namespace std;