Robot Raconteur Core C++ Library
Loading...
Searching...
No Matches
ServiceStructure.h
Go to the documentation of this file.
1
23
24#pragma once
25
30
31namespace RobotRaconteur
32{
33
34// struct
35
36class ROBOTRACONTEUR_CORE_API StructureStub
37{
38 public:
39 virtual RR_INTRUSIVE_PTR<MessageElementNestedElementList> PackStructure(const RR_INTRUSIVE_PTR<RRValue>& s) = 0;
40
41 virtual RR_INTRUSIVE_PTR<RRStructure> UnpackStructure(
42 const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& m) = 0;
43
44 StructureStub(const RR_SHARED_PTR<RobotRaconteurNode>& node);
45
46 RR_SHARED_PTR<RobotRaconteurNode> GetNode();
47 RR_SHARED_PTR<RobotRaconteurNode> RRGetNode() { return GetNode(); }
48 RR_WEAK_PTR<RobotRaconteurNode> RRGetNodeWeak() { return node; }
49
50 virtual ~StructureStub() {}
51
52 protected:
53 RR_WEAK_PTR<RobotRaconteurNode> node;
54};
55
56// pod
57
58template <typename T>
59class PodStub
60{
61 BOOST_STATIC_ASSERT(sizeof(T) == -1);
62};
63
82template <typename T, size_t N, bool varlength>
83class pod_field_array : public boost::array<T, N>
84{
85 private:
86 size_t len;
87
88 public:
89 pod_field_array() : len(0) {}
90 pod_field_array(size_t n) : len(0) { resize(n); }
91 typename boost::array<T, N>::iterator end() { return boost::array<T, N>::elems + len; }
92 typename boost::array<T, N>::const_iterator end() const { return boost::array<T, N>::elems + len; }
93 typename boost::array<T, N>::const_iterator cend() const { return boost::array<T, N>::elems + len; }
94 void resize(size_t n)
95 {
96 if (n > N)
97 {
98 throw std::out_of_range("requested size exceeds array max size");
99 }
100 len = n;
101 }
102 void clear() { resize(0); }
103 size_t size() const { return len; }
104 size_t max_size() const { return N; }
105 typename boost::array<T, N>::reference at(size_t i) { return rangecheck(i), boost::array<T, N>::elems[i]; }
106 typename boost::array<T, N>::const_reference at(size_t i) const
107 {
108 return rangecheck(i), boost::array<T, N>::elems[i];
109 }
110 typename boost::array<T, N>::reference back() { return at(size() - 1); }
111 typename boost::array<T, N>::const_reference back() const { return at(size() - 1); }
112 template <typename T2>
113 pod_field_array<T, N, varlength>& operator=(const pod_field_array<T2, N, varlength>& rhs)
114 {
115 std::copy(rhs.begin(), rhs.end(), boost::array<T, N>::begin());
116 this->len = rhs->len;
117 return *this;
118 }
119 bool rangecheck(size_t i) const
120 {
121 return i > size() ? boost::throw_exception(std::out_of_range("array<>: index out of range")), true : true;
122 }
123};
124
125template <typename T, size_t N>
126class pod_field_array<T, N, false> : public boost::array<T, N>
127{
128 public:
129 void resize(size_t n)
130 {
131 if (n != N)
132 throw std::out_of_range("requested size does not match fixed array size");
133 }
134 size_t max_size() { return N; }
135};
136
137template <typename T, size_t N, bool varlength>
138RR_INTRUSIVE_PTR<RRArray<T> > pod_field_array_ToRRArray(const pod_field_array<T, N, varlength>& i)
139{
140 return AttachRRArrayCopy<T>(&i[0], i.size());
141}
142
143template <typename T, size_t N, bool varlength>
144void RRArrayTo_pod_field_array(pod_field_array<T, N, varlength>& v, const RR_INTRUSIVE_PTR<RRArray<T> >& i)
145{
146 if (!i)
147 throw NullValueException("Pod array must not be null");
148 v.resize(i->size());
149 memcpy((void*)&v[0], (void*)i->data(), sizeof(T) * i->size());
150}
151
152// NOLINTBEGIN(bugprone-macro-parentheses)
153#define RRPodStubNumberType(type) \
154 template <> \
155 class PodStub<type> \
156 { \
157 public: \
158 template <typename U> \
159 static void PackField(const type& v, MessageStringRef name, U& out) \
160 { \
161 out.push_back(CreateMessageElement(name, ScalarToRRArray<type>(v))); \
162 } \
163 \
164 template <typename U> \
165 static void UnpackField(type& v, MessageStringRef name, U& in) \
166 { \
167 v = RRArrayToScalar<type>(MessageElement::FindElement(in, name)->template CastData<RRArray<type> >()); \
168 } \
169 }; \
170 \
171 template <size_t N, bool varlength> \
172 class PodStub<pod_field_array<type, N, varlength> > \
173 { \
174 public: \
175 template <typename U> \
176 static void PackField(const pod_field_array<type, N, varlength>& v, MessageStringRef name, U& out) \
177 { \
178 out.push_back(CreateMessageElement(name, pod_field_array_ToRRArray(v))); \
179 } \
180 \
181 template <typename U> \
182 static void UnpackField(pod_field_array<type, N, varlength>& v, MessageStringRef name, U& in) \
183 { \
184 RR_INTRUSIVE_PTR<RRArray<type> > a = \
185 MessageElement::FindElement(in, name)->template CastData<RRArray<type> >(); \
186 RRArrayTo_pod_field_array(v, a); \
187 } \
188 };
189// NOLINTEND(bugprone-macro-parentheses)
190
191RRPodStubNumberType(double);
192RRPodStubNumberType(float);
193RRPodStubNumberType(int8_t);
194RRPodStubNumberType(uint8_t);
195RRPodStubNumberType(int16_t);
196RRPodStubNumberType(uint16_t);
197RRPodStubNumberType(int32_t);
198RRPodStubNumberType(uint32_t);
199RRPodStubNumberType(int64_t);
200RRPodStubNumberType(uint64_t);
201
202template <typename T, size_t N, bool varlength>
203RR_INTRUSIVE_PTR<RRNamedArray<T> > pod_field_array_ToRRNamedArray(const pod_field_array<T, N, varlength>& i)
204{
205 typedef typename RRPrimUtil<T>::ElementArrayType element_type;
206 typename RR_INTRUSIVE_PTR<RRArray<element_type> > a = AttachRRArrayCopy<element_type>(
207 reinterpret_cast<const element_type*>(&i[0]), i.size() * RRPrimUtil<T>::GetElementArrayCount());
208 return new RRNamedArray<T>(a); // NOLINT(cppcoreguidelines-owning-memory)
209}
210
211template <typename T, size_t N, bool varlength>
212void RRNamedArrayTo_pod_field_array(pod_field_array<T, N, varlength>& v, const RR_INTRUSIVE_PTR<RRNamedArray<T> >& i)
213{
214 if (!i)
215 throw NullValueException("Pod array must not be null");
216 v.resize(i->size());
217 memcpy((void*)&v[0], (void*)i->GetNumericArray()->data(), sizeof(T) * i->size());
218}
219
220// NOLINTBEGIN(bugprone-macro-parentheses)
221#define RRPodStubNamedArrayType(type) \
222 template <> \
223 class PodStub<type> \
224 { \
225 public: \
226 template <typename U> \
227 static void PackField(const type& v, MessageStringRef name, U& out) \
228 { \
229 std::vector<RR_INTRUSIVE_PTR<MessageElement> > v1; \
230 v1.push_back(CreateMessageElement("array", ScalarToRRNamedArray<type>(v)->GetNumericArray())); \
231 out.push_back(CreateMessageElement( \
232 name, CreateMessageElementNestedElementList(DataTypes_namedarray_array_t, \
233 RRPrimUtil<type>::GetElementTypeString(), RR_MOVE(v1)))); \
234 } \
235 \
236 template <typename U> \
237 static void UnpackField(type& v, MessageStringRef name, U& in) \
238 { \
239 typedef typename RRPrimUtil<type>::ElementArrayType element_type; \
240 RR_INTRUSIVE_PTR<MessageElementNestedElementList> m = \
241 MessageElement::FindElement(in, name)->CastDataToNestedList(DataTypes_namedarray_array_t); \
242 if (m->TypeName != RRPrimUtil<type>::GetElementTypeString()) \
243 throw DataTypeException("Invalid namedarray"); \
244 RR_INTRUSIVE_PTR<RRArray<element_type> > a = \
245 MessageElement::FindElement(m->Elements, "array")->CastData<RRArray<element_type> >(); \
246 if (a->size() != RRPrimUtil<type>::GetElementArrayCount()) \
247 throw DataTypeException("Invalid namedarray"); \
248 memcpy((void*)&v, a->void_ptr(), sizeof(v)); \
249 } \
250 }; \
251 \
252 template <size_t N, bool varlength> \
253 class PodStub<pod_field_array<type, N, varlength> > \
254 { \
255 public: \
256 template <typename U> \
257 static void PackField(const pod_field_array<type, N, varlength>& v, MessageStringRef name, U& out) \
258 { \
259 RR_INTRUSIVE_PTR<RRNamedArray<type> > a = pod_field_array_ToRRNamedArray(v); \
260 std::vector<RR_INTRUSIVE_PTR<MessageElement> > a1; \
261 a1.push_back(CreateMessageElement("array", a->GetNumericArray())); \
262 out.push_back(CreateMessageElement( \
263 name, CreateMessageElementNestedElementList(DataTypes_namedarray_array_t, \
264 RRPrimUtil<type>::GetElementTypeString(), RR_MOVE(a1)))); \
265 } \
266 \
267 template <typename U> \
268 static void UnpackField(pod_field_array<type, N, varlength>& v, MessageStringRef name, U& in) \
269 { \
270 typedef RRPrimUtil<type>::ElementArrayType element_type; \
271 RR_INTRUSIVE_PTR<MessageElementNestedElementList> a = \
272 MessageElement::FindElement(in, name)->CastDataToNestedList(DataTypes_namedarray_array_t); \
273 RR_INTRUSIVE_PTR<RRArray<element_type> > a1 = \
274 MessageElement::FindElement(a->Elements, "array")->template CastData<RRArray<element_type> >(); \
275 v.resize(a1->size() / RRPrimUtil<type>::GetElementArrayCount()); \
276 memcpy((void*)&v, (void*)a1->data(), a1->size() * sizeof(element_type)); \
277 } \
278 };
279// NOLINTEND(bugprone-macro-parentheses)
280template <typename T, size_t N, bool varlength>
281class PodStub<pod_field_array<T, N, varlength> >
282{
283 public:
284 template <typename U>
285 static void PackField(const pod_field_array<T, N, varlength>& v, MessageStringRef name, U& out)
286 {
287 std::vector<RR_INTRUSIVE_PTR<MessageElement> > o;
288 o.reserve(v.size());
289 for (size_t j = 0; j < v.size(); j++)
290 {
291 RR_INTRUSIVE_PTR<MessageElement> m =
292 CreateMessageElement(boost::numeric_cast<int32_t>(j), PodStub<T>::PackToMessageElementPod(v[j]));
293 o.push_back(m);
294 }
295 out.push_back(
296 CreateMessageElement(name, CreateMessageElementNestedElementList(
297 DataTypes_pod_array_t, RRPrimUtil<T>::GetElementTypeString(), RR_MOVE(o))));
298 }
299
300 template <typename U>
301 static void UnpackField(pod_field_array<T, N, varlength>& v, MessageStringRef name, U& in)
302 {
303 RR_INTRUSIVE_PTR<MessageElementNestedElementList> a =
304 MessageElement::FindElement(in, name)->CastDataToNestedList(DataTypes_pod_array_t);
305 if (!a)
306 throw NullValueException("Unexpected null array");
307 if (a->TypeName != RRPrimUtil<T>::GetElementTypeString())
308 throw DataTypeException("Pod data type mismatch");
309
310 v.resize(a->Elements.size());
311 for (int32_t i = 0; i < boost::numeric_cast<int32_t>(a->Elements.size()); i++)
312 {
313 RR_INTRUSIVE_PTR<MessageElement> m = a->Elements.at(i);
314 int32_t key = 0;
315 if (!MessageElement_GetElementNumber(m, key))
316 {
317 throw DataTypeException("Invalid pod array format");
318 }
319
320 if (key != i)
321 throw DataTypeException("Invalid pod array format");
322
323 PodStub<T>::UnpackFromMessageElementPod(v[i], m->CastDataToNestedList());
324 }
325 }
326};
327
328template <typename T, typename U>
329void PodStub_PackField(const T& v, MessageStringRef name, U& out)
330{
331 PodStub<T>::PackField(v, name, out);
332}
333
334template <typename T, typename U>
335void PodStub_UnpackField(T& v, MessageStringRef name, U& out)
336{
337 PodStub<T>::UnpackField(v, name, out);
338}
339
340template <typename T>
341RR_INTRUSIVE_PTR<MessageElementNestedElementList> PodStub_PackPodToArray(const T& v)
342{
343 std::vector<RR_INTRUSIVE_PTR<MessageElement> > o;
344
345 RR_INTRUSIVE_PTR<MessageElement> m = CreateMessageElement(0, PodStub<T>::PackToMessageElementPod(v));
346 o.push_back(m);
347
348 return CreateMessageElementNestedElementList(DataTypes_pod_array_t, RRPrimUtil<T>::GetElementTypeString(),
349 RR_MOVE(o));
350}
351
352template <typename T>
353void PodStub_UnpackPodFromArray(T& v, const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& a)
354{
355 if (!a)
356 throw DataTypeException("Pod scalar array must not be null");
357 if (a->GetTypeID() != DataTypes_pod_array_t)
358 throw DataTypeMismatchException("Expected a pod array");
359 if (a->TypeName != RRPrimUtil<T>::GetElementTypeString())
360 throw DataTypeException("Pod data type mismatch");
361 if (a->Elements.size() != 1)
362 throw DataTypeException("Invalid pod scalar array format");
363
364 RR_INTRUSIVE_PTR<MessageElement> m = a->Elements.at(0);
365 int32_t key = 0;
366 if (!MessageElement_GetElementNumber(m, key))
367 {
368 throw DataTypeException("Invalid pod scalar array format");
369 }
370
371 if (key != 0)
372 throw DataTypeException("Invalid pod scalar array format");
373
374 PodStub<T>::UnpackFromMessageElementPod(v, m->CastDataToNestedList());
375}
376
377template <typename T>
378T PodStub_UnpackPodFromArray(const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& a)
379{
380 T v;
381 PodStub_UnpackPodFromArray<T>(v, a);
382 return v;
383}
384
385template <typename T>
386RR_INTRUSIVE_PTR<MessageElementNestedElementList> PodStub_PackPodArray(const RR_INTRUSIVE_PTR<RRPodArray<T> >& a)
387{
388 if (!a)
389 return RR_INTRUSIVE_PTR<MessageElementNestedElementList>();
390 std::vector<RR_INTRUSIVE_PTR<MessageElement> > o;
391 o.reserve(a->size());
392 for (size_t i = 0; i < a->size(); i++)
393 {
394 RR_INTRUSIVE_PTR<MessageElement> m =
395 CreateMessageElement(boost::numeric_cast<int32_t>(i), PodStub<T>::PackToMessageElementPod(a->at(i)));
396 o.push_back(m);
397 }
398 return CreateMessageElementNestedElementList(DataTypes_pod_array_t, RRPrimUtil<T>::GetElementTypeString(),
399 RR_MOVE(o));
400}
401
402template <typename T>
403RR_INTRUSIVE_PTR<RRPodArray<T> > PodStub_UnpackPodArray(const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& a)
404{
405 if (!a)
406 return RR_INTRUSIVE_PTR<RRPodArray<T> >();
407 if (a->GetTypeID() != DataTypes_pod_array_t)
408 throw DataTypeMismatchException("Expected pod array");
409
410 RR_INTRUSIVE_PTR<RRPodArray<T> > o = AllocateEmptyRRPodArray<T>(a->Elements.size());
411 for (size_t i = 0; i < a->Elements.size(); i++)
412 {
413 RR_INTRUSIVE_PTR<MessageElement> m = a->Elements.at(i);
414 int32_t key = 0;
415 if (!MessageElement_GetElementNumber(m, key))
416 {
417 throw DataTypeException("Invalid pod array format");
418 }
419
420 if (key != boost::numeric_cast<int32_t>(i))
421 throw DataTypeException("Invalid pod array format");
422 PodStub<T>::UnpackFromMessageElementPod(o->at(i), m->CastDataToNestedList());
423 }
424
425 return o;
426}
427
428template <typename T>
429RR_INTRUSIVE_PTR<MessageElementNestedElementList> PodStub_PackPodMultiDimArray(
430 const RR_INTRUSIVE_PTR<RRPodMultiDimArray<T> >& a)
431{
432 if (!a)
433 return RR_INTRUSIVE_PTR<MessageElementNestedElementList>();
434
435 std::vector<RR_INTRUSIVE_PTR<MessageElement> > m;
436 m.reserve(2);
437 m.push_back(CreateMessageElement("dims", a->Dims));
438 if (!a->PodArray)
439 throw NullValueException("Multidimarray array must not be null");
440 m.push_back(CreateMessageElement("array", PodStub_PackPodArray(a->PodArray)));
441 return CreateMessageElementNestedElementList(DataTypes_pod_multidimarray_t, RRPrimUtil<T>::GetElementTypeString(),
442 RR_MOVE(m));
443}
444
445template <typename T>
446RR_INTRUSIVE_PTR<RRPodMultiDimArray<T> > PodStub_UnpackPodMultiDimArray(
447 const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& m)
448{
449 if (!m)
450 return RR_INTRUSIVE_PTR<RRPodMultiDimArray<T> >();
451 if (m->GetTypeID() != DataTypes_pod_multidimarray_t)
452 throw DataTypeMismatchException("Expected pod multidimarray message");
453
454 RR_INTRUSIVE_PTR<RRPodMultiDimArray<T> > o = AllocateEmptyRRPodMultiDimArray<T>();
455 o->Dims = (MessageElement::FindElement(m->Elements, "dims")->CastData<RRArray<uint32_t> >());
456 o->PodArray = PodStub_UnpackPodArray<T>(
457 MessageElement::FindElement(m->Elements, "array")->CastDataToNestedList(DataTypes_pod_array_t));
458 if (!o->PodArray)
459 throw NullValueException("Multidimarray array must not be null");
460 return o;
461}
462
463// MessageElement pack helper functions for pod
464template <typename T>
465RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackPodToArrayElement(MessageStringRef elementname, const T& s)
466{
467 return CreateMessageElement(elementname, PodStub_PackPodToArray(s));
468}
469
470template <typename T>
471RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackPodArrayElement(MessageStringRef elementname,
472 const RR_INTRUSIVE_PTR<RRPodArray<T> >& s)
473{
474 if (!s)
475 throw NullValueException("Arrays must not be null");
476 return CreateMessageElement(elementname, PodStub_PackPodArray(s));
477}
478
479template <typename T>
480RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackPodMultiDimArrayElement(
481 MessageStringRef elementname, const RR_INTRUSIVE_PTR<RRPodMultiDimArray<T> >& s)
482{
483 if (!s)
484 throw NullValueException("Arrays must not be null");
485 return CreateMessageElement(elementname, PodStub_PackPodMultiDimArray(s));
486}
487
488// MessageElement unpack helper functions for pod
489template <typename T>
490T MessageElement_UnpackPodFromArray(const RR_INTRUSIVE_PTR<MessageElement>& m)
491{
492 return RobotRaconteur::PodStub_UnpackPodFromArray<T>(m->CastDataToNestedList(DataTypes_pod_array_t));
493}
494
495template <typename T>
496RR_INTRUSIVE_PTR<RRPodArray<T> > MessageElement_UnpackPodArray(const RR_INTRUSIVE_PTR<MessageElement>& m)
497{
498 RR_INTRUSIVE_PTR<RRPodArray<T> > a =
499 RobotRaconteur::PodStub_UnpackPodArray<T>(m->CastDataToNestedList(DataTypes_pod_array_t));
500 if (!a)
501 throw NullValueException("Arrays must not be null");
502 return a;
503}
504
505template <typename T>
506RR_INTRUSIVE_PTR<RRPodMultiDimArray<T> > MessageElement_UnpackPodMultiDimArray(
507 const RR_INTRUSIVE_PTR<MessageElement>& m)
508{
509 RR_INTRUSIVE_PTR<RRPodMultiDimArray<T> > a =
510 RobotRaconteur::PodStub_UnpackPodMultiDimArray<T>(m->CastDataToNestedList(DataTypes_pod_multidimarray_t));
511 if (!a)
512 throw NullValueException("Arrays must not be null");
513 return a;
514}
515
516template <typename T>
517static RR_INTRUSIVE_PTR<RRPodArray<T> > VerifyRRArrayLength(const RR_INTRUSIVE_PTR<RRPodArray<T> >& a, size_t len,
518 bool varlength)
519{
520 if (!a)
521 throw NullValueException("Arrays must not be null");
522 if (len != 0)
523 {
524 if (varlength && (a->size() > len))
525 {
526 throw DataTypeException("Array dimension mismatch");
527 }
528 if (!varlength && (a->size() != len))
529 {
530 throw DataTypeException("Array dimension mismatch");
531 }
532 }
533 return a;
534}
535
536template <size_t Ndims, typename T>
537static RR_INTRUSIVE_PTR<RRPodMultiDimArray<T> > VerifyRRMultiDimArrayLength(
538 const RR_INTRUSIVE_PTR<RRPodMultiDimArray<T> >& a, size_t n_elems, boost::array<uint32_t, Ndims> dims)
539{
540 if (!a)
541 throw NullValueException("Arrays must not be null");
542
543 if (a->Dims->size() != Ndims)
544 {
545 throw DataTypeException("Array dimension mismatch");
546 }
547
548 if (a->PodArray->size() != n_elems)
549 {
550 throw DataTypeException("Array dimension mismatch");
551 }
552
553 for (size_t i = 0; i < Ndims; i++)
554 {
555 if ((*a->Dims)[i] != dims[i])
556 {
557 throw DataTypeException("Array dimension mismatch");
558 }
559 }
560
561 return a;
562}
563
564// namedarray
565
566template <typename T>
567RR_INTRUSIVE_PTR<MessageElementNestedElementList> NamedArrayStub_PackNamedArrayToArray(const T& v)
568{
569 typedef typename RRPrimUtil<T>::ElementArrayType element_type;
570 RR_INTRUSIVE_PTR<RRArray<element_type> > a = AllocateRRArray<element_type>(RRPrimUtil<T>::GetElementArrayCount());
571 memcpy(a->void_ptr(), (void*)&v, sizeof(T));
572 std::vector<RR_INTRUSIVE_PTR<MessageElement> > a1;
573 a1.push_back(CreateMessageElement("array", a));
574 return CreateMessageElementNestedElementList(DataTypes_namedarray_array_t, RRPrimUtil<T>::GetElementTypeString(),
575 RR_MOVE(a1));
576}
577
578template <typename T>
579void NamedArrayStub_UnpackNamedArrayFromArray(T& v, const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& a)
580{
581 typedef typename RRPrimUtil<T>::ElementArrayType element_type;
582 if (!a)
583 throw DataTypeException("NamedArray scalar array must not be null");
584 if (a->GetTypeID() != DataTypes_namedarray_array_t)
585 throw DataTypeMismatchException("Expected namedarray array message");
586 if (a->TypeName != RRPrimUtil<T>::GetElementTypeString())
587 throw DataTypeException("NamedArray data type mismatch");
588 if (a->Elements.size() != 1)
589 throw DataTypeException("Invalid namedarray array format");
590 typename RR_INTRUSIVE_PTR<RRArray<element_type> > a1 =
591 MessageElement::FindElement(a->Elements, "array")->template CastData<RRArray<element_type> >();
592 if (a1->size() != sizeof(T) / sizeof(element_type))
593 throw DataTypeException("Invalid scalar namedarray array format");
594
595 v = *(static_cast<T*>(a1->void_ptr()));
596}
597
598template <typename T>
599T NamedArrayStub_UnpackNamedArrayFromArray(const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& a)
600{
601 T o; // NOLINT(cppcoreguidelines-pro-type-member-init)
602 NamedArrayStub_UnpackNamedArrayFromArray(o, a);
603 return o;
604}
605
606template <typename T>
607RR_INTRUSIVE_PTR<MessageElementNestedElementList> NamedArrayStub_PackNamedArray(
608 const RR_INTRUSIVE_PTR<RRNamedArray<T> >& a)
609{
610 if (!a)
611 return RR_INTRUSIVE_PTR<MessageElementNestedElementList>();
612 std::vector<RR_INTRUSIVE_PTR<MessageElement> > a1;
613 a1.push_back(CreateMessageElement("array", a->GetNumericArray()));
614 return CreateMessageElementNestedElementList(DataTypes_namedarray_array_t, RRPrimUtil<T>::GetElementTypeString(),
615 RR_MOVE(a1));
616}
617
618template <typename T>
619RR_INTRUSIVE_PTR<RRNamedArray<T> > NamedArrayStub_UnpackNamedArray(
620 const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& a)
621{
622 typedef typename RRPrimUtil<T>::ElementArrayType element_type;
623 if (!a)
624 return RR_INTRUSIVE_PTR<RRNamedArray<T> >();
625 if (a->GetTypeID() != DataTypes_namedarray_array_t)
626 throw DataTypeMismatchException("Expected namedarray array message");
627 if (a->TypeName != RRPrimUtil<T>::GetElementTypeString())
628 throw DataTypeException("Invalid namedarray type");
629 typename RR_INTRUSIVE_PTR<RRArray<element_type> > a2 =
630 MessageElement::FindElement(a->Elements, "array")->CastData<RRArray<element_type> >();
631 return new RRNamedArray<T>(a2); // NOLINT(cppcoreguidelines-owning-memory)
632}
633
634template <typename T>
635RR_INTRUSIVE_PTR<MessageElementNestedElementList> NamedArrayStub_PackNamedMultiDimArray(
636 const RR_INTRUSIVE_PTR<RRNamedMultiDimArray<T> >& a)
637{
638 if (!a)
639 return RR_INTRUSIVE_PTR<MessageElementNestedElementList>();
640
641 std::vector<RR_INTRUSIVE_PTR<MessageElement> > m;
642 m.reserve(2);
643 m.push_back(CreateMessageElement("dims", a->Dims));
644 if (!a->NamedArray)
645 throw NullValueException("Multidimarray array must not be null");
646 m.push_back(CreateMessageElement("array", NamedArrayStub_PackNamedArray(a->NamedArray)));
647 return CreateMessageElementNestedElementList(DataTypes_namedarray_multidimarray_t,
648 RRPrimUtil<T>::GetElementTypeString(), RR_MOVE(m));
649}
650
651template <typename T>
652RR_INTRUSIVE_PTR<RRNamedMultiDimArray<T> > NamedArrayStub_UnpackNamedMultiDimArray(
653 const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& m)
654{
655 if (!m)
656 return RR_INTRUSIVE_PTR<RRNamedMultiDimArray<T> >();
657 if (m->GetTypeID() != DataTypes_namedarray_multidimarray_t)
658 throw DataTypeMismatchException("Expected namedarray multidimarray message");
659
660 typename RR_INTRUSIVE_PTR<RRNamedMultiDimArray<T> > o = AllocateEmptyRRNamedMultiDimArray<T>();
661 o->Dims = (MessageElement::FindElement(m->Elements, "dims")->CastData<RRArray<uint32_t> >());
662 o->NamedArray = NamedArrayStub_UnpackNamedArray<T>(
663 MessageElement::FindElement(m->Elements, "array")->CastDataToNestedList(DataTypes_namedarray_array_t));
664 if (!o->NamedArray)
665 throw NullValueException("Multidimarray array must not be null");
666 return o;
667}
668
669// MessageElement pack helper functions for namedarray
670template <typename T>
671RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackNamedArrayToArrayElement(MessageStringRef elementname, const T& s)
672{
673 return CreateMessageElement(elementname, NamedArrayStub_PackNamedArrayToArray(s));
674}
675
676template <typename T>
677RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackNamedArrayElement(MessageStringRef elementname,
678 const RR_INTRUSIVE_PTR<RRNamedArray<T> >& s)
679{
680 if (!s)
681 throw NullValueException("Arrays must not be null");
682 return CreateMessageElement(elementname, NamedArrayStub_PackNamedArray(s));
683}
684
685template <typename T>
686RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackNamedMultiDimArrayElement(
687 MessageStringRef elementname, const RR_INTRUSIVE_PTR<RRNamedMultiDimArray<T> >& s)
688{
689 if (!s)
690 throw NullValueException("Arrays must not be null");
691 return CreateMessageElement(elementname, NamedArrayStub_PackNamedMultiDimArray(s));
692}
693
694// MessageElement unpack helper functions for namedarray
695template <typename T>
696T MessageElement_UnpackNamedArrayFromArray(const RR_INTRUSIVE_PTR<MessageElement>& m)
697{
698 return RobotRaconteur::NamedArrayStub_UnpackNamedArrayFromArray<T>(
699 m->CastDataToNestedList(DataTypes_namedarray_array_t));
700}
701
702template <typename T>
703RR_INTRUSIVE_PTR<RRNamedArray<T> > MessageElement_UnpackNamedArray(const RR_INTRUSIVE_PTR<MessageElement>& m)
704{
705 RR_INTRUSIVE_PTR<RRNamedArray<T> > a =
706 RobotRaconteur::NamedArrayStub_UnpackNamedArray<T>(m->CastDataToNestedList(DataTypes_namedarray_array_t));
707 if (!a)
708 throw NullValueException("Arrays must not be null");
709 return a;
710}
711
712template <typename T>
713RR_INTRUSIVE_PTR<RRNamedMultiDimArray<T> > MessageElement_UnpackNamedMultiDimArray(
714 const RR_INTRUSIVE_PTR<MessageElement>& m)
715{
716 RR_INTRUSIVE_PTR<RRNamedMultiDimArray<T> > a = RobotRaconteur::NamedArrayStub_UnpackNamedMultiDimArray<T>(
717 m->CastDataToNestedList(DataTypes_namedarray_multidimarray_t));
718 if (!a)
719 throw NullValueException("Arrays must not be null");
720 return a;
721}
722
723template <typename T>
724static RR_INTRUSIVE_PTR<RRNamedArray<T> > VerifyRRArrayLength(const RR_INTRUSIVE_PTR<RRNamedArray<T> >& a, size_t len,
725 bool varlength)
726{
727 if (!a)
728 throw NullValueException("Arrays must not be null");
729 if (len != 0)
730 {
731 if (varlength && (a->size() > len))
732 {
733 throw DataTypeException("Array dimension mismatch");
734 }
735 if (!varlength && (a->size() != len))
736 {
737 throw DataTypeException("Array dimension mismatch");
738 }
739 }
740 return a;
741}
742
743template <size_t Ndims, typename T>
744static RR_INTRUSIVE_PTR<RRNamedMultiDimArray<T> > VerifyRRMultiDimArrayLength(
745 const RR_INTRUSIVE_PTR<RRNamedMultiDimArray<T> >& a, size_t n_elems, boost::array<uint32_t, Ndims> dims)
746{
747 if (!a)
748 throw NullValueException("Arrays must not be null");
749
750 if (a->Dims->size() != Ndims)
751 {
752 throw DataTypeException("Array dimension mismatch");
753 }
754
755 if (a->NamedArray->size() != n_elems)
756 {
757 throw DataTypeException("Array dimension mismatch");
758 }
759
760 for (size_t i = 0; i < Ndims; i++)
761 {
762 if ((*a->Dims)[i] != dims[i])
763 {
764 throw DataTypeException("Array dimension mismatch");
765 }
766 }
767
768 return a;
769}
770
771} // namespace RobotRaconteur
static boost::intrusive_ptr< RRPodArray< T > > AllocateEmptyRRPodArray(size_t length)
Allocate a pod array with the specified type and length and initialize to zero.
Definition DataTypes.h:2171
static boost::intrusive_ptr< RRArray< T > > AttachRRArrayCopy(const T *data, const size_t length)
Allocates an array object and copies existing numeric.
Definition DataTypes.h:1101
static boost::intrusive_ptr< RRPodMultiDimArray< T > > AllocateEmptyRRPodMultiDimArray(const std::vector< uint32_t > &dims)
Allocate an empty multidimensional pod array with the specified dimensions.
Definition DataTypes.h:2190
static boost::intrusive_ptr< RRArray< T > > AllocateRRArray(size_t length)
Allocate a numeric primitive or character array with the specified type and length.
Definition DataTypes.h:1059
static boost::intrusive_ptr< RRNamedMultiDimArray< T > > AllocateEmptyRRNamedMultiDimArray(const std::vector< uint32_t > &dims)
Allocate an empty multidimensional namedarray array with the specified dimensions.
Definition DataTypes.h:2573
@ DataTypes_pod_array_t
pod array type (nested message type)
Definition RobotRaconteurConstants.h:90
@ DataTypes_namedarray_multidimarray_t
namedarray multidimarray type (nested message type)
Definition RobotRaconteurConstants.h:102
@ DataTypes_namedarray_array_t
namedarray array type (nested message type)
Definition RobotRaconteurConstants.h:100
@ DataTypes_pod_multidimarray_t
pod multidimarray type (nested message type)
Definition RobotRaconteurConstants.h:92
Exception thrown when unexpected or incompatible data is provided.
Definition Error.h:493
Exception thrown when incorrect data is received by a member.
Definition Error.h:467
Exception thrown for an unexpected null value.
Definition Error.h:669
Numeric primitive or character array value type.
Definition DataTypes.h:581
namedarray array value type
Definition DataTypes.h:2271
namedarray multidimensional array value type
Definition DataTypes.h:2457
pod array value type
Definition DataTypes.h:1889
pod multidimensional array value type
Definition DataTypes.h:2042
Storage for pod array fields.
Definition ServiceStructure.h:84