//===----------------------------------------------------------------------===// // DuckDB // // duckdb/common/serializer/format_serializer.hpp // // //===----------------------------------------------------------------------===// #pragma once #include "duckdb/common/field_writer.hpp" #include "duckdb/common/serializer.hpp" #include "duckdb/common/enum_util.hpp" #include "duckdb/common/serializer/serialization_traits.hpp" #include "duckdb/common/types/interval.hpp" #include "duckdb/common/types/string_type.hpp" #include "duckdb/common/unordered_map.hpp" #include "duckdb/common/unordered_set.hpp" namespace duckdb { class FormatDeserializer { friend Vector; protected: bool deserialize_enum_from_string = false; public: // Read into an existing value template inline void ReadProperty(const char *tag, T &ret) { SetTag(tag); ret = Read(); } // Read and return a value template inline T ReadProperty(const char *tag) { SetTag(tag); return Read(); } // Read optional property and return a value, or forward a default value template inline T ReadOptionalPropertyOrDefault(const char *tag, T &&default_value) { SetTag(tag); auto present = OnOptionalBegin(); if (present) { auto item = Read(); OnOptionalEnd(); return item; } else { OnOptionalEnd(); return std::forward(default_value); } } // Read optional property into an existing value, or use a default value template inline void ReadOptionalPropertyOrDefault(const char *tag, T &ret, T &&default_value) { SetTag(tag); auto present = OnOptionalBegin(); if (present) { ret = Read(); OnOptionalEnd(); } else { ret = std::forward(default_value); OnOptionalEnd(); } } // Read optional property and return a value, or default construct it template inline typename std::enable_if::value, T>::type ReadOptionalProperty(const char *tag) { SetTag(tag); auto present = OnOptionalBegin(); if (present) { auto item = Read(); OnOptionalEnd(); return item; } else { OnOptionalEnd(); return T(); } } // Read optional property into an existing value, or default construct it template inline typename std::enable_if::value, void>::type ReadOptionalProperty(const char *tag, T &ret) { SetTag(tag); auto present = OnOptionalBegin(); if (present) { ret = Read(); OnOptionalEnd(); } else { ret = T(); OnOptionalEnd(); } } // Special case: // Read into an existing data_ptr_t inline void ReadProperty(const char *tag, data_ptr_t ret, idx_t count) { SetTag(tag); ReadDataPtr(ret, count); } private: // Deserialize anything implementing a FormatDeserialize method template inline typename std::enable_if::value, T>::type Read() { OnObjectBegin(); auto val = T::FormatDeserialize(*this); OnObjectEnd(); return val; } // Structural Types // Deserialize a unique_ptr template inline typename std::enable_if::value, T>::type Read() { using ELEMENT_TYPE = typename is_unique_ptr::ELEMENT_TYPE; OnObjectBegin(); auto val = ELEMENT_TYPE::FormatDeserialize(*this); OnObjectEnd(); return val; } // Deserialize shared_ptr template inline typename std::enable_if::value, T>::type Read() { using ELEMENT_TYPE = typename is_shared_ptr::ELEMENT_TYPE; OnObjectBegin(); auto val = ELEMENT_TYPE::FormatDeserialize(*this); OnObjectEnd(); return val; } // Deserialize a vector template inline typename std::enable_if::value, T>::type Read() { using ELEMENT_TYPE = typename is_vector::ELEMENT_TYPE; T vec; auto size = OnListBegin(); for (idx_t i = 0; i < size; i++) { vec.push_back(Read()); } OnListEnd(); return vec; } // Deserialize a map template inline typename std::enable_if::value, T>::type Read() { using KEY_TYPE = typename is_unordered_map::KEY_TYPE; using VALUE_TYPE = typename is_unordered_map::VALUE_TYPE; T map; auto size = OnMapBegin(); for (idx_t i = 0; i < size; i++) { OnMapEntryBegin(); OnMapKeyBegin(); auto key = Read(); OnMapKeyEnd(); OnMapValueBegin(); auto value = Read(); OnMapValueEnd(); OnMapEntryEnd(); map[std::move(key)] = std::move(value); } OnMapEnd(); return map; } // Deserialize an unordered set template inline typename std::enable_if::value, T>::type Read() { using ELEMENT_TYPE = typename is_unordered_set::ELEMENT_TYPE; auto size = OnListBegin(); T set; for (idx_t i = 0; i < size; i++) { set.insert(Read()); } OnListEnd(); return set; } // Deserialize a set template inline typename std::enable_if::value, T>::type Read() { using ELEMENT_TYPE = typename is_set::ELEMENT_TYPE; auto size = OnListBegin(); T set; for (idx_t i = 0; i < size; i++) { set.insert(Read()); } OnListEnd(); return set; } // Deserialize a pair template inline typename std::enable_if::value, T>::type Read() { using FIRST_TYPE = typename is_pair::FIRST_TYPE; using SECOND_TYPE = typename is_pair::SECOND_TYPE; OnPairBegin(); OnPairKeyBegin(); FIRST_TYPE first = Read(); OnPairKeyEnd(); OnPairValueBegin(); SECOND_TYPE second = Read(); OnPairValueEnd(); OnPairEnd(); return std::make_pair(first, second); } // Primitive types // Deserialize a bool template inline typename std::enable_if::value, T>::type Read() { return ReadBool(); } // Deserialize a int8_t template inline typename std::enable_if::value, T>::type Read() { return ReadSignedInt8(); } // Deserialize a uint8_t template inline typename std::enable_if::value, T>::type Read() { return ReadUnsignedInt8(); } // Deserialize a int16_t template inline typename std::enable_if::value, T>::type Read() { return ReadSignedInt16(); } // Deserialize a uint16_t template inline typename std::enable_if::value, T>::type Read() { return ReadUnsignedInt16(); } // Deserialize a int32_t template inline typename std::enable_if::value, T>::type Read() { return ReadSignedInt32(); } // Deserialize a uint32_t template inline typename std::enable_if::value, T>::type Read() { return ReadUnsignedInt32(); } // Deserialize a int64_t template inline typename std::enable_if::value, T>::type Read() { return ReadSignedInt64(); } // Deserialize a uint64_t template inline typename std::enable_if::value, T>::type Read() { return ReadUnsignedInt64(); } // Deserialize a float template inline typename std::enable_if::value, T>::type Read() { return ReadFloat(); } // Deserialize a double template inline typename std::enable_if::value, T>::type Read() { return ReadDouble(); } // Deserialize a string template inline typename std::enable_if::value, T>::type Read() { return ReadString(); } // Deserialize a Enum template inline typename std::enable_if::value, T>::type Read() { if (deserialize_enum_from_string) { auto str = ReadString(); return EnumUtil::FromString(str.c_str()); } else { return (T)Read::type>(); } } // Deserialize a interval_t template inline typename std::enable_if::value, T>::type Read() { return ReadInterval(); } // Deserialize a interval_t template inline typename std::enable_if::value, T>::type Read() { return ReadHugeInt(); } protected: virtual void SetTag(const char *tag) { (void)tag; } virtual idx_t OnListBegin() = 0; virtual void OnListEnd() { } virtual idx_t OnMapBegin() = 0; virtual void OnMapEnd() { } virtual void OnMapEntryBegin() { } virtual void OnMapEntryEnd() { } virtual void OnMapKeyBegin() { } virtual void OnMapKeyEnd() { } virtual void OnMapValueBegin() { } virtual void OnMapValueEnd() { } virtual bool OnOptionalBegin() = 0; virtual void OnOptionalEnd() { } virtual void OnObjectBegin() { } virtual void OnObjectEnd() { } virtual void OnPairBegin() { } virtual void OnPairKeyBegin() { } virtual void OnPairKeyEnd() { } virtual void OnPairValueBegin() { } virtual void OnPairValueEnd() { } virtual void OnPairEnd() { } virtual bool ReadBool() = 0; virtual int8_t ReadSignedInt8() = 0; virtual uint8_t ReadUnsignedInt8() = 0; virtual int16_t ReadSignedInt16() = 0; virtual uint16_t ReadUnsignedInt16() = 0; virtual int32_t ReadSignedInt32() = 0; virtual uint32_t ReadUnsignedInt32() = 0; virtual int64_t ReadSignedInt64() = 0; virtual uint64_t ReadUnsignedInt64() = 0; virtual hugeint_t ReadHugeInt() = 0; virtual float ReadFloat() = 0; virtual double ReadDouble() = 0; virtual string ReadString() = 0; virtual interval_t ReadInterval() = 0; virtual void ReadDataPtr(data_ptr_t &ptr, idx_t count) = 0; }; } // namespace duckdb