Ariles
Loading...
Searching...
No Matches
reader.cpp
Go to the documentation of this file.
1/**
2 @file
3 @author Alexander Sherikov
4
5 @copyright 2018 Alexander Sherikov, Licensed under the Apache License, Version 2.0.
6 (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
7
8 @brief
9*/
10
11#include <set>
12
13#include <boost/lexical_cast.hpp>
14
16
17#include "node_wrapper.h"
18
19
20namespace ariles2
21{
22 namespace ns_ros2param
23 {
25 {
26 protected:
27 std::set<std::string> childs_;
28 std::set<std::string>::const_iterator childs_iterator_;
29 const rclcpp::Parameter parameter_;
30
31 public:
32 using NodeBase::NodeBase;
33
34 ReaderNodeWrapper(const std::string &name, std::set<std::string> childs)
35 : NodeBase(name, NodeBase::Type::ITERATED_MAP), childs_(std::move(childs))
36 {
37 size_ = childs_.size();
38 childs_iterator_ = childs_.begin();
39 }
40
41 const std::string &getChildName()
42 {
43 return (*childs_iterator_++);
44 }
45
46 explicit ReaderNodeWrapper(const rclcpp::Parameter &&parameter)
47 : NodeBase(NodeBase::Type::ARRAY), parameter_(parameter)
48 {
49 index_ = 0;
51
52 switch (parameter_.get_type())
53 {
54 case rclcpp::ParameterType::PARAMETER_BYTE_ARRAY:
55 size_ = parameter_.as_byte_array().size();
56 return;
57 case rclcpp::ParameterType::PARAMETER_BOOL_ARRAY:
58 size_ = parameter_.as_bool_array().size();
59 return;
60 case rclcpp::ParameterType::PARAMETER_INTEGER_ARRAY:
61 size_ = parameter_.as_integer_array().size();
62 return;
63 case rclcpp::ParameterType::PARAMETER_DOUBLE_ARRAY:
64 size_ = parameter_.as_double_array().size();
65 return;
66 case rclcpp::ParameterType::PARAMETER_STRING_ARRAY:
67 size_ = parameter_.as_string_array().size();
68 return;
69 default:
70 CPPUT_THROW("Unexpected value type");
71 }
72 }
73
74 bool tryReadArray(int64_t &value)
75 {
76 if (isBuiltinArray())
77 {
78 switch (parameter_.get_type())
79 {
80 case rclcpp::ParameterType::PARAMETER_BYTE_ARRAY:
81 value = parameter_.as_byte_array()[index_];
82 return (true);
83 case rclcpp::ParameterType::PARAMETER_INTEGER_ARRAY:
84 value = parameter_.as_integer_array()[index_];
85 return (true);
86 default:
87 CPPUT_THROW("Unexpected array value type");
88 }
89 }
90 return (false);
91 }
92
93 bool tryReadArray(double &value)
94 {
95 if (isBuiltinArray())
96 {
97 switch (parameter_.get_type())
98 {
99 case rclcpp::ParameterType::PARAMETER_DOUBLE_ARRAY:
100 value = parameter_.as_double_array()[index_];
101 return (true);
102 default:
103 CPPUT_THROW("Unexpected array value type");
104 }
105 }
106 return (false);
107 }
108
109 bool tryReadArray(std::string &value)
110 {
111 if (isBuiltinArray())
112 {
113 switch (parameter_.get_type())
114 {
115 case rclcpp::ParameterType::PARAMETER_STRING_ARRAY:
116 value = parameter_.as_string_array()[index_];
117 return (true);
118 default:
119 CPPUT_THROW("Unexpected array value type");
120 }
121 }
122 return (false);
123 }
124
125 bool tryReadArray(bool &value)
126 {
127 if (isBuiltinArray())
128 {
129 switch (parameter_.get_type())
130 {
131 case rclcpp::ParameterType::PARAMETER_BOOL_ARRAY:
132 value = parameter_.as_bool_array()[index_];
133 return (true);
134 default:
135 CPPUT_THROW("Unexpected array value type");
136 }
137 }
138 return (false);
139 }
140 };
141
142 namespace impl
143 {
144 class Reader : public serialization::NodeStackBase<ReaderNodeWrapper>
145 {
146 public:
147 // https://docs.ros2.org/latest/api/rclcpp/classrclcpp_1_1Node.html
148 rclcpp::node_interfaces::NodeParametersInterface::SharedPtr nh_;
149
150 std::vector<std::string> parameter_names_;
151
152 const std::string separator_ = ".";
153
154
155 public:
156 explicit Reader(const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr &nh)
157 {
158 nh_ = nh;
159 }
160
161
162 bool getParameter(rclcpp::Parameter &parameter) const
163 {
165 CPPUT_TRACE_VALUE(back().node_);
166
167 return (nh_->get_parameter(back().node_, parameter));
168 }
169
170
171 [[nodiscard]] bool isParameter() const
172 {
173 for (const std::string &name : parameter_names_)
174 {
175 if (back().node_ == name)
176 {
177 return (true);
178 }
179 }
180 return (false);
181 }
182
183 void reset()
184 {
185 clear();
186
187 parameter_names_ = std::move(nh_->list_parameters({}, std::numeric_limits<uint64_t>::max()).names);
188 }
189
190
191 [[nodiscard]] static bool isPrefix(const std::string &prefix, const std::string &name)
192 {
193 if (prefix.empty())
194 {
195 return (true); // zero prefix
196 }
197
198 if (prefix.size() <= name.size())
199 {
200 if (name.substr(0, prefix.size()) == prefix)
201 {
202 if (prefix.size() == name.size())
203 {
204 return (true); // name = prefix
205 }
206
207 if ('.' == name[prefix.size()])
208 {
209 return (true); // normal prefix
210 }
211 }
212 }
213
214 return (false);
215 }
216
217
218 [[nodiscard]] std::set<std::string> listParameters() const
219 {
220 std::size_t substr_start = 0;
221
222 if (not empty())
223 {
224 substr_start = back().node_.size() + 1; // + 1 for dot
225 }
226
227 std::set<std::string> names;
228 for (const std::string &name : parameter_names_)
229 {
230 if (isPrefix(back().node_, name))
231 {
232 const std::size_t substr_end = name.find('.', substr_start);
233 names.insert(name.substr(substr_start, substr_end - substr_start));
234 }
235 }
236
237 return (names);
238 }
239
241 {
242 for (const std::string &name : parameter_names_)
243 {
244 if (isPrefix(back().node_, name))
245 {
246 return (true);
247 }
248 }
249 return (false);
250 }
251
252 template <int t_expected_parameter_type, class t_Element>
253 void readElement(t_Element &element)
254 {
256 if (not back().tryReadArray(element))
257 {
258 rclcpp::Parameter parameter;
259 CPPUT_ASSERT(getParameter(parameter), std::string("Cannot read parameter: ") + back().node_);
260 CPPUT_ASSERT(t_expected_parameter_type == parameter.get_type(), "Unexpected parameter type.");
261 element = parameter.get_value<t_Element>();
262 }
263 }
264 };
265 } // namespace impl
266 } // namespace ns_ros2param
267} // namespace ariles2
268
269
270namespace ariles2
271{
272 namespace ns_ros2param
273 {
274 Reader::Reader(const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr &nh)
275 {
276 makeImplPtr(nh);
277 }
278
279
280 bool Reader::startRoot(const std::string &name)
281 {
283 CPPUT_TRACE_VALUE(name);
284
285 impl_->reset();
286 return (Parent::startRoot(name));
287 }
288
289
290 bool Reader::startMapEntry(const std::string &child_name)
291 {
293 if (impl_->empty())
294 {
295 impl_->emplace(child_name);
296 }
297 else
298 {
299 CPPUT_ASSERT(not impl_->back().isBuiltinArray(), "Unexpected parent type (builtin array).");
300
301 impl_->concatWithNodeAndEmplace(impl_->separator_, child_name);
302 }
303
304 return (impl_->hasParameterPrefix());
305 }
306
308 {
310 impl_->pop();
311 }
312
313
314
316 const SizeLimitEnforcementType limit_type,
317 const std::size_t min,
318 const std::size_t max)
319 {
321
322 std::set<std::string> name_list = impl_->listParameters();
323
324 checkSize(limit_type, name_list.size(), min, max);
325
326 impl_->emplace(impl_->back().node_, std::move(name_list));
327 return (true);
328 }
329
330 bool Reader::startIteratedMapElement(std::string &entry_name)
331 {
333 if (impl_->back().isCompleted())
334 {
335 return (false);
336 }
337
338 entry_name = impl_->back().getChildName();
339 impl_->concatWithNodeAndEmplace(impl_->separator_, entry_name);
340
341 return (true);
342 }
343
345 {
346 impl_->pop();
347 ++(impl_->back().index_);
348 }
349
351 {
353 CPPUT_ASSERT(impl_->back().isCompleted(), "End of iterated map has not been reached.");
354 impl_->pop();
355 }
356
357
358 std::size_t Reader::startArray()
359 {
361
362 if (not impl_->empty() and impl_->isParameter())
363 {
364 rclcpp::Parameter values;
365 impl_->getParameter(values);
366 impl_->emplace(std::move(values));
367 }
368 else
369 {
370 impl_->emplace(impl_->back().node_, 0, impl_->listParameters().size());
371 }
372
373 return (impl_->back().size_);
374 }
375
377 {
379
380 CPPUT_ASSERT(not impl_->back().isCompleted(), "Internal error: array has more elements than expected.");
381 if (impl_->back().isNonBuiltinArray())
382 {
383 impl_->concatWithNodeAndEmplace(
384 impl_->separator_, boost::lexical_cast<std::string>(impl_->back().index_));
385 }
386 }
387
389 {
391 if (not impl_->back().isBuiltinArray())
392 {
393 impl_->pop();
394 }
395 impl_->shiftArray();
396 }
397
399 {
401 impl_->pop();
402 }
403
404
405
406#define ARILES2_BASIC_TYPE(type) \
407 void Reader::readElement(type &element) \
408 { \
409 int64_t tmp_value; \
410 impl_->readElement<rclcpp::ParameterType::PARAMETER_INTEGER>(tmp_value); \
411 CPPUT_ASSERT( \
412 tmp_value <= std::numeric_limits<type>::max() && tmp_value >= std::numeric_limits<type>::min(), \
413 "Value is out of range."); \
414 element = static_cast<type>(tmp_value); \
415 }
416
418
419#undef ARILES2_BASIC_TYPE
420
421
422#define ARILES2_BASIC_TYPE(type) \
423 void Reader::readElement(type &element) \
424 { \
425 CPPUT_TRACE_FUNCTION; \
426 int64_t tmp_value; \
427 impl_->readElement<rclcpp::ParameterType::PARAMETER_INTEGER>(tmp_value); \
428 CPPUT_ASSERT(tmp_value >= 0, "Expected positive value."); \
429 CPPUT_ASSERT(static_cast<uint64_t>(tmp_value) <= std::numeric_limits<type>::max(), "Value is too large."); \
430 element = static_cast<type>(tmp_value); \
431 }
432
434
435#undef ARILES2_BASIC_TYPE
436
437
438#define ARILES2_BASIC_TYPE(type) \
439 void Reader::readElement(type &element) \
440 { \
441 CPPUT_TRACE_FUNCTION; \
442 double tmp_value; \
443 impl_->readElement<rclcpp::ParameterType::PARAMETER_DOUBLE>(tmp_value); \
444 element = static_cast<type>(tmp_value); \
445 }
446
448
449#undef ARILES2_BASIC_TYPE
450
451
452 void Reader::readElement(std::string &element)
453 {
455 impl_->readElement<rclcpp::ParameterType::PARAMETER_STRING>(element);
456 }
457
458
459 void Reader::readElement(bool &element)
460 {
462 impl_->readElement<rclcpp::ParameterType::PARAMETER_BOOL>(element);
463 }
464 } // namespace ns_ros2param
465} // namespace ariles2
bool tryReadArray(std::string &value)
Definition reader.cpp:109
std::set< std::string > childs_
Definition reader.cpp:27
const std::string & getChildName()
Definition reader.cpp:41
ReaderNodeWrapper(const std::string &name, std::set< std::string > childs)
Definition reader.cpp:34
const rclcpp::Parameter parameter_
Definition reader.cpp:29
std::set< std::string >::const_iterator childs_iterator_
Definition reader.cpp:28
ReaderNodeWrapper(const rclcpp::Parameter &&parameter)
Definition reader.cpp:46
bool startIteratedMap(const SizeLimitEnforcementType=SIZE_LIMIT_NONE, const std::size_t=0, const std::size_t=0)
Definition reader.cpp:315
void endMapEntry()
endMapEntry from the current entry to its parent.
Definition reader.cpp:307
bool startIteratedMapElement(std::string &entry_name)
Definition reader.cpp:330
bool startMapEntry(const std::string &child_name)
startMapEntry to the entry with the given name
Definition reader.cpp:290
Reader(const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr &nh)
Constructor.
Definition reader.cpp:274
bool startRoot(const std::string &name)
Definition reader.cpp:280
rclcpp::node_interfaces::NodeParametersInterface::SharedPtr nh_
Definition reader.cpp:148
Reader(const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr &nh)
Definition reader.cpp:156
bool getParameter(rclcpp::Parameter &parameter) const
Definition reader.cpp:162
std::set< std::string > listParameters() const
Definition reader.cpp:218
void readElement(t_Element &element)
Definition reader.cpp:253
std::vector< std::string > parameter_names_
Definition reader.cpp:150
static bool isPrefix(const std::string &prefix, const std::string &name)
Definition reader.cpp:191
void checkSize(const SizeLimitEnforcementType limit_type, const std::size_t size=0, const std::size_t min=0, const std::size_t max=0) const
Definition read.h:47
virtual bool startRoot(const std::string &name)
Definition read.h:73
void readElement(std::complex< t_Scalar > &entry)
Definition read.h:357
#define CPPUT_THROW(...)
Definition exception.h:19
#define CPPUT_ASSERT(condition,...)
Definition exception.h:32
#define ARILES2_BASIC_REAL_TYPES_LIST
Definition helpers.h:59
#define ARILES2_BASIC_UNSIGNED_INTEGER_TYPES_LIST
Definition helpers.h:50
#define ARILES2_BASIC_SIGNED_INTEGER_TYPES_LIST
Definition helpers.h:37
#define CPPUT_MACRO_SUBSTITUTE(macro)
Definition misc.h:21
#define CPPUT_TRACE_FUNCTION
Definition trace.h:126
#define CPPUT_TRACE_VALUE(value)
Definition trace.h:127