Robot Raconteur Core C++ Library
Loading...
Searching...
No Matches
Message.h
Go to the documentation of this file.
1
23
24#pragma once
25
28
29#include <boost/intrusive/list.hpp>
30
31namespace RobotRaconteur
32{
33
34class ROBOTRACONTEUR_CORE_API ArrayBinaryReader;
35class ROBOTRACONTEUR_CORE_API ArrayBinaryWriter;
36class ROBOTRACONTEUR_CORE_API NodeID;
37
38class ROBOTRACONTEUR_CORE_API Message;
39class ROBOTRACONTEUR_CORE_API MessageHeader;
40class ROBOTRACONTEUR_CORE_API MessageEntry;
41class ROBOTRACONTEUR_CORE_API MessageElement;
42class ROBOTRACONTEUR_CORE_API MessageElementNestedElementList;
43
44class ROBOTRACONTEUR_CORE_API Message : public RRValue
45{
46 public:
47 RR_INTRUSIVE_PTR<MessageHeader> header;
48 std::vector<RR_INTRUSIVE_PTR<MessageEntry> > entries;
49
50 Message();
51
52 RR_INTRUSIVE_PTR<MessageEntry> FindEntry(MessageStringRef name);
53
54 RR_INTRUSIVE_PTR<MessageEntry> AddEntry(MessageEntryType t, MessageStringRef name);
55
56 // Version 2 Message
57 uint32_t ComputeSize();
58 void Write(ArrayBinaryWriter& w);
59 void Read(ArrayBinaryReader& r);
60
61 // Version 4 Message
62 uint32_t ComputeSize4();
63 void Write4(ArrayBinaryWriter& w);
64 void Read4(ArrayBinaryReader& r);
65
66 RR_OVIRTUAL std::string RRType() RR_OVERRIDE { return "RobotRaconteur::Message"; }
67};
68
69class ROBOTRACONTEUR_CORE_API MessageHeader : public RRValue
70{
71 public:
72 RR_OVIRTUAL ~MessageHeader() RR_OVERRIDE {}
73
74 uint32_t HeaderSize;
75
76 uint8_t MessageFlags;
77
78 uint32_t SenderEndpoint;
79
80 uint32_t ReceiverEndpoint;
81
82 MessageStringPtr SenderNodeName;
83
84 MessageStringPtr ReceiverNodeName;
85
86 NodeID SenderNodeID;
87
88 NodeID ReceiverNodeID;
89
90 MessageStringPtr MetaData;
91
92 uint16_t EntryCount;
93
94 uint16_t MessageID;
95
96 uint16_t MessageResID;
97
98 uint32_t MessageSize;
99
100 std::vector<boost::tuple<uint32_t, MessageStringPtr> > StringTable;
101
102 uint16_t Priority;
103
104 std::vector<uint8_t> Extended;
105
106 // Version 2 Message
107 uint16_t ComputeSize();
108 void UpdateHeader(uint32_t message_size, uint16_t entry_count);
109 void Write(ArrayBinaryWriter& w);
110 void Read(ArrayBinaryReader& r);
111
112 // Version 4 Message
113 protected:
114 uint32_t ComputeSize4();
115
116 public:
117 void UpdateHeader4(uint32_t message_entry_size, uint16_t entry_count);
118 void Write4(ArrayBinaryWriter& w);
119 void Read4(ArrayBinaryReader& r);
120
121 RR_OVIRTUAL std::string RRType() RR_OVERRIDE { return "RobotRaconteur::MessageHeader"; }
122
123 MessageHeader();
124};
125
126class ROBOTRACONTEUR_CORE_API MessageEntry : public RRValue
127{
128 public:
129 RR_OVIRTUAL ~MessageEntry() RR_OVERRIDE {}
130
131 uint32_t EntrySize;
132
133 uint8_t EntryFlags;
134
135 MessageEntryType EntryType;
136
137 MessageStringPtr ServicePath;
138
139 uint32_t ServicePathCode;
140
141 MessageStringPtr MemberName;
142
143 uint32_t MemberNameCode;
144
145 uint32_t RequestID;
146
147 MessageErrorType Error;
148
149 MessageStringPtr MetaData;
150
151 std::vector<uint8_t> Extended;
152
153 std::vector<RR_INTRUSIVE_PTR<MessageElement> > elements;
154
155 MessageEntry();
156
157 MessageEntry(MessageEntryType t, MessageStringRef n);
158
159 RR_INTRUSIVE_PTR<MessageElement> FindElement(MessageStringRef name);
160
161 bool TryFindElement(MessageStringRef name, RR_INTRUSIVE_PTR<MessageElement>& elem);
162
163 RR_INTRUSIVE_PTR<MessageElement> AddElement(MessageStringRef name,
164 const RR_INTRUSIVE_PTR<MessageElementData>& data);
165
166 RR_INTRUSIVE_PTR<MessageElement> AddElement(const RR_INTRUSIVE_PTR<MessageElement>& m);
167
168 // Version 2 Message
169 uint32_t ComputeSize();
170 void UpdateData();
171 void Write(ArrayBinaryWriter& w);
172 void Read(ArrayBinaryReader& r);
173
174 // Version 4 Message
175 uint32_t ComputeSize4();
176 void UpdateData4();
177 void Write4(ArrayBinaryWriter& w);
178 void Read4(ArrayBinaryReader& r);
179
180 RR_OVIRTUAL std::string RRType() RR_OVERRIDE { return "RobotRaconteur::MessageEntry"; }
181};
182
183class ROBOTRACONTEUR_CORE_API MessageElement : public RRValue
184{
185 public:
186 RR_OVIRTUAL ~MessageElement() RR_OVERRIDE {}
187
188 uint32_t ElementSize;
189
190 uint8_t ElementFlags;
191
192 MessageStringPtr ElementName;
193
194 uint32_t ElementNameCode;
195
196 int32_t ElementNumber;
197
198 DataTypes ElementType;
199
200 MessageStringPtr ElementTypeName;
201
202 uint32_t ElementTypeNameCode;
203
204 MessageStringPtr MetaData;
205
206 std::vector<uint8_t> Extended;
207
208 uint32_t DataCount;
209
210 private:
211 RR_INTRUSIVE_PTR<MessageElementData> dat;
212
213 public:
214 MessageElement();
215
216 // cSpell: ignore datin
217 MessageElement(MessageStringRef name, const RR_INTRUSIVE_PTR<MessageElementData>& datin);
218
219 RR_INTRUSIVE_PTR<MessageElementData> GetData();
220 void SetData(const RR_INTRUSIVE_PTR<MessageElementData>& value);
221
222 // Version 2 Message
223 uint32_t ComputeSize();
224 void UpdateData();
225 void Write(ArrayBinaryWriter& w);
226 void Read(ArrayBinaryReader& r);
227
228 // Version 4 Message
229 uint32_t ComputeSize4();
230 void UpdateData4();
231 void Write4(ArrayBinaryWriter& w);
232 void Read4(ArrayBinaryReader& r);
233
234 static RR_INTRUSIVE_PTR<MessageElement> FindElement(std::vector<RR_INTRUSIVE_PTR<MessageElement> >& m,
235 MessageStringRef name);
236
237 static bool TryFindElement(std::vector<RR_INTRUSIVE_PTR<MessageElement> >& m, MessageStringRef name,
238 RR_INTRUSIVE_PTR<MessageElement>& elem);
239
240 static bool ContainsElement(std::vector<RR_INTRUSIVE_PTR<MessageElement> >& m, MessageStringRef name);
241
242 template <typename T>
243 RR_INTRUSIVE_PTR<T> CastData()
244 {
245 return rr_cast<T>(dat);
246 }
247
248 std::string CastDataToString();
249
250 RR_INTRUSIVE_PTR<MessageElementNestedElementList> CastDataToNestedList();
251
252 RR_INTRUSIVE_PTR<MessageElementNestedElementList> CastDataToNestedList(DataTypes expected_type);
253
254 template <typename T>
255 static RR_INTRUSIVE_PTR<T> CastData(const RR_INTRUSIVE_PTR<MessageElementData>& Data)
256 {
257 return rr_cast<T>(Data);
258 }
259
260 RR_OVIRTUAL std::string RRType() RR_OVERRIDE { return "RobotRaconteur::MessageElement"; }
261};
262
263class ROBOTRACONTEUR_CORE_API MessageElementNestedElementList : public MessageElementData
264{
265 public:
266 DataTypes Type;
267 MessageStringPtr TypeName;
268 std::vector<RR_INTRUSIVE_PTR<MessageElement> > Elements;
269
270 MessageElementNestedElementList(DataTypes type_, MessageStringRef type_name_,
271 const std::vector<RR_INTRUSIVE_PTR<MessageElement> >& elements_);
272#ifndef ROBOTRACONTEUR_NO_CXX11
273 MessageElementNestedElementList(DataTypes type_, MessageStringRef type_name_,
274 std::vector<RR_INTRUSIVE_PTR<MessageElement> >&& elements_);
275#endif
276 RR_OVIRTUAL MessageStringPtr GetTypeString() RR_OVERRIDE;
277 RR_OVIRTUAL DataTypes GetTypeID() RR_OVERRIDE;
278 RR_OVIRTUAL std::string RRType() RR_OVERRIDE;
279};
280
281ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<Message> CreateMessage();
282ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageHeader> CreateMessageHeader();
283ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageEntry> CreateMessageEntry();
284ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageEntry> CreateMessageEntry(MessageEntryType t, MessageStringRef n);
285ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElement> CreateMessageElement();
286ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElement> CreateMessageElement(
287 MessageStringRef name, const RR_INTRUSIVE_PTR<MessageElementData>& datin);
288ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElement> CreateMessageElement(
289 int32_t number, const RR_INTRUSIVE_PTR<MessageElementData>& datin);
290ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElementNestedElementList> CreateMessageElementNestedElementList(
291 DataTypes type_, MessageStringRef type_name_, const std::vector<RR_INTRUSIVE_PTR<MessageElement> >& elements_);
292#ifndef ROBOTRACONTEUR_NO_CXX11
293ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElementNestedElementList> CreateMessageElementNestedElementList(
294 DataTypes type_, MessageStringRef type_name_, std::vector<RR_INTRUSIVE_PTR<MessageElement> >&& elements_);
295#endif
296ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<Message> ShallowCopyMessage(const RR_INTRUSIVE_PTR<Message>& m);
297ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageEntry> ShallowCopyMessageEntry(
298 const RR_INTRUSIVE_PTR<MessageEntry>& mm);
299ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElement> ShallowCopyMessageElement(
300 const RR_INTRUSIVE_PTR<MessageElement>& mm);
301
302// MessageElement packing functions
303template <typename T>
304RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackScalar(const T& value)
305{
306 return RobotRaconteur::ScalarToRRArray<T>(value);
307}
308
309template <typename T>
310RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackScalarElement(MessageStringRef elementname, const T& value)
311{
312 return CreateMessageElement(elementname, MessageElement_PackScalar(value));
313}
314
315template <typename T>
316RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackArray(const RR_INTRUSIVE_PTR<RRArray<T> >& value)
317{
318 if (!value)
319 throw NullValueException("Arrays must not be null");
320 return value;
321}
322
323template <typename T>
324RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackArrayElement(MessageStringRef elementname,
325 const RR_INTRUSIVE_PTR<RRArray<T> >& value)
326{
327 return CreateMessageElement(elementname, MessageElement_PackArray(value));
328}
329
330template <typename T, typename N>
331RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackMultiDimArray(
332 RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<RRMultiDimArray<T> >& value)
333{
334 if (!value)
335 throw NullValueException("Arrays must not be null");
336 RR_SHARED_PTR<N> node1 = node.lock();
337 if (!node1)
338 throw InvalidOperationException("Node has been released");
339 return node1->template PackMultiDimArray<T>(RobotRaconteur::rr_cast<RobotRaconteur::RRMultiDimArray<T> >(value));
340}
341
342template <typename T, typename N>
343RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackMultiDimArrayElement(
344 RR_WEAK_PTR<N> node, MessageStringRef elementname, const RR_INTRUSIVE_PTR<RRMultiDimArray<T> >& value)
345{
346 return CreateMessageElement(elementname, MessageElement_PackMultiDimArray(node, value));
347}
348
349template <typename T>
350RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackString(const T& str)
351{
353}
354
355template <typename T>
356RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackStringElement(MessageStringRef elementname, const T& str)
357{
358 return CreateMessageElement(elementname, MessageElement_PackString(str));
359}
360
361template <typename T, typename N>
362RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackVarType(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<T>& s)
363{
364 RR_SHARED_PTR<N> node1 = node.lock();
365 if (!node1)
366 throw InvalidOperationException("Node has been released");
367 return node1->PackVarType(s);
368}
369
370template <typename T, typename N>
371RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackVarTypeElement(RR_WEAK_PTR<N> node, MessageStringRef elementname,
372 const RR_INTRUSIVE_PTR<T>& s)
373{
374 return CreateMessageElement(elementname, MessageElement_PackVarType(node, s));
375}
376
377template <typename T, typename N>
378RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackStruct(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<T>& s)
379{
380 RR_SHARED_PTR<N> node1 = node.lock();
381 if (!node1)
382 throw InvalidOperationException("Node has been released");
383 return node1->PackStructure(RobotRaconteur::rr_cast<RobotRaconteur::RRStructure>(s));
384}
385
386template <typename T, typename N>
387RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackStructElement(RR_WEAK_PTR<N> node, MessageStringRef elementname,
388 const RR_INTRUSIVE_PTR<T>& s)
389{
390 return CreateMessageElement(elementname, MessageElement_PackStruct(node, s));
391}
392
393template <typename T>
394RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackEnum(const T& value)
395{
396 return RobotRaconteur::ScalarToRRArray<int32_t>(static_cast<int32_t>(value));
397}
398
399template <typename T>
400RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackEnumElement(MessageStringRef elementname, const T& value)
401{
402 return CreateMessageElement(elementname, MessageElement_PackEnum(value));
403}
404
405template <typename K, typename T, typename N>
406RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackMap(RR_WEAK_PTR<N> node,
407 const RR_INTRUSIVE_PTR<RRMap<K, T> >& m)
408{
409 RR_SHARED_PTR<N> node1 = node.lock();
410 if (!node1)
411 throw InvalidOperationException("Node has been released");
412 return node1->template PackMapType<K, T>(m);
413}
414
415template <typename K, typename T, typename N>
416RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackMapElement(RR_WEAK_PTR<N> node, MessageStringRef elementname,
417 const RR_INTRUSIVE_PTR<RRMap<K, T> >& m)
418{
419 return CreateMessageElement(elementname, MessageElement_PackMap(node, m));
420}
421
422template <typename T, typename N>
423RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackList(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<RRList<T> >& m)
424{
425 RR_SHARED_PTR<N> node1 = node.lock();
426 if (!node1)
427 throw InvalidOperationException("Node has been released");
428 return node1->template PackListType<T>(m);
429}
430
431template <typename T, typename N>
432RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackListElement(RR_WEAK_PTR<N> node, MessageStringRef elementname,
433 const RR_INTRUSIVE_PTR<RRList<T> >& m)
434{
435 return CreateMessageElement(elementname, MessageElement_PackList(node, m));
436}
437
438// MessageElement unpacking functions
439template <typename T>
440T MessageElement_UnpackScalar(const RR_INTRUSIVE_PTR<MessageElement>& m)
441{
442 return RRArrayToScalar<T>(m->CastData<RRArray<T> >());
443}
444
445template <typename T>
446RR_INTRUSIVE_PTR<RRArray<T> > MessageElement_UnpackArray(const RR_INTRUSIVE_PTR<MessageElement>& m)
447{
448 RR_INTRUSIVE_PTR<RRArray<T> > a = (m->CastData<RRArray<T> >());
449 if (!a)
450 throw NullValueException("Arrays must not be null");
451 return a;
452}
453
454template <typename T, typename N>
455RR_INTRUSIVE_PTR<RRMultiDimArray<T> > MessageElement_UnpackMultiDimArray(RR_WEAK_PTR<N> node,
456 const RR_INTRUSIVE_PTR<MessageElement>& m)
457{
458 RR_SHARED_PTR<N> node1 = node.lock();
459 if (!node1)
460 throw InvalidOperationException("Node has been released");
461 RR_INTRUSIVE_PTR<RRMultiDimArray<T> > a = RobotRaconteur::rr_cast<RRMultiDimArray<T> >(
462 node1->template UnpackMultiDimArray<T>(m->CastDataToNestedList(DataTypes_multidimarray_t)));
463 if (!a)
464 throw NullValueException("Arrays must not be null");
465 return a;
466}
467
468// cSpell: ignore Wunused
469RR_GCC_DISABLE_WARNING("-Wunused-function")
470
471static std::string MessageElement_UnpackString(const RR_INTRUSIVE_PTR<MessageElement>& m)
472{
473 return RRArrayToString(m->CastData<RRArray<char> >());
474}
475RR_GCC_ENABLE_WARNING()
476
477template <typename T, typename N>
478RR_INTRUSIVE_PTR<T> MessageElement_UnpackStructure(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<MessageElement>& m)
479{
480 RR_SHARED_PTR<N> node1 = node.lock();
481 if (!node1)
482 throw InvalidOperationException("Node has been released");
483 return RobotRaconteur::rr_cast<T>(
484 node1->UnpackStructure(m->CastData<RobotRaconteur::MessageElementNestedElementList>()));
485}
486
487template <typename T>
488T MessageElement_UnpackEnum(const RR_INTRUSIVE_PTR<MessageElement>& m)
489{
490 return static_cast<T>(RRArrayToScalar<int32_t>(m->CastData<RRArray<int32_t> >()));
491}
492
493template <typename N>
494RR_INTRUSIVE_PTR<RRValue> MessageElement_UnpackVarValue(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<MessageElement>& m)
495{
496 RR_SHARED_PTR<N> node1 = node.lock();
497 if (!node1)
498 throw InvalidOperationException("Node has been released");
499 return node1->UnpackVarType(m);
500}
501
502template <typename K, typename T, typename N>
503RR_INTRUSIVE_PTR<RRMap<K, T> > MessageElement_UnpackMap(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<MessageElement>& m)
504{
505 RR_SHARED_PTR<N> node1 = node.lock();
506 if (!node1)
507 throw InvalidOperationException("Node has been released");
508 return node1->template UnpackMapType<K, T>(m->CastData<RobotRaconteur::MessageElementNestedElementList>());
509}
510
511template <typename T, typename N>
512RR_INTRUSIVE_PTR<RRList<T> > MessageElement_UnpackList(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<MessageElement>& m)
513{
514 RR_SHARED_PTR<N> node1 = node.lock();
515 if (!node1)
516 throw InvalidOperationException("Node has been released");
517 return node1->template UnpackListType<T>(m->CastDataToNestedList());
518}
519
520ROBOTRACONTEUR_CORE_API bool MessageElement_GetElementNumber(const RR_INTRUSIVE_PTR<MessageElement>& m,
521 int32_t& number);
522ROBOTRACONTEUR_CORE_API void MessageElement_SetElementNumber(const RR_INTRUSIVE_PTR<MessageElement>& m, int32_t number);
523ROBOTRACONTEUR_CORE_API bool MessageElement_GetElementName(const RR_INTRUSIVE_PTR<MessageElement>& m,
524 MessageStringPtr& name);
525
526#ifndef ROBOTRACONTEUR_NO_CXX11_TEMPLATE_ALIASES
527using MessagePtr = RR_INTRUSIVE_PTR<Message>;
528using MessageHeaderPtr = RR_INTRUSIVE_PTR<MessageHeader>;
529using MessageEntryPtr = RR_INTRUSIVE_PTR<MessageEntry>;
530using MessageElementPtr = RR_INTRUSIVE_PTR<MessageElement>;
531using MessageElementNestedElementListPtr = RR_INTRUSIVE_PTR<MessageElementNestedElementList>;
532#endif
533} // namespace RobotRaconteur
boost::intrusive_ptr< RRArray< char > > stringToRRArray(boost::string_ref str)
Convert a string to an array of characters.
std::string RRArrayToString(const boost::intrusive_ptr< RRArray< char > > &arr)
Convert an array of characters into std::string.
MessageErrorType
Message error type codes enum.
Definition RobotRaconteurConstants.h:396
DataTypes
Type codes for types supported by Robot Raconteur.
Definition RobotRaconteurConstants.h:41
MessageEntryType
Message entry type codes.
Definition RobotRaconteurConstants.h:225
Base class for types that can be stored in MessageElement.
Definition DataTypes.h:374
NodeID UUID storage and generation.
Definition NodeID.h:58
Base class for all Robot Raconteur value types (except primitives).
Definition DataTypes.h:252