diff --git a/CMakeLists.txt b/CMakeLists.txt index c6c36847c..bfa63cb55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -406,7 +406,7 @@ set(TINYUSDZ_DEP_SOURCES #${PROJECT_SOURCE_DIR}/src/pxrLZ4/lz4.cpp ${PROJECT_SOURCE_DIR}/src/lz4/lz4.c ${PROJECT_SOURCE_DIR}/src/external/pystring.cpp - ${PROJECT_SOURCE_DIR}/src/external/staticstruct.cc + #${PROJECT_SOURCE_DIR}/src/external/staticstruct.cc #${PROJECT_SOURCE_DIR}/src/external/tinyxml2/tinyxml2.cpp ) diff --git a/README.md b/README.md index 9915d8513..8d857e5d1 100644 --- a/README.md +++ b/README.md @@ -476,7 +476,6 @@ TinyUSDZ is licensed under MIT license and Apache 2.0 license. * expected-lite: BSL 1.0 license. https://github.com/martinmoene/expected-lite * mapbox/earcut.hpp: ISC license. https://github.com/mapbox/earcut.hpp * par_shapes.h generate parametric surfaces and other simple shapes: MIT license https://github.com/prideout/par -* staticstruct: MIT license. https://github.com/syoyo/staticstruct * MaterialX: Apache 2.0 license. https://github.com/AcademySoftwareFoundation/MaterialX * tinyxml2: zlib license. https://github.com/leethomason/tinyxml2 * string_id: zlib license. https://github.com/foonathan/string_id diff --git a/src/external/staticstruct.cc b/src/external/staticstruct.cc deleted file mode 100644 index 14a709965..000000000 --- a/src/external/staticstruct.cc +++ /dev/null @@ -1,393 +0,0 @@ -#include "staticstruct.hh" - -#include -#include // dbg -#include - -namespace staticstruct { - -Error* TypeMismatchError(std::string expected_type, std::string actual_type) { - printf("type mismatch err\n"); - return new Error(Error::TYPE_MISMATCH, - "Type mismatch error: type `" + expected_type + - "` expected but got type `" + actual_type + "`"); -} - -Error* RequiredFieldMissingError() { - return new Error(Error::TYPE_MISMATCH, "Required field(s) is missing: "); -} - -Error* UnknownFieldError(std::string field_name) { - return new Error(Error::UNKNOWN_FIELD, - "Unknown field with name: `" + field_name + "`"); -} - -Error* ArrayLengthMismatchError() { - return new Error(Error::ARRAY_LENGTH_MISMATCH, "Array length mismatch"); -} - -Error* ArrayElementError(size_t idx) { - return new Error(Error::ARRAY_ELEMENT, - "Error at array element at index " + std::to_string(idx)); -} - -Error* ObjectMemberError(std::string key) { - return new Error(Error::OBJECT_MEMBER, - "Error at object member with name `" + key + "`"); -} - -Error* DuplicateKeyError(std::string key) { - return new Error(Error::DUPLICATE_KEYS, "Duplicated key name `" + key + "`"); -} - -IHandler::~IHandler() {} - -BaseHandler::BaseHandler() {} -BaseHandler::~BaseHandler() {} - -bool BaseHandler::set_out_of_range(const char* actual_type) { - the_error.reset(new Error(Error::NUMBER_OUT_OF_RANGE, - "Number out-of-range: type `" + type_name() + - "`, actual_type `" + actual_type + "`")); - return false; -} - -bool BaseHandler::set_type_mismatch(const char* actual_type) { - std::cout << "set type mismatch : " << this->type_name() << "\n"; - the_error.reset(new Error(Error::TYPE_MISMATCH, - "Type mismatch error: type `" + type_name() + - "` expected but got type `" + actual_type + - "`")); - std::cout << "the_error = " << !the_error << "\n"; - return false; -} - -ObjectHandler::ObjectHandler() {} - -ObjectHandler::~ObjectHandler() {} - -std::string ObjectHandler::type_name() const { return "object"; } - -bool ObjectHandler::precheck(const char* actual_type) { - if (depth <= 0) { - the_error.reset(TypeMismatchError(type_name(), actual_type)); - return false; - } - if (current && current->handler && current->handler->is_parsed()) { - if (flags & Flags::AllowDuplicateKey) { - current->handler->prepare_for_reuse(); - } else { - the_error.reset(DuplicateKeyError(current_name)); - return false; - } - } - return true; -} - -bool ObjectHandler::postcheck(bool success) { - if (!success) { - the_error.reset(ObjectMemberError(current_name)); - } - return success; -} - -void ObjectHandler::set_missing_required(const std::string& name) { - if (!the_error || the_error->error_type != Error::MISSING_REQUIRED) - the_error.reset(RequiredFieldMissingError()); - - // Add error message - the_error->error_msg += " " + name + ", "; -} - -#define POSTCHECK(x) (!current || !(current->handler) || postcheck(x)) - -bool ObjectHandler::Float(float value) { - if (!precheck("float")) return false; - return POSTCHECK(current->handler->Float(value)); -} - -bool ObjectHandler::Double(double value) { - if (!precheck("double")) return false; - return POSTCHECK(current->handler->Double(value)); -} - -bool ObjectHandler::Short(short value) { - if (!precheck("short")) return false; - return POSTCHECK(current->handler->Short(value)); -} - -bool ObjectHandler::Ushort(unsigned short value) { - if (!precheck("unsigned short")) return false; - return POSTCHECK(current->handler->Ushort(value)); -} - -bool ObjectHandler::Int(int value) { - if (!precheck("int")) return false; - return POSTCHECK(current->handler->Int(value)); -} - -bool ObjectHandler::Uint(unsigned value) { - if (!precheck("unsigned")) return false; - return POSTCHECK(current->handler->Uint(value)); -} - -bool ObjectHandler::Bool(bool value) { - if (!precheck("bool")) return false; - return POSTCHECK(current->handler->Bool(value)); -} - -bool ObjectHandler::Int64(std::int64_t value) { - if (!precheck("std::int64_t")) return false; - return POSTCHECK(current->handler->Int64(value)); -} - -bool ObjectHandler::Uint64(std::uint64_t value) { - if (!precheck("std::uint64_t")) return false; - return POSTCHECK(current->handler->Uint64(value)); -} - -bool ObjectHandler::Null() { - if (!precheck("null")) return false; - return POSTCHECK(current->handler->Null()); -} - -bool ObjectHandler::StartArray() { - if (!precheck("array")) return false; - return POSTCHECK(current->handler->StartArray()); -} - -bool ObjectHandler::EndArray(SizeType sz) { - if (!precheck("array")) return false; - return POSTCHECK(current->handler->EndArray(sz)); -} - -bool ObjectHandler::String(const char* str, SizeType sz, bool copy) { - if (!precheck("string")) return false; - return POSTCHECK(current->handler->String(str, sz, copy)); -} - -bool ObjectHandler::Key(const char* str, SizeType sz, bool copy) { - if (depth <= 0) { - the_error.reset(new Error(Error::CORRUPTED_DOM, "Corrupted DOM")); - return false; - } - if (depth == 1) { - current_name.assign(str, sz); - auto it = internals.find(current_name); - if (it == internals.end()) { - current = nullptr; - if ((flags & Flags::DisallowUnknownKey)) { - the_error.reset(UnknownFieldError(str)); // sz? - return false; - } - } else if (it->second.flags & Flags::IgnoreRead) { - current = nullptr; - } else { - current = &it->second; - } - return true; - } else { - return POSTCHECK(current->handler->Key(str, sz, copy)); - } -} - -bool ObjectHandler::StartObject() { - ++depth; - if (depth > 1) { - return POSTCHECK(current->handler->StartObject()); - } - return true; -} - -bool ObjectHandler::EndObject(SizeType sz) { - --depth; - if (depth > 0) { - return POSTCHECK(current->handler->EndObject(sz)); - } - for (auto&& pair : internals) { - if (pair.second.handler && !(pair.second.flags & Flags::Optional) && - !pair.second.handler->is_parsed()) { - set_missing_required(pair.first); - } - } - if (!the_error) { - this->parsed = true; - return true; - } - return false; -} - -void ObjectHandler::reset() { - current = nullptr; - current_name.clear(); - depth = 0; - for (auto&& pair : internals) { - if (pair.second.handler) pair.second.handler->prepare_for_reuse(); - } -} - -void ObjectHandler::add_handler(std::string&& name, - ObjectHandler::FlaggedHandler&& fh) { - internals.emplace(std::move(name), std::move(fh)); -} - -bool ObjectHandler::reap_error(ErrorStack& stack) { - if (!the_error) { - return false; - } - - stack.push(*the_error); - - if (current && current->handler) { - current->handler->reap_error(stack); - } - - return true; -} - -bool ObjectHandler::write(IHandler* output) const { - SizeType count = 0; - if (!output->StartObject()) return false; - - for (auto&& pair : internals) { - if (!pair.second.handler || (pair.second.flags & Flags::IgnoreWrite)) - continue; - if (!output->Key(pair.first.data(), - static_cast(pair.first.size()), - true)) - return false; - if (!pair.second.handler->write(output)) return false; - ++count; - } - return output->EndObject(count); -} - -// void ObjectHandler::generate_schema(Value& output, MemoryPoolAllocator& -// alloc) const -//{ -// output.SetObject(); -// output.AddMember(rapidjson::StringRef("type"), -// rapidjson::StringRef("object"), alloc); -// -// Value properties(rapidjson::kObjectType); -// Value required(rapidjson::kArrayType); -// for (auto&& pair : internals) -// { -// Value schema; -// if (pair.second.handler) -// pair.second.handler->generate_schema(schema, alloc); -// else -// std::abort(); -// Value key; -// key.SetString(pair.first.c_str(), -// static_cast(pair.first.size()), alloc); -// properties.AddMember(key, schema, alloc); -// if (!(pair.second.flags & Flags::Optional)) -// { -// key.SetString(pair.first.c_str(), -// static_cast(pair.first.size()), alloc); -// required.PushBack(key, alloc); -// } -// } -// output.AddMember(rapidjson::StringRef("properties"), properties, alloc); -// if (!required.Empty()) -// { -// output.AddMember(rapidjson::StringRef("required"), required, alloc); -// } -// output.AddMember(rapidjson::StringRef("additionalProperties"), -// !(get_flags() & Flags::DisallowUnknownKey), -// alloc); -//} - -Handler::Handler(bool* value) : m_value(value) {} -Handler::~Handler() {} -Handler::~Handler() {} -Handler::~Handler() {} -Handler::~Handler() {} -Handler::~Handler() {} -Handler::~Handler() {} -Handler::~Handler() {} -Handler::~Handler() {} -Handler::~Handler() {} -Handler::~Handler() {} -Handler::~Handler() {} - -Handler>::~Handler() {} - -bool ParseUtil::SetValue(bool b, BaseHandler& handler) { - return handler.Bool(b); -} - -bool ParseUtil::SetValue(short i, BaseHandler& handler) { - return handler.Short(i); -} - -bool ParseUtil::SetValue(unsigned short i, BaseHandler& handler) { - return handler.Ushort(i); -} - -bool ParseUtil::SetValue(int i, BaseHandler& handler) { return handler.Int(i); } - -bool ParseUtil::SetValue(unsigned int i, BaseHandler& handler) { - return handler.Uint(i); -} - -bool ParseUtil::SetValue(int64_t i, BaseHandler& handler) { - return handler.Int64(i); -} - -bool ParseUtil::SetValue(uint64_t i, BaseHandler& handler) { - return handler.Uint64(i); -} - -bool ParseUtil::SetValue(float f, BaseHandler& handler) { - return handler.Float(f); -} - -bool ParseUtil::SetValue(double f, BaseHandler& handler) { - return handler.Double(f); -} - -bool ParseUtil::SetValue(const std::string& s, BaseHandler& handler) { - return handler.String(s.c_str(), s.size(), /* not used */ false); -} - -bool ParseUtil::SetValue(const char* s, BaseHandler& handler) { - return handler.String(s, strlen(s), /* not used */ false); -} - -// explicit specialization for frequently used data types -template <> -bool ParseUtil::SetValue(const std::vector& v, BaseHandler& handler) { - if (!handler.StartArray()) { - return false; - } - - for (size_t i = 0; i < v.size(); i++) { - if (!handler.Float(v[i])) { - return false; - } - } - - return handler.EndArray(v.size()); -} - -bool Reader::ParseStruct( - ObjectHandler* handler, - std::function&& fn, - std::string* err_msg) { - ErrorStack err_stack; - - bool ret = handler->visit(fn, err_stack); - - if (err_stack.size() && (err_msg)) { - Error err; - while (err_stack.pop(&err)) { - (*err_msg) += err.error_msg + "\n"; - } - } - - return ret; -} - -} // namespace staticstruct diff --git a/src/external/staticstruct.hh b/src/external/staticstruct.hh deleted file mode 100644 index 46c2654ff..000000000 --- a/src/external/staticstruct.hh +++ /dev/null @@ -1,2131 +0,0 @@ -// -// Simple single-file statically typed struct/value -// serialization/deserialization library supporting frequently used STL -// containers. Code is based on StaticJSON: -// https://github.com/netheril96/StaticJSON -// -// MIT license -// -// Copyright (c) 2014 Siyuan Ren (netheril96@gmail.com) -// -// Modification: Copyright (c) 2020 Syoyo Fujita -// - -#pragma once - -#ifdef _MSC_VER -#ifndef NOMINMAX -#define NOMINMAX -#endif -#endif - - -#include -#include -#include // dbg -#include -#include -#include - -// -// STL types -// -#include -#include -#include -#include -#include - -// TODO: deque, tuple - -namespace staticstruct { - -// TODO: -// [ ] EnumHandler -// [ ] Better error report -// [ ] std::optional type - -struct NonMobile { - NonMobile() {} - ~NonMobile() {} - NonMobile(const NonMobile&) = delete; - NonMobile(NonMobile&&) = delete; - NonMobile& operator=(const NonMobile&) = delete; - NonMobile& operator=(NonMobile&&) = delete; -}; - -typedef std::size_t SizeType; - -struct Error { - int error_type; - static const int SUCCESS = 0, OBJECT_MEMBER = 1, ARRAY_ELEMENT = 2, - MISSING_REQUIRED = 3, TYPE_MISMATCH = 4, - NUMBER_OUT_OF_RANGE = 5, ARRAY_LENGTH_MISMATCH = 6, - UNKNOWN_FIELD = 7, DUPLICATE_KEYS = 8, CORRUPTED_DOM = 9, - TOO_DEEP_RECURSION = 10, INVALID_ENUM = 11, CUSTOM = -1; - - std::string error_msg; - - Error() : error_type(0) {} - Error(int ty, std::string msg) : error_type(ty), error_msg(msg) {} -}; - -Error* TypeMismatchError(std::string expected_type, std::string actual_type); -Error* RequiredFieldMissingError(); -Error* UnknownFieldError(std::string field_name); -Error* ArrayElementError(size_t n); -Error* ArrayLengthMismatchError(); -Error* ObjectMemberError(std::string key); -Error* DuplicateKeyError(std::string key); - -class ErrorStack { - private: - std::stack m_stack; - - ErrorStack(const ErrorStack&); - ErrorStack& operator=(const ErrorStack&); - - public: - // typedef error::internal::error_stack_const_iterator const_iterator; - - explicit ErrorStack() {} - - void push(Error& e) { m_stack.push(e); } - - bool pop(Error* err) { - if (m_stack.size()) { - (*err) = m_stack.top(); - m_stack.pop(); - return true; - } else { - return false; - } - } - - ~ErrorStack() {} - - size_t size() const { return m_stack.size(); } -}; - -class IHandler { - public: - IHandler() {} - - virtual ~IHandler(); - - virtual bool Null() = 0; - - virtual bool Bool(bool) = 0; - - virtual bool Short(short) = 0; - - virtual bool Ushort(unsigned short) = 0; - - virtual bool Int(int) = 0; - - virtual bool Uint(unsigned) = 0; - - virtual bool Int64(std::int64_t) = 0; - - virtual bool Uint64(std::uint64_t) = 0; - - virtual bool Float(float) = 0; - - virtual bool Double(double) = 0; - - virtual bool String(const char*, SizeType, bool) = 0; - - virtual bool StartObject() = 0; - - virtual bool Key(const char*, SizeType, bool) = 0; - - virtual bool EndObject(SizeType) = 0; - - virtual bool StartArray() = 0; - - virtual bool EndArray(SizeType) = 0; - - // virtual bool RawNumber(const char*, SizeType, bool); - - virtual void prepare_for_reuse() = 0; -}; - -class BaseHandler : public IHandler -//, private NonMobile -{ - friend class NullableHandler; - - protected: - std::unique_ptr the_error; - bool parsed = false; - - protected: - bool set_out_of_range(const char* actual_type); - bool set_type_mismatch(const char* actual_type); - - virtual void reset() {} - - public: - BaseHandler(); - - virtual ~BaseHandler() override; - - virtual std::string type_name() const = 0; - - virtual bool Null() override { return set_type_mismatch("null"); } - - virtual bool Bool(bool) override { return set_type_mismatch("bool"); } - - virtual bool Short(short) override { return set_type_mismatch("short"); } - - virtual bool Ushort(unsigned short) override { - return set_type_mismatch("ushort"); - } - - virtual bool Int(int) override { return set_type_mismatch("int"); } - - virtual bool Uint(unsigned) override { return set_type_mismatch("unsigned"); } - - virtual bool Int64(std::int64_t) override { - return set_type_mismatch("int64_t"); - } - - virtual bool Uint64(std::uint64_t) override { - return set_type_mismatch("uint64_t"); - } - - virtual bool Float(float) override { return set_type_mismatch("float"); } - - virtual bool Double(double) override { return set_type_mismatch("double"); } - - virtual bool String(const char*, SizeType, bool) override { - return set_type_mismatch("string"); - } - - virtual bool StartObject() override { return set_type_mismatch("object"); } - - virtual bool Key(const char*, SizeType, bool) override { - return set_type_mismatch("object"); - } - - virtual bool EndObject(SizeType) override { - return set_type_mismatch("object"); - } - - virtual bool StartArray() override { return set_type_mismatch("array"); } - - virtual bool EndArray(SizeType) override { - return set_type_mismatch("array"); - } - - virtual bool has_error() const { return bool(the_error); } - - virtual bool reap_error(ErrorStack& errs) { - if (!the_error) return false; - errs.push(*the_error); - return true; - } - - bool is_parsed() const { return parsed; } - - void prepare_for_reuse() override { - the_error.reset(); - parsed = false; - reset(); - } - - virtual bool write(IHandler* output) const = 0; - - // virtual void generate_schema(Value& output, MemoryPoolAllocator& alloc) - // const = 0; -}; - -struct Flags { - static const unsigned Default = 0x0, AllowDuplicateKey = 0x1, Optional = 0x2, - IgnoreRead = 0x4, IgnoreWrite = 0x8, - DisallowUnknownKey = 0x10; -}; - -// Forward declaration -template -class Handler; - -class ObjectHandler : public BaseHandler { - protected: - struct FlaggedHandler { - std::unique_ptr handler; - unsigned flags; - uint32_t type_id_; - }; - - protected: - std::map internals; - FlaggedHandler* current = nullptr; - std::string current_name; - int depth = 0; - unsigned flags = Flags::Default; - uint32_t type_id_ = 0; // user supplied type id - - protected: - bool precheck(const char* type); - bool postcheck(bool success); - void set_missing_required(const std::string& name); - void add_handler(std::string&&, FlaggedHandler&&); - void reset() override; - - public: - ObjectHandler(); - - ~ObjectHandler() override; - - std::string type_name() const override; - - virtual bool Null() override; - - virtual bool Bool(bool) override; - - virtual bool Short(short) override; - - virtual bool Ushort(unsigned short) override; - - virtual bool Int(int) override; - - virtual bool Uint(unsigned) override; - - virtual bool Int64(std::int64_t) override; - - virtual bool Uint64(std::uint64_t) override; - - virtual bool Float(float) override; - - virtual bool Double(double) override; - - virtual bool String(const char*, SizeType, bool) override; - - virtual bool StartObject() override; - - virtual bool Key(const char*, SizeType, bool) override; - - virtual bool EndObject(SizeType) override; - - virtual bool StartArray() override; - - virtual bool EndArray(SizeType) override; - - virtual bool reap_error(ErrorStack&) override; - - virtual bool write(IHandler* output) const override; - - // virtual void generate_schema(Value& output, MemoryPoolAllocator& alloc) - // const override; - - unsigned get_flags() const { return flags; } - - void set_flags(unsigned f) { flags = f; } - - void set_type_id(uint32_t idx) { type_id_ = idx; } - - template - void add_property(std::string name, T* pointer, - unsigned flags_ = Flags::Default, uint32_t tyid_ = 0) { - FlaggedHandler fh; - fh.handler.reset(new Handler(pointer)); - fh.flags = flags_; - fh.type_id_ = tyid_; - add_handler(std::move(name), std::move(fh)); - } - - // - // Iterate over properties and call callbacks for each property. - // TODO(syoyo): Call visit recursively for ObjectType. - // - bool visit(std::function& callback, - ErrorStack& err_stack) { - if (!StartObject()) { - return false; - } - - for (auto&& pair : internals) { - if (pair.second.handler && !(pair.second.flags & Flags::IgnoreRead)) { - std::cout << "parse " << pair.first << "\n"; - bool ret = - callback(pair.first, pair.second.flags, pair.second.type_id_, *pair.second.handler); - - std::cout << "parse " << pair.second.handler->type_name() << "\n"; - - // reap(accumulate) error - pair.second.handler->reap_error(err_stack); - - if (!ret) { - if (pair.second.handler->has_error()) { - std::cout << pair.first << " has error. ret = " << ret << "\n"; - } - - // TODO - // Make it ok for optional property - if (!(pair.second.flags & Flags::Optional)) { - return false; - } - } - } - } - - size_t n = internals.size(); - if (!EndObject(n)) { - return false; - } - - return true; - } -}; - -template -struct Converter { - typedef T shadow_type; - - static std::string from_shadow(const shadow_type& shadow, T& value) { - (void)shadow; - (void)value; - return nullptr; - } - - static void to_shadow(const T& value, shadow_type& shadow) { - (void)shadow; - (void)value; - } - - static std::string type_name() { return "T"; } - static uint32_t type_id() { return 0; } - - static constexpr bool has_specialized_type_name = false; -}; - -template -void init(T* t, ObjectHandler* h) { - t->staticstruct_init(h); -} - -template -class ObjectTypeHandler : public ObjectHandler { - public: - explicit ObjectTypeHandler(T* t) { init(t, this); } -}; - -template -class ConversionHandler : public BaseHandler { - private: - typedef typename Converter::shadow_type shadow_type; - typedef Handler internal_type; - - private: - shadow_type shadow; - internal_type internal; - T* m_value; - - protected: - bool postprocess(bool success) { - if (!success) { - return false; - } - if (!internal.is_parsed()) return true; - this->parsed = true; - auto err = Converter::from_shadow(shadow, *m_value); - if (err) { - this->the_error.swap(err); - return false; - } - return true; - } - - void reset() override { - shadow = shadow_type(); - internal.prepare_for_reuse(); - } - - public: - explicit ConversionHandler(T* t) : shadow(), internal(&shadow), m_value(t) {} - - std::string type_name() const override { - // if (Converter::has_specialized_type_name) - // return Converter::type_name(); - return internal.type_name(); - } - - bool Null() override { return postprocess(internal.Null()); } - - bool Bool(bool b) override { return postprocess(internal.Bool(b)); } - - bool Short(short i) override { return postprocess(internal.Short(i)); } - - bool Ushort(unsigned short u) override { - return postprocess(internal.Ushort(u)); - } - - bool Int(int i) override { return postprocess(internal.Int(i)); } - - bool Uint(unsigned u) override { return postprocess(internal.Uint(u)); } - - bool Int64(std::int64_t i) override { return postprocess(internal.Int64(i)); } - - bool Uint64(std::uint64_t u) override { - return postprocess(internal.Uint64(u)); - } - - bool Float(float d) override { return postprocess(internal.Float(d)); } - bool Double(double d) override { return postprocess(internal.Double(d)); } - - bool String(const char* str, SizeType size, bool copy) override { - return postprocess(internal.String(str, size, copy)); - } - - bool StartObject() override { return postprocess(internal.StartObject()); } - - bool Key(const char* str, SizeType size, bool copy) override { - return postprocess(internal.Key(str, size, copy)); - } - - bool EndObject(SizeType sz) override { - return postprocess(internal.EndObject(sz)); - } - - bool StartArray() override { return postprocess(internal.StartArray()); } - - bool EndArray(SizeType sz) override { - return postprocess(internal.EndArray(sz)); - } - - bool has_error() const override { - return BaseHandler::has_error() || internal.has_error(); - } - - bool reap_error(ErrorStack& errs) override { - return BaseHandler::reap_error(errs) || internal.reap_error(errs); - } - - virtual bool write(IHandler* output) const override { - Converter::to_shadow(*m_value, const_cast(shadow)); - return internal.write(output); - } - - // void generate_schema(Value& output, MemoryPoolAllocator& alloc) const - // override - //{ - // return internal.generate_schema(output, alloc); - //} -}; - -namespace helper { -template -class DispatchHandler; -template -class DispatchHandler : public ::staticstruct::ObjectTypeHandler { - public: - explicit DispatchHandler(T* t) : ::staticstruct::ObjectTypeHandler(t) {} -}; - -template -class DispatchHandler : public ::staticstruct::ConversionHandler { - public: - explicit DispatchHandler(T* t) : ::staticstruct::ConversionHandler(t) {} -}; -} // namespace helper - -template -class Handler - : public helper::DispatchHandler< - T, std::is_same::shadow_type, T>::value> { - public: - typedef helper::DispatchHandler< - T, std::is_same::shadow_type, T>::value> - base_type; - explicit Handler(T* t) : base_type(t) {} - // explicit Handler(T* t); -}; - -// ---- primitive types ---- - -template -class IntegerHandler : public BaseHandler { - static_assert(std::is_arithmetic::value, - "Only arithmetic types are allowed"); - - protected: - IntType* m_value; - - template - static constexpr - typename std::enable_if::value, - bool>::type - is_out_of_range(AnotherIntType a) { - typedef typename std::common_type::type CommonType; - typedef typename std::numeric_limits this_limits; - typedef typename std::numeric_limits that_limits; - - // The extra logic related to this_limits::min/max allows the compiler to - // short circuit this check at compile time. For instance, a `uint32_t` - // will NEVER be out of range for an `int64_t` - return ( - (this_limits::is_signed == that_limits::is_signed) - ? ((CommonType(this_limits::min()) > CommonType(a) || - CommonType(this_limits::max()) < CommonType(a))) - : (this_limits::is_signed) - ? (CommonType(this_limits::max()) < CommonType(a)) - : (a < 0 || CommonType(a) > CommonType(this_limits::max()))); - } - - template - static constexpr - typename std::enable_if::value, - bool>::type - is_out_of_range(FloatType f) { - // return static_cast(static_cast(f)) != f; - return std::isfinite(f); - } - - template - bool receive(ReceiveNumType r, const char* actual_type) { - if (is_out_of_range(r)) return set_out_of_range(actual_type); - *m_value = static_cast(r); - this->parsed = true; - return true; - } - - public: - explicit IntegerHandler(IntType* value) : m_value(value) {} - - virtual bool Short(short i) override { return receive(i, "short"); } - - virtual bool Ushort(unsigned short i) override { - return receive(i, "unsigned short"); - } - - virtual bool Int(int i) override { return receive(i, "int"); } - - virtual bool Uint(unsigned i) override { return receive(i, "unsigned int"); } - - virtual bool Int64(std::int64_t i) override { - return receive(i, "std::int64_t"); - } - - virtual bool Uint64(std::uint64_t i) override { - return receive(i, "std::uint64_t"); - } - - virtual bool Float(float d) override { return receive(d, "float"); } - virtual bool Double(double d) override { return receive(d, "double"); } - - virtual bool write(IHandler* output) const override { - if (std::numeric_limits::is_signed) { - return output->Int64(int64_t(*m_value)); - } else { - return output->Uint64(uint64_t(*m_value)); - } - } - - // virtual void generate_schema(Value& output, MemoryPoolAllocator& alloc) - // const override - //{ - // output.SetObject(); - // output.AddMember(rapidjson::StringRef("type"), - // rapidjson::StringRef("integer"), alloc); Value minimum, maximum; if - // (std::numeric_limits::is_signed) - // { - // minimum.SetInt64(std::numeric_limits::min()); - // maximum.SetInt64(std::numeric_limits::max()); - // } - // else - // { - // minimum.SetUint64(std::numeric_limits::min()); - // maximum.SetUint64(std::numeric_limits::max()); - // } - // output.AddMember(rapidjson::StringRef("minimum"), minimum, alloc); - // output.AddMember(rapidjson::StringRef("maximum"), maximum, alloc); - //} -}; - -template <> -class Handler : public BaseHandler { - public: - explicit Handler(std::nullptr_t*); - - bool Null() override { - this->parsed = true; - return true; - } - - std::string type_name() const override { return "null"; } - - bool write(IHandler* output) const override { return output->Null(); } - - // void generate_schema(Value& output, MemoryPoolAllocator& alloc) const - // override - //{ - // output.SetObject(); - // output.AddMember(rapidjson::StringRef("type"), - // rapidjson::StringRef("null"), alloc); - //} -}; - -template <> -class Handler : public BaseHandler { - private: - bool* m_value; - - public: - explicit Handler(bool* value); - ~Handler() override; - - bool Bool(bool v) override { - *m_value = v; - this->parsed = true; - return true; - } - - std::string type_name() const override { return "bool"; } - - bool write(IHandler* output) const override { return output->Bool(*m_value); } - - // void generate_schema(Value& output, MemoryPoolAllocator& alloc) const - // override - //{ - // output.SetObject(); - // output.AddMember(rapidjson::StringRef("type"), - // rapidjson::StringRef("boolean"), alloc); - //} -}; - -template <> -class Handler : public IntegerHandler { - public: - explicit Handler(short* i) : IntegerHandler(i) {} - ~Handler() override; - - std::string type_name() const override { return "short"; } - - bool write(IHandler* output) const override { - return output->Short(*m_value); - } -}; - -template <> -class Handler : public IntegerHandler { - public: - explicit Handler(unsigned short* i) : IntegerHandler(i) {} - ~Handler() override; - - std::string type_name() const override { return "unsigned short"; } - - bool write(IHandler* output) const override { - return output->Ushort(*m_value); - } -}; - -template <> -class Handler : public IntegerHandler { - public: - explicit Handler(int* i) : IntegerHandler(i) {} - ~Handler() override; - - std::string type_name() const override { return "int"; } - - bool write(IHandler* output) const override { return output->Int(*m_value); } -}; - -template <> -class Handler : public IntegerHandler { - public: - explicit Handler(unsigned* i) : IntegerHandler(i) {} - ~Handler() override; - - std::string type_name() const override { return "unsigned int"; } - - bool write(IHandler* output) const override { return output->Uint(*m_value); } -}; - -template <> -class Handler : public IntegerHandler { - public: - explicit Handler(int64_t* i) : IntegerHandler(i) {} - ~Handler() override; - - std::string type_name() const override { return "int64"; } -}; - -template <> -class Handler : public IntegerHandler { - public: - explicit Handler(uint64_t* i) : IntegerHandler(i) {} - ~Handler() override; - - std::string type_name() const override { return "unsigned int64"; } -}; - -// char is an alias for bool to work around the stupid `std::vector` -template <> -class Handler : public BaseHandler { - private: - char* m_value; - - public: - explicit Handler(char* i) : m_value(i) {} - ~Handler() override; - - std::string type_name() const override { return "bool"; } - - bool Bool(bool v) override { - *this->m_value = v; - this->parsed = true; - return true; - } - - bool write(IHandler* out) const override { return out->Bool(*m_value != 0); } - - // void generate_schema(Value& output, MemoryPoolAllocator& alloc) const - // override - //{ - // output.SetObject(); - // output.AddMember(rapidjson::StringRef("type"), - // rapidjson::StringRef("boolean"), alloc); - //} -}; - -template <> -class Handler : public BaseHandler { - private: - double* m_value; - - public: - explicit Handler(double* v) : m_value(v) {} - ~Handler() override; - - bool Short(short i) override { - *m_value = i; - this->parsed = true; - return true; - } - - bool Ushort(unsigned short i) override { - *m_value = i; - this->parsed = true; - return true; - } - - bool Int(int i) override { - *m_value = i; - this->parsed = true; - return true; - } - - bool Uint(unsigned i) override { - *m_value = i; - this->parsed = true; - return true; - } - - bool Int64(std::int64_t i) override { - *m_value = static_cast(i); - if (static_cast(*m_value) != i) - return set_out_of_range("std::int64_t"); - this->parsed = true; - return true; - } - - bool Uint64(std::uint64_t i) override { - *m_value = static_cast(i); - if (static_cast(*m_value) != i) - return set_out_of_range("std::uint64_t"); - this->parsed = true; - return true; - } - - bool Float(float d) override { - *m_value = double(d); - this->parsed = true; - return true; - } - - bool Double(double d) override { - *m_value = d; - this->parsed = true; - return true; - } - - std::string type_name() const override { return "double"; } - - bool write(IHandler* out) const override { return out->Double(*m_value); } - - // void generate_schema(Value& output, MemoryPoolAllocator& alloc) const - // override - //{ - // output.SetObject(); - // output.AddMember(rapidjson::StringRef("type"), - // rapidjson::StringRef("number"), alloc); - //} -}; - -template <> -class Handler : public BaseHandler { - private: - float* m_value; - - public: - explicit Handler(float* v) : m_value(v) {} - ~Handler() override; - - bool Short(short i) override { - *m_value = i; - this->parsed = true; - return true; - } - - bool Ushort(unsigned short i) override { - *m_value = i; - this->parsed = true; - return true; - } - - bool Int(int i) override { - *m_value = static_cast(i); - if (static_cast(*m_value) != i) return set_out_of_range("int"); - this->parsed = true; - return true; - } - - bool Uint(unsigned i) override { - *m_value = static_cast(i); - if (static_cast(*m_value) != i) - return set_out_of_range("unsigned int"); - this->parsed = true; - return true; - } - - bool Int64(std::int64_t i) override { - *m_value = static_cast(i); - if (static_cast(*m_value) != i) - return set_out_of_range("std::int64_t"); - this->parsed = true; - return true; - } - - bool Uint64(std::uint64_t i) override { - *m_value = static_cast(i); - if (static_cast(*m_value) != i) - return set_out_of_range("std::uint64_t"); - this->parsed = true; - return true; - } - - bool Float(float d) override { - *m_value = d; - this->parsed = true; - return true; - } - - bool Double(double d) override { - *m_value = static_cast(d); - this->parsed = true; - return true; - } - - std::string type_name() const override { return "float"; } - - bool write(IHandler* out) const override { return out->Float(*m_value); } - - // void generate_schema(Value& output, MemoryPoolAllocator& alloc) const - // override - //{ - // output.SetObject(); - // output.AddMember(rapidjson::StringRef("type"), - // rapidjson::StringRef("number"), alloc); - //} -}; - -template <> -class Handler : public BaseHandler { - private: - std::string* m_value; - - public: - explicit Handler(std::string* v) : m_value(v) {} - ~Handler() override; - - bool String(const char* str, SizeType length, bool) override { - m_value->assign(str, length); - this->parsed = true; - return true; - } - - std::string type_name() const override { return "string"; } - - bool write(IHandler* out) const override { - return out->String(m_value->data(), SizeType(m_value->size()), true); - } - - // void generate_schema(Value& output, MemoryPoolAllocator& alloc) const - // override - //{ - // output.SetObject(); - // output.AddMember(rapidjson::StringRef("type"), - // rapidjson::StringRef("string"), alloc); - //} -}; - -// -// STL types -// - -template -class ArrayHandler : public BaseHandler { - public: - typedef typename ArrayType::value_type ElementType; - - protected: - ElementType element; - Handler internal; - ArrayType* m_value; - int depth = 0; - - protected: - void set_element_error() { - the_error.reset(ArrayElementError(m_value->size())); - } - - bool precheck(const char* type) { - if (depth <= 0) { - the_error.reset(TypeMismatchError(type_name(), type)); - return false; - } - return true; - } - - bool postcheck(bool success) { - if (!success) { - set_element_error(); - return false; - } - if (internal.is_parsed()) { - m_value->emplace_back(std::move(element)); - element = ElementType(); - internal.prepare_for_reuse(); - } - return true; - } - - void reset() override { - element = ElementType(); - internal.prepare_for_reuse(); - depth = 0; - } - - public: - explicit ArrayHandler(ArrayType* value) - : element(), internal(&element), m_value(value) {} - - bool Null() override { - return precheck("null") && postcheck(internal.Null()); - } - - bool Bool(bool b) override { - return precheck("bool") && postcheck(internal.Bool(b)); - } - - bool Short(short i) override { - return precheck("short") && postcheck(internal.Short(i)); - } - - bool Ushort(unsigned short i) override { - return precheck("unsigned short") && postcheck(internal.Ushort(i)); - } - - bool Int(int i) override { - return precheck("int") && postcheck(internal.Int(i)); - } - - bool Uint(unsigned i) override { - return precheck("unsigned") && postcheck(internal.Uint(i)); - } - - bool Int64(std::int64_t i) override { - return precheck("int64_t") && postcheck(internal.Int64(i)); - } - - bool Uint64(std::uint64_t i) override { - return precheck("uint64_t") && postcheck(internal.Uint64(i)); - } - - bool Float(float d) override { - return precheck("float") && postcheck(internal.Float(d)); - } - - bool Double(double d) override { - return precheck("double") && postcheck(internal.Double(d)); - } - - bool String(const char* str, SizeType length, bool copy) override { - return precheck("string") && postcheck(internal.String(str, length, copy)); - } - - bool Key(const char* str, SizeType length, bool copy) override { - return precheck("object") && postcheck(internal.Key(str, length, copy)); - } - - bool StartObject() override { - return precheck("object") && postcheck(internal.StartObject()); - } - - bool EndObject(SizeType length) override { - return precheck("object") && postcheck(internal.EndObject(length)); - } - - bool StartArray() override { - ++depth; - if (depth > 1) - return postcheck(internal.StartArray()); - else - m_value->clear(); - return true; - } - - bool EndArray(SizeType length) override { - --depth; - - // When depth >= 1, this event should be forwarded to the element - if (depth > 0) return postcheck(internal.EndArray(length)); - - this->parsed = true; - return true; - } - - bool reap_error(ErrorStack& stk) override { - if (!the_error) return false; - stk.push(*the_error); - internal.reap_error(stk); - return true; - } - - bool write(IHandler* output) const override { - if (!output->StartArray()) return false; - for (auto&& e : *m_value) { - Handler h(&e); - if (!h.write(output)) return false; - } - return output->EndArray( - static_cast(m_value->size())); - } - - // void generate_schema(Value& output, MemoryPoolAllocator& alloc) const - // override - //{ - // output.SetObject(); - // output.AddMember(rapidjson::StringRef("type"), - // rapidjson::StringRef("array"), alloc); Value items; - // internal.generate_schema(items, alloc); - // output.AddMember(rapidjson::StringRef("items"), items, alloc); - //} -}; - -template -class Handler> : public ArrayHandler> { - public: - explicit Handler(std::vector* value) - : ArrayHandler>(value) {} - - std::string type_name() const override { - return "std::vector<" + this->internal.type_name() + ">"; - } -}; - -// specialized version -template <> -class Handler> : public BaseHandler { - protected: - std::vector* m_value; - int depth{0}; - - public: - explicit Handler(std::vector* value) : m_value(value) {} - ~Handler() override; - - std::string type_name() const override { return "std::vector"; } - - bool Float(float d) override { - if (depth == 0) { - // `StartArray` is not called. - return false; - } - - m_value->emplace_back(d); - - return true; - } - - bool StartArray() override { - ++depth; - if (depth > 1) { - // recursive array - return false; - } else { - m_value->clear(); - } - return true; - } - - bool EndArray(SizeType length) override { - (void)length; - - --depth; - - if (depth > 0) return false; - - this->parsed = true; - return true; - } - - bool write(IHandler* output) const override { - if (!output->StartArray()) return false; - for (auto&& e : *m_value) { - Handler h(&e); - if (!h.write(output)) return false; - } - return output->EndArray( - static_cast(m_value->size())); - } -}; - -#if 0 -template -class Handler> : public ArrayHandler> -{ -public: - explicit Handler(std::deque* value) : ArrayHandler>(value) {} - - std::string type_name() const override - { - return "std::deque<" + this->internal.type_name() + ">"; - } -}; -#endif - -template -class Handler> : public ArrayHandler> { - public: - explicit Handler(std::list* value) : ArrayHandler>(value) {} - - std::string type_name() const override { - return "std::list<" + this->internal.type_name() + ">"; - } -}; - -template -class Handler> : public BaseHandler { - protected: - T element; - Handler internal; - std::array* m_value; - size_t count = 0; - int depth = 0; - - protected: - void set_element_error() { the_error.reset(ArrayElementError(count)); } - - void set_length_error() { the_error.reset(ArrayLengthMismatchError()); } - - bool precheck(const char* type) { - if (depth <= 0) { - the_error.reset(TypeMismatchError(type_name(), type)); - return false; - } - return true; - } - - bool postcheck(bool success) { - if (!success) { - set_element_error(); - return false; - } - if (internal.is_parsed()) { - if (count >= N) { - set_length_error(); - return false; - } - (*m_value)[count] = std::move(element); - ++count; - element = T(); - internal.prepare_for_reuse(); - } - return true; - } - - void reset() override { - element = T(); - internal.prepare_for_reuse(); - depth = 0; - count = 0; - } - - public: - explicit Handler(std::array* value) - : element(), internal(&element), m_value(value) {} - - bool Null() override { - return precheck("null") && postcheck(internal.Null()); - } - - bool Bool(bool b) override { - return precheck("bool") && postcheck(internal.Bool(b)); - } - - bool Short(short i) override { - return precheck("short") && postcheck(internal.Short(i)); - } - - bool Ushort(unsigned short i) override { - return precheck("unsigned short") && postcheck(internal.Ushort(i)); - } - - bool Int(int i) override { - return precheck("int") && postcheck(internal.Int(i)); - } - - bool Uint(unsigned i) override { - return precheck("unsigned") && postcheck(internal.Uint(i)); - } - - bool Int64(std::int64_t i) override { - return precheck("int64_t") && postcheck(internal.Int64(i)); - } - - bool Uint64(std::uint64_t i) override { - return precheck("uint64_t") && postcheck(internal.Uint64(i)); - } - - bool Float(float d) override { - return precheck("float") && postcheck(internal.Float(d)); - } - - bool Double(double d) override { - return precheck("double") && postcheck(internal.Double(d)); - } - - bool String(const char* str, SizeType length, bool copy) override { - return precheck("string") && postcheck(internal.String(str, length, copy)); - } - - bool Key(const char* str, SizeType length, bool copy) override { - return precheck("object") && postcheck(internal.Key(str, length, copy)); - } - - bool StartObject() override { - return precheck("object") && postcheck(internal.StartObject()); - } - - bool EndObject(SizeType length) override { - return precheck("object") && postcheck(internal.EndObject(length)); - } - - bool StartArray() override { - ++depth; - if (depth > 1) return postcheck(internal.StartArray()); - return true; - } - - bool EndArray(SizeType length) override { - --depth; - - // When depth >= 1, this event should be forwarded to the element - if (depth > 0) return postcheck(internal.EndArray(length)); - if (count != N) { - set_length_error(); - return false; - } - this->parsed = true; - return true; - } - - bool reap_error(ErrorStack& stk) override { - if (!the_error) return false; - stk.push(*the_error); - internal.reap_error(stk); - return true; - } - - bool write(IHandler* output) const override { - if (!output->StartArray()) return false; - for (auto&& e : *m_value) { - Handler h(&e); - if (!h.write(output)) return false; - } - return output->EndArray( - static_cast(m_value->size())); - } - - // void generate_schema(Value& output, MemoryPoolAllocator& alloc) const - // override - //{ - // output.SetObject(); - // output.AddMember(rapidjson::StringRef("type"), - // rapidjson::StringRef("array"), alloc); Value items; - // internal.generate_schema(items, alloc); - // output.AddMember(rapidjson::StringRef("items"), items, alloc); - // output.AddMember(rapidjson::StringRef("minItems"), - // static_cast(N), alloc); - // output.AddMember(rapidjson::StringRef("maxItems"), - // static_cast(N), alloc); - //} - - std::string type_name() const override { - return "std::array<" + internal.type_name() + ", " + std::to_string(N) + - ">"; - } -}; - -#if 0 -template -class PointerHandler : public BaseHandler -{ -public: - typedef typename std::pointer_traits::element_type ElementType; - -protected: - mutable PointerType* m_value; - mutable std::unique_ptr> internal_handler; - int depth = 0; - -protected: - explicit PointerHandler(PointerType* value) : m_value(value) {} - - void initialize() - { - if (!internal_handler) - { - m_value->reset(new ElementType()); - internal_handler.reset(new Handler(m_value->get())); - } - } - - void reset() override - { - depth = 0; - internal_handler.reset(); - m_value->reset(); - } - - bool postcheck(bool success) - { - if (success) - this->parsed = internal_handler->is_parsed(); - return success; - } - -public: - bool Null() override - { - if (depth == 0) - { - m_value->reset(); - this->parsed = true; - return true; - } - else - { - initialize(); - return postcheck(internal_handler->Null()); - } - } - - bool write(IHandler* out) const override - { - if (!m_value || !m_value->get()) - { - return out->Null(); - } - if (!internal_handler) - { - internal_handler.reset(new Handler(m_value->get())); - } - return internal_handler->write(out); - } - - void generate_schema(Value& output, MemoryPoolAllocator& alloc) const override - { - const_cast*>(this)->initialize(); - output.SetObject(); - Value anyOf(rapidjson::kArrayType); - Value nullDescriptor(rapidjson::kObjectType); - nullDescriptor.AddMember(rapidjson::StringRef("type"), rapidjson::StringRef("null"), alloc); - Value descriptor; - internal_handler->generate_schema(descriptor, alloc); - anyOf.PushBack(nullDescriptor, alloc); - anyOf.PushBack(descriptor, alloc); - output.AddMember(rapidjson::StringRef("anyOf"), anyOf, alloc); - } - - bool Bool(bool b) override - { - initialize(); - return postcheck(internal_handler->Bool(b)); - } - - bool Int(int i) override - { - initialize(); - return postcheck(internal_handler->Int(i)); - } - - bool Uint(unsigned i) override - { - initialize(); - return postcheck(internal_handler->Uint(i)); - } - - bool Int64(std::int64_t i) override - { - initialize(); - return postcheck(internal_handler->Int64(i)); - } - - bool Uint64(std::uint64_t i) override - { - initialize(); - return postcheck(internal_handler->Uint64(i)); - } - - bool Float(float i) override - { - initialize(); - return postcheck(internal_handler->Float(i)); - } - - bool Double(double i) override - { - initialize(); - return postcheck(internal_handler->Double(i)); - } - - bool String(const char* str, SizeType len, bool copy) override - { - initialize(); - return postcheck(internal_handler->String(str, len, copy)); - } - - bool Key(const char* str, SizeType len, bool copy) override - { - initialize(); - return postcheck(internal_handler->Key(str, len, copy)); - } - - bool StartObject() override - { - initialize(); - ++depth; - return internal_handler->StartObject(); - } - - bool EndObject(SizeType len) override - { - initialize(); - --depth; - return postcheck(internal_handler->EndObject(len)); - } - - bool StartArray() override - { - initialize(); - ++depth; - return postcheck(internal_handler->StartArray()); - } - - bool EndArray(SizeType len) override - { - initialize(); - --depth; - return postcheck(internal_handler->EndArray(len)); - } - - bool has_error() const override { return internal_handler && internal_handler->has_error(); } - - bool reap_error(ErrorStack& stk) override - { - return internal_handler && internal_handler->reap_error(stk); - } -}; - -template -class Handler> : public PointerHandler> -{ -public: - explicit Handler(std::unique_ptr* value) - : PointerHandler>(value) - { - } - - std::string type_name() const override - { - if (this->internal_handler) - { - return "std::unique_ptr<" + this->internal_handler->type_name() + ">"; - } - return "std::unique_ptr"; - } -}; - -template -class Handler> : public PointerHandler> -{ -public: - explicit Handler(std::shared_ptr* value) : PointerHandler>(value) {} - - std::string type_name() const override - { - if (this->internal_handler) - { - return "std::shared_ptr<" + this->internal_handler->type_name() + ">"; - } - return "std::shared_ptr"; - } -}; -#endif - -template -class MapHandler : public BaseHandler { - protected: - typedef typename MapType::mapped_type ElementType; - - protected: - ElementType element; - Handler internal_handler; - MapType* m_value; - std::string current_key; - int depth = 0; - - protected: - void reset() override { - element = ElementType(); - current_key.clear(); - internal_handler.prepare_for_reuse(); - depth = 0; - } - - bool precheck(const char* type) { - if (depth <= 0) { - set_type_mismatch(type); - return false; - } - return true; - } - - bool postcheck(bool success) { - if (!success) { - the_error.reset(ObjectMemberError(current_key)); - } else { - if (internal_handler.is_parsed()) { - m_value->emplace(std::move(current_key), std::move(element)); - element = ElementType(); - internal_handler.prepare_for_reuse(); - } - } - return success; - } - - public: - explicit MapHandler(MapType* value) - : element(), internal_handler(&element), m_value(value) {} - - bool Null() override { - return precheck("null") && postcheck(internal_handler.Null()); - } - - bool Bool(bool b) override { - return precheck("bool") && postcheck(internal_handler.Bool(b)); - } - - bool Short(short i) override { - return precheck("short") && postcheck(internal_handler.Short(i)); - } - - bool Ushort(unsigned short i) override { - return precheck("unsigned short") && postcheck(internal_handler.Ushort(i)); - } - - bool Int(int i) override { - return precheck("int") && postcheck(internal_handler.Int(i)); - } - - bool Uint(unsigned i) override { - return precheck("unsigned") && postcheck(internal_handler.Uint(i)); - } - - bool Int64(std::int64_t i) override { - return precheck("int64_t") && postcheck(internal_handler.Int64(i)); - } - - bool Uint64(std::uint64_t i) override { - return precheck("uint64_t") && postcheck(internal_handler.Uint64(i)); - } - - bool Float(float d) override { - return precheck("float") && postcheck(internal_handler.Float(d)); - } - - bool Double(double d) override { - return precheck("double") && postcheck(internal_handler.Double(d)); - } - - bool String(const char* str, SizeType length, bool copy) override { - return precheck("string") && - postcheck(internal_handler.String(str, length, copy)); - } - - bool Key(const char* str, SizeType length, bool copy) override { - if (depth > 1) return postcheck(internal_handler.Key(str, length, copy)); - - current_key.assign(str, length); - return true; - } - - bool StartArray() override { - return precheck("array") && postcheck(internal_handler.StartArray()); - } - - bool EndArray(SizeType length) override { - return precheck("array") && postcheck(internal_handler.EndArray(length)); - } - - bool StartObject() override { - ++depth; - if (depth > 1) - return postcheck(internal_handler.StartObject()); - else - m_value->clear(); - return true; - } - - bool EndObject(SizeType length) override { - --depth; - if (depth > 0) return postcheck(internal_handler.EndObject(length)); - this->parsed = true; - return true; - } - - bool reap_error(ErrorStack& errs) override { - if (!this->the_error) return false; - - errs.push((*this->the_error)); - internal_handler.reap_error(errs); - return true; - } - - bool write(IHandler* out) const override { - if (!out->StartObject()) return false; - for (auto&& pair : *m_value) { - if (!out->Key(pair.first.data(), static_cast(pair.first.size()), - true)) - return false; - Handler h(&pair.second); - if (!h.write(out)) return false; - } - return out->EndObject(static_cast(m_value->size())); - } - - // void generate_schema(Value& output, MemoryPoolAllocator& alloc) const - // override - //{ - // Value internal_schema; - // internal_handler.generate_schema(internal_schema, alloc); - // output.SetObject(); - // output.AddMember(rapidjson::StringRef("type"), - // rapidjson::StringRef("object"), alloc); - - // Value empty_obj(rapidjson::kObjectType); - // output.AddMember(rapidjson::StringRef("properties"), empty_obj, alloc); - // output.AddMember(rapidjson::StringRef("additionalProperties"), - // internal_schema, alloc); - //} -}; - -template -class Handler> - : public MapHandler> { - public: - explicit Handler(std::unordered_map* value) - : MapHandler>(value) {} - - std::string type_name() const override { - return "std::unordered_mapinternal_handler.type_name() + ">"; - } -}; - -template -class Handler> - : public MapHandler> { - public: - explicit Handler(std::map* value) - : MapHandler>(value) {} - - std::string type_name() const override { - return "std::mapinternal_handler.type_name() + ">"; - } -}; - -template -class Handler> - : public MapHandler> { - public: - explicit Handler(std::unordered_multimap* value) - : MapHandler>( - value) {} - - std::string type_name() const override { - return "std::unordered_mulitimapinternal_handler.type_name() + ">"; - } -}; - -template -class Handler> - : public MapHandler> { - public: - explicit Handler(std::multimap* value) - : MapHandler>(value) {} - - std::string type_name() const override { - return "std::multimapinternal_handler.type_name() + - ">"; - } -}; - -#if 0 -template -class TupleHander : public BaseHandler -{ -protected: - std::array, N> handlers; - std::size_t index = 0; - int depth = 0; - - bool postcheck(bool success) - { - if (!success) - { - the_error.reset(new error::ArrayElementError(index)); - return false; - } - if (handlers[index]->is_parsed()) - { - ++index; - } - return true; - } - -protected: - void reset() override - { - index = 0; - depth = 0; - for (auto&& h : handlers) - h->prepare_for_reuse(); - } - -public: - bool Null() override - { - if (index >= N) - return true; - return postcheck(handlers[index]->Null()); - } - - bool Bool(bool b) override - { - if (index >= N) - return true; - return postcheck(handlers[index]->Bool(b)); - } - - bool Int(int i) override - { - if (index >= N) - return true; - return postcheck(handlers[index]->Int(i)); - } - - bool Uint(unsigned i) override - { - if (index >= N) - return true; - return postcheck(handlers[index]->Uint(i)); - } - - bool Int64(std::int64_t i) override - { - if (index >= N) - return true; - return postcheck(handlers[index]->Int64(i)); - } - - bool Uint64(std::uint64_t i) override - { - if (index >= N) - return true; - return postcheck(handlers[index]->Uint64(i)); - } - - bool Float(float d) override - { - if (index >= N) - return true; - return postcheck(handlers[index]->Float(d)); - } - - bool Double(double d) override - { - if (index >= N) - return true; - return postcheck(handlers[index]->Double(d)); - } - - bool String(const char* str, SizeType length, bool copy) override - { - if (index >= N) - return true; - return postcheck(handlers[index]->String(str, length, copy)); - } - - bool Key(const char* str, SizeType length, bool copy) override - { - if (index >= N) - return true; - return postcheck(handlers[index]->Key(str, length, copy)); - } - - bool StartArray() override - { - if (++depth > 1) - { - if (index >= N) - return true; - return postcheck(handlers[index]->StartArray()); - } - return true; - } - - bool EndArray(SizeType length) override - { - if (--depth > 0) - { - if (index >= N) - return true; - return postcheck(handlers[index]->EndArray(length)); - } - this->parsed = true; - return true; - } - - bool StartObject() override - { - if (index >= N) - return true; - return postcheck(handlers[index]->StartObject()); - } - - bool EndObject(SizeType length) override - { - if (index >= N) - return true; - return postcheck(handlers[index]->EndObject(length)); - } - - bool reap_error(ErrorStack& errs) override - { - if (!this->the_error) - return false; - - errs.push(*this->the_error); - for (auto&& h : handlers) - h->reap_error(errs); - return true; - } - - bool write(IHandler* out) const override - { - if (!out->StartArray()) - return false; - for (auto&& h : handlers) - { - if (!h->write(out)) - return false; - } - return out->EndArray(N); - } - - //void generate_schema(Value& output, MemoryPoolAllocator& alloc) const override - //{ - // output.SetObject(); - // output.AddMember(rapidjson::StringRef("type"), rapidjson::StringRef("array"), alloc); - // Value items(rapidjson::kArrayType); - // for (auto&& h : handlers) - // { - // Value item; - // h->generate_schema(item, alloc); - // items.PushBack(item, alloc); - // } - // output.AddMember(rapidjson::StringRef("items"), items, alloc); - //} -}; - -namespace nonpublic -{ - template - struct TupleIniter - { - void operator()(std::unique_ptr* handlers, Tuple& t) const - { - handlers[index].reset( - new Handler::type>(&std::get(t))); - TupleIniter{}(handlers, t); - } - }; - - template - struct TupleIniter - { - void operator()(std::unique_ptr* handlers, Tuple& t) const - { - (void)handlers; - (void)t; - } - }; -} - -template -class Handler> : public TupleHander>::value> -{ -private: - static const std::size_t N = std::tuple_size>::value; - -public: - explicit Handler(std::tuple* t) - { - nonpublic::TupleIniter<0, N, std::tuple> initer; - initer(this->handlers.data(), *t); - } - - std::string type_name() const override - { - std::string str = "std::tuple<"; - for (auto&& h : this->handlers) - { - str += h->type_name(); - str += ", "; - } - str.pop_back(); - str.pop_back(); - str += '>'; - return str; - } -}; -#endif - -struct ParseUtil { - static bool SetValue(bool, BaseHandler& handler); - static bool SetValue(short, BaseHandler& handler); - static bool SetValue(unsigned short, BaseHandler& handler); - static bool SetValue(int, BaseHandler& handler); - static bool SetValue(unsigned int, BaseHandler& handler); - static bool SetValue(int64_t, BaseHandler& handler); - static bool SetValue(uint64_t, BaseHandler& handler); - static bool SetValue(float f, BaseHandler& handler); - static bool SetValue(double f, BaseHandler& handler); - static bool SetValue(char, BaseHandler& handler); - static bool SetValue(const std::string& s, BaseHandler& handler); - static bool SetValue(const char* s, BaseHandler& handler); - - template - static bool SetValue(const std::vector& v, BaseHandler& handler) { - if (!handler.StartArray()) { - return false; - } - - for (size_t i = 0; i < v.size(); i++) { - if (!SetValue(v[i], handler)) { - return false; - } - } - - return handler.EndArray(v.size()); - } - - template - static bool SetValue(const std::array& v, BaseHandler& handler) { - if (!handler.StartArray()) { - return false; - } - - for (size_t i = 0; i < N; i++) { - if (!SetValue(v[i], handler)) { - return false; - } - } - - return handler.EndArray(v.size()); - } - - template - static bool SetValue(const std::map& m, - BaseHandler& handler) { - if (!handler.StartObject()) { - return false; - } - - for (auto item : m) { - if (!handler.Key(item.first.c_str(), item.first.size(), - /* copy(not used) */ true)) { - return false; - } - - if (!SetValue(item.second, handler)) { - return false; - } - } - - return handler.EndObject(m.size()); - } - - template - static bool SetValue(const std::unordered_map& m, - BaseHandler& handler) { - if (!handler.StartObject()) { - return false; - } - - for (auto item : m) { - if (!handler.Key(item.first)) { - return false; - } - - if (!SetValue(item.second, handler)) { - return false; - } - } - - return handler.EndObject(m.size()); - } -}; - -// -// Parser interface -// -class Reader { - public: - /// - /// @param[in] handler Object(Struct) handler - /// @param[in] fn Callback function - /// @param[in] err Error message(filled when the function returns false) - bool ParseStruct(ObjectHandler* handler, - std::function&& fn, - std::string* err); -}; - -} // namespace staticstruct