Zserio C++ runtime library  1.0.2
Built for Zserio 2.14.1
BitStreamReader.h
Go to the documentation of this file.
1 #ifndef ZSERIO_BIT_STREAM_READER_H_INC
2 #define ZSERIO_BIT_STREAM_READER_H_INC
3 
4 #include <algorithm>
5 #include <cstddef>
6 #include <cstring>
7 
8 #include "zserio/BitBuffer.h"
9 #include "zserio/RebindAlloc.h"
10 #include "zserio/Span.h"
11 #include "zserio/String.h"
12 #include "zserio/Types.h"
13 #include "zserio/Vector.h"
14 
15 namespace zserio
16 {
17 
22 {
23 public:
25  using BitPosType = size_t;
26 
31  {
38  explicit ReaderContext(Span<const uint8_t> readBuffer, size_t readBufferBitSize);
39 
43  ~ReaderContext() = default;
44 
49  ReaderContext(const ReaderContext&) = delete;
51 
52  ReaderContext(const ReaderContext&&) = delete;
61  uintptr_t cache;
62  uint8_t cacheNumBits;
65  };
66 
73  explicit BitStreamReader(const uint8_t* buffer, size_t bufferByteSize);
74 
80  explicit BitStreamReader(Span<const uint8_t> buffer);
81 
88  explicit BitStreamReader(Span<const uint8_t> buffer, size_t bufferBitSize);
89 
96  explicit BitStreamReader(const uint8_t* buffer, size_t bufferBitSize, BitsTag);
97 
103  template <typename ALLOC>
104  explicit BitStreamReader(const BasicBitBuffer<ALLOC>& bitBuffer) :
105  BitStreamReader(bitBuffer.getData(), bitBuffer.getBitSize())
106  {}
107 
111  ~BitStreamReader() = default;
112 
120  uint32_t readBits(uint8_t numBits = 32);
121 
129  uint64_t readBits64(uint8_t numBits = 64);
130 
138  int32_t readSignedBits(uint8_t numBits = 32);
139 
147  int64_t readSignedBits64(uint8_t numBits = 64);
148 
154  int64_t readVarInt64();
155 
161  int32_t readVarInt32();
162 
168  int16_t readVarInt16();
169 
175  uint64_t readVarUInt64();
176 
182  uint32_t readVarUInt32();
183 
189  uint16_t readVarUInt16();
190 
196  int64_t readVarInt();
197 
203  uint64_t readVarUInt();
204 
210  uint32_t readVarSize();
211 
217  float readFloat16();
218 
224  float readFloat32();
225 
231  double readFloat64();
232 
240  template <typename ALLOC = std::allocator<uint8_t>>
241  vector<uint8_t, ALLOC> readBytes(const ALLOC& alloc = ALLOC())
242  {
243  const size_t len = static_cast<size_t>(readVarSize());
244  const BitPosType beginBitPosition = getBitPosition();
245  if ((beginBitPosition & 0x07U) != 0)
246  {
247  // we are not aligned to byte
248  vector<uint8_t, ALLOC> value{alloc};
249  value.reserve(len);
250  for (size_t i = 0; i < len; ++i)
251  {
252  value.push_back(readByte());
253  }
254  return value;
255  }
256  else
257  {
258  // we are aligned to byte
259  setBitPosition(beginBitPosition + len * 8);
260  Span<const uint8_t>::iterator beginIt = m_context.buffer.begin() + beginBitPosition / 8;
261  return vector<uint8_t, ALLOC>(beginIt, beginIt + len, alloc);
262  }
263  }
264 
272  template <typename ALLOC = std::allocator<char>>
273  string<ALLOC> readString(const ALLOC& alloc = ALLOC())
274  {
275  const size_t len = static_cast<size_t>(readVarSize());
276  const BitPosType beginBitPosition = getBitPosition();
277  if ((beginBitPosition & 0x07U) != 0)
278  {
279  // we are not aligned to byte
280  string<ALLOC> value{alloc};
281  value.reserve(len);
282  for (size_t i = 0; i < len; ++i)
283  {
284  value.push_back(static_cast<char>(readByte()));
285  }
286  return value;
287  }
288  else
289  {
290  // we are aligned to byte
291  setBitPosition(beginBitPosition + len * 8);
292  Span<const uint8_t>::iterator beginIt = m_context.buffer.begin() + beginBitPosition / 8;
293  return string<ALLOC>(beginIt, beginIt + len, alloc);
294  }
295  }
296 
302  bool readBool();
303 
311  template <typename ALLOC = std::allocator<uint8_t>>
313  {
314  const size_t bitSize = static_cast<size_t>(readVarSize());
315  const size_t numBytesToRead = bitSize / 8;
316  const uint8_t numRestBits = static_cast<uint8_t>(bitSize - numBytesToRead * 8);
317  BasicBitBuffer<RebindAlloc<ALLOC, uint8_t>> bitBuffer(bitSize, allocator);
318  Span<uint8_t> buffer = bitBuffer.getData();
319  const BitPosType beginBitPosition = getBitPosition();
320  const Span<uint8_t>::iterator itEnd = buffer.begin() + numBytesToRead;
321  if ((beginBitPosition & 0x07U) != 0)
322  {
323  // we are not aligned to byte
324  for (Span<uint8_t>::iterator it = buffer.begin(); it != itEnd; ++it)
325  {
326  *it = static_cast<uint8_t>(readBits(8));
327  }
328  }
329  else
330  {
331  // we are aligned to byte
332  setBitPosition(beginBitPosition + numBytesToRead * 8);
333  Span<const uint8_t>::const_iterator sourceIt = m_context.buffer.begin() + beginBitPosition / 8;
334  std::copy(sourceIt, sourceIt + numBytesToRead, buffer.begin());
335  }
336 
337  if (numRestBits > 0)
338  {
339  *itEnd = static_cast<uint8_t>(readBits(numRestBits) << (8U - numRestBits));
340  }
341 
342  return bitBuffer;
343  }
344 
351  {
352  return m_context.bitIndex;
353  }
354 
360  void setBitPosition(BitPosType position);
361 
367  void alignTo(size_t alignment);
368 
374  size_t getBufferBitSize() const
375  {
376  return m_context.bufferBitSize;
377  }
378 
379 private:
380  uint8_t readByte();
381 
382  ReaderContext m_context;
383 };
384 
385 } // namespace zserio
386 
387 #endif // ifndef ZSERIO_BIT_STREAM_READER_H_INC
Span< const uint8_t > getData() const
Definition: BitBuffer.h:421
void setBitPosition(BitPosType position)
void alignTo(size_t alignment)
uint64_t readBits64(uint8_t numBits=64)
BitStreamReader(const uint8_t *buffer, size_t bufferByteSize)
uint32_t readBits(uint8_t numBits=32)
BitStreamReader(const BasicBitBuffer< ALLOC > &bitBuffer)
BasicBitBuffer< RebindAlloc< ALLOC, uint8_t > > readBitBuffer(const ALLOC &allocator=ALLOC())
size_t getBufferBitSize() const
string< ALLOC > readString(const ALLOC &alloc=ALLOC())
vector< uint8_t, ALLOC > readBytes(const ALLOC &alloc=ALLOC())
int32_t readSignedBits(uint8_t numBits=32)
int64_t readSignedBits64(uint8_t numBits=64)
BitPosType getBitPosition() const
constexpr iterator begin() const noexcept
Definition: Span.h:200
uint8_t numBits(uint64_t numValues)
std::basic_string< char, std::char_traits< char >, RebindAlloc< ALLOC, char > > string
Definition: String.h:17
std::vector< T, RebindAlloc< ALLOC, T > > vector
Definition: Vector.h:17
ReaderContext(Span< const uint8_t > readBuffer, size_t readBufferBitSize)
ReaderContext & operator=(const ReaderContext &&)=delete
ReaderContext(const ReaderContext &&)=delete
ReaderContext & operator=(const ReaderContext &)=delete
ReaderContext(const ReaderContext &)=delete