Robot Raconteur Core C++ Library
Loading...
Searching...
No Matches
DataTypesPacking.h
Go to the documentation of this file.
1
23
25
26#pragma once
27
28namespace RobotRaconteur
29{
30
31class ROBOTRACONTEUR_CORE_API RobotRaconteurNode;
32
33namespace detail
34{
35namespace packing
36{
37ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElementNestedElementList> PackStructure(
38 const RR_INTRUSIVE_PTR<RRStructure>& structure, RobotRaconteurNode* node);
39
40ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<RRStructure> UnpackStructure(
41 const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& structure, RobotRaconteurNode* node);
42
43ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElementNestedElementList> PackPodArray(
44 const RR_INTRUSIVE_PTR<RRPodBaseArray>& structure, RobotRaconteurNode* node);
45
46ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<RRPodBaseArray> UnpackPodArray(
47 const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& structure, RobotRaconteurNode* node);
48
49ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElementNestedElementList> PackPodMultiDimArray(
50 const RR_INTRUSIVE_PTR<RRPodBaseMultiDimArray>& structure, RobotRaconteurNode* node);
51
52ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<RRPodBaseMultiDimArray> UnpackPodMultiDimArray(
53 const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& structure, RobotRaconteurNode* node);
54
55ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElementNestedElementList> PackNamedArray(
56 const RR_INTRUSIVE_PTR<RRNamedBaseArray>& structure, RobotRaconteurNode* node);
57
58ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<RRNamedBaseArray> UnpackNamedArray(
59 const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& structure, RobotRaconteurNode* node);
60
61ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElementNestedElementList> PackNamedMultiDimArray(
62 const RR_INTRUSIVE_PTR<RRNamedBaseMultiDimArray>& structure, RobotRaconteurNode* node);
63
64ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<RRNamedBaseMultiDimArray> UnpackNamedMultiDimArray(
65 const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& structure, RobotRaconteurNode* node);
66
67template <typename T>
68RR_INTRUSIVE_PTR<MessageElementNestedElementList> PackMultiDimArray(const RR_INTRUSIVE_PTR<RRMultiDimArray<T> >& arr)
69{
70 if (!arr)
71 return RR_INTRUSIVE_PTR<MessageElementNestedElementList>();
72
73 std::vector<RR_INTRUSIVE_PTR<MessageElement> > ar;
74 ar.reserve(2);
75 ar.push_back(CreateMessageElement("dims", arr->Dims));
76 ar.push_back(CreateMessageElement("array", arr->Array));
77 return CreateMessageElementNestedElementList(DataTypes_multidimarray_t, "", RR_MOVE(ar));
78}
79
80template <typename T>
81RR_INTRUSIVE_PTR<RRMultiDimArray<T> > UnpackMultiDimArray(const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& ar)
82{
83 if (!ar)
84 return RR_INTRUSIVE_PTR<RRMultiDimArray<T> >();
85 if (ar->GetTypeID() != DataTypes_multidimarray_t)
86 throw DataTypeMismatchException("Expected a multidimarray");
87
88 RR_INTRUSIVE_PTR<RRMultiDimArray<T> > arr = AllocateEmptyRRMultiDimArray<T>();
89 arr->Dims = MessageElement::FindElement(ar->Elements, "dims")->CastData<RRArray<uint32_t> >();
90 arr->Array = MessageElement::FindElement(ar->Elements, "array")->CastData<RRArray<T> >();
91 return arr;
92}
93
94ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElementData> PackVarType(const RR_INTRUSIVE_PTR<RRValue>& vardata,
95 RobotRaconteurNode* node);
96
97ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<RRValue> UnpackVarType(const RR_INTRUSIVE_PTR<MessageElement>& mvardata,
98 RobotRaconteurNode* node);
99
100template <typename T, typename U>
101RR_INTRUSIVE_PTR<MessageElementData> PackAnyType(const RR_INTRUSIVE_PTR<U>& data, RobotRaconteurNode* node);
102
103template <typename T>
104T UnpackAnyType(const RR_INTRUSIVE_PTR<MessageElement>& mdata, RobotRaconteurNode* node);
105
106template <typename K, typename T>
107class PackMapTypeSupport
108{
109 public:
110 static RR_INTRUSIVE_PTR<MessageElementNestedElementList> PackMapType(RobotRaconteurNode* node,
111 const RR_INTRUSIVE_PTR<RRValue>& set)
112 {
113 RR_UNUSED(node);
114 RR_UNUSED(set);
115 BOOST_STATIC_ASSERT(sizeof(T) == 0);
116 return RR_INTRUSIVE_PTR<MessageElementNestedElementList>();
117 }
118
119 static RR_INTRUSIVE_PTR<RRValue> UnpackMapType(RobotRaconteurNode* node,
120 const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& mset)
121 {
122 RR_UNUSED(node);
123 RR_UNUSED(mset);
124 BOOST_STATIC_ASSERT(sizeof(T) == 0);
125 return RR_INTRUSIVE_PTR<RRValue>();
126 }
127};
128
129template <typename T>
130class PackMapTypeSupport<int32_t, T>
131{
132 public:
133 template <typename U>
134 static RR_INTRUSIVE_PTR<MessageElementNestedElementList> PackMapType(RobotRaconteurNode* node, const U& set)
135 {
136 if (!set)
137 return RR_INTRUSIVE_PTR<MessageElementNestedElementList>();
138
139 RR_INTRUSIVE_PTR<RRMap<int32_t, T> > set2 = rr_cast<RRMap<int32_t, T> >(set);
140
141 std::vector<RR_INTRUSIVE_PTR<MessageElement> > mret;
142 mret.reserve(set2->size());
143
144 for (typename std::map<int32_t, RR_INTRUSIVE_PTR<T> >::iterator e = set2->begin(); e != set2->end(); e++)
145 {
146 int32_t key = e->first;
147
148 RR_INTRUSIVE_PTR<MessageElementData> dat = PackAnyType<RR_INTRUSIVE_PTR<T> >(e->second, node);
149
150 RR_INTRUSIVE_PTR<MessageElement> m = CreateMessageElement(key, dat);
151 mret.push_back(m);
152 }
153
154 return CreateMessageElementNestedElementList(DataTypes_vector_t, "", RR_MOVE(mret));
155 }
156
157 static RR_INTRUSIVE_PTR<RRMap<int32_t, T> > UnpackMapType(
158 RobotRaconteurNode* node, const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& mset)
159 {
160 if (!mset)
161 return RR_INTRUSIVE_PTR<RRMap<int32_t, T> >();
162 if (mset->GetTypeID() != DataTypes_vector_t)
163 throw DataTypeMismatchException("Expected an int32 map");
164
165 RR_INTRUSIVE_PTR<RRMap<int32_t, T> > ret = AllocateEmptyRRMap<int32_t, T>();
166
167 for (std::vector<RR_INTRUSIVE_PTR<MessageElement> >::iterator e = mset->Elements.begin();
168 e != mset->Elements.end(); e++)
169 {
170 RR_INTRUSIVE_PTR<MessageElement> m = *e;
171 int32_t key = 0;
172 if (!MessageElement_GetElementNumber(m, key))
173 {
174 throw DataTypeException("Invalid map format");
175 }
176
177 RR_INTRUSIVE_PTR<T> dat = UnpackAnyType<RR_INTRUSIVE_PTR<T> >(m, node);
178 ret->insert(std::make_pair(key, dat));
179 }
180
181 return ret;
182 }
183};
184
185template <typename T>
186class PackMapTypeSupport<std::string, T>
187{
188 public:
189 template <typename U>
190 static RR_INTRUSIVE_PTR<MessageElementNestedElementList> PackMapType(RobotRaconteurNode* node, const U& set)
191 {
192 if (!set)
193 return RR_INTRUSIVE_PTR<MessageElementNestedElementList>();
194
195 RR_INTRUSIVE_PTR<RRMap<std::string, T> > set2 = rr_cast<RRMap<std::string, T> >(set);
196
197 std::vector<RR_INTRUSIVE_PTR<MessageElement> > mret;
198 mret.reserve(set2->size());
199
200 for (typename std::map<std::string, RR_INTRUSIVE_PTR<T> >::iterator e = set2->begin(); e != set2->end(); e++)
201 {
202 RR_INTRUSIVE_PTR<MessageElementData> dat = PackAnyType<RR_INTRUSIVE_PTR<T> >(e->second, node);
203
204 RR_INTRUSIVE_PTR<MessageElement> m = CreateMessageElement("", dat);
205 m->ElementName = e->first;
206 mret.push_back(m);
207 }
208
209 return CreateMessageElementNestedElementList(DataTypes_dictionary_t, "", RR_MOVE(mret));
210 }
211
212 static RR_INTRUSIVE_PTR<RRMap<std::string, T> > UnpackMapType(
213 RobotRaconteurNode* node, const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& mset)
214 {
215 if (!mset)
216 return RR_INTRUSIVE_PTR<RRMap<std::string, T> >();
217 if (mset->GetTypeID() != DataTypes_dictionary_t)
218 throw DataTypeMismatchException("Expected a string map");
219
220 RR_INTRUSIVE_PTR<RRMap<std::string, T> > ret = AllocateEmptyRRMap<std::string, T>();
221
222 for (std::vector<RR_INTRUSIVE_PTR<MessageElement> >::iterator e = mset->Elements.begin();
223 e != mset->Elements.end(); e++)
224 {
225 RR_INTRUSIVE_PTR<MessageElement> m = *e;
226
227 MessageStringPtr key;
228
229 if (!MessageElement_GetElementName(m, key))
230 {
231 throw DataTypeException("Invalid map format");
232 }
233
234 RR_INTRUSIVE_PTR<T> dat = UnpackAnyType<RR_INTRUSIVE_PTR<T> >(m, node);
235 ret->insert(std::make_pair(RR_MOVE(key.str().to_string()), dat));
236 }
237
238 return ret;
239 }
240};
241
242template <typename K, typename T, typename U>
243RR_INTRUSIVE_PTR<MessageElementNestedElementList> PackMapType(const U& set, RobotRaconteurNode* node)
244{
245 return detail::packing::PackMapTypeSupport<K, T>::PackMapType(node, set);
246}
247
248template <typename K, typename T>
249RR_INTRUSIVE_PTR<RRMap<K, T> > UnpackMapType(const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& mset,
250 RobotRaconteurNode* node)
251{
252 return detail::packing::PackMapTypeSupport<K, T>::UnpackMapType(node, mset);
253}
254
255template <typename T, typename U>
256RR_INTRUSIVE_PTR<MessageElementNestedElementList> PackListType(U& set, RobotRaconteurNode* node)
257{
258 if (!set)
259 return RR_INTRUSIVE_PTR<MessageElementNestedElementList>();
260
261 RR_INTRUSIVE_PTR<RRList<T> > set2 = rr_cast<RRList<T> >(set);
262
263 std::vector<RR_INTRUSIVE_PTR<MessageElement> > mret;
264 mret.reserve(set2->size());
265
266 typename RRList<T>::iterator set2_iter = set2->begin();
267 for (int32_t i = 0; i < boost::numeric_cast<int32_t>(set2->size()); i++)
268 {
269 int32_t key = i;
270
271 RR_INTRUSIVE_PTR<MessageElementData> dat = PackAnyType<RR_INTRUSIVE_PTR<T> >(*set2_iter, node);
272
273 RR_INTRUSIVE_PTR<MessageElement> m = CreateMessageElement(key, dat);
274 mret.push_back(m);
275 ++set2_iter;
276 }
277
278 return CreateMessageElementNestedElementList(DataTypes_list_t, "", RR_MOVE(mret));
279}
280
281template <typename T>
282RR_INTRUSIVE_PTR<RRList<T> > UnpackListType(const RR_INTRUSIVE_PTR<MessageElementNestedElementList>& mset,
283 RobotRaconteurNode* node)
284{
285 if (!mset)
286 return RR_INTRUSIVE_PTR<RRList<T> >();
287 if (mset->GetTypeID() != DataTypes_list_t)
288 throw DataTypeMismatchException("Expected message element list");
289
290 RR_INTRUSIVE_PTR<RRList<T> > ret = AllocateEmptyRRList<T>();
291
292 for (int32_t i = 0; i < boost::numeric_cast<int32_t>(mset->Elements.size()); i++)
293 {
294 RR_INTRUSIVE_PTR<MessageElement> m = mset->Elements.at(i);
295 int32_t key = 0;
296 if (!MessageElement_GetElementNumber(m, key))
297 {
298 throw DataTypeException("Invalid list format");
299 }
300
301 if (key != i)
302 throw DataTypeException("Invalid list format");
303
304 RR_INTRUSIVE_PTR<T> dat = UnpackAnyType<RR_INTRUSIVE_PTR<T> >(m, node);
305 ret->push_back(dat);
306 }
307
308 return ret;
309}
310
311template <typename T>
312class PackAnyTypeSupport
313{
314 public:
315 template <typename NodeType>
316 static RR_INTRUSIVE_PTR<MessageElementData> PackAnyType(const RR_INTRUSIVE_PTR<RRValue>& data, NodeType node)
317 {
318 return PackVarType(data, node);
319 }
320
321 template <typename NodeType>
322 static RR_INTRUSIVE_PTR<RRValue> UnpackAnyType(const RR_INTRUSIVE_PTR<MessageElement>& mdata, NodeType node)
323 {
324 return UnpackVarType(mdata, node);
325 }
326};
327
328template <typename T>
329class PackAnyTypeSupport<RR_INTRUSIVE_PTR<T> >
330{
331 public:
332 template <typename U, typename NodeType>
333 static RR_INTRUSIVE_PTR<MessageElementData> PackAnyType(const U& data, NodeType node)
334 {
335 if (boost::is_base_of<RRStructure, T>::value)
336 {
337 return PackStructure(rr_cast<RRStructure>(data), node);
338 }
339 return PackVarType(data, node);
340 }
341
342 template <typename NodeType>
343 static RR_INTRUSIVE_PTR<T> UnpackAnyType(const RR_INTRUSIVE_PTR<MessageElement>& mdata, NodeType node)
344 {
345 if (boost::is_base_of<RRStructure, T>::value)
346 {
347 return rr_cast<T>(UnpackStructure(mdata->CastDataToNestedList(DataTypes_structure_t), node));
348 }
349
350 return rr_cast<T>(UnpackVarType(mdata, node));
351 }
352};
353
354template <typename T>
355class PackAnyTypeSupport<RR_INTRUSIVE_PTR<RRArray<T> > >
356{
357 public:
358 template <typename U, typename NodeType>
359 static RR_INTRUSIVE_PTR<MessageElementData> PackAnyType(const U& data, NodeType node)
360 {
361 RR_UNUSED(node);
362 return RR_STATIC_POINTER_CAST<MessageElementData>(data);
363 }
364
365 template <typename NodeType>
366 static RR_INTRUSIVE_PTR<RRArray<T> > UnpackAnyType(const RR_INTRUSIVE_PTR<MessageElement>& mdata, NodeType node)
367 {
368 RR_UNUSED(node);
369 return mdata->CastData<RRArray<T> >();
370 }
371};
372
373template <typename K, typename T>
374class PackAnyTypeSupport<RR_INTRUSIVE_PTR<RRMap<K, T> > >
375{
376 public:
377 template <typename U, typename NodeType>
378 static RR_INTRUSIVE_PTR<MessageElementData> PackAnyType(const U& data, NodeType node)
379 {
380 return PackMapType<K, T>(data, node);
381 }
382
383 template <typename NodeType>
384 static RR_INTRUSIVE_PTR<RRMap<K, T> > UnpackAnyType(const RR_INTRUSIVE_PTR<MessageElement>& mdata, NodeType node)
385 {
386 return UnpackMapType<K, T>(mdata->CastDataToNestedList(), node);
387 }
388};
389
390template <typename T>
391class PackAnyTypeSupport<RR_INTRUSIVE_PTR<RRList<T> > >
392{
393 public:
394 template <typename U, typename NodeType>
395 static RR_INTRUSIVE_PTR<MessageElementData> PackAnyType(const U& data, NodeType node)
396 {
397 return PackListType<T>(data, node);
398 }
399
400 template <typename NodeType>
401 static RR_INTRUSIVE_PTR<RRList<T> > UnpackAnyType(const RR_INTRUSIVE_PTR<MessageElement>& mdata, NodeType node)
402 {
403 return UnpackListType<T>(mdata->CastDataToNestedList(), node);
404 }
405};
406
407template <typename T>
408class PackAnyTypeSupport<RR_INTRUSIVE_PTR<RRMultiDimArray<T> > >
409{
410 public:
411 template <typename U, typename NodeType>
412 static RR_INTRUSIVE_PTR<MessageElementData> PackAnyType(const U& data, NodeType node)
413 {
414 RR_UNUSED(node);
415 return PackMultiDimArray<T>(rr_cast<RRMultiDimArray<T> >(data));
416 }
417
418 template <typename NodeType>
419 static RR_INTRUSIVE_PTR<RRMultiDimArray<T> > UnpackAnyType(const RR_INTRUSIVE_PTR<MessageElement>& mdata,
420 NodeType node)
421 {
422 RR_UNUSED(node);
423 return UnpackMultiDimArray<T>(mdata->CastDataToNestedList(DataTypes_multidimarray_t));
424 }
425};
426
427template <typename T, typename U>
428RR_INTRUSIVE_PTR<MessageElementData> PackAnyType(const RR_INTRUSIVE_PTR<U>& data, RobotRaconteurNode* node)
429{
430 return PackAnyTypeSupport<T>::PackAnyType(data, node);
431}
432
433template <typename T>
434T UnpackAnyType(const RR_INTRUSIVE_PTR<MessageElement>& mdata, RobotRaconteurNode* node)
435{
436 return PackAnyTypeSupport<T>::UnpackAnyType(mdata, node);
437}
438
439} // namespace packing
440} // namespace detail
441} // namespace RobotRaconteur
std::list< boost::intrusive_ptr< T > >::iterator iterator
Definition DataTypes.h:952
The central node implementation.
Definition RobotRaconteurNode.h:132