Robot Raconteur Core C++ Library
Message.h
Go to the documentation of this file.
1 
24 #pragma once
25 
27 #include "RobotRaconteur/NodeID.h"
28 
29 #include <boost/intrusive/list.hpp>
30 
31 namespace RobotRaconteur
32 {
33 
34 class ROBOTRACONTEUR_CORE_API ArrayBinaryReader;
35 class ROBOTRACONTEUR_CORE_API ArrayBinaryWriter;
36 class ROBOTRACONTEUR_CORE_API NodeID;
37 
38 class ROBOTRACONTEUR_CORE_API Message;
39 class ROBOTRACONTEUR_CORE_API MessageHeader;
40 class ROBOTRACONTEUR_CORE_API MessageEntry;
41 class ROBOTRACONTEUR_CORE_API MessageElement;
42 class ROBOTRACONTEUR_CORE_API MessageElementNestedElementList;
43 
44 class 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 
69 class 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 
126 class 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 
183 class 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  MessageElement(MessageStringRef name, const RR_INTRUSIVE_PTR<MessageElementData>& datin);
217 
218  RR_INTRUSIVE_PTR<MessageElementData> GetData();
219  void SetData(const RR_INTRUSIVE_PTR<MessageElementData>& value);
220 
221  // Version 2 Message
222  uint32_t ComputeSize();
223  void UpdateData();
224  void Write(ArrayBinaryWriter& w);
225  void Read(ArrayBinaryReader& r);
226 
227  // Version 4 Message
228  uint32_t ComputeSize4();
229  void UpdateData4();
230  void Write4(ArrayBinaryWriter& w);
231  void Read4(ArrayBinaryReader& r);
232 
233  static RR_INTRUSIVE_PTR<MessageElement> FindElement(std::vector<RR_INTRUSIVE_PTR<MessageElement> >& m,
234  MessageStringRef name);
235 
236  static bool TryFindElement(std::vector<RR_INTRUSIVE_PTR<MessageElement> >& m, MessageStringRef name,
237  RR_INTRUSIVE_PTR<MessageElement>& elem);
238 
239  static bool ContainsElement(std::vector<RR_INTRUSIVE_PTR<MessageElement> >& m, MessageStringRef name);
240 
241  template <typename T>
242  RR_INTRUSIVE_PTR<T> CastData()
243  {
244  return rr_cast<T>(dat);
245  }
246 
247  std::string CastDataToString();
248 
249  RR_INTRUSIVE_PTR<MessageElementNestedElementList> CastDataToNestedList();
250 
251  RR_INTRUSIVE_PTR<MessageElementNestedElementList> CastDataToNestedList(DataTypes expected_type);
252 
253  template <typename T>
254  static RR_INTRUSIVE_PTR<T> CastData(const RR_INTRUSIVE_PTR<MessageElementData>& Data)
255  {
256  return rr_cast<T>(Data);
257  }
258 
259  RR_OVIRTUAL std::string RRType() RR_OVERRIDE { return "RobotRaconteur::MessageElement"; }
260 };
261 
262 class ROBOTRACONTEUR_CORE_API MessageElementNestedElementList : public MessageElementData
263 {
264  public:
265  DataTypes Type;
266  MessageStringPtr TypeName;
267  std::vector<RR_INTRUSIVE_PTR<MessageElement> > Elements;
268 
269  MessageElementNestedElementList(DataTypes type_, MessageStringRef type_name_,
270  const std::vector<RR_INTRUSIVE_PTR<MessageElement> >& elements_);
271 #ifndef ROBOTRACONTEUR_NO_CXX11
272  MessageElementNestedElementList(DataTypes type_, MessageStringRef type_name_,
273  std::vector<RR_INTRUSIVE_PTR<MessageElement> >&& elements_);
274 #endif
275  RR_OVIRTUAL MessageStringPtr GetTypeString() RR_OVERRIDE;
276  RR_OVIRTUAL DataTypes GetTypeID() RR_OVERRIDE;
277  RR_OVIRTUAL std::string RRType() RR_OVERRIDE;
278 };
279 
280 ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<Message> CreateMessage();
281 ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageHeader> CreateMessageHeader();
282 ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageEntry> CreateMessageEntry();
283 ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageEntry> CreateMessageEntry(MessageEntryType t, MessageStringRef n);
284 ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElement> CreateMessageElement();
285 ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElement> CreateMessageElement(
286  MessageStringRef name, const RR_INTRUSIVE_PTR<MessageElementData>& datin);
287 ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElement> CreateMessageElement(
288  int32_t number, const RR_INTRUSIVE_PTR<MessageElementData>& datin);
289 ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElementNestedElementList> CreateMessageElementNestedElementList(
290  DataTypes type_, MessageStringRef type_name_, const std::vector<RR_INTRUSIVE_PTR<MessageElement> >& elements_);
291 #ifndef ROBOTRACONTEUR_NO_CXX11
292 ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElementNestedElementList> CreateMessageElementNestedElementList(
293  DataTypes type_, MessageStringRef type_name_, std::vector<RR_INTRUSIVE_PTR<MessageElement> >&& elements_);
294 #endif
295 ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<Message> ShallowCopyMessage(const RR_INTRUSIVE_PTR<Message>& m);
296 ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageEntry> ShallowCopyMessageEntry(
297  const RR_INTRUSIVE_PTR<MessageEntry>& mm);
298 ROBOTRACONTEUR_CORE_API RR_INTRUSIVE_PTR<MessageElement> ShallowCopyMessageElement(
299  const RR_INTRUSIVE_PTR<MessageElement>& mm);
300 
301 // MessageElement packing functions
302 template <typename T>
303 RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackScalar(const T& value)
304 {
305  return RobotRaconteur::ScalarToRRArray<T>(value);
306 }
307 
308 template <typename T>
309 RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackScalarElement(MessageStringRef elementname, const T& value)
310 {
311  return CreateMessageElement(elementname, MessageElement_PackScalar(value));
312 }
313 
314 template <typename T>
315 RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackArray(const RR_INTRUSIVE_PTR<RRArray<T> >& value)
316 {
317  if (!value)
318  throw NullValueException("Arrays must not be null");
319  return value;
320 }
321 
322 template <typename T>
323 RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackArrayElement(MessageStringRef elementname,
324  const RR_INTRUSIVE_PTR<RRArray<T> >& value)
325 {
326  return CreateMessageElement(elementname, MessageElement_PackArray(value));
327 }
328 
329 template <typename T, typename N>
330 RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackMultiDimArray(
331  RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<RRMultiDimArray<T> >& value)
332 {
333  if (!value)
334  throw NullValueException("Arrays must not be null");
335  RR_SHARED_PTR<N> node1 = node.lock();
336  if (!node1)
337  throw InvalidOperationException("Node has been released");
338  return node1->template PackMultiDimArray<T>(RobotRaconteur::rr_cast<RobotRaconteur::RRMultiDimArray<T> >(value));
339 }
340 
341 template <typename T, typename N>
342 RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackMultiDimArrayElement(
343  RR_WEAK_PTR<N> node, MessageStringRef elementname, const RR_INTRUSIVE_PTR<RRMultiDimArray<T> >& value)
344 {
345  return CreateMessageElement(elementname, MessageElement_PackMultiDimArray(node, value));
346 }
347 
348 template <typename T>
349 RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackString(const T& str)
350 {
352 }
353 
354 template <typename T>
355 RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackStringElement(MessageStringRef elementname, const T& str)
356 {
357  return CreateMessageElement(elementname, MessageElement_PackString(str));
358 }
359 
360 template <typename T, typename N>
361 RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackVarType(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<T>& s)
362 {
363  RR_SHARED_PTR<N> node1 = node.lock();
364  if (!node1)
365  throw InvalidOperationException("Node has been released");
366  return node1->PackVarType(s);
367 }
368 
369 template <typename T, typename N>
370 RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackVarTypeElement(RR_WEAK_PTR<N> node, MessageStringRef elementname,
371  const RR_INTRUSIVE_PTR<T>& s)
372 {
373  return CreateMessageElement(elementname, MessageElement_PackVarType(node, s));
374 }
375 
376 template <typename T, typename N>
377 RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackStruct(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<T>& s)
378 {
379  RR_SHARED_PTR<N> node1 = node.lock();
380  if (!node1)
381  throw InvalidOperationException("Node has been released");
382  return node1->PackStructure(RobotRaconteur::rr_cast<RobotRaconteur::RRStructure>(s));
383 }
384 
385 template <typename T, typename N>
386 RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackStructElement(RR_WEAK_PTR<N> node, MessageStringRef elementname,
387  const RR_INTRUSIVE_PTR<T>& s)
388 {
389  return CreateMessageElement(elementname, MessageElement_PackStruct(node, s));
390 }
391 
392 template <typename T>
393 RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackEnum(const T& value)
394 {
395  return RobotRaconteur::ScalarToRRArray<int32_t>(static_cast<int32_t>(value));
396 }
397 
398 template <typename T>
399 RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackEnumElement(MessageStringRef elementname, const T& value)
400 {
401  return CreateMessageElement(elementname, MessageElement_PackEnum(value));
402 }
403 
404 template <typename K, typename T, typename N>
405 RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackMap(RR_WEAK_PTR<N> node,
406  const RR_INTRUSIVE_PTR<RRMap<K, T> >& m)
407 {
408  RR_SHARED_PTR<N> node1 = node.lock();
409  if (!node1)
410  throw InvalidOperationException("Node has been released");
411  return node1->template PackMapType<K, T>(m);
412 }
413 
414 template <typename K, typename T, typename N>
415 RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackMapElement(RR_WEAK_PTR<N> node, MessageStringRef elementname,
416  const RR_INTRUSIVE_PTR<RRMap<K, T> >& m)
417 {
418  return CreateMessageElement(elementname, MessageElement_PackMap(node, m));
419 }
420 
421 template <typename T, typename N>
422 RR_INTRUSIVE_PTR<MessageElementData> MessageElement_PackList(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<RRList<T> >& m)
423 {
424  RR_SHARED_PTR<N> node1 = node.lock();
425  if (!node1)
426  throw InvalidOperationException("Node has been released");
427  return node1->template PackListType<T>(m);
428 }
429 
430 template <typename T, typename N>
431 RR_INTRUSIVE_PTR<MessageElement> MessageElement_PackListElement(RR_WEAK_PTR<N> node, MessageStringRef elementname,
432  const RR_INTRUSIVE_PTR<RRList<T> >& m)
433 {
434  return CreateMessageElement(elementname, MessageElement_PackList(node, m));
435 }
436 
437 // MessageElement unpacking functions
438 template <typename T>
439 T MessageElement_UnpackScalar(const RR_INTRUSIVE_PTR<MessageElement>& m)
440 {
441  return RRArrayToScalar<T>(m->CastData<RRArray<T> >());
442 }
443 
444 template <typename T>
445 RR_INTRUSIVE_PTR<RRArray<T> > MessageElement_UnpackArray(const RR_INTRUSIVE_PTR<MessageElement>& m)
446 {
447  RR_INTRUSIVE_PTR<RRArray<T> > a = (m->CastData<RRArray<T> >());
448  if (!a)
449  throw NullValueException("Arrays must not be null");
450  return a;
451 }
452 
453 template <typename T, typename N>
454 RR_INTRUSIVE_PTR<RRMultiDimArray<T> > MessageElement_UnpackMultiDimArray(RR_WEAK_PTR<N> node,
455  const RR_INTRUSIVE_PTR<MessageElement>& m)
456 {
457  RR_SHARED_PTR<N> node1 = node.lock();
458  if (!node1)
459  throw InvalidOperationException("Node has been released");
460  RR_INTRUSIVE_PTR<RRMultiDimArray<T> > a = RobotRaconteur::rr_cast<RRMultiDimArray<T> >(
461  node1->template UnpackMultiDimArray<T>(m->CastDataToNestedList(DataTypes_multidimarray_t)));
462  if (!a)
463  throw NullValueException("Arrays must not be null");
464  return a;
465 }
466 
467 static std::string MessageElement_UnpackString(const RR_INTRUSIVE_PTR<MessageElement>& m)
468 {
469  return RRArrayToString(m->CastData<RRArray<char> >());
470 }
471 
472 template <typename T, typename N>
473 RR_INTRUSIVE_PTR<T> MessageElement_UnpackStructure(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<MessageElement>& m)
474 {
475  RR_SHARED_PTR<N> node1 = node.lock();
476  if (!node1)
477  throw InvalidOperationException("Node has been released");
478  return RobotRaconteur::rr_cast<T>(
479  node1->UnpackStructure(m->CastData<RobotRaconteur::MessageElementNestedElementList>()));
480 }
481 
482 template <typename T>
483 T MessageElement_UnpackEnum(const RR_INTRUSIVE_PTR<MessageElement>& m)
484 {
485  return static_cast<T>(RRArrayToScalar<int32_t>(m->CastData<RRArray<int32_t> >()));
486 }
487 
488 template <typename N>
489 RR_INTRUSIVE_PTR<RRValue> MessageElement_UnpackVarValue(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<MessageElement>& m)
490 {
491  RR_SHARED_PTR<N> node1 = node.lock();
492  if (!node1)
493  throw InvalidOperationException("Node has been released");
494  return node1->UnpackVarType(m);
495 }
496 
497 template <typename K, typename T, typename N>
498 RR_INTRUSIVE_PTR<RRMap<K, T> > MessageElement_UnpackMap(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<MessageElement>& m)
499 {
500  RR_SHARED_PTR<N> node1 = node.lock();
501  if (!node1)
502  throw InvalidOperationException("Node has been released");
503  return node1->template UnpackMapType<K, T>(m->CastData<RobotRaconteur::MessageElementNestedElementList>());
504 }
505 
506 template <typename T, typename N>
507 RR_INTRUSIVE_PTR<RRList<T> > MessageElement_UnpackList(RR_WEAK_PTR<N> node, const RR_INTRUSIVE_PTR<MessageElement>& m)
508 {
509  RR_SHARED_PTR<N> node1 = node.lock();
510  if (!node1)
511  throw InvalidOperationException("Node has been released");
512  return node1->template UnpackListType<T>(m->CastDataToNestedList());
513 }
514 
515 ROBOTRACONTEUR_CORE_API bool MessageElement_GetElementNumber(const RR_INTRUSIVE_PTR<MessageElement>& m,
516  int32_t& number);
517 ROBOTRACONTEUR_CORE_API void MessageElement_SetElementNumber(const RR_INTRUSIVE_PTR<MessageElement>& m, int32_t number);
518 ROBOTRACONTEUR_CORE_API bool MessageElement_GetElementName(const RR_INTRUSIVE_PTR<MessageElement>& m,
519  MessageStringPtr& name);
520 
521 #ifndef ROBOTRACONTEUR_NO_CXX11_TEMPLATE_ALIASES
522 using MessagePtr = RR_INTRUSIVE_PTR<Message>;
523 using MessageHeaderPtr = RR_INTRUSIVE_PTR<MessageHeader>;
524 using MessageEntryPtr = RR_INTRUSIVE_PTR<MessageEntry>;
525 using MessageElementPtr = RR_INTRUSIVE_PTR<MessageElement>;
526 using MessageElementNestedElementListPtr = RR_INTRUSIVE_PTR<MessageElementNestedElementList>;
527 #endif
528 } // 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
Numeric primitive multidimensional array value type.
Definition: DataTypes.h:1600