Zserio C++ runtime library  1.3.0
Built for Zserio 2.18.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 <cstring>
6 
7 #include "zserio/BitBuffer.h"
10 #include "zserio/Span.h"
11 #include "zserio/StringView.h"
12 #include "zserio/Types.h"
13 
14 namespace zserio
15 {
16 
21 {
22 public:
25  {
26  public:
28  };
29 
31  using BitPosType = size_t;
32 
39  explicit BitStreamWriter(uint8_t* buffer, size_t bufferBitSize, BitsTag);
40 
47  explicit BitStreamWriter(uint8_t* buffer, size_t bufferByteSize);
48 
54  explicit BitStreamWriter(Span<uint8_t> buffer);
55 
62  explicit BitStreamWriter(Span<uint8_t> buffer, size_t bufferBitSize);
63 
69  template <typename ALLOC>
70  explicit BitStreamWriter(BasicBitBuffer<ALLOC>& bitBuffer) :
71  BitStreamWriter(bitBuffer.getData(), bitBuffer.getBitSize())
72  {}
73 
77  ~BitStreamWriter() = default;
78 
83  BitStreamWriter(const BitStreamWriter&) = delete;
85 
86  BitStreamWriter(const BitStreamWriter&&) = delete;
98  void writeBits(uint32_t data, uint8_t numBits = 32);
99 
106  void writeBits64(uint64_t data, uint8_t numBits = 64);
107 
114  void writeSignedBits(int32_t data, uint8_t numBits = 32);
115 
122  void writeSignedBits64(int64_t data, uint8_t numBits = 64);
123 
129  void writeVarInt64(int64_t data);
130 
136  void writeVarInt32(int32_t data);
137 
143  void writeVarInt16(int16_t data);
144 
150  void writeVarUInt64(uint64_t data);
151 
157  void writeVarUInt32(uint32_t data);
158 
164  void writeVarUInt16(uint16_t data);
165 
171  void writeVarInt(int64_t data);
172 
178  void writeVarUInt(uint64_t data);
179 
185  void writeVarSize(uint32_t data);
186 
192  void writeFloat16(float data);
193 
199  void writeFloat32(float data);
200 
206  void writeFloat64(double data);
207 
213  void writeBytes(Span<const uint8_t> data);
214 
220  void writeString(StringView data);
221 
227  void writeBool(bool data);
228 
234  template <typename ALLOC>
235  void writeBitBuffer(const BasicBitBuffer<ALLOC>& bitBuffer)
236  {
237  const size_t bitSize = bitBuffer.getBitSize();
239 
240  Span<const uint8_t> buffer = bitBuffer.getData();
241  size_t numBytesToWrite = bitSize / 8;
242  const uint8_t numRestBits = static_cast<uint8_t>(bitSize - numBytesToWrite * 8);
243  const BitPosType beginBitPosition = getBitPosition();
244  const Span<const uint8_t>::iterator itEnd = buffer.begin() + numBytesToWrite;
245  if ((beginBitPosition & 0x07U) != 0)
246  {
247  // we are not aligned to byte
248  for (Span<const uint8_t>::iterator it = buffer.begin(); it != itEnd; ++it)
249  {
250  writeUnsignedBits(*it, 8);
251  }
252  }
253  else
254  {
255  // we are aligned to byte
256  setBitPosition(beginBitPosition + numBytesToWrite * 8);
257  if (hasWriteBuffer())
258  {
259  (void)std::copy(buffer.begin(), buffer.begin() + numBytesToWrite,
260  m_buffer.data() + beginBitPosition / 8);
261  }
262  }
263 
264  if (numRestBits > 0)
265  {
266  writeUnsignedBits(static_cast<uint32_t>(*itEnd) >> (8U - numRestBits), numRestBits);
267  }
268  }
269 
276  {
277  return m_bitIndex;
278  }
279 
285  void setBitPosition(BitPosType position);
286 
292  void alignTo(size_t alignment);
293 
299  bool hasWriteBuffer() const
300  {
301  return m_buffer.data() != nullptr;
302  }
303 
309  const uint8_t* getWriteBuffer() const;
310 
317 
323  size_t getBufferBitSize() const
324  {
325  return m_bufferBitSize;
326  }
327 
328 private:
329  void writeUnsignedBits(uint32_t data, uint8_t numBits);
330  void writeUnsignedBits64(uint64_t data, uint8_t numBits);
331  void writeSignedVarNum(int64_t value, size_t maxVarBytes, size_t numVarBytes);
332  void writeUnsignedVarNum(uint64_t value, size_t maxVarBytes, size_t numVarBytes);
333  void writeVarNum(uint64_t value, bool hasSign, bool isNegative, size_t maxVarBytes, size_t numVarBytes);
334 
335  void checkCapacity(size_t bitSize) const;
336  void throwInsufficientCapacityException() const;
337 
338  Span<uint8_t> m_buffer;
339  size_t m_bitIndex;
340  size_t m_bufferBitSize;
341 };
342 
343 } // namespace zserio
344 
345 #endif // ifndef ZSERIO_BIT_STREAM_WRITER_H_INC
Span< const uint8_t > getData() const
Definition: BitBuffer.h:420
size_t getBitSize() const
Definition: BitBuffer.h:402
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:273
constexpr iterator begin() const noexcept
Definition: Span.h:202
uint8_t numBits(uint64_t numValues)
uint32_t convertSizeToUInt32(size_t value)