DDS  ver. 3.6
BasicCmd.h
Go to the documentation of this file.
1 // Copyright 2014 GSI, Inc. All rights reserved.
2 //
3 //
4 //
5 #ifndef __DDS__BasicCmd__
6 #define __DDS__BasicCmd__
7 
8 // dds::misc
9 #include "INet.h"
10 #include "def.h"
11 // STD
12 #include <sstream>
13 #include <string>
14 // BOOST
15 #include <boost/uuid/uuid.hpp>
16 #include <boost/uuid/uuid_io.hpp>
17 
18 namespace inet = dds::misc::INet;
19 
20 namespace dds
21 {
22  namespace protocol_api
23  {
32  template <typename T>
33  size_t dsize(const T& _value);
34 
36  template <>
37  inline size_t dsize<uint8_t>(const uint8_t& /*_value*/)
38  {
39  return sizeof(uint8_t);
40  }
41 
43  template <>
44  inline size_t dsize<uint16_t>(const uint16_t& /*_value*/)
45  {
46  return sizeof(uint16_t);
47  }
48 
50  template <>
51  inline size_t dsize<uint32_t>(const uint32_t& /*_value*/)
52  {
53  return sizeof(uint32_t);
54  }
55 
57  template <>
58  inline size_t dsize<uint64_t>(const uint64_t& /*_value*/)
59  {
60  return sizeof(uint64_t);
61  }
62 
64  template <>
65  inline size_t dsize<std::string>(const std::string& _value)
66  {
67  return _value.size() + sizeof(uint16_t);
68  }
69 
71  template <>
72  inline size_t dsize<std::vector<uint8_t>>(const std::vector<uint8_t>& _value)
73  {
74  return _value.size() * sizeof(uint8_t) + sizeof(uint32_t);
75  }
76 
78  template <>
79  inline size_t dsize<std::vector<uint16_t>>(const std::vector<uint16_t>& _value)
80  {
81  return _value.size() * sizeof(uint16_t) + sizeof(uint16_t);
82  }
83 
85  template <>
86  inline size_t dsize<std::vector<uint32_t>>(const std::vector<uint32_t>& _value)
87  {
88  return _value.size() * sizeof(uint32_t) + sizeof(uint16_t);
89  }
90 
92  template <>
93  inline size_t dsize<std::vector<uint64_t>>(const std::vector<uint64_t>& _value)
94  {
95  return _value.size() * sizeof(uint64_t) + sizeof(uint16_t);
96  }
97 
99  template <>
100  inline size_t dsize<std::vector<std::string>>(const std::vector<std::string>& _value)
101  {
102  size_t sum(sizeof(uint16_t));
103  for (const auto& v : _value)
104  sum += (v.size() + sizeof(uint16_t));
105  return sum;
106  }
107 
109  template <>
110  inline size_t dsize<boost::uuids::uuid>(const boost::uuids::uuid& /*_value*/)
111  {
112  return boost::uuids::uuid::static_size();
113  }
114 
118  template <typename T>
119  void readData(T* _value, const dds::misc::BYTEVector_t* _data, size_t* _nPos);
120 
121  template <>
122  inline void readData<uint8_t>(uint8_t* _value, const dds::misc::BYTEVector_t* _data, size_t* _nPos)
123  {
124  if (_data == nullptr || _nPos == nullptr || _value == nullptr)
125  throw std::invalid_argument("readDataFromContainer");
126 
127  *_value = (*_data)[*_nPos];
128 
129  ++(*_nPos);
130  }
131 
132  template <>
133  inline void readData<uint16_t>(uint16_t* _value, const dds::misc::BYTEVector_t* _data, size_t* _nPos)
134  {
135  if (_data == nullptr || _nPos == nullptr || _value == nullptr)
136  throw std::invalid_argument("readDataFromContainer");
137 
138  *_value = (*_data)[*_nPos];
139  *_value += ((*_data)[++(*_nPos)] << 8);
140 
141  *_value = inet::normalizeRead(*_value);
142 
143  ++(*_nPos);
144  }
145 
146  template <>
147  inline void readData<uint32_t>(uint32_t* _value, const dds::misc::BYTEVector_t* _data, size_t* _nPos)
148  {
149  if (_data == nullptr || _nPos == nullptr || _value == nullptr)
150  throw std::invalid_argument("readDataFromContainer");
151 
152  *_value = (*_data)[*_nPos];
153  *_value += ((*_data)[++(*_nPos)] << 8);
154  *_value += ((*_data)[++(*_nPos)] << 16);
155  *_value += ((*_data)[++(*_nPos)] << 24);
156 
157  *_value = inet::normalizeRead(*_value);
158 
159  ++(*_nPos);
160  }
161 
162  template <>
163  inline void readData<uint64_t>(uint64_t* _value, const dds::misc::BYTEVector_t* _data, size_t* _nPos)
164  {
165  if (_data == nullptr || _nPos == nullptr || _value == nullptr)
166  throw std::invalid_argument("readDataFromContainer");
167 
168  *_value = (*_data)[*_nPos];
169  *_value += ((uint64_t)(*_data)[++(*_nPos)] << 8);
170  *_value += ((uint64_t)(*_data)[++(*_nPos)] << 16);
171  *_value += ((uint64_t)(*_data)[++(*_nPos)] << 24);
172  *_value += ((uint64_t)(*_data)[++(*_nPos)] << 32);
173  *_value += ((uint64_t)(*_data)[++(*_nPos)] << 40);
174  *_value += ((uint64_t)(*_data)[++(*_nPos)] << 48);
175  *_value += ((uint64_t)(*_data)[++(*_nPos)] << 56);
176 
177  *_value = inet::normalizeRead(*_value);
178 
179  ++(*_nPos);
180  }
181 
182  template <>
183  inline void readData<std::string>(std::string* _value, const dds::misc::BYTEVector_t* _data, size_t* _nPos)
184  {
185  if (_data == nullptr || _nPos == nullptr || _value == nullptr)
186  throw std::invalid_argument("readDataFromContainer");
187 
188  if (_value->size() > std::numeric_limits<uint16_t>::max())
189  throw std::invalid_argument("String size can't exceed 2^16 symbols. String size: " +
190  std::to_string(_value->size()));
191 
192  // Read number of elements in the string
193  uint16_t n = 0;
194  readData(&n, _data, _nPos);
195 
196  dds::misc::BYTEVector_t::const_iterator iter = _data->begin();
197  std::advance(iter, *_nPos);
198  dds::misc::BYTEVector_t::const_iterator iter_end = _data->begin();
199  std::advance(iter_end, (*_nPos + n));
200  std::copy(iter, iter_end, back_inserter(*_value));
201 
202  *_nPos += n;
203  }
204 
205  template <>
206  inline void readData<boost::uuids::uuid>(boost::uuids::uuid* _value,
207  const dds::misc::BYTEVector_t* _data,
208  size_t* _nPos)
209  {
210  if (_data == nullptr || _nPos == nullptr || _value == nullptr)
211  throw std::invalid_argument("readDataFromContainer");
212 
213  dds::misc::BYTEVector_t::const_iterator iter = _data->begin();
214  std::advance(iter, *_nPos);
215  dds::misc::BYTEVector_t::const_iterator iter_end = _data->begin();
216  std::advance(iter_end, (*_nPos + boost::uuids::uuid::static_size()));
217  copy(iter, iter_end, _value->begin());
218  (*_nPos) += boost::uuids::uuid::static_size();
219  }
220 
221  template <typename T>
222  inline void readDataVector(std::vector<T>* _value, const dds::misc::BYTEVector_t* _data, size_t* _nPos)
223  {
224  if (_data == nullptr || _nPos == nullptr || _value == nullptr)
225  throw std::invalid_argument("readDataFromContainer");
226 
227  if (_value->size() > std::numeric_limits<uint16_t>::max())
228  throw std::invalid_argument("Vector size can't exceed 2^16 symbols. Vector size: " +
229  std::to_string(_value->size()));
230 
231  // Read number of elements in the vector
232  uint16_t n = 0;
233  readData(&n, _data, _nPos);
234 
235  _value->reserve(n);
236  for (size_t i = 0; i < n; ++i)
237  {
238  T v;
239  readData(&v, _data, _nPos);
240  _value->push_back(v);
241  }
242  }
243 
244  template <>
245  inline void readData<std::vector<uint8_t>>(std::vector<uint8_t>* _value,
246  const dds::misc::BYTEVector_t* _data,
247  size_t* _nPos)
248  {
249  if (_data == nullptr || _nPos == nullptr || _value == nullptr)
250  throw std::invalid_argument("readDataFromContainer");
251 
252  if (_value->size() > std::numeric_limits<uint32_t>::max())
253  throw std::invalid_argument("Vector<uint8_t> size can't exceed 2^32 symbols. Vector size: " +
254  std::to_string(_value->size()));
255 
256  uint32_t n = 0;
257  readData(&n, _data, _nPos);
258 
259  dds::misc::BYTEVector_t::const_iterator iter = _data->begin();
260  std::advance(iter, *_nPos);
261  dds::misc::BYTEVector_t::const_iterator iter_end = _data->begin();
262  std::advance(iter_end, (*_nPos + n));
263  std::copy(iter, iter_end, back_inserter(*_value));
264 
265  *_nPos += n;
266  }
267 
268  template <>
269  inline void readData<std::vector<uint16_t>>(std::vector<uint16_t>* _value,
270  const dds::misc::BYTEVector_t* _data,
271  size_t* _nPos)
272  {
273  readDataVector<uint16_t>(_value, _data, _nPos);
274  }
275 
276  template <>
277  inline void readData<std::vector<uint32_t>>(std::vector<uint32_t>* _value,
278  const dds::misc::BYTEVector_t* _data,
279  size_t* _nPos)
280  {
281  readDataVector<uint32_t>(_value, _data, _nPos);
282  }
283 
284  template <>
285  inline void readData<std::vector<uint64_t>>(std::vector<uint64_t>* _value,
286  const dds::misc::BYTEVector_t* _data,
287  size_t* _nPos)
288  {
289  readDataVector<uint64_t>(_value, _data, _nPos);
290  }
291 
292  template <>
293  inline void readData<std::vector<std::string>>(std::vector<std::string>* _value,
294  const dds::misc::BYTEVector_t* _data,
295  size_t* _nPos)
296  {
297  readDataVector<std::string>(_value, _data, _nPos);
298  }
299 
304  template <typename T>
305  void pushData(const T& _value, dds::misc::BYTEVector_t* _data);
306 
307  template <>
308  inline void pushData<uint8_t>(const uint8_t& _value, dds::misc::BYTEVector_t* _data)
309  {
310  if (_data == nullptr)
311  throw std::invalid_argument("pushDataFromContainer");
312 
313  _data->push_back(_value);
314  }
315 
316  template <>
317  inline void pushData<uint16_t>(const uint16_t& _value, dds::misc::BYTEVector_t* _data)
318  {
319  if (_data == nullptr)
320  throw std::invalid_argument("pushDataFromContainer");
321 
322  uint16_t value = inet::normalizeWrite(_value);
323  _data->push_back(value & 0xFF);
324  _data->push_back(value >> 8);
325  }
326 
327  template <>
328  inline void pushData<uint32_t>(const uint32_t& _value, dds::misc::BYTEVector_t* _data)
329  {
330  if (_data == nullptr)
331  throw std::invalid_argument("pushDataFromContainer");
332 
333  uint32_t value = inet::normalizeWrite(_value);
334  _data->push_back(value & 0xFF);
335  _data->push_back((value >> 8) & 0xFF);
336  _data->push_back((value >> 16) & 0xFF);
337  _data->push_back((value >> 24) & 0xFF);
338  }
339 
340  template <>
341  inline void pushData<uint64_t>(const uint64_t& _value, dds::misc::BYTEVector_t* _data)
342  {
343  if (_data == nullptr)
344  throw std::invalid_argument("pushDataFromContainer");
345 
346  uint64_t value = inet::normalizeWrite(_value);
347  _data->push_back(value & 0xFF);
348  _data->push_back((value >> 8) & 0xFF);
349  _data->push_back((value >> 16) & 0xFF);
350  _data->push_back((value >> 24) & 0xFF);
351  _data->push_back((value >> 32) & 0xFF);
352  _data->push_back((value >> 40) & 0xFF);
353  _data->push_back((value >> 48) & 0xFF);
354  _data->push_back((value >> 56) & 0xFF);
355  }
356 
357  template <>
358  inline void pushData<std::string>(const std::string& _value, dds::misc::BYTEVector_t* _data)
359  {
360  if (_data == nullptr)
361  throw std::invalid_argument("pushDataFromContainer");
362 
363  if (_value.size() > std::numeric_limits<uint16_t>::max())
364  throw std::invalid_argument("String size can't exceed 2^16 symbols. String size: " +
365  std::to_string(_value.size()));
366 
367  uint16_t n = _value.size();
368  pushData(n, _data);
369  copy(_value.begin(), _value.end(), back_inserter(*_data));
370  }
371 
372  template <>
373  inline void pushData<boost::uuids::uuid>(const boost::uuids::uuid& _value, dds::misc::BYTEVector_t* _data)
374  {
375  if (_data == nullptr)
376  throw std::invalid_argument("pushDataFromContainer");
377 
378  copy(_value.begin(), _value.end(), back_inserter(*_data));
379  }
380 
381  template <typename T>
382  inline void pushDataVector(const std::vector<T>& _value, dds::misc::BYTEVector_t* _data)
383  {
384  if (_data == nullptr)
385  throw std::invalid_argument("pushDataFromContainer");
386 
387  if (_value.size() > std::numeric_limits<uint16_t>::max())
388  throw std::invalid_argument("Vector size can't exceed 2^16 symbols. Vector size: " +
389  std::to_string(_value.size()));
390 
391  // Read number of elements in the vector
392  uint16_t n = _value.size();
393  pushData(n, _data);
394 
395  for (const T& v : _value)
396  {
397  pushData(v, _data);
398  }
399  }
400 
401  template <>
402  inline void pushData<std::vector<uint8_t>>(const std::vector<uint8_t>& _value, dds::misc::BYTEVector_t* _data)
403  {
404  if (_data == nullptr)
405  throw std::invalid_argument("pushDataFromContainer");
406 
407  if (_value.size() > std::numeric_limits<uint32_t>::max())
408  throw std::invalid_argument("Vector<uint32_t> size can't exceed 2^32 symbols. Vector size: " +
409  std::to_string(_value.size()));
410 
411  uint32_t n = _value.size();
412  pushData(n, _data);
413  copy(_value.begin(), _value.end(), back_inserter(*_data));
414  }
415 
416  template <>
417  inline void pushData<std::vector<uint16_t>>(const std::vector<uint16_t>& _value, dds::misc::BYTEVector_t* _data)
418  {
419  pushDataVector<uint16_t>(_value, _data);
420  }
421 
422  template <>
423  inline void pushData<std::vector<uint32_t>>(const std::vector<uint32_t>& _value, dds::misc::BYTEVector_t* _data)
424  {
425  pushDataVector<uint32_t>(_value, _data);
426  }
427 
428  template <>
429  inline void pushData<std::vector<uint64_t>>(const std::vector<uint64_t>& _value, dds::misc::BYTEVector_t* _data)
430  {
431  pushDataVector<uint64_t>(_value, _data);
432  }
433 
434  template <>
435  inline void pushData<std::vector<std::string>>(const std::vector<std::string>& _value,
437  {
438  pushDataVector<std::string>(_value, _data);
439  }
440 
442  {
444  : m_data(_data)
445  , m_pos(0)
446  {
447  }
448 
450  : m_data(const_cast<dds::misc::BYTEVector_t*>(&_data))
451  , m_pos(0)
452  {
453  }
454 
455  template <typename T>
457  {
458  readData(&_value, m_data, &m_pos);
459  return *this;
460  }
461 
462  template <typename T>
463  const SAttachmentDataProvider& put(const T& _value) const
464  {
465  pushData(_value, m_data);
466  return *this;
467  }
468 
469  private:
470  dds::misc::BYTEVector_t* m_data;
471  size_t m_pos;
472  };
473 
474  template <class _Owner>
475  struct SBasicCmd
476  {
478  {
479  _Owner* p = reinterpret_cast<_Owner*>(this);
480  if (_data.size() < p->size())
481  {
482  std::stringstream ss;
483  ss << "Protocol message data is too short, expected " << p->size() << " received " << _data.size();
484  throw std::runtime_error(ss.str());
485  }
486  p->_convertFromData(_data);
487  }
489  {
490  const _Owner* p = reinterpret_cast<const _Owner*>(this);
491  p->_convertToData(_data);
492  }
493  };
494  } // namespace protocol_api
495 } // namespace dds
496 
497 #endif /* defined(__DDS__BasicCmd__) */
void readData< uint8_t >(uint8_t *_value, const dds::misc::BYTEVector_t *_data, size_t *_nPos)
Definition: BasicCmd.h:122
Definition: BasicCmd.h:475
void convertToData(dds::misc::BYTEVector_t *_data) const
Definition: BasicCmd.h:488
T normalizeWrite(T _value)
size_t dsize< uint8_t >(const uint8_t &)
Helper function calculating size of uint8_t.
Definition: BasicCmd.h:37
SAttachmentDataProvider & get(T &_value)
Definition: BasicCmd.h:456
void pushDataVector(const std::vector< T > &_value, dds::misc::BYTEVector_t *_data)
Definition: BasicCmd.h:382
SAttachmentDataProvider(const dds::misc::BYTEVector_t &_data)
Definition: BasicCmd.h:449
T normalizeRead(T _value)
size_t dsize(const T &_value)
All vectors (except uint8_t) have a maximum size of uint16_t i.e. 2^16. All vector<uint8_t>'s have a ...
size_t dsize< uint64_t >(const uint64_t &)
Helper function calculating size of uint64_t.
Definition: BasicCmd.h:58
void readData< uint32_t >(uint32_t *_value, const dds::misc::BYTEVector_t *_data, size_t *_nPos)
Definition: BasicCmd.h:147
void pushData< uint16_t >(const uint16_t &_value, dds::misc::BYTEVector_t *_data)
Definition: BasicCmd.h:317
void readData< uint16_t >(uint16_t *_value, const dds::misc::BYTEVector_t *_data, size_t *_nPos)
Definition: BasicCmd.h:133
std::vector< unsigned char > BYTEVector_t
An STL vector of bytes.
Definition: def.h:124
void readData< uint64_t >(uint64_t *_value, const dds::misc::BYTEVector_t *_data, size_t *_nPos)
Definition: BasicCmd.h:163
void pushData< uint32_t >(const uint32_t &_value, dds::misc::BYTEVector_t *_data)
Definition: BasicCmd.h:328
SAttachmentDataProvider(dds::misc::BYTEVector_t *_data)
Definition: BasicCmd.h:443
Miscellaneous functions and helpers are located here.
Definition: AgentConnectionManager.h:13
size_t dsize< uint32_t >(const uint32_t &)
Helper function calculating size of uint32_t.
Definition: BasicCmd.h:51
void pushData(const T &_value, dds::misc::BYTEVector_t *_data)
void convertFromData(const dds::misc::BYTEVector_t &_data)
Definition: BasicCmd.h:477
void readData(T *_value, const dds::misc::BYTEVector_t *_data, size_t *_nPos)
Helper template function reading data from byte array.
const SAttachmentDataProvider & put(const T &_value) const
Definition: BasicCmd.h:463
void pushData< uint64_t >(const uint64_t &_value, dds::misc::BYTEVector_t *_data)
Definition: BasicCmd.h:341
size_t dsize< uint16_t >(const uint16_t &)
Helper function calculating size of uint16_t.
Definition: BasicCmd.h:44
void readDataVector(std::vector< T > *_value, const dds::misc::BYTEVector_t *_data, size_t *_nPos)
Definition: BasicCmd.h:222
INet declares helpers for Socket and Network operations.
Definition: INet.h:37
void pushData< uint8_t >(const uint8_t &_value, dds::misc::BYTEVector_t *_data)
Definition: BasicCmd.h:308