1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/common/serializer.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/common/common.hpp"
12#include "duckdb/common/exception.hpp"
13
14namespace duckdb {
15
16//! The Serialize class is a base class that can be used to serializing objects into a binary buffer
17class Serializer {
18public:
19 virtual ~Serializer() {
20 }
21
22 virtual void WriteData(const_data_ptr_t buffer, idx_t write_size) = 0;
23
24 template <class T> void Write(T element) {
25 WriteData((const_data_ptr_t)&element, sizeof(T));
26 }
27
28 void WriteString(const string &val) {
29 assert(val.size() <= std::numeric_limits<uint32_t>::max());
30 Write<uint32_t>((uint32_t)val.size());
31 if (val.size() > 0) {
32 WriteData((const_data_ptr_t)val.c_str(), val.size());
33 }
34 }
35
36 template <class T> void WriteList(vector<unique_ptr<T>> &list) {
37 assert(list.size() <= std::numeric_limits<uint32_t>::max());
38 Write<uint32_t>((uint32_t)list.size());
39 for (auto &child : list) {
40 child->Serialize(*this);
41 }
42 }
43
44 template <class T> void WriteOptional(unique_ptr<T> &element) {
45 Write<bool>(element ? true : false);
46 if (element) {
47 element->Serialize(*this);
48 }
49 }
50};
51
52//! The Deserializer class assists in deserializing a binary blob back into an
53//! object
54class Deserializer {
55public:
56 virtual ~Deserializer() {
57 }
58
59 //! Reads [read_size] bytes into the buffer
60 virtual void ReadData(data_ptr_t buffer, idx_t read_size) = 0;
61
62 template <class T> T Read() {
63 T value;
64 ReadData((data_ptr_t)&value, sizeof(T));
65 return value;
66 }
67
68 template <class T> void ReadList(vector<unique_ptr<T>> &list) {
69 auto select_count = Read<uint32_t>();
70 for (uint32_t i = 0; i < select_count; i++) {
71 auto child = T::Deserialize(*this);
72 list.push_back(move(child));
73 }
74 }
75
76 template <class T> unique_ptr<T> ReadOptional() {
77 auto has_entry = Read<bool>();
78 if (has_entry) {
79 return T::Deserialize(*this);
80 }
81 return nullptr;
82 }
83};
84
85template <> string Deserializer::Read();
86
87} // namespace duckdb
88