packetize.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Jonathan Eastep
  2. // Build up / consume unstructured packets through a simple interface
  3. #ifndef PACKETIZE_H
  4. #define PACKETIZE_H
  5. #include "log.h"
  6. #include "fixed_types.h"
  7. #include "subsecond_time.h"
  8. //#define DEBUG_UNSTRUCTURED_BUFFER
  9. #include <assert.h>
  10. #include <iostream>
  11. #include <utility>
  12. class UnstructuredBuffer
  13. {
  14. private:
  15. String m_chars;
  16. public:
  17. UnstructuredBuffer();
  18. const void* getBuffer();
  19. void clear();
  20. int size();
  21. // These put / get scalars
  22. template<class T> void put(const T & data);
  23. template<class T> bool get(T& data);
  24. // These put / get arrays
  25. // Note: these are shallow copy only
  26. template<class T> void put(const T * data, int num);
  27. template<class T> bool get(T* data, int num);
  28. // Wrappers
  29. template<class T>
  30. UnstructuredBuffer& operator<<(const T & data);
  31. template<class T>
  32. UnstructuredBuffer& operator>>(T & data);
  33. template<class T, class I>
  34. UnstructuredBuffer& operator<<(std::pair<T*, I> buffer);
  35. template<class T, class I>
  36. UnstructuredBuffer& operator>>(std::pair<T*, I> buffer);
  37. UnstructuredBuffer& operator<<(std::pair<const void*, int> buffer);
  38. UnstructuredBuffer& operator>>(std::pair<void*, int> buffer);
  39. };
  40. template<class T> void UnstructuredBuffer::put(const T* data, int num)
  41. {
  42. assert(num >= 0);
  43. m_chars.append((const char *) data, num * sizeof(T));
  44. }
  45. template<class T> bool UnstructuredBuffer::get(T* data, int num)
  46. {
  47. assert(num >= 0);
  48. if (m_chars.size() < (num * sizeof(T)))
  49. return false;
  50. m_chars.copy((char *) data, num * sizeof(T));
  51. m_chars.erase(0, num * sizeof(T));
  52. return true;
  53. }
  54. template<class T> void UnstructuredBuffer::put(const T& data)
  55. {
  56. put<T>(&data, 1);
  57. }
  58. template<> inline void UnstructuredBuffer::put(const SubsecondTime& _data)
  59. {
  60. subsecond_time_t data;
  61. data = _data;
  62. put<subsecond_time_t>(&data, 1);
  63. }
  64. template<class T> bool UnstructuredBuffer::get(T& data)
  65. {
  66. return get<T>(&data, 1);
  67. }
  68. template<> inline bool UnstructuredBuffer::get(SubsecondTime& _data)
  69. {
  70. subsecond_time_t data;
  71. bool res = get<subsecond_time_t>(&data, 1);
  72. _data = data;
  73. return res;
  74. }
  75. template<class T>
  76. UnstructuredBuffer& UnstructuredBuffer::operator<<(const T & data)
  77. {
  78. put<T>(data);
  79. return *this;
  80. }
  81. // Specialize for SubsecondTime
  82. template<>
  83. inline UnstructuredBuffer& UnstructuredBuffer::operator<<(const SubsecondTime & _data)
  84. {
  85. subsecond_time_t data = _data;
  86. put<subsecond_time_t>(data);
  87. return *this;
  88. }
  89. template<class T>
  90. UnstructuredBuffer& UnstructuredBuffer::operator>>(T & data)
  91. {
  92. __attribute__((unused)) bool res = get<T>(data);
  93. assert(res);
  94. return *this;
  95. }
  96. // Specialize for SubsecondTime
  97. template<>
  98. inline UnstructuredBuffer& UnstructuredBuffer::operator>>(SubsecondTime & _data)
  99. {
  100. subsecond_time_t data;
  101. __attribute__((unused)) bool res = get<subsecond_time_t>(data);
  102. assert(res);
  103. _data = data;
  104. return *this;
  105. }
  106. template<class T, class I>
  107. UnstructuredBuffer& UnstructuredBuffer::operator<<(std::pair<T*, I> buffer)
  108. {
  109. return (*this) << std::make_pair((const void *) buffer.first, (int) buffer.second);
  110. }
  111. template<class T, class I>
  112. UnstructuredBuffer& UnstructuredBuffer::operator>>(std::pair<T*, I> buffer)
  113. {
  114. return (*this) >> std::make_pair((void*) buffer.first, (int) buffer.second);
  115. }
  116. #endif