Zserio C++ runtime library  1.0.2
Built for Zserio 2.14.1
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  {
251  writeUnsignedBits(*it, 8);
252  }
253  }
254  else
255  {
256  // we are aligned to byte
257  setBitPosition(beginBitPosition + numBytesToWrite * 8);
258  if (hasWriteBuffer())
259  {
260  std::copy(buffer.begin(), buffer.begin() + numBytesToWrite,
261  m_buffer.data() + beginBitPosition / 8);
262  }
263  }
264 
265  if (numRestBits > 0)
266  {
267  writeUnsignedBits(static_cast<uint32_t>(*itEnd) >> (8U - numRestBits), numRestBits);
268  }
269  }
270 
277  {
278  return m_bitIndex;
279  }
280 
286  void setBitPosition(BitPosType position);
287 
293  void alignTo(size_t alignment);
294 
300  bool hasWriteBuffer() const
301  {
302  return m_buffer.data() != nullptr;
303  }
304 
310  const uint8_t* getWriteBuffer() const;
311 
318 
324  size_t getBufferBitSize() const
325  {
326  return m_bufferBitSize;
327  }
328 
329 private:
330  void writeUnsignedBits(uint32_t data, uint8_t numBits);
331  void writeUnsignedBits64(uint64_t data, uint8_t numBits);
332  void writeSignedVarNum(int64_t value, size_t maxVarBytes, size_t numVarBytes);
333  void writeUnsignedVarNum(uint64_t value, size_t maxVarBytes, size_t numVarBytes);
334  void writeVarNum(uint64_t value, bool hasSign, bool isNegative, size_t maxVarBytes, size_t numVarBytes);
335 
336  void checkCapacity(size_t bitSize) const;
337  void throwInsufficientCapacityException() const;
338 
339  Span<uint8_t> m_buffer;
340  size_t m_bitIndex;
341  size_t m_bufferBitSize;
342 };
343 
344 } // namespace zserio
345 
346 #endif // ifndef ZSERIO_BIT_STREAM_WRITER_H_INC
Span< const uint8_t > getData() const
Definition: BitBuffer.h:421
size_t getBitSize() const
Definition: BitBuffer.h:403
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)