Zserio C++ runtime library  1.0.1
Built for Zserio 2.14.0
BitStreamWriter.h
Go to the documentation of this file.
1 #ifndef ZSERIO_BIT_STREAM_WRITER_H_INC
2 #define ZSERIO_BIT_STREAM_WRITER_H_INC
3 
4 #include <algorithm>
5 #include <cstddef>
6 #include <cstring>
7 
8 #include "zserio/BitBuffer.h"
10 #include "zserio/SizeConvertUtil.h"
11 #include "zserio/Span.h"
12 #include "zserio/StringView.h"
13 #include "zserio/Types.h"
14 
15 namespace zserio
16 {
17 
22 {
23 public:
26  {
27  public:
29  };
30 
32  using BitPosType = size_t;
33 
40  explicit BitStreamWriter(uint8_t* buffer, size_t bufferBitSize, BitsTag);
41 
48  explicit BitStreamWriter(uint8_t* buffer, size_t bufferByteSize);
49 
55  explicit BitStreamWriter(Span<uint8_t> buffer);
56 
63  explicit BitStreamWriter(Span<uint8_t> buffer, size_t bufferBitSize);
64 
70  template <typename ALLOC>
71  explicit BitStreamWriter(BasicBitBuffer<ALLOC>& bitBuffer) :
72  BitStreamWriter(bitBuffer.getData(), bitBuffer.getBitSize())
73  {}
74 
78  ~BitStreamWriter() = default;
79 
84  BitStreamWriter(const BitStreamWriter&) = delete;
86 
87  BitStreamWriter(const BitStreamWriter&&) = delete;
99  void writeBits(uint32_t data, uint8_t numBits = 32);
100 
107  void writeBits64(uint64_t data, uint8_t numBits = 64);
108 
115  void writeSignedBits(int32_t data, uint8_t numBits = 32);
116 
123  void writeSignedBits64(int64_t data, uint8_t numBits = 64);
124 
130  void writeVarInt64(int64_t data);
131 
137  void writeVarInt32(int32_t data);
138 
144  void writeVarInt16(int16_t data);
145 
151  void writeVarUInt64(uint64_t data);
152 
158  void writeVarUInt32(uint32_t data);
159 
165  void writeVarUInt16(uint16_t data);
166 
172  void writeVarInt(int64_t data);
173 
179  void writeVarUInt(uint64_t data);
180 
186  void writeVarSize(uint32_t data);
187 
193  void writeFloat16(float data);
194 
200  void writeFloat32(float data);
201 
207  void writeFloat64(double data);
208 
214  void writeBytes(Span<const uint8_t> data);
215 
221  void writeString(StringView data);
222 
228  void writeBool(bool data);
229 
235  template <typename ALLOC>
236  void writeBitBuffer(const BasicBitBuffer<ALLOC>& bitBuffer)
237  {
238  const size_t bitSize = bitBuffer.getBitSize();
240 
241  Span<const uint8_t> buffer = bitBuffer.getData();
242  size_t numBytesToWrite = bitSize / 8;
243  const uint8_t numRestBits = static_cast<uint8_t>(bitSize - numBytesToWrite * 8);
244  const BitPosType beginBitPosition = getBitPosition();
245  const Span<const uint8_t>::iterator itEnd = buffer.begin() + numBytesToWrite;
246  if ((beginBitPosition & 0x07U) != 0)
247  {
248  // we are not aligned to byte
249  for (Span<const uint8_t>::iterator it = buffer.begin(); it != itEnd; ++it)
250  writeUnsignedBits(*it, 8);
251  }
252  else
253  {
254  // we are aligned to byte
255  setBitPosition(beginBitPosition + numBytesToWrite * 8);
256  if (hasWriteBuffer())
257  {
258  std::copy(buffer.begin(), buffer.begin() + numBytesToWrite,
259  m_buffer.data() + beginBitPosition / 8);
260  }
261  }
262 
263  if (numRestBits > 0)
264  writeUnsignedBits(*itEnd >> (8U - numRestBits), numRestBits);
265  }
266 
273  {
274  return m_bitIndex;
275  }
276 
282  void setBitPosition(BitPosType position);
283 
289  void alignTo(size_t alignment);
290 
296  bool hasWriteBuffer() const
297  {
298  return m_buffer.data() != nullptr;
299  }
300 
306  const uint8_t* getWriteBuffer() const;
307 
314 
320  size_t getBufferBitSize() const
321  {
322  return m_bufferBitSize;
323  }
324 
325 private:
326  void writeUnsignedBits(uint32_t data, uint8_t numBits);
327  void writeUnsignedBits64(uint64_t data, uint8_t numBits);
328  void writeSignedVarNum(int64_t value, size_t maxVarBytes, size_t numVarBytes);
329  void writeUnsignedVarNum(uint64_t value, size_t maxVarBytes, size_t numVarBytes);
330  void writeVarNum(uint64_t value, bool hasSign, bool isNegative, size_t maxVarBytes, size_t numVarBytes);
331 
332  void checkCapacity(size_t bitSize) const;
333  void throwInsufficientCapacityException() const;
334 
335  Span<uint8_t> m_buffer;
336  size_t m_bitIndex;
337  size_t m_bufferBitSize;
338 };
339 
340 } // namespace zserio
341 
342 #endif // ifndef ZSERIO_BIT_STREAM_WRITER_H_INC
Span< const uint8_t > getData() const
Definition: BitBuffer.h:401
size_t getBitSize() const
Definition: BitBuffer.h:383
void writeFloat64(double data)
void writeVarInt64(int64_t data)
void writeVarInt16(int16_t data)
Span< const uint8_t > getBuffer() const
void writeString(StringView data)
void writeSignedBits(int32_t data, uint8_t numBits=32)
void writeFloat32(float data)
size_t getBufferBitSize() const
BitPosType getBitPosition() const
void writeVarUInt64(uint64_t data)
void writeVarUInt16(uint16_t data)
const uint8_t * getWriteBuffer() const
void writeVarInt32(int32_t data)
void writeSignedBits64(int64_t data, uint8_t numBits=64)
void writeVarSize(uint32_t data)
void writeVarUInt32(uint32_t data)
void writeVarUInt(uint64_t data)
BitStreamWriter(const BitStreamWriter &&)=delete
void writeVarInt(int64_t data)
void writeFloat16(float data)
BitStreamWriter(const BitStreamWriter &)=delete
BitStreamWriter & operator=(const BitStreamWriter &)=delete
void writeBits64(uint64_t data, uint8_t numBits=64)
void writeBytes(Span< const uint8_t > data)
void writeBitBuffer(const BasicBitBuffer< ALLOC > &bitBuffer)
BitStreamWriter(BasicBitBuffer< ALLOC > &bitBuffer)
BitStreamWriter(uint8_t *buffer, size_t bufferBitSize, BitsTag)
BitStreamWriter & operator=(BitStreamWriter &&)=delete
void writeBits(uint32_t data, uint8_t numBits=32)
void setBitPosition(BitPosType position)
void alignTo(size_t alignment)
CppRuntimeException(const char *message="")
constexpr pointer data() const noexcept
Definition: Span.h:271
constexpr iterator begin() const noexcept
Definition: Span.h:200
uint8_t numBits(uint64_t numValues)
uint32_t convertSizeToUInt32(size_t value)