/src/Fast-DDS/include/fastdds/rtps/common/Property.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). |
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 | | // http://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 | | /*! |
16 | | * @file Property.hpp |
17 | | */ |
18 | | #ifndef FASTDDS_RTPS_COMMON__PROPERTY_HPP |
19 | | #define FASTDDS_RTPS_COMMON__PROPERTY_HPP |
20 | | |
21 | | #include <functional> |
22 | | #include <stdexcept> |
23 | | #include <string> |
24 | | #include <vector> |
25 | | |
26 | | namespace eprosima { |
27 | | namespace fastdds { |
28 | | namespace rtps { |
29 | | |
30 | | class Property |
31 | | { |
32 | | public: |
33 | | |
34 | | Property() |
35 | 0 | { |
36 | 0 | } |
37 | | |
38 | | Property( |
39 | | const Property& property) |
40 | 15 | : name_(property.name_) |
41 | 15 | , value_(property.value_) |
42 | 15 | , propagate_(property.propagate_) |
43 | 15 | { |
44 | 15 | } |
45 | | |
46 | | Property( |
47 | | Property&& property) |
48 | 0 | : name_(std::move(property.name_)) |
49 | 0 | , value_(std::move(property.value_)) |
50 | 0 | , propagate_(property.propagate_) |
51 | 0 | { |
52 | 0 | } |
53 | | |
54 | | Property( |
55 | | const std::string& name, |
56 | | const std::string& value, |
57 | | bool propagate = false) |
58 | | : name_(name) |
59 | | , value_(value) |
60 | | , propagate_(propagate) |
61 | 0 | { |
62 | 0 | } |
63 | | |
64 | | Property( |
65 | | std::string&& name, |
66 | | std::string&& value, |
67 | | bool propagate = false) |
68 | 20 | : name_(std::move(name)) |
69 | 20 | , value_(std::move(value)) |
70 | 20 | , propagate_(propagate) |
71 | 20 | { |
72 | 20 | } |
73 | | |
74 | | Property& operator =( |
75 | | const Property& property) |
76 | 0 | { |
77 | 0 | name_ = property.name_; |
78 | 0 | value_ = property.value_; |
79 | 0 | propagate_ = property.propagate_; |
80 | 0 | return *this; |
81 | 0 | } |
82 | | |
83 | | Property& operator =( |
84 | | Property&& property) |
85 | 0 | { |
86 | 0 | name_ = std::move(property.name_); |
87 | 0 | value_ = std::move(property.value_); |
88 | 0 | propagate_ = property.propagate_; |
89 | 0 | return *this; |
90 | 0 | } |
91 | | |
92 | | bool operator ==( |
93 | | const Property& b) const |
94 | 0 | { |
95 | 0 | return (this->name_ == b.name_) && |
96 | 0 | (this->value_ == b.value_); |
97 | 0 | } |
98 | | |
99 | | void name( |
100 | | const std::string& name) |
101 | 0 | { |
102 | 0 | name_ = name; |
103 | 0 | } |
104 | | |
105 | | void name( |
106 | | std::string&& name) |
107 | 0 | { |
108 | 0 | name_ = std::move(name); |
109 | 0 | } |
110 | | |
111 | | const std::string& name() const |
112 | 0 | { |
113 | 0 | return name_; |
114 | 0 | } |
115 | | |
116 | | std::string& name() |
117 | 0 | { |
118 | 0 | return name_; |
119 | 0 | } |
120 | | |
121 | | void value( |
122 | | const std::string& value) |
123 | 0 | { |
124 | 0 | value_ = value; |
125 | 0 | } |
126 | | |
127 | | void value( |
128 | | std::string&& value) |
129 | 0 | { |
130 | 0 | value_ = std::move(value); |
131 | 0 | } |
132 | | |
133 | | const std::string& value() const |
134 | 0 | { |
135 | 0 | return value_; |
136 | 0 | } |
137 | | |
138 | | std::string& value() |
139 | 0 | { |
140 | 0 | return value_; |
141 | 0 | } |
142 | | |
143 | | void propagate( |
144 | | bool propagate) |
145 | 0 | { |
146 | 0 | propagate_ = propagate; |
147 | 0 | } |
148 | | |
149 | | bool propagate() const |
150 | 0 | { |
151 | 0 | return propagate_; |
152 | 0 | } |
153 | | |
154 | | bool& propagate() |
155 | 0 | { |
156 | 0 | return propagate_; |
157 | 0 | } |
158 | | |
159 | | private: |
160 | | |
161 | | std::string name_; |
162 | | |
163 | | std::string value_; |
164 | | |
165 | | bool propagate_ = false; |
166 | | }; |
167 | | |
168 | | typedef std::vector<Property> PropertySeq; |
169 | | |
170 | | class PropertyHelper |
171 | | { |
172 | | public: |
173 | | |
174 | | static size_t serialized_size( |
175 | | const Property& property, |
176 | | size_t current_alignment = 0) |
177 | 0 | { |
178 | 0 | if (property.propagate()) |
179 | 0 | { |
180 | 0 | size_t initial_alignment = current_alignment; |
181 | 0 |
|
182 | 0 | current_alignment += 4 + alignment(current_alignment, 4) + property.name().size() + 1; |
183 | 0 | current_alignment += 4 + alignment(current_alignment, 4) + property.value().size() + 1; |
184 | 0 |
|
185 | 0 | return current_alignment - initial_alignment; |
186 | 0 | } |
187 | 0 | else |
188 | 0 | { |
189 | 0 | return 0; |
190 | 0 | } |
191 | 0 | } |
192 | | |
193 | | static size_t serialized_size( |
194 | | const PropertySeq& properties, |
195 | | size_t current_alignment = 0) |
196 | 0 | { |
197 | 0 | size_t initial_alignment = current_alignment; |
198 | 0 |
|
199 | 0 | current_alignment += 4 + alignment(current_alignment, 4); |
200 | 0 | for (auto property = properties.begin(); property != properties.end(); ++property) |
201 | 0 | { |
202 | 0 | current_alignment += serialized_size(*property, current_alignment); |
203 | 0 | } |
204 | 0 |
|
205 | 0 | return current_alignment - initial_alignment; |
206 | 0 | } |
207 | | |
208 | | private: |
209 | | |
210 | | inline static size_t alignment( |
211 | | size_t current_alignment, |
212 | | size_t dataSize) |
213 | 0 | { |
214 | 0 | return (dataSize - (current_alignment % dataSize)) & (dataSize - 1); |
215 | 0 | } |
216 | | |
217 | | }; |
218 | | |
219 | | struct PropertyParser |
220 | | { |
221 | | |
222 | | /** |
223 | | * @brief Parse a property value as an integer |
224 | | * @param property Property to parse |
225 | | * @param check_upper_bound If true, check that the value is lower than upper_bound |
226 | | * @param upper_bound Upper bound to check |
227 | | * @param check_lower_bound If true, check that the value is greater than lower_bound |
228 | | * @param lower_bound Lower bound to check |
229 | | * @param exception Exception to throw if the value is not a valid integer or if it is out of bounds |
230 | | * @return The parsed integer value |
231 | | * |
232 | | * @warning May throw an exception_t if the value is not a valid integer |
233 | | * or if it is out of bounds. |
234 | | */ |
235 | | template<typename exception_t> |
236 | | inline static int as_int( |
237 | | const Property& property, |
238 | | const bool& check_upper_bound, |
239 | | const int& upper_bound, |
240 | | const bool& check_lower_bound, |
241 | | const int& lower_bound, |
242 | | const exception_t& exception) |
243 | | { |
244 | | return parse_value( |
245 | | std::function<int(const Property& property)>( |
246 | | [](const Property& property) |
247 | | { |
248 | | return std::stoi(property.value()); |
249 | | } |
250 | | ), |
251 | | property, |
252 | | check_upper_bound, |
253 | | upper_bound, |
254 | | check_lower_bound, |
255 | | lower_bound, |
256 | | exception); |
257 | | } |
258 | | |
259 | | /** |
260 | | * @brief Parse a property value as a double |
261 | | * @param property Property to parse |
262 | | * @param check_upper_bound If true, check that the value is lower than upper_bound |
263 | | * @param upper_bound Upper bound to check |
264 | | * @param check_lower_bound If true, check that the value is greater than lower_bound |
265 | | * @param lower_bound Lower bound to check |
266 | | * @param exception Exception to throw if the value is not a valid double or if it is out of bounds |
267 | | * @return The parsed double value |
268 | | * |
269 | | * @warning May throw an exception_t if the value is not a valid double |
270 | | * or if it is out of bounds. |
271 | | */ |
272 | | template<typename exception_t> |
273 | | inline static double as_double( |
274 | | const Property& property, |
275 | | const bool& check_upper_bound, |
276 | | const double& upper_bound, |
277 | | const bool& check_lower_bound, |
278 | | const double& lower_bound, |
279 | | const exception_t& exception) |
280 | | { |
281 | | return parse_value( |
282 | | std::function<double(const Property& property)>( |
283 | | [](const Property& property) |
284 | | { |
285 | | return std::stod(property.value()); |
286 | | } |
287 | | ), |
288 | | property, |
289 | | check_upper_bound, |
290 | | upper_bound, |
291 | | check_lower_bound, |
292 | | lower_bound, |
293 | | exception); |
294 | | } |
295 | | |
296 | | /** |
297 | | * @brief Parse a property value as a boolean |
298 | | * @param property Property to parse |
299 | | * @return The parsed boolean value |
300 | | * |
301 | | */ |
302 | | inline static bool as_bool( |
303 | | const Property& property) |
304 | 0 | { |
305 | 0 | bool ret = false; |
306 | 0 | const std::string& value = property.value(); |
307 | 0 | if (value == "true" || value == "TRUE" || value == "True" || value == "1") |
308 | 0 | { |
309 | 0 | ret = true; |
310 | 0 | } |
311 | 0 | return ret; |
312 | 0 | } |
313 | | |
314 | | private: |
315 | | |
316 | | template <typename value_t, |
317 | | typename exception_t> |
318 | | inline static value_t parse_value( |
319 | | const std::function<value_t(const Property&)>& conversor, |
320 | | const Property& property, |
321 | | const bool& check_upper_bound, |
322 | | const value_t& upper_bound, |
323 | | const bool& check_lower_bound, |
324 | | const value_t& lower_bound, |
325 | | const exception_t& exception) |
326 | | { |
327 | | try |
328 | | { |
329 | | value_t converted_value = conversor(property); |
330 | | |
331 | | if (check_lower_bound && converted_value < lower_bound) |
332 | | { |
333 | | throw exception_t("Value '" + property.value() + |
334 | | "' for " + property.name() + " must be greater or equal to " + |
335 | | std::to_string(lower_bound)); |
336 | | } |
337 | | |
338 | | if (check_upper_bound && converted_value > upper_bound) |
339 | | { |
340 | | throw exception_t("Value '" + property.value() + |
341 | | "' for " + property.name() + " must be lower or equal to " + |
342 | | std::to_string(upper_bound)); |
343 | | } |
344 | | |
345 | | return converted_value; |
346 | | } |
347 | | catch (const std::invalid_argument&) |
348 | | { |
349 | | throw exception; |
350 | | } |
351 | | catch (const std::out_of_range&) |
352 | | { |
353 | | throw exception; |
354 | | } |
355 | | } |
356 | | |
357 | | }; |
358 | | |
359 | | } //namespace eprosima |
360 | | } //namespace fastdds |
361 | | } //namespace rtps |
362 | | |
363 | | #endif // FASTDDS_RTPS_COMMON__PROPERTY_HPP |