Robot Raconteur Core C++ Library
ServiceStructure.h
Go to the documentation of this file.
1 
24 #pragma once
25 
30 
31 namespace RobotRaconteur
32 {
33 
34 // struct
35 
36 class 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 
58 template <typename T>
59 class PodStub
60 {
61  BOOST_STATIC_ASSERT(sizeof(T) == -1);
62 };
63 
82 template <typename T, size_t N, bool varlength>
83 class 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>
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 
125 template <typename T, size_t N>
126 class 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 
137 template <typename T, size_t N, bool varlength>
138 RR_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 
143 template <typename T, size_t N, bool varlength>
144 void 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(&v[0], 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 
191 RRPodStubNumberType(double);
192 RRPodStubNumberType(float);
193 RRPodStubNumberType(int8_t);
194 RRPodStubNumberType(uint8_t);
195 RRPodStubNumberType(int16_t);
196 RRPodStubNumberType(uint16_t);
197 RRPodStubNumberType(int32_t);
198 RRPodStubNumberType(uint32_t);
199 RRPodStubNumberType(int64_t);
200 RRPodStubNumberType(uint64_t);
201 
202 template <typename T, size_t N, bool varlength>
203 RR_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 
211 template <typename T, size_t N, bool varlength>
212 void 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(&v[0], 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(&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(&v, a1->data(), a1->size() * sizeof(element_type)); \
277  } \
278  };
279 // NOLINTEND(bugprone-macro-parentheses)
280 template <typename T, size_t N, bool varlength>
281 class 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  // if (a->Elements.size() > N) throw OutOfRangeException("Array is too large for static vector size");
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 
328 template <typename T, typename U>
329 void PodStub_PackField(const T& v, MessageStringRef name, U& out)
330 {
331  PodStub<T>::PackField(v, name, out);
332 }
333 
334 template <typename T, typename U>
335 void PodStub_UnpackField(T& v, MessageStringRef name, U& out)
336 {
337  PodStub<T>::UnpackField(v, name, out);
338 }
339 
340 template <typename T>
341 RR_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 
352 template <typename T>
353 void 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 
377 template <typename T>
378 T PodStub_UnpackPodFromArray(const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& a)
379 {
380  T v;
381  PodStub_UnpackPodFromArray<T>(v, a);
382  return v;
383 }
384 
385 template <typename T>
386 RR_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 
402 template <typename T>
403 RR_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 != i)
421  throw DataTypeException("Invalid pod array format");
422  PodStub<T>::UnpackFromMessageElementPod(o->at(i), m->CastDataToNestedList());
423  }
424 
425  return o;
426 }
427 
428 template <typename T>
429 RR_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 
445 template <typename T>
446 RR_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
464 template <typename T>
465 RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackPodToArrayElement(MessageStringRef elementname, const T& s)
466 {
467  return CreateMessageElement(elementname, PodStub_PackPodToArray(s));
468 }
469 
470 template <typename T>
471 RR_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 
479 template <typename T>
480 RR_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
489 template <typename T>
490 T MessageElement_UnpackPodFromArray(const RR_INTRUSIVE_PTR<MessageElement>& m)
491 {
492  return RobotRaconteur::PodStub_UnpackPodFromArray<T>(m->CastDataToNestedList(DataTypes_pod_array_t));
493 }
494 
495 template <typename T>
496 RR_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 
505 template <typename T>
506 RR_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 
516 template <typename T>
517 static 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 
536 template <size_t Ndims, typename T>
537 static 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 
566 template <typename T>
567 RR_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(), &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 
578 template <typename T>
579 void 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 
598 template <typename T>
599 T 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 
606 template <typename T>
607 RR_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 
618 template <typename T>
619 RR_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 
634 template <typename T>
635 RR_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 
651 template <typename T>
652 RR_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
670 template <typename T>
671 RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackNamedArrayToArrayElement(MessageStringRef elementname, const T& s)
672 {
673  return CreateMessageElement(elementname, NamedArrayStub_PackNamedArrayToArray(s));
674 }
675 
676 template <typename T>
677 RR_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 
685 template <typename T>
686 RR_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
695 template <typename T>
696 T MessageElement_UnpackNamedArrayFromArray(const RR_INTRUSIVE_PTR<MessageElement>& m)
697 {
698  return RobotRaconteur::NamedArrayStub_UnpackNamedArrayFromArray<T>(
699  m->CastDataToNestedList(DataTypes_namedarray_array_t));
700 }
701 
702 template <typename T>
703 RR_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 
712 template <typename T>
713 RR_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 
723 template <typename T>
724 static 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 
743 template <size_t Ndims, typename T>
744 static 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
@ 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
Storage for pod array fields.
Definition: ServiceStructure.h:84