//----------------------------------------------------------------------------- // ___ __ _ _ // / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __ // / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ / // / ___/ (_| | | \__ \ __/ /__| | | | | < // \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ . // //----------------------------------------------------------------------------- // Author: Kurt Sassenrath // Module: msgpack // // Default unpacker implementation, utilizing pull-style parsing semantics for // deserializing data with an expected structure akin to a schema. // // The default unpacker maintains some flexibility in how data was originally // packed. // // E.g. If a std::uint8_t is requested, it is perfectly valid to read a uint32 // format, provided the stored value is less than 255. // // core/reader (to be renamed verbatim_unpacker) can be utilized in scenarios // where code size is critical and exact type matching is not a considerable // downside. // // For schemaless data, the token API can be used instead. // // Copyright (c) 2023 Kurt Sassenrath. // // License TBD. //----------------------------------------------------------------------------- #ifndef msgpack_core_unpacker_910ec357d397ac7e #define msgpack_core_unpacker_910ec357d397ac7e #include "parselink/msgpack/core/detail/builtin_unpackable_types.h" #include "parselink/msgpack/core/detail/unpackable_concepts.h" #include "parselink/msgpack/core/error.h" #include #include #include namespace msgpack { class unpacker { using BufferType = std::span; public: constexpr unpacker(BufferType buff) : buff_(buff) , curr_(std::begin(buff_)) , end_(std::end(buff_)) {} // IDK if we need this yet struct context { decltype(std::begin(BufferType{})) in; decltype(std::begin(BufferType{})) end; constexpr auto remaining() noexcept { return std::ranges::distance(in, end); } template constexpr tl::expected unpack() noexcept { if (remaining() == 0) return tl::make_unexpected(error::end_of_message); using unpacker_impl = detail::unpacker_impl; return unpacker_impl::unpack(*this); } }; template constexpr tl::expected unpack() noexcept { context ctx{curr_, end_}; auto ret = ctx.unpack(); if (ret) { curr_ = ctx.in; } return ret; } private: BufferType buff_; decltype(std::begin(buff_)) curr_; decltype(std::end(buff_)) end_; }; } // namespace msgpack #endif // msgpack_core_unpacker_910ec357d397ac7e