Zserio C++ runtime library  1.0.0
Built for Zserio 2.13.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 <cstddef>
5 #include <cstring>
6 #include <algorithm>
7 
8 #include "zserio/BitBuffer.h"
10 #include "zserio/Span.h"
11 #include "zserio/StringView.h"
12 #include "zserio/Types.h"
13 #include "zserio/SizeConvertUtil.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  }
75 
79  ~BitStreamWriter() = default;
80 
85  BitStreamWriter(const BitStreamWriter&) = delete;
86  BitStreamWriter& operator=(const BitStreamWriter&) = delete;
87 
88  BitStreamWriter(const BitStreamWriter&&) = delete;
100  void writeBits(uint32_t data, uint8_t numBits = 32);
101 
108  void writeBits64(uint64_t data, uint8_t numBits = 64);
109 
116  void writeSignedBits(int32_t data, uint8_t numBits = 32);
117 
124  void writeSignedBits64(int64_t data, uint8_t numBits = 64);
125 
131  void writeVarInt64(int64_t data);
132 
138  void writeVarInt32(int32_t data);
139 
145  void writeVarInt16(int16_t data);
146 
152  void writeVarUInt64(uint64_t data);
153 
159  void writeVarUInt32(uint32_t data);
160 
166  void writeVarUInt16(uint16_t data);
167 
173  void writeVarInt(int64_t data);
174 
180  void writeVarUInt(uint64_t data);
181 
187  void writeVarSize(uint32_t data);
188 
194  void writeFloat16(float data);
195 
201  void writeFloat32(float data);
202 
208  void writeFloat64(double data);
209 
215  void writeBytes(Span<const uint8_t> data);
216 
222  void writeString(StringView data);
223 
229  void writeBool(bool data);
230 
236  template <typename ALLOC>
237  void writeBitBuffer(const BasicBitBuffer<ALLOC>& bitBuffer)
238  {
239  const size_t bitSize = bitBuffer.getBitSize();
241 
242  Span<const uint8_t> buffer = bitBuffer.getData();
243  size_t numBytesToWrite = bitSize / 8;
244  const uint8_t numRestBits = static_cast<uint8_t>(bitSize - numBytesToWrite * 8);
245  const BitPosType beginBitPosition = getBitPosition();
246  const Span<const uint8_t>::iterator itEnd = buffer.begin() + numBytesToWrite;
247  if ((beginBitPosition & 0x07U) != 0)
248  {
249  // we are not aligned to byte
250  for (Span<const uint8_t>::iterator it = buffer.begin(); it != itEnd; ++it)
251  writeUnsignedBits(*it, 8);
252  }
253  else
254  {
255  // we are aligned to byte
256  setBitPosition(beginBitPosition + numBytesToWrite * 8);
257  if (hasWriteBuffer())
258  {
259  std::copy(buffer.begin(), buffer.begin() + numBytesToWrite,
260  m_buffer.data() + beginBitPosition / 8);
261  }
262  }
263 
264  if (numRestBits > 0)
265  writeUnsignedBits(*itEnd >> (8U - numRestBits), numRestBits);
266  }
267 
273  BitPosType getBitPosition() const { return m_bitIndex; }
274 
280  void setBitPosition(BitPosType position);
281 
287  void alignTo(size_t alignment);
288 
294  bool hasWriteBuffer() const { return m_buffer.data() != nullptr; }
295 
301  const uint8_t* getWriteBuffer() const;
302 
309 
315  size_t getBufferBitSize() const { return m_bufferBitSize; }
316 
317 private:
318  void writeUnsignedBits(uint32_t data, uint8_t numBits);
319  void writeUnsignedBits64(uint64_t data, uint8_t numBits);
320  void writeSignedVarNum(int64_t value, size_t maxVarBytes, size_t numVarBytes);
321  void writeUnsignedVarNum(uint64_t value, size_t maxVarBytes, size_t numVarBytes);
322  void writeVarNum(uint64_t value, bool hasSign, bool isNegative, size_t maxVarBytes, size_t numVarBytes);
323 
324  void checkCapacity(size_t bitSize) const;
325  void throwInsufficientCapacityException() const;
326 
327  Span<uint8_t> m_buffer;
328  size_t m_bitIndex;
329  size_t m_bufferBitSize;
330 };
331 
332 } // namespace zserio
333 
334 #endif // ifndef ZSERIO_BIT_STREAM_WRITER_H_INC
void writeVarInt64(int64_t data)
void alignTo(size_t alignment)
void writeVarUInt16(uint16_t data)
void writeBytes(Span< const uint8_t > data)
void writeFloat16(float data)
void writeVarUInt64(uint64_t data)
void writeVarInt16(int16_t data)
BitStreamWriter(BasicBitBuffer< ALLOC > &bitBuffer)
uint8_t numBits(uint64_t numValues)
const uint8_t * getWriteBuffer() const
BitStreamWriter(uint8_t *buffer, size_t bufferBitSize, BitsTag)
void writeFloat32(float data)
void writeBitBuffer(const BasicBitBuffer< ALLOC > &bitBuffer)
void writeVarInt(int64_t data)
void writeVarInt32(int32_t data)
void writeVarUInt32(uint32_t data)
void writeString(StringView data)
void writeVarSize(uint32_t data)
void writeSignedBits(int32_t data, uint8_t numBits=32)
uint32_t convertSizeToUInt32(size_t value)
bool hasWriteBuffer() const
Span< const uint8_t > getBuffer() const
void writeFloat64(double data)
void setBitPosition(BitPosType position)
BitPosType getBitPosition() const
void writeBits(uint32_t data, uint8_t numBits=32)
void writeVarUInt(uint64_t data)
size_t getBitSize() const
Definition: BitBuffer.h:381
constexpr iterator begin() const noexcept
Definition: Span.h:195
CppRuntimeException & operator=(const CppRuntimeException &other)=default
Span< const uint8_t > getData() const
Definition: BitBuffer.h:399
void writeSignedBits64(int64_t data, uint8_t numBits=64)
CppRuntimeException(const char *message="")
size_t getBufferBitSize() const
void writeBits64(uint64_t data, uint8_t numBits=64)