1 | //===----------------------------------------------------------------------===// |
2 | // DuckDB |
3 | // |
4 | // duckdb/common/serializer/format_serializer.hpp |
5 | // |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #pragma once |
10 | |
11 | #include "duckdb/common/field_writer.hpp" |
12 | #include "duckdb/common/serializer.hpp" |
13 | #include "duckdb/common/enum_util.hpp" |
14 | #include "duckdb/common/serializer/serialization_traits.hpp" |
15 | #include "duckdb/common/types/interval.hpp" |
16 | #include "duckdb/common/types/string_type.hpp" |
17 | #include "duckdb/common/unordered_map.hpp" |
18 | #include "duckdb/common/unordered_set.hpp" |
19 | |
20 | namespace duckdb { |
21 | |
22 | class FormatDeserializer { |
23 | friend Vector; |
24 | |
25 | protected: |
26 | bool deserialize_enum_from_string = false; |
27 | |
28 | public: |
29 | // Read into an existing value |
30 | template <typename T> |
31 | inline void ReadProperty(const char *tag, T &ret) { |
32 | SetTag(tag); |
33 | ret = Read<T>(); |
34 | } |
35 | |
36 | // Read and return a value |
37 | template <typename T> |
38 | inline T ReadProperty(const char *tag) { |
39 | SetTag(tag); |
40 | return Read<T>(); |
41 | } |
42 | |
43 | // Read optional property and return a value, or forward a default value |
44 | template <typename T> |
45 | inline T ReadOptionalPropertyOrDefault(const char *tag, T &&default_value) { |
46 | SetTag(tag); |
47 | auto present = OnOptionalBegin(); |
48 | if (present) { |
49 | auto item = Read<T>(); |
50 | OnOptionalEnd(); |
51 | return item; |
52 | } else { |
53 | OnOptionalEnd(); |
54 | return std::forward<T>(default_value); |
55 | } |
56 | } |
57 | |
58 | // Read optional property into an existing value, or use a default value |
59 | template <typename T> |
60 | inline void ReadOptionalPropertyOrDefault(const char *tag, T &ret, T &&default_value) { |
61 | SetTag(tag); |
62 | auto present = OnOptionalBegin(); |
63 | if (present) { |
64 | ret = Read<T>(); |
65 | OnOptionalEnd(); |
66 | } else { |
67 | ret = std::forward<T>(default_value); |
68 | OnOptionalEnd(); |
69 | } |
70 | } |
71 | |
72 | // Read optional property and return a value, or default construct it |
73 | template <typename T> |
74 | inline typename std::enable_if<std::is_default_constructible<T>::value, T>::type |
75 | ReadOptionalProperty(const char *tag) { |
76 | SetTag(tag); |
77 | auto present = OnOptionalBegin(); |
78 | if (present) { |
79 | auto item = Read<T>(); |
80 | OnOptionalEnd(); |
81 | return item; |
82 | } else { |
83 | OnOptionalEnd(); |
84 | return T(); |
85 | } |
86 | } |
87 | |
88 | // Read optional property into an existing value, or default construct it |
89 | template <typename T> |
90 | inline typename std::enable_if<std::is_default_constructible<T>::value, void>::type |
91 | ReadOptionalProperty(const char *tag, T &ret) { |
92 | SetTag(tag); |
93 | auto present = OnOptionalBegin(); |
94 | if (present) { |
95 | ret = Read<T>(); |
96 | OnOptionalEnd(); |
97 | } else { |
98 | ret = T(); |
99 | OnOptionalEnd(); |
100 | } |
101 | } |
102 | |
103 | // Special case: |
104 | // Read into an existing data_ptr_t |
105 | inline void ReadProperty(const char *tag, data_ptr_t ret, idx_t count) { |
106 | SetTag(tag); |
107 | ReadDataPtr(ptr&: ret, count); |
108 | } |
109 | |
110 | private: |
111 | // Deserialize anything implementing a FormatDeserialize method |
112 | template <typename T = void> |
113 | inline typename std::enable_if<has_deserialize<T>::value, T>::type Read() { |
114 | OnObjectBegin(); |
115 | auto val = T::FormatDeserialize(*this); |
116 | OnObjectEnd(); |
117 | return val; |
118 | } |
119 | |
120 | // Structural Types |
121 | // Deserialize a unique_ptr |
122 | template <class T = void> |
123 | inline typename std::enable_if<is_unique_ptr<T>::value, T>::type Read() { |
124 | using ELEMENT_TYPE = typename is_unique_ptr<T>::ELEMENT_TYPE; |
125 | OnObjectBegin(); |
126 | auto val = ELEMENT_TYPE::FormatDeserialize(*this); |
127 | OnObjectEnd(); |
128 | return val; |
129 | } |
130 | |
131 | // Deserialize shared_ptr |
132 | template <typename T = void> |
133 | inline typename std::enable_if<is_shared_ptr<T>::value, T>::type Read() { |
134 | using ELEMENT_TYPE = typename is_shared_ptr<T>::ELEMENT_TYPE; |
135 | OnObjectBegin(); |
136 | auto val = ELEMENT_TYPE::FormatDeserialize(*this); |
137 | OnObjectEnd(); |
138 | return val; |
139 | } |
140 | |
141 | // Deserialize a vector |
142 | template <typename T = void> |
143 | inline typename std::enable_if<is_vector<T>::value, T>::type Read() { |
144 | using ELEMENT_TYPE = typename is_vector<T>::ELEMENT_TYPE; |
145 | T vec; |
146 | auto size = OnListBegin(); |
147 | for (idx_t i = 0; i < size; i++) { |
148 | vec.push_back(Read<ELEMENT_TYPE>()); |
149 | } |
150 | OnListEnd(); |
151 | |
152 | return vec; |
153 | } |
154 | |
155 | // Deserialize a map |
156 | template <typename T = void> |
157 | inline typename std::enable_if<is_unordered_map<T>::value, T>::type Read() { |
158 | using KEY_TYPE = typename is_unordered_map<T>::KEY_TYPE; |
159 | using VALUE_TYPE = typename is_unordered_map<T>::VALUE_TYPE; |
160 | |
161 | T map; |
162 | auto size = OnMapBegin(); |
163 | for (idx_t i = 0; i < size; i++) { |
164 | OnMapEntryBegin(); |
165 | OnMapKeyBegin(); |
166 | auto key = Read<KEY_TYPE>(); |
167 | OnMapKeyEnd(); |
168 | OnMapValueBegin(); |
169 | auto value = Read<VALUE_TYPE>(); |
170 | OnMapValueEnd(); |
171 | OnMapEntryEnd(); |
172 | map[std::move(key)] = std::move(value); |
173 | } |
174 | OnMapEnd(); |
175 | return map; |
176 | } |
177 | |
178 | // Deserialize an unordered set |
179 | template <typename T = void> |
180 | inline typename std::enable_if<is_unordered_set<T>::value, T>::type Read() { |
181 | using ELEMENT_TYPE = typename is_unordered_set<T>::ELEMENT_TYPE; |
182 | auto size = OnListBegin(); |
183 | T set; |
184 | for (idx_t i = 0; i < size; i++) { |
185 | set.insert(Read<ELEMENT_TYPE>()); |
186 | } |
187 | OnListEnd(); |
188 | return set; |
189 | } |
190 | |
191 | // Deserialize a set |
192 | template <typename T = void> |
193 | inline typename std::enable_if<is_set<T>::value, T>::type Read() { |
194 | using ELEMENT_TYPE = typename is_set<T>::ELEMENT_TYPE; |
195 | auto size = OnListBegin(); |
196 | T set; |
197 | for (idx_t i = 0; i < size; i++) { |
198 | set.insert(Read<ELEMENT_TYPE>()); |
199 | } |
200 | OnListEnd(); |
201 | return set; |
202 | } |
203 | |
204 | // Deserialize a pair |
205 | template <typename T = void> |
206 | inline typename std::enable_if<is_pair<T>::value, T>::type Read() { |
207 | using FIRST_TYPE = typename is_pair<T>::FIRST_TYPE; |
208 | using SECOND_TYPE = typename is_pair<T>::SECOND_TYPE; |
209 | |
210 | OnPairBegin(); |
211 | OnPairKeyBegin(); |
212 | FIRST_TYPE first = Read<FIRST_TYPE>(); |
213 | OnPairKeyEnd(); |
214 | OnPairValueBegin(); |
215 | SECOND_TYPE second = Read<SECOND_TYPE>(); |
216 | OnPairValueEnd(); |
217 | OnPairEnd(); |
218 | return std::make_pair(first, second); |
219 | } |
220 | |
221 | // Primitive types |
222 | // Deserialize a bool |
223 | template <typename T = void> |
224 | inline typename std::enable_if<std::is_same<T, bool>::value, T>::type Read() { |
225 | return ReadBool(); |
226 | } |
227 | |
228 | // Deserialize a int8_t |
229 | template <typename T = void> |
230 | inline typename std::enable_if<std::is_same<T, int8_t>::value, T>::type Read() { |
231 | return ReadSignedInt8(); |
232 | } |
233 | |
234 | // Deserialize a uint8_t |
235 | template <typename T = void> |
236 | inline typename std::enable_if<std::is_same<T, uint8_t>::value, T>::type Read() { |
237 | return ReadUnsignedInt8(); |
238 | } |
239 | |
240 | // Deserialize a int16_t |
241 | template <typename T = void> |
242 | inline typename std::enable_if<std::is_same<T, int16_t>::value, T>::type Read() { |
243 | return ReadSignedInt16(); |
244 | } |
245 | |
246 | // Deserialize a uint16_t |
247 | template <typename T = void> |
248 | inline typename std::enable_if<std::is_same<T, uint16_t>::value, T>::type Read() { |
249 | return ReadUnsignedInt16(); |
250 | } |
251 | |
252 | // Deserialize a int32_t |
253 | template <typename T = void> |
254 | inline typename std::enable_if<std::is_same<T, int32_t>::value, T>::type Read() { |
255 | return ReadSignedInt32(); |
256 | } |
257 | |
258 | // Deserialize a uint32_t |
259 | template <typename T = void> |
260 | inline typename std::enable_if<std::is_same<T, uint32_t>::value, T>::type Read() { |
261 | return ReadUnsignedInt32(); |
262 | } |
263 | |
264 | // Deserialize a int64_t |
265 | template <typename T = void> |
266 | inline typename std::enable_if<std::is_same<T, int64_t>::value, T>::type Read() { |
267 | return ReadSignedInt64(); |
268 | } |
269 | |
270 | // Deserialize a uint64_t |
271 | template <typename T = void> |
272 | inline typename std::enable_if<std::is_same<T, uint64_t>::value, T>::type Read() { |
273 | return ReadUnsignedInt64(); |
274 | } |
275 | |
276 | // Deserialize a float |
277 | template <typename T = void> |
278 | inline typename std::enable_if<std::is_same<T, float>::value, T>::type Read() { |
279 | return ReadFloat(); |
280 | } |
281 | |
282 | // Deserialize a double |
283 | template <typename T = void> |
284 | inline typename std::enable_if<std::is_same<T, double>::value, T>::type Read() { |
285 | return ReadDouble(); |
286 | } |
287 | |
288 | // Deserialize a string |
289 | template <typename T = void> |
290 | inline typename std::enable_if<std::is_same<T, string>::value, T>::type Read() { |
291 | return ReadString(); |
292 | } |
293 | |
294 | // Deserialize a Enum |
295 | template <typename T = void> |
296 | inline typename std::enable_if<std::is_enum<T>::value, T>::type Read() { |
297 | if (deserialize_enum_from_string) { |
298 | auto str = ReadString(); |
299 | return EnumUtil::FromString<T>(str.c_str()); |
300 | } else { |
301 | return (T)Read<typename std::underlying_type<T>::type>(); |
302 | } |
303 | } |
304 | |
305 | // Deserialize a interval_t |
306 | template <typename T = void> |
307 | inline typename std::enable_if<std::is_same<T, interval_t>::value, T>::type Read() { |
308 | return ReadInterval(); |
309 | } |
310 | |
311 | // Deserialize a interval_t |
312 | template <typename T = void> |
313 | inline typename std::enable_if<std::is_same<T, hugeint_t>::value, T>::type Read() { |
314 | return ReadHugeInt(); |
315 | } |
316 | |
317 | protected: |
318 | virtual void SetTag(const char *tag) { |
319 | (void)tag; |
320 | } |
321 | |
322 | virtual idx_t OnListBegin() = 0; |
323 | virtual void OnListEnd() { |
324 | } |
325 | virtual idx_t OnMapBegin() = 0; |
326 | virtual void OnMapEnd() { |
327 | } |
328 | virtual void OnMapEntryBegin() { |
329 | } |
330 | virtual void OnMapEntryEnd() { |
331 | } |
332 | virtual void OnMapKeyBegin() { |
333 | } |
334 | virtual void OnMapKeyEnd() { |
335 | } |
336 | virtual void OnMapValueBegin() { |
337 | } |
338 | virtual void OnMapValueEnd() { |
339 | } |
340 | virtual bool OnOptionalBegin() = 0; |
341 | virtual void OnOptionalEnd() { |
342 | } |
343 | virtual void OnObjectBegin() { |
344 | } |
345 | virtual void OnObjectEnd() { |
346 | } |
347 | virtual void OnPairBegin() { |
348 | } |
349 | virtual void OnPairKeyBegin() { |
350 | } |
351 | virtual void OnPairKeyEnd() { |
352 | } |
353 | virtual void OnPairValueBegin() { |
354 | } |
355 | virtual void OnPairValueEnd() { |
356 | } |
357 | virtual void OnPairEnd() { |
358 | } |
359 | |
360 | virtual bool ReadBool() = 0; |
361 | virtual int8_t ReadSignedInt8() = 0; |
362 | virtual uint8_t ReadUnsignedInt8() = 0; |
363 | virtual int16_t ReadSignedInt16() = 0; |
364 | virtual uint16_t ReadUnsignedInt16() = 0; |
365 | virtual int32_t ReadSignedInt32() = 0; |
366 | virtual uint32_t ReadUnsignedInt32() = 0; |
367 | virtual int64_t ReadSignedInt64() = 0; |
368 | virtual uint64_t ReadUnsignedInt64() = 0; |
369 | virtual hugeint_t ReadHugeInt() = 0; |
370 | virtual float ReadFloat() = 0; |
371 | virtual double ReadDouble() = 0; |
372 | virtual string ReadString() = 0; |
373 | virtual interval_t ReadInterval() = 0; |
374 | virtual void ReadDataPtr(data_ptr_t &ptr, idx_t count) = 0; |
375 | }; |
376 | |
377 | } // namespace duckdb |
378 | |