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