3es  0.7
3espacketstream.h
1 //
2 // author: Kazys Stepanas
3 //
4 #ifndef _3ESHEADERSTREAM_H_
5 #define _3ESHEADERSTREAM_H_
6 
7 #include "3es-core.h"
8 
9 #include "3esendian.h"
10 #include "3espacketheader.h"
11 
12 namespace tes
13 {
18  template <class HEADER>
20  {
21  public:
23  typedef uint16_t CrcType;
24 
26  enum SeekPos
27  {
30  End
31  };
32 
34  enum Status
35  {
37  Ok = 0,
39  EOP = (1 << 0),
41  Fail = (1 << 1),
43  ReadOnly = (1 << 2),
45  CrcValid = (1 << 3),
46  };
47 
50  PacketStream(HEADER &packet);
51 
52  // PacketHeader member access. Ensures network endian swap as required.
55  uint32_t marker() const { return networkEndianSwapValue(_packet.marker); }
58  uint16_t versionMajor() const { return networkEndianSwapValue(_packet.versionMajor); }
61  uint16_t versionMinor() const { return networkEndianSwapValue(_packet.versionMinor); }
64  uint16_t payloadSize() const { return networkEndianSwapValue(_packet.payloadSize); }
67  uint16_t packetSize() const { return sizeof(HEADER) + payloadSize() + (((packet().flags & PF_NoCrc) == 0) ? sizeof(CrcType) : 0); }
70  uint16_t routingId() const { return networkEndianSwapValue(_packet.routingId); }
73  uint16_t messageId() const { return networkEndianSwapValue(_packet.messageId); }
77  CrcType crc() const { return networkEndianSwapValue(*crcPtr()); }
81  CrcType *crcPtr();
83  const CrcType *crcPtr() const;
84 
87  inline uint16_t status() const;
88 
91  inline bool isEop() const { return _status & EOP; }
94  inline bool isOk() const { return !isFail(); }
97  inline bool isFail() const { return (_status & Fail) != 0; }
100  inline bool isReadOnly() const { return (_status & ReadOnly) != 0; }
103  inline bool isCrcValid() const { return (_status & CrcValid) != 0; }
104 
108  HEADER &packet() const;
109 
112  uint16_t tell() const;
116  bool seek(int offset, SeekPos pos = Begin);
119  const uint8_t *payload() const;
120 
121  protected:
122  HEADER &_packet;
123  uint16_t _status;
124  uint16_t _payloadPosition;
125 
127  template <class T>
128  struct IsConst
129  {
132  inline bool check() const { return false; }
133  };
134 
136  template <class T>
137  struct IsConst<const T>
138  {
141  inline bool check() const { return true; }
142  };
143  };
144 
145  template class _3es_coreAPI PacketStream<PacketHeader>;
146  template class _3es_coreAPI PacketStream<const PacketHeader>;
147 
148  template <class HEADER>
150  : _packet(packet)
151  , _status(Ok)
152  , _payloadPosition(0u)
153  {
154  if (IsConst<HEADER>().check())
155  {
156  _status |= ReadOnly;
157  }
158  }
159 
160 
161  template <class HEADER>
162  bool PacketStream<HEADER>::seek(int offset, SeekPos pos)
163  {
164  switch (pos)
165  {
166  case Begin:
167  if (offset <= _packet.payloadSize)
168  {
169  _payloadPosition = offset;
170  return true;
171  }
172  break;
173 
174  case Current:
175  if (offset >= 0 && offset + _payloadPosition <= _packet.payloadSize ||
176  offset < 0 && _payloadPosition >= -offset)
177  {
178  _payloadPosition += offset;
179  return true;
180  }
181  break;
182 
183  case End:
184  if (offset < _packet.payloadSize)
185  {
186  _payloadPosition = _packet.payloadSize - 1 - offset;
187  return true;
188  }
189  break;
190 
191  default:
192  break;
193  }
194 
195  return false;
196  }
197 
198 
199  template <class HEADER>
201  {
202  // CRC appears after the payload.
203  // TODO: fix the const correctness of this.
204  uint8_t *pos = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&_packet)) + sizeof(HEADER) + payloadSize();
205  return reinterpret_cast<CrcType*>(pos);
206  }
207 
208 
209  template <class HEADER>
211  {
212  // CRC appears after the payload.
213  const uint8_t *pos = reinterpret_cast<const uint8_t*>(&_packet) + sizeof(HEADER) + payloadSize();
214  return reinterpret_cast<const CrcType*>(pos);
215  }
216 
217 
218  template <class HEADER>
219  inline uint16_t PacketStream<HEADER>::status() const
220  {
221  return _status;
222  }
223 
224  template <class HEADER>
225  inline HEADER &PacketStream<HEADER>::packet() const
226  {
227  return _packet;
228  }
229 
230  template <class HEADER>
231  inline uint16_t PacketStream<HEADER>::tell() const
232  {
233  return _payloadPosition;
234  }
235 
236  template <class HEADER>
237  inline const uint8_t *PacketStream<HEADER>::payload() const
238  {
239  return reinterpret_cast<const uint8_t*>(&_packet) + sizeof(HEADER);
240  }
241 }
242 
243 #endif // _3ESHEADERSTREAM_H_
HEADER & packet() const
Access the head of the packet buffer, for direct PacketHeader access.
Definition: 3espacketstream.h:225
Type traits: is T const?
Definition: 3espacketstream.h:128
bool isOk() const
Status OK?
Definition: 3espacketstream.h:94
Read only stream?
Definition: 3espacketstream.h:43
uint16_t payloadSize() const
Fetch the payload size bytes in local endian.
Definition: 3espacketstream.h:64
Seek from the beginning of the stream.
Definition: 3espacketstream.h:28
End at of packet/stream.
Definition: 3espacketstream.h:39
Seek from the end of the stream.
Definition: 3espacketstream.h:30
uint16_t messageId() const
Fetch the message ID bytes in local endian.
Definition: 3espacketstream.h:73
bool isReadOnly() const
Read only stream?
Definition: 3espacketstream.h:100
bool isEop() const
At end of packet/stream?
Definition: 3espacketstream.h:91
Definition: 3esbounds.h:13
PacketStream(HEADER &packet)
Create a stream to read from beginning at packet.
Definition: 3espacketstream.h:149
uint16_t status() const
Report the Status bits.
Definition: 3espacketstream.h:219
uint16_t packetSize() const
Returns the size of the packet plus payload, giving the full data packet size including the CRC...
Definition: 3espacketstream.h:67
uint16_t tell() const
Tell the current stream position.
Definition: 3espacketstream.h:231
uint16_t _status
Status bits.
Definition: 3espacketstream.h:123
const uint8_t * payload() const
Direct payload pointer access.
Definition: 3espacketstream.h:237
Is the CRC valid?
Definition: 3espacketstream.h:45
A utility class used for managing read/write operations to a PacketHeader payload.
Definition: 3espacketstream.h:19
bool isCrcValid() const
CRC validated?
Definition: 3espacketstream.h:103
Status
Status bits.
Definition: 3espacketstream.h:34
SeekPos
Control values for seeking.
Definition: 3espacketstream.h:26
CrcType crc() const
Fetch the CRC bytes in local endian.
Definition: 3espacketstream.h:77
bool check() const
Check the traits.
Definition: 3espacketstream.h:141
uint16_t versionMajor() const
Fetch the major version bytes in local endian.
Definition: 3espacketstream.h:58
uint32_t marker() const
Fetch the marker bytes in local endian.
Definition: 3espacketstream.h:55
uint16_t routingId() const
Fetch the routing ID bytes in local endian.
Definition: 3espacketstream.h:70
bool check() const
Check the traits.
Definition: 3espacketstream.h:132
T networkEndianSwapValue(const T &data)
Return a copy of data with byte order switched if host byte order is not network byte order...
Definition: 3esendian.h:244
bool seek(int offset, SeekPos pos=Begin)
Seek to the indicated position.
Definition: 3espacketstream.h:162
Seek from the current position.
Definition: 3espacketstream.h:29
Marks a PacketHeader as missing its 16-bit CRC.
Definition: 3espacketheader.h:24
Set after an operation fails.
Definition: 3espacketstream.h:41
uint16_t _payloadPosition
Payload cursor.
Definition: 3espacketstream.h:124
uint16_t versionMinor() const
Fetch the minor version bytes in local endian.
Definition: 3espacketstream.h:61
uint16_t CrcType
Defies the packet CRC type.
Definition: 3espacketstream.h:23
CrcType * crcPtr()
Fetch a pointer to the CRC bytes.
Definition: 3espacketstream.h:200
No issues.
Definition: 3espacketstream.h:37
bool isFail() const
Fail bit set?
Definition: 3espacketstream.h:97
HEADER & _packet
Packet header and buffer start address.
Definition: 3espacketstream.h:122