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