Zserio C++ runtime library  1.1.0
Built for Zserio 2.15.0
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 #include <string>
8 
9 #include "zserio/BitBuffer.h"
10 #include "zserio/RebindAlloc.h"
11 #include "zserio/Span.h"
12 #include "zserio/String.h"
13 #include "zserio/Types.h"
14 #include "zserio/Vector.h"
15 
16 namespace zserio
17 {
18 
23 {
24 public:
26  using BitPosType = size_t;
27 
32  {
39  explicit ReaderContext(Span<const uint8_t> readBuffer, size_t readBufferBitSize);
40 
44  ~ReaderContext() = default;
45 
50  ReaderContext(const ReaderContext&) = delete;
52 
53  ReaderContext(const ReaderContext&&) = delete;
62  uintptr_t cache;
63  uint8_t cacheNumBits;
66  };
67 
74  explicit BitStreamReader(const uint8_t* buffer, size_t bufferByteSize);
75 
81  explicit BitStreamReader(Span<const uint8_t> buffer);
82 
89  explicit BitStreamReader(Span<const uint8_t> buffer, size_t bufferBitSize);
90 
97  explicit BitStreamReader(const uint8_t* buffer, size_t bufferBitSize, BitsTag);
98 
104  template <typename ALLOC>
105  explicit BitStreamReader(const BasicBitBuffer<ALLOC>& bitBuffer) :
106  BitStreamReader(bitBuffer.getData(), bitBuffer.getBitSize())
107  {}
108 
112  ~BitStreamReader() = default;
113 
121  uint32_t readBits(uint8_t numBits = 32);
122 
130  uint64_t readBits64(uint8_t numBits = 64);
131 
139  int32_t readSignedBits(uint8_t numBits = 32);
140 
148  int64_t readSignedBits64(uint8_t numBits = 64);
149 
155  int64_t readVarInt64();
156 
162  int32_t readVarInt32();
163 
169  int16_t readVarInt16();
170 
176  uint64_t readVarUInt64();
177 
183  uint32_t readVarUInt32();
184 
190  uint16_t readVarUInt16();
191 
197  int64_t readVarInt();
198 
204  uint64_t readVarUInt();
205 
211  uint32_t readVarSize();
212 
218  float readFloat16();
219 
225  float readFloat32();
226 
232  double readFloat64();
233 
241  template <typename ALLOC = std::allocator<uint8_t>>
242  vector<uint8_t, ALLOC> readBytes(const ALLOC& alloc = ALLOC())
243  {
244  const size_t len = static_cast<size_t>(readVarSize());
245  const BitPosType beginBitPosition = getBitPosition();
246  if ((beginBitPosition & 0x07U) != 0)
247  {
248  // we are not aligned to byte
249  vector<uint8_t, ALLOC> value{alloc};
250  value.reserve(len);
251  for (size_t i = 0; i < len; ++i)
252  {
253  value.push_back(readByte());
254  }
255  return value;
256  }
257  else
258  {
259  // we are aligned to byte
260  setBitPosition(beginBitPosition + len * 8);
261  Span<const uint8_t>::iterator beginIt = m_context.buffer.begin() + beginBitPosition / 8;
262  return vector<uint8_t, ALLOC>(beginIt, beginIt + len, alloc);
263  }
264  }
265 
273  template <typename ALLOC = std::allocator<char>>
274  string<ALLOC> readString(const ALLOC& alloc = ALLOC())
275  {
276  const size_t len = static_cast<size_t>(readVarSize());
277  const BitPosType beginBitPosition = getBitPosition();
278  if ((beginBitPosition & 0x07U) != 0)
279  {
280  // we are not aligned to byte
281  string<ALLOC> value{alloc};
282  value.reserve(len);
283  for (size_t i = 0; i < len; ++i)
284  {
285  using char_traits = std::char_traits<char>;
286  const char readCharacter =
287  char_traits::to_char_type(static_cast<char_traits::int_type>(readByte()));
288  value.push_back(readCharacter);
289  }
290  return value;
291  }
292  else
293  {
294  // we are aligned to byte
295  setBitPosition(beginBitPosition + len * 8);
296  Span<const uint8_t>::iterator beginIt = m_context.buffer.begin() + beginBitPosition / 8;
297  return string<ALLOC>(beginIt, beginIt + len, alloc);
298  }
299  }
300 
306  bool readBool();
307 
315  template <typename ALLOC = std::allocator<uint8_t>>
317  {
318  const size_t bitSize = static_cast<size_t>(readVarSize());
319  const size_t numBytesToRead = bitSize / 8;
320  const uint8_t numRestBits = static_cast<uint8_t>(bitSize - numBytesToRead * 8);
321  BasicBitBuffer<RebindAlloc<ALLOC, uint8_t>> bitBuffer(bitSize, allocator);
322  Span<uint8_t> buffer = bitBuffer.getData();
323  const BitPosType beginBitPosition = getBitPosition();
324  const Span<uint8_t>::iterator itEnd = buffer.begin() + numBytesToRead;
325  if ((beginBitPosition & 0x07U) != 0)
326  {
327  // we are not aligned to byte
328  for (Span<uint8_t>::iterator it = buffer.begin(); it != itEnd; ++it)
329  {
330  *it = static_cast<uint8_t>(readBits(8));
331  }
332  }
333  else
334  {
335  // we are aligned to byte
336  setBitPosition(beginBitPosition + numBytesToRead * 8);
337  Span<const uint8_t>::const_iterator sourceIt = m_context.buffer.begin() + beginBitPosition / 8;
338  (void)std::copy(sourceIt, sourceIt + numBytesToRead, buffer.begin());
339  }
340 
341  if (numRestBits > 0)
342  {
343  *itEnd = static_cast<uint8_t>(readBits(numRestBits) << (8U - numRestBits));
344  }
345 
346  return bitBuffer;
347  }
348 
355  {
356  return m_context.bitIndex;
357  }
358 
364  void setBitPosition(BitPosType position);
365 
371  void alignTo(size_t alignment);
372 
378  size_t getBufferBitSize() const
379  {
380  return m_context.bufferBitSize;
381  }
382 
383 private:
384  uint8_t readByte();
385 
386  ReaderContext m_context;
387 };
388 
389 } // namespace zserio
390 
391 #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