Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Utilities/cmcppdap/src/rapid_json_serializer.cpp
3153 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
#include "rapid_json_serializer.h"
16
17
#include "null_json_serializer.h"
18
19
#include <rapidjson/document.h>
20
#include <rapidjson/prettywriter.h>
21
22
namespace dap {
23
namespace json {
24
25
RapidDeserializer::RapidDeserializer(const std::string& str)
26
: doc(new rapidjson::Document()) {
27
doc->Parse(str.c_str());
28
}
29
30
RapidDeserializer::RapidDeserializer(rapidjson::Value* json) : val(json) {}
31
32
RapidDeserializer::~RapidDeserializer() {
33
delete doc;
34
}
35
36
bool RapidDeserializer::deserialize(dap::boolean* v) const {
37
if (!json()->IsBool()) {
38
return false;
39
}
40
*v = json()->GetBool();
41
return true;
42
}
43
44
bool RapidDeserializer::deserialize(dap::integer* v) const {
45
if (json()->IsInt()) {
46
*v = json()->GetInt();
47
return true;
48
} else if (json()->IsUint()) {
49
*v = static_cast<int64_t>(json()->GetUint());
50
return true;
51
} else if (json()->IsInt64()) {
52
*v = json()->GetInt64();
53
return true;
54
} else if (json()->IsUint64()) {
55
*v = static_cast<int64_t>(json()->GetUint64());
56
return true;
57
}
58
return false;
59
}
60
61
bool RapidDeserializer::deserialize(dap::number* v) const {
62
if (!json()->IsNumber()) {
63
return false;
64
}
65
*v = json()->GetDouble();
66
return true;
67
}
68
69
bool RapidDeserializer::deserialize(dap::string* v) const {
70
if (!json()->IsString()) {
71
return false;
72
}
73
*v = json()->GetString();
74
return true;
75
}
76
77
bool RapidDeserializer::deserialize(dap::object* v) const {
78
v->reserve(json()->MemberCount());
79
for (auto el = json()->MemberBegin(); el != json()->MemberEnd(); el++) {
80
dap::any el_val;
81
RapidDeserializer d(&(el->value));
82
if (!d.deserialize(&el_val)) {
83
return false;
84
}
85
(*v)[el->name.GetString()] = el_val;
86
}
87
return true;
88
}
89
90
bool RapidDeserializer::deserialize(dap::any* v) const {
91
if (json()->IsBool()) {
92
*v = dap::boolean(json()->GetBool());
93
} else if (json()->IsDouble()) {
94
*v = dap::number(json()->GetDouble());
95
} else if (json()->IsInt()) {
96
*v = dap::integer(json()->GetInt());
97
} else if (json()->IsString()) {
98
*v = dap::string(json()->GetString());
99
} else if (json()->IsNull()) {
100
*v = null();
101
} else if (json()->IsObject()) {
102
dap::object obj;
103
if (!deserialize(&obj)) {
104
return false;
105
}
106
*v = obj;
107
} else if (json()->IsArray()){
108
dap::array<any> arr;
109
if (!deserialize(&arr)){
110
return false;
111
}
112
*v = arr;
113
} else {
114
return false;
115
}
116
return true;
117
}
118
119
size_t RapidDeserializer::count() const {
120
return json()->Size();
121
}
122
123
bool RapidDeserializer::array(
124
const std::function<bool(dap::Deserializer*)>& cb) const {
125
if (!json()->IsArray()) {
126
return false;
127
}
128
for (uint32_t i = 0; i < json()->Size(); i++) {
129
RapidDeserializer d(&(*json())[i]);
130
if (!cb(&d)) {
131
return false;
132
}
133
}
134
return true;
135
}
136
137
bool RapidDeserializer::field(
138
const std::string& name,
139
const std::function<bool(dap::Deserializer*)>& cb) const {
140
if (!json()->IsObject()) {
141
return false;
142
}
143
auto it = json()->FindMember(name.c_str());
144
if (it == json()->MemberEnd()) {
145
return cb(&NullDeserializer::instance);
146
}
147
RapidDeserializer d(&(it->value));
148
return cb(&d);
149
}
150
151
RapidSerializer::RapidSerializer()
152
: doc(new rapidjson::Document(rapidjson::kObjectType)),
153
allocator(doc->GetAllocator()) {}
154
155
RapidSerializer::RapidSerializer(rapidjson::Value* json,
156
rapidjson::Document::AllocatorType& allocator)
157
: val(json), allocator(allocator) {}
158
159
RapidSerializer::~RapidSerializer() {
160
delete doc;
161
}
162
163
std::string RapidSerializer::dump() const {
164
rapidjson::StringBuffer sb;
165
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
166
json()->Accept(writer);
167
return sb.GetString();
168
}
169
170
bool RapidSerializer::serialize(dap::boolean v) {
171
json()->SetBool(v);
172
return true;
173
}
174
175
bool RapidSerializer::serialize(dap::integer v) {
176
json()->SetInt64(v);
177
return true;
178
}
179
180
bool RapidSerializer::serialize(dap::number v) {
181
json()->SetDouble(v);
182
return true;
183
}
184
185
bool RapidSerializer::serialize(const dap::string& v) {
186
json()->SetString(v.data(), static_cast<uint32_t>(v.length()), allocator);
187
return true;
188
}
189
190
bool RapidSerializer::serialize(const dap::object& v) {
191
if (!json()->IsObject()) {
192
json()->SetObject();
193
}
194
for (auto& it : v) {
195
if (!json()->HasMember(it.first.c_str())) {
196
rapidjson::Value name_value{it.first.c_str(), allocator};
197
json()->AddMember(name_value, rapidjson::Value(), allocator);
198
}
199
rapidjson::Value& member = (*json())[it.first.c_str()];
200
RapidSerializer s(&member, allocator);
201
if (!s.serialize(it.second)) {
202
return false;
203
}
204
}
205
return true;
206
}
207
208
bool RapidSerializer::serialize(const dap::any& v) {
209
if (v.is<dap::boolean>()) {
210
json()->SetBool((bool)v.get<dap::boolean>());
211
} else if (v.is<dap::integer>()) {
212
json()->SetInt64(v.get<dap::integer>());
213
} else if (v.is<dap::number>()) {
214
json()->SetDouble((double)v.get<dap::number>());
215
} else if (v.is<dap::string>()) {
216
auto s = v.get<dap::string>();
217
json()->SetString(s.data(), static_cast<uint32_t>(s.length()), allocator);
218
} else if (v.is<dap::object>()) {
219
// reachable if dap::object nested is inside other dap::object
220
return serialize(v.get<dap::object>());
221
} else if (v.is<dap::null>()) {
222
} else {
223
// reachable if array or custom serialized type is nested inside other dap::object
224
auto type = get_any_type(v);
225
auto value = get_any_val(v);
226
if (type && value) {
227
return type->serialize(this, value);
228
}
229
return false;
230
}
231
232
return true;
233
}
234
235
bool RapidSerializer::array(size_t count,
236
const std::function<bool(dap::Serializer*)>& cb) {
237
if (!json()->IsArray()) {
238
json()->SetArray();
239
}
240
241
while (count > json()->Size()) {
242
json()->PushBack(rapidjson::Value(), allocator);
243
}
244
245
for (uint32_t i = 0; i < count; i++) {
246
RapidSerializer s(&(*json())[i], allocator);
247
if (!cb(&s)) {
248
return false;
249
}
250
}
251
return true;
252
}
253
254
bool RapidSerializer::object(
255
const std::function<bool(dap::FieldSerializer*)>& cb) {
256
struct FS : public FieldSerializer {
257
rapidjson::Value* const json;
258
rapidjson::Document::AllocatorType& allocator;
259
260
FS(rapidjson::Value* json, rapidjson::Document::AllocatorType& allocator)
261
: json(json), allocator(allocator) {}
262
bool field(const std::string& name, const SerializeFunc& cb) override {
263
if (!json->HasMember(name.c_str())) {
264
rapidjson::Value name_value{name.c_str(), allocator};
265
json->AddMember(name_value, rapidjson::Value(), allocator);
266
}
267
rapidjson::Value& member = (*json)[name.c_str()];
268
RapidSerializer s(&member, allocator);
269
auto res = cb(&s);
270
if (s.removed) {
271
json->RemoveMember(name.c_str());
272
}
273
return res;
274
}
275
};
276
277
if (!json()->IsObject()) {
278
json()->SetObject();
279
}
280
FS fs{json(), allocator};
281
return cb(&fs);
282
}
283
284
void RapidSerializer::remove() {
285
removed = true;
286
}
287
288
} // namespace json
289
} // namespace dap
290
291