1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef dap_serialization_h
#define dap_serialization_h
#include "typeof.h"
#include "types.h"
#include <cstddef> // ptrdiff_t
#include <type_traits>
namespace dap {
// Field describes a single field of a struct.
struct Field {
std::string name; // name of the field
ptrdiff_t offset; // offset of the field to the base of the struct
const TypeInfo* type; // type of the field
};
////////////////////////////////////////////////////////////////////////////////
// Deserializer
////////////////////////////////////////////////////////////////////////////////
// Deserializer is the interface used to decode data from structured storage.
// Methods that return a bool use this to indicate success.
class Deserializer {
public:
virtual ~Deserializer() = default;
// deserialization methods for simple data types.
// If the stored object is not of the correct type, then these function will
// return false.
virtual bool deserialize(boolean*) const = 0;
virtual bool deserialize(integer*) const = 0;
virtual bool deserialize(number*) const = 0;
virtual bool deserialize(string*) const = 0;
virtual bool deserialize(object*) const = 0;
virtual bool deserialize(any*) const = 0;
// count() returns the number of elements in the array object referenced by
// this Deserializer.
virtual size_t count() const = 0;
// array() calls the provided std::function for deserializing each array
// element in the array object referenced by this Deserializer.
virtual bool array(const std::function<bool(Deserializer*)>&) const = 0;
// field() calls the provided std::function for deserializing the field with
// the given name from the struct object referenced by this Deserializer.
virtual bool field(const std::string& name,
const std::function<bool(Deserializer*)>&) const = 0;
// deserialize() delegates to TypeOf<T>::type()->deserialize().
template <typename T,
typename = std::enable_if<TypeOf<T>::has_custom_serialization>>
inline bool deserialize(T*) const;
// deserialize() decodes an array.
template <typename T>
inline bool deserialize(dap::array<T>*) const;
// deserialize() decodes an optional.
template <typename T>
inline bool deserialize(dap::optional<T>*) const;
// deserialize() decodes an variant.
template <typename T0, typename... Types>
inline bool deserialize(dap::variant<T0, Types...>*) const;
// deserialize() decodes the struct field f with the given name.
template <typename T>
inline bool field(const std::string& name, T* f) const;
};
template <typename T, typename>
bool Deserializer::deserialize(T* ptr) const {
return TypeOf<T>::type()->deserialize(this, ptr);
}
template <typename T>
bool Deserializer::deserialize(dap::array<T>* vec) const {
auto n = count();
vec->resize(n);
size_t i = 0;
if (!array([&](Deserializer* d) { return d->deserialize(&(*vec)[i++]); })) {
return false;
}
return true;
}
template <typename T>
bool Deserializer::deserialize(dap::optional<T>* opt) const {
T v;
if (deserialize(&v)) {
*opt = v;
}
return true;
}
template <typename T0, typename... Types>
bool Deserializer::deserialize(dap::variant<T0, Types...>* var) const {
return deserialize(&var->value);
}
template <typename T>
bool Deserializer::field(const std::string& name, T* v) const {
return this->field(name,
[&](const Deserializer* d) { return d->deserialize(v); });
}
////////////////////////////////////////////////////////////////////////////////
// Serializer
////////////////////////////////////////////////////////////////////////////////
class FieldSerializer;
// Serializer is the interface used to encode data to structured storage.
// A Serializer is associated with a single storage object, whos type and value
// is assigned by a call to serialize().
// If serialize() is called multiple times on the same Serializer instance,
// the last type and value is stored.
// Methods that return a bool use this to indicate success.
class Serializer {
public:
virtual ~Serializer() = default;
// serialization methods for simple data types.
virtual bool serialize(boolean) = 0;
virtual bool serialize(integer) = 0;
virtual bool serialize(number) = 0;
virtual bool serialize(const string&) = 0;
virtual bool serialize(const dap::object&) = 0;
virtual bool serialize(const any&) = 0;
// array() encodes count array elements to the array object referenced by this
// Serializer. The std::function will be called count times, each time with a
// Serializer that should be used to encode the n'th array element's data.
virtual bool array(size_t count, const std::function<bool(Serializer*)>&) = 0;
// object() begins encoding the object referenced by this Serializer.
// The std::function will be called with a FieldSerializer to serialize the
// object's fields.
virtual bool object(const std::function<bool(dap::FieldSerializer*)>&) = 0;
// remove() deletes the object referenced by this Serializer.
// remove() can be used to serialize optionals with no value assigned.
virtual void remove() = 0;
// serialize() delegates to TypeOf<T>::type()->serialize().
template <typename T,
typename = std::enable_if<TypeOf<T>::has_custom_serialization>>
inline bool serialize(const T&);
// serialize() encodes the given array.
template <typename T>
inline bool serialize(const dap::array<T>&);
// serialize() encodes the given optional.
template <typename T>
inline bool serialize(const dap::optional<T>& v);
// serialize() encodes the given variant.
template <typename T0, typename... Types>
inline bool serialize(const dap::variant<T0, Types...>&);
// deserialize() encodes the given string.
inline bool serialize(const char* v);
protected:
static inline const TypeInfo* get_any_type(const any&);
static inline const void* get_any_val(const any&);
};
inline const TypeInfo* Serializer::get_any_type(const any& a){
return a.type;
}
const void* Serializer::get_any_val(const any& a) {
return a.value;
}
template <typename T, typename>
bool Serializer::serialize(const T& object) {
return TypeOf<T>::type()->serialize(this, &object);
}
template <typename T>
bool Serializer::serialize(const dap::array<T>& vec) {
auto it = vec.begin();
return array(vec.size(), [&](Serializer* s) { return s->serialize(*it++); });
}
template <typename T>
bool Serializer::serialize(const dap::optional<T>& opt) {
if (!opt.has_value()) {
remove();
return true;
}
return serialize(opt.value());
}
template <typename T0, typename... Types>
bool Serializer::serialize(const dap::variant<T0, Types...>& var) {
return serialize(var.value);
}
bool Serializer::serialize(const char* v) {
return serialize(std::string(v));
}
////////////////////////////////////////////////////////////////////////////////
// FieldSerializer
////////////////////////////////////////////////////////////////////////////////
// FieldSerializer is the interface used to serialize fields of an object.
class FieldSerializer {
public:
using SerializeFunc = std::function<bool(Serializer*)>;
template <typename T>
using IsSerializeFunc = std::is_convertible<T, SerializeFunc>;
virtual ~FieldSerializer() = default;
// field() encodes a field to the struct object referenced by this Serializer.
// The SerializeFunc will be called with a Serializer used to encode the
// field's data.
virtual bool field(const std::string& name, const SerializeFunc&) = 0;
// field() encodes the field with the given name and value.
template <
typename T,
typename = typename std::enable_if<!IsSerializeFunc<T>::value>::type>
inline bool field(const std::string& name, const T& v);
};
template <typename T, typename>
bool FieldSerializer::field(const std::string& name, const T& v) {
return this->field(name, [&](Serializer* s) { return s->serialize(v); });
}
} // namespace dap
#endif // dap_serialization_h
|