Zserio C++ runtime library  1.3.0
Built for Zserio 2.18.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 <cstring>
6 #include <string>
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  using char_traits = std::char_traits<char>;
285  const char readCharacter =
286  char_traits::to_char_type(static_cast<char_traits::int_type>(readByte()));
287  value.push_back(readCharacter);
288  }
289  return value;
290  }
291  else
292  {
293  // we are aligned to byte
294  setBitPosition(beginBitPosition + len * 8);
295  Span<const uint8_t>::iterator beginIt = m_context.buffer.begin() + beginBitPosition / 8;
296  return string<ALLOC>(beginIt, beginIt + len, alloc);
297  }
298  }
299 
305  bool readBool();
306 
314  template <typename ALLOC = std::allocator<uint8_t>>
316  {
317  const size_t bitSize = static_cast<size_t>(readVarSize());
318  const size_t numBytesToRead = bitSize / 8;
319  const uint8_t numRestBits = static_cast<uint8_t>(bitSize - numBytesToRead * 8);
320  BasicBitBuffer<RebindAlloc<ALLOC, uint8_t>> bitBuffer(bitSize, allocator);
321  Span<uint8_t> buffer = bitBuffer.getData();
322  const BitPosType beginBitPosition = getBitPosition();
323  const Span<uint8_t>::iterator itEnd = buffer.begin() + numBytesToRead;
324  if ((beginBitPosition & 0x07U) != 0)
325  {
326  // we are not aligned to byte
327  for (Span<uint8_t>::iterator it = buffer.begin(); it != itEnd; ++it)
328  {
329  *it = static_cast<uint8_t>(readBits(8));
330  }
331  }
332  else
333  {
334  // we are aligned to byte
335  setBitPosition(beginBitPosition + numBytesToRead * 8);
336  Span<const uint8_t>::const_iterator sourceIt = m_context.buffer.begin() + beginBitPosition / 8;
337  (void)std::copy(sourceIt, sourceIt + numBytesToRead, buffer.begin());
338  }
339 
340  if (numRestBits > 0)
341  {
342  *itEnd = static_cast<uint8_t>(readBits(numRestBits) << (8U - numRestBits));
343  }
344 
345  return bitBuffer;
346  }
347 
354  {
355  return m_context.bitIndex;
356  }
357 
363  void setBitPosition(BitPosType position);
364 
370  void alignTo(size_t alignment);
371 
377  size_t getBufferBitSize() const
378  {
379  return m_context.bufferBitSize;
380  }
381 
382 private:
383  uint8_t readByte();
384 
385  ReaderContext m_context;
386 };
387 
388 } // namespace zserio
389 
390 #endif // ifndef ZSERIO_BIT_STREAM_READER_H_INC
Span< const uint8_t > getData() const
Definition: BitBuffer.h:420
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:202
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