LibMultiSense
LibMultiSense Documentation
Loading...
Searching...
No Matches
BufferStream.hh
Go to the documentation of this file.
1
39#ifndef CRL_MULTISENSE_BUFFERSTREAM_HH
40#define CRL_MULTISENSE_BUFFERSTREAM_HH
41
42#include "utility/Exception.hh"
43#include "utility/TimeStamp.hh"
46
47#include <stdint.h>
48#include <cstddef>
49#include <vector>
50
51namespace crl {
52namespace multisense {
53namespace details {
54namespace utility {
55
56
57
58//
59// The base storage class.
60//
61// To read/write from the stream, use the Reader/Writer
62// derivatives below.
63//
64// SENSORPOD_FIRMWARE: microblaze build, no shared() interface
65
67public:
68
69 void clear () { m_tell = 0; };
70 std::size_t tell () const { return m_tell; };
71 std::size_t size () const { return m_size; };
72 void *data () const { return m_bufferP; };
73 void *peek () const { return &(m_bufferP[m_tell]); };
74
75#ifndef SENSORPOD_FIRMWARE
76 bool shared() const { return m_ref.isShared(); };
77#endif // SENSORPOD_FIRMWARE
78
79 virtual void read (void *bufferP, std::size_t length) {
80 (void) bufferP;
81 (void) length;
82 CRL_EXCEPTION("not implemented", "");
83 };
84 virtual void write(const void *bufferP, std::size_t length) {
85 (void) bufferP;
86 (void) length;
87 CRL_EXCEPTION("not implemented", "");
88 };
89
90 //
91 // Move the r/w pointer in the buffer, checking bounds
92
93 void seek(std::size_t idx) {
94
95 if (idx > m_size)
96 CRL_EXCEPTION("invalid seek location %lu, [0, %lu] valid\n",
97 idx, m_size);
98 m_tell = idx;
99 };
100
101 //
102 // Default constructor
103
105 m_alloced(false),
106 m_size(0),
107 m_tell(0),
108 m_bufferP(NULL) {};
109
110 //
111 // Construction, we allocate memory
112
113 BufferStream(std::size_t size) :
114 m_alloced(false),
115 m_size(size),
116 m_tell(0),
117 m_bufferP(NULL) {
118
119 m_bufferP = new (std::nothrow) uint8_t[size];
120 if (NULL == m_bufferP)
121 CRL_EXCEPTION("unable to allocate %d bytes", size);
122 m_alloced = true;
123 };
124
125 //
126 // Construction, memory is already allocated
127
128 BufferStream(uint8_t *bufP, std::size_t size) :
129 m_alloced(false),
130 m_size(size),
131 m_tell(0),
132 m_bufferP(bufP) {};
133
134 //
135 // Destruction, free memory only if we allocated
136
137 virtual ~BufferStream() {
138#ifdef SENSORPOD_FIRMWARE
139 if (m_alloced)
140#else
141 if (m_alloced && false == m_ref.isShared())
142#endif // SENSORPOD_FIRMWARE
143 delete[] m_bufferP;
144 };
145
146 //
147 // Copy constructor
148
149 BufferStream(const BufferStream& source) {
150 m_alloced = source.m_alloced;
151 m_size = source.m_size;
152 m_tell = 0; // reset
153 m_bufferP = source.m_bufferP;
154
155#ifndef SENSORPOD_FIRMWARE
156 m_ref = source.m_ref;
157#endif // SENSORPOD_FIRMWARE
158 };
159
160 //
161 // Assignment Operator
162
164 m_alloced = source.m_alloced;
165 m_size = source.m_size;
166 m_tell = 0; // reset
167 m_bufferP = source.m_bufferP;
168
169#ifndef SENSORPOD_FIRMWARE
170 m_ref = source.m_ref;
171#endif // SENSORPOD_FIRMWARE
172
173 return *this;
174 };
175
176protected:
177
179 std::size_t m_size;
180 std::size_t m_tell;
181 uint8_t *m_bufferP;
182
183#ifndef SENSORPOD_FIRMWARE
185#endif // SENSORPOD_FIRMWARE
186};
187
188//
189// The input (deserialization) implementation. Must operate on
190// non-const data.
191
193public:
194
197 BufferStreamReader(const uint8_t *p, std::size_t s) : BufferStream(const_cast<uint8_t*>(p), s) {};
198 BufferStreamReader(std::size_t s) : BufferStream(s) {};
199
200 virtual void read (void *bufferP, std::size_t length) {
201
202 if (length > (m_size - m_tell))
203 CRL_EXCEPTION("read overflow: tell=%d, size=%d, length=%d\n",
204 m_tell, m_size, length);
205
206 memcpy(bufferP, &(m_bufferP[m_tell]), length);
207 m_tell += length;
208 }
209
210 template <typename T> BufferStreamReader& operator&(T &value) {
211 this->read(&value, sizeof(T));
212 return *this;
213 }
214
215 template <typename T> BufferStreamReader& operator&(std::vector<T>& v) {
216 uint16_t version;
217 uint32_t num;
218 *this & version;
219 *this & num;
220 v.resize(num);
221 for(uint32_t i=0; i<num; i++)
222 v[i].serialize(*this, version);
223 return *this;
224 }
225
226 BufferStreamReader& operator&(std::string& value) {
227 uint16_t length;
228
229 this->read(&length, sizeof(length));
230 if (length > 512)
231 CRL_EXCEPTION("unusually large string: %d bytes",
232 length);
233 else if (length > 0) {
234 char buffer[512+1]; // length is guaranteed to be less than or equal to 512
235 buffer[length] = '\0';
236 this->read(buffer, length);
237 value = std::string(buffer);
238 }
239 return *this;
240 }
241
243 uint32_t seconds;
244 uint32_t microseconds;
245
246 this->read(&seconds, sizeof(seconds));
247 this->read(&microseconds, sizeof(microseconds));
248
249 value.set(seconds, microseconds);
250
251 return *this;
252 }
253};
254
255//
256// The output (serialization) implementation. Able to operate
257// purely on const data.
258
260public:
261
264 BufferStreamWriter(uint8_t *b, std::size_t s) : BufferStream(b, s) {};
265 BufferStreamWriter(std::size_t s) : BufferStream(s) {};
266
267 virtual void write(const void *bufferP, std::size_t length) {
268
269 if ((length + m_tell) > m_size)
270 CRL_EXCEPTION("write overflow: tell=%d, size=%d, length=%d\n",
271 m_tell, m_size, length);
272
273 memcpy(&(m_bufferP[m_tell]), bufferP, length);
274 m_tell += length;
275 };
276
277 template <typename T> BufferStreamWriter& operator&(const T& value) {
278 this->write(&value, sizeof(T));
279 return *this;
280 }
281
282 template <typename T> BufferStreamWriter& operator&(const std::vector<T>& v) {
283 uint16_t version = T::VERSION;
284 uint32_t num = static_cast<uint32_t> (v.size());
285 *this & version;
286 *this & num;
287 for(uint32_t i=0; i<num; i++)
288 const_cast<T*>(&v[i])->serialize(*this, version);
289 return *this;
290 }
291
292 BufferStreamWriter& operator&(const std::string& value) {
293 size_t length = value.size();
294
295 if (length > 512)
296 CRL_EXCEPTION("unusually large string: %d bytes", length);
297
298 uint16_t length16 = static_cast<uint16_t> (length);
299 this->write(&length16, sizeof(length16));
300
301 if (length > 0)
302 this->write(value.c_str(), length);
303 return *this;
304 };
305
307 const uint32_t seconds = value.getSeconds();
308 const uint32_t microseconds = value.getMicroSeconds();
309
310 this->write(&seconds, sizeof(seconds));
311 this->write(&microseconds, sizeof(microseconds));
312
313 return *this;
314 };
315};
316
317}}}} // namespaces
318
319#endif /* #ifndef CRL_MULTISENSE_BUFFERSTREAM_HH */
This header file is adapted from Eric Kratzer's (and Dan Tascione's?) StandardException....
#define CRL_EXCEPTION(fmt,...)
Definition Exception.hh:85
Macros and symbols to help portability between different compiler versions.
Declares a ReferenceCount class for tracking resources.
The timestamp class gives some type-safety and helper routines for managing time stamps.
BufferStream & operator=(const BufferStream &source)
BufferStream(uint8_t *bufP, std::size_t size)
virtual void read(void *bufferP, std::size_t length)
virtual void write(const void *bufferP, std::size_t length)
virtual void read(void *bufferP, std::size_t length)
BufferStreamReader & operator&(TimeStamp &value)
BufferStreamReader & operator&(std::string &value)
BufferStreamReader & operator&(std::vector< T > &v)
BufferStreamReader(const uint8_t *p, std::size_t s)
BufferStreamWriter & operator&(const std::string &value)
virtual void write(const void *bufferP, std::size_t length)
BufferStreamWriter & operator&(const std::vector< T > &v)
BufferStreamWriter & operator&(const TimeStamp &value)
BufferStreamWriter & operator&(const T &value)
void set(const struct timeval &value)
Definition TimeStamp.cc:98