Robot Raconteur Core C++ Library
IOUtils.h
Go to the documentation of this file.
1 
24 #pragma once
25 
27 #include <boost/predef/other/endian.h>
28 #include <stack>
29 
30 namespace RobotRaconteur
31 
32 {
33 class ROBOTRACONTEUR_CORE_API ArrayBinaryReader : private boost::noncopyable
34 {
35  public:
36  ArrayBinaryReader(const uint8_t* buffer, size_t start_position, size_t length, bool nativeorder = false);
37 
38  size_t Length() const;
39 
40  size_t Position() const;
41  void Seek(size_t position);
42 
43  size_t Read(void* buffer, size_t index, size_t length);
44 
45  template <typename T>
46  T ReadNumber()
47  {
48  T out;
49  Read(reinterpret_cast<uint8_t*>(&out), 0, sizeof(T));
50 #if BOOST_ENDIAN_BIG_BYTE
51  if (!nativeorder)
52  std::reverse(reinterpret_cast<uint8_t*>(&out), (reinterpret_cast<uint8_t*>(&out)) + sizeof(T));
53 #endif
54  return out;
55  }
56 
57  void ReadArray(RR_INTRUSIVE_PTR<RRBaseArray>& arr);
58 
59  MessageStringPtr ReadString8(size_t length);
60 
61  uint32_t ReadUintX();
62  uint64_t ReadUintX2();
63 
64  int32_t ReadIntX();
65  int64_t ReadIntX2();
66 
67  // A stack to set local limits on the
68  // length of reads. This will detect errors
69  // in binary messages.
70 
71  size_t CurrentLimit();
72 
73  void PushRelativeLimit(size_t limit);
74 
75  void PushAbsoluteLimit(size_t limit);
76 
77  void PopLimit();
78 
79  int32_t DistanceFromLimit();
80 
81  private:
82  const uint8_t* buffer;
83  size_t position;
84  size_t length;
85  bool nativeorder;
86 
87 #ifdef ROBOTRACONTEUR_USE_SMALL_VECTOR
88  boost::container::small_vector<size_t, 8> limits;
89 #else
90  std::vector<size_t> limits;
91 #endif
92 };
93 
94 class ROBOTRACONTEUR_CORE_API ArrayBinaryWriter : private boost::noncopyable
95 {
96  public:
97  ArrayBinaryWriter(uint8_t* buffer, size_t start_position, size_t length, bool nativeorder = false);
98 
99  size_t Length() const;
100 
101  size_t Position() const;
102  void Seek(size_t position);
103 
104  size_t Write(const void* buffer, size_t index, size_t length);
105 
106  template <typename T>
107  void WriteNumber(T number)
108  {
109  void* n1 = static_cast<void*>(&number);
110 #if BOOST_ENDIAN_BIG_BYTE
111  if (!nativeorder)
112  std::reverse(static_cast<uint8_t*>(n1), (static_cast<uint8_t*>(n1)) + sizeof(T));
113 #endif
114  Write(static_cast<uint8_t*>(n1), 0, sizeof(T));
115  }
116 
117  void WriteArray(RR_INTRUSIVE_PTR<RRBaseArray>& arr);
118 
119  void WriteString8(MessageStringRef str);
120  void WriteString8WithXLen(MessageStringRef str);
121 
122  void WriteUintX(uint32_t v);
123  void WriteUintX2(uint64_t v);
124 
125  void WriteIntX(int32_t v);
126  void WriteIntX2(int64_t v);
127 
128  static size_t GetStringByteCount8(MessageStringRef str);
129  static size_t GetStringByteCount8WithXLen(MessageStringRef str);
130 
131  static size_t GetUintXByteCount(uint32_t v);
132  static size_t GetUintX2ByteCount(uint64_t v);
133 
134  static size_t GetSizePlusUintX(size_t s);
135 
136  static size_t GetIntXByteCount(int32_t v);
137  static size_t GetIntX2ByteCount(int64_t v);
138 
139  // A stack to set local limits on the
140  // length of reads. This will detect errors
141  // in binary messages.
142 
143  size_t CurrentLimit();
144 
145  void PushRelativeLimit(size_t limit);
146 
147  void PushAbsoluteLimit(size_t limit);
148 
149  void PopLimit();
150 
151  int32_t DistanceFromLimit();
152 
153  private:
154  uint8_t* buffer;
155  size_t position;
156  size_t length;
157  bool nativeorder;
158 
159 #ifdef ROBOTRACONTEUR_USE_SMALL_VECTOR
160  boost::container::small_vector<size_t, 8> limits;
161 #else
162  std::vector<size_t> limits;
163 #endif
164 };
165 
166 } // namespace RobotRaconteur