-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathYamlReader.hpp
More file actions
336 lines (300 loc) · 9.9 KB
/
Copy pathYamlReader.hpp
File metadata and controls
336 lines (300 loc) · 9.9 KB
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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// 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
//
// http://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.
#pragma once
#include <cpp_utils/types/Fuzzy.hpp>
#include <cpp_utils/enum/EnumBuilder.hpp>
#include <ddspipe_yaml/library/library_dll.h>
#include <ddspipe_yaml/Yaml.hpp>
namespace eprosima {
namespace ddspipe {
namespace yaml {
/**
* @brief Yaml Configuration Version
*
* With each version, the yaml format could change in different aspects
* - new fields
* - eliminate fields
* - change key words / tags
* - change requirement of field
* - etc.
*
* Each version is stored in a value of this enumeration, and each \c get method (without tag) is speciallized
* for each different versions.
*
* There is a version call \c LATEST that refers to the lates valid Yaml Configuration Versions.
* Most elemnts will not change from a version change to other. Thus, all of them must be implemented as
* the \c LATEST version, and then if a specific object changes with a specific version, implement that version
* (not latest) separately.
* This way, any new version uses \c LATEST as default implementation, and old versions that diverged from latest
* have their own implementation. As old versions will not change, those methods are definitive, and do not
* need further maintenance.
*/
enum YamlReaderVersion
{
/**
* @brief First version.
*
* @version 0.1.0
*/
V_1_0,
/**
* @brief Version 2.0
*
* @version 0.1.0
*
* - Adds builtin-topics tag.
* - Adds participants list.
* - Changes the parent of guid for DS to a new tag discovery-server-guid.
* - Adds domain tag in Address to remplace ip when DNS.
*/
V_2_0,
/**
* @brief Version 3.0
*
* @version 0.1.0
*
* - Change wan to initial peers participant
* - Add Specs
*/
V_3_0,
/**
* @brief Version 3.1.
*
* @version 0.2.0
*
* - Add XML load by file or raw
* - Add xml participant
*/
V_3_1,
/**
* @brief Version 4.0.
*
* @version 0.3.0
*
* - Forwarding Routes.
* - Remove Unused Entities.
* - Manual Topics.
* - Max Transmission Rate.
* - Max Reception Rate.
* - Downsampling.
* - Rename the `max-depth` under the `specs` tag to `history-depth`.
*/
V_4_0,
/**
* @brief Latest version.
*
* @version 1.0.0
*
* - Make discovery server's guid prefix optional.
* - Remove server's guid prefix from discovery server clients' connection addresses.
* - Remove 'addresses' tag from discovery server clients' connection addresses (now it's just a list of addresses).
*/
V_5_0,
/**
* @brief Main version.
*
* This is the version used when the method is not specialized regarding the version,
* or the latest version when it does.
*/
LATEST,
};
/**
* @brief Class that encapsulates methods to get values from Yaml Node.
*
* Every method is implemented
*/
class
DDSPIPE_YAML_DllAPI
YamlReader
{
public:
/**
* @brief Whether key \c tag is present in \c yml
*
* The key \c tag must be in base level of \c yml , it will no be looked for recursively.
*
* It could only look for keys in yaml map and empty yaml. It will fail in array and scalar cases.
* In this second case, return will always be false.
*
* @param yml base yaml
* @param tag key to look for in \c yml
* @return true id \c tag is a key in \c yml
* @return false otherwise
*
* @throw \c ConfigurationException if \c yml is not a map or empty yaml
*/
static bool is_tag_present(
const Yaml& yml,
const TagType& tag);
/**
* @brief Get the yaml inside key \c tag in \c yml
*
* \c tag must be present in \c yml . It uses \c is_tag_present to check the key is present.
* Use \c is_tag_present before calling this method in order to avoid the exception.
*
* @param yml base yaml
* @param tag key refering the value returned
* @return yaml value inside key \c tag
*
* @throw \c ConfigurationException if \c tag is not present in \c yml
*/
static Yaml get_value_in_tag(
const Yaml& yml,
const TagType& tag);
/**
* @brief Takes the element \c yml and builds the object \c T
*
* This method takes a yaml node and then builds and return and object of type \c T.
*
* @tparam T type of the object to build
* @param yml base yaml
* @param version configuration version
*/
template<typename T>
static T get(
const Yaml& yml,
const YamlReaderVersion version);
/**
* @brief Extracts the sub-yaml from the \c tag and then builds the object \c T
*
* This method calls \c get_value_in_tag to extract the sub-yaml from the \c tag and then it calls \c get to build
* the object \c T.
*
* @tparam T type of the object to build
* @param yml base yaml
* @param tag key to yaml containing the object
* @param version configuration version
*/
template<typename T>
static T get(
const Yaml& yml,
const TagType& tag,
const YamlReaderVersion version);
/**
* @brief Fill an element given by parameter with the values inside \c yml
*
* This method simplifies the process of retrieving an object whose parent has its own \c fill method,
* as the code is reused from one another calling parent \c fill in child.
* It is also very helpful to handle default creation values. Without this, every different default value
* must have its own if-else clause, forcing to create the respective constructor. With this method,
* the default values are initialized with the default constructor, and then are overwritten by the yaml.
* [this problem arises because C++ does not allow different order of parameters in method call]
*/
template<typename T>
static void fill(
T& object,
const Yaml& yml,
const YamlReaderVersion version);
//! Fill an element given by parameter with the values inside \c tag in \c yml
template<typename T>
static void fill(
T& object,
const Yaml& yml,
const TagType& tag,
const YamlReaderVersion version);
//! TODO comment
template<typename T>
static std::list<T> get_list(
const Yaml& yml,
const YamlReaderVersion version);
//! Get list inside \c tag
template<typename T>
static std::list<T> get_list(
const Yaml& yml,
const TagType& tag,
const YamlReaderVersion version);
/**
* @brief Get set inside \c tag
*
* It get a list of elements T with \c get_list and then convert it to set.
*
* @tparam T type of each object of the set
* @param yml base yaml
* @param tag key to yaml containing set
* @param version configuration version
* @return set of elements
*/
template<typename T>
static std::set<T> get_set(
const Yaml& yml,
const TagType& tag,
const YamlReaderVersion version);
//! TODO comment
template<typename T>
static T get_scalar(
const Yaml& yml);
//! Get scalar value inside \c tag
template<typename T>
static T get_scalar(
const Yaml& yml,
const TagType& tag);
//! Get nonnegative integer value inside \c tag
static unsigned int get_nonnegative_int(
const Yaml& yml,
const TagType& tag);
//! Get positive integer value inside \c tag
static unsigned int get_positive_int(
const Yaml& yml,
const TagType& tag);
//! Get nonnegative float value inside \c tag
static float get_nonnegative_float(
const Yaml& yml,
const TagType& tag);
//! Get positive float value inside \c tag
static float get_positive_float(
const Yaml& yml,
const TagType& tag);
//! Get nonnegative double value inside \c tag
static double get_nonnegative_double(
const Yaml& yml,
const TagType& tag);
//! Get positive double value inside \c tag
static double get_positive_double(
const Yaml& yml,
const TagType& tag);
//! TODO comment
template<typename T>
static T get_enumeration(
const Yaml& yml,
const std::map<TagType, T>& enum_values);
//! Get enumeration value inside \c tag
template<typename T>
static T get_enumeration(
const Yaml& yml,
const TagType& tag,
const std::map<TagType, T>& enum_values);
//! TODO comment
template<typename T>
static T get_enumeration_from_builder(
const Yaml& yml,
const utils::EnumBuilder<T>& enum_builder);
//! Get enumeration value inside \c tag
template<typename T>
static T get_enumeration_from_builder(
const Yaml& yml,
const TagType& tag,
const utils::EnumBuilder<T>& enum_builder);
};
/**
* @brief \c YamlReaderVersion to stream serialization
*/
DDSPIPE_YAML_DllAPI
std::ostream& operator <<(
std::ostream& os,
const YamlReaderVersion& version);
} /* namespace yaml */
} /* namespace ddspipe */
} /* namespace eprosima */
// Include implementation template file
#include <ddspipe_yaml/impl/YamlReader.ipp>