Zserio C++17 runtime library 1.3.0
Built for Zserio 2.20.0
Loading...
Searching...
No Matches
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 <string_view>
7#include <type_traits>
8
9#include "zserio/BitBuffer.h"
10#include "zserio/Bytes.h"
13#include "zserio/String.h"
14#include "zserio/Types.h"
15
16namespace zserio
17{
18
23{
24public:
33
36
43 explicit BitStreamWriter(uint8_t* buffer, size_t bufferBitSize, BitsTag);
44
51 explicit BitStreamWriter(uint8_t* buffer, size_t bufferByteSize);
52
58 explicit BitStreamWriter(Span<uint8_t> buffer);
59
66 explicit BitStreamWriter(Span<uint8_t> buffer, size_t bufferBitSize);
67
73 template <typename ALLOC>
75 BitStreamWriter(bitBuffer.getData(), bitBuffer.getBitSize())
76 {}
77
81 ~BitStreamWriter() = default;
82
89
102 void writeUnsignedBits32(uint32_t data, uint8_t numBits = 32);
103
110 void writeUnsignedBits64(uint64_t data, uint8_t numBits = 64);
111
118 void writeSignedBits32(int32_t data, uint8_t numBits = 32);
119
126 void writeSignedBits64(int64_t data, uint8_t numBits = 64);
127
133 void writeBool(Bool data);
134
140 void writeVarInt16(VarInt16 data);
141
147 void writeVarInt32(VarInt32 data);
148
154 void writeVarInt64(VarInt64 data);
155
161 void writeVarInt(VarInt data);
162
168 void writeVarUInt16(VarUInt16 data);
169
175 void writeVarUInt32(VarUInt32 data);
176
182 void writeVarUInt64(VarUInt64 data);
183
189 void writeVarUInt(VarUInt data);
190
196 void writeVarSize(VarSize data);
197
203 void writeFloat16(Float16 data);
204
210 void writeFloat32(Float32 data);
211
217 void writeFloat64(Float64 data);
218
224 void writeBytes(BytesView data);
225
231 void writeString(std::string_view data);
232
238 template <typename ALLOC>
240 {
243
244 Span<const uint8_t> buffer = bitBuffer.getData();
245 size_t numBytesToWrite = bitSize / 8;
246 const uint8_t numRestBits = static_cast<uint8_t>(bitSize - numBytesToWrite * 8);
248 const Span<const uint8_t>::iterator itEnd = buffer.begin() + numBytesToWrite;
249 if ((beginBitPosition & 0x07U) != 0)
250 {
251 // we are not aligned to byte
252 for (Span<const uint8_t>::iterator it = buffer.begin(); it != itEnd; ++it)
253 {
254 writeUnsignedBits32Impl(*it, 8);
255 }
256 }
257 else
258 {
259 // we are aligned to byte
261 if (hasWriteBuffer())
262 {
263 (void)std::copy(buffer.begin(), buffer.begin() + numBytesToWrite,
264 m_buffer.data() + beginBitPosition / 8);
265 }
266 }
267
268 if (numRestBits > 0)
269 {
270 writeUnsignedBits32Impl(static_cast<uint32_t>(*itEnd) >> (8U - numRestBits), numRestBits);
271 }
272 }
273
280 {
281 return m_bitIndex;
282 }
283
290
296 void alignTo(size_t alignment);
297
303 bool hasWriteBuffer() const
304 {
305 return m_buffer.data() != nullptr;
306 }
307
313 const uint8_t* getWriteBuffer() const;
314
321
327 size_t getBufferBitSize() const
328 {
329 return m_bufferBitSize;
330 }
331
332private:
333 void writeUnsignedBits32Impl(uint32_t data, uint8_t numBits);
334 void writeUnsignedBits64Impl(uint64_t data, uint8_t numBits);
335 void writeSignedVarNum(int64_t value, size_t maxVarBytes, size_t numVarBytes);
336 void writeUnsignedVarNum(uint64_t value, size_t maxVarBytes, size_t numVarBytes);
337 void writeVarNum(uint64_t value, bool hasSign, bool isNegative, size_t maxVarBytes, size_t numVarBytes);
338
339 void checkCapacity(size_t bitSize) const;
340 void throwInsufficientCapacityException() const;
341
342 Span<uint8_t> m_buffer;
343 size_t m_bitIndex;
344 size_t m_bufferBitSize;
345};
346
347namespace detail
348{
349
350inline void write(BitStreamWriter& writer, Bool value)
351{
352 writer.writeBool(value);
353}
354
355template <BitSize BIT_SIZE, bool IS_SIGNED>
356void write(BitStreamWriter& writer, FixedIntWrapper<BIT_SIZE, IS_SIGNED> value)
357{
358 using ValueType = typename FixedIntWrapper<BIT_SIZE, IS_SIGNED>::ValueType;
359
360 static_assert(BIT_SIZE != 0, "Variable dynamic bit fields not allowed here!");
361 if constexpr (sizeof(ValueType) <= 4)
362 {
363 if constexpr (std::is_signed_v<ValueType>)
364 {
365 writer.writeSignedBits32(value, BIT_SIZE);
366 }
367 else
368 {
369 writer.writeUnsignedBits32(value, BIT_SIZE);
370 }
371 }
372 else
373 {
374 if constexpr (std::is_signed_v<ValueType>)
375 {
376 writer.writeSignedBits64(value, BIT_SIZE);
377 }
378 else
379 {
380 writer.writeUnsignedBits64(value, BIT_SIZE);
381 }
382 }
383}
384
385template <typename T>
386void write(BitStreamWriter& writer, DynIntWrapper<T> value, uint8_t numBits)
387{
388 if constexpr (sizeof(T) <= 4)
389 {
390 if constexpr (std::is_signed_v<T>)
391 {
392 writer.writeSignedBits32(value, numBits);
393 }
394 else
395 {
396 writer.writeUnsignedBits32(value, numBits);
397 }
398 }
399 else
400 {
401 if constexpr (std::is_signed_v<T>)
402 {
403 writer.writeSignedBits64(value, numBits);
404 }
405 else
406 {
407 writer.writeUnsignedBits64(value, numBits);
408 }
409 }
410}
411
412inline void write(BitStreamWriter& writer, VarInt16 value)
413{
414 writer.writeVarInt16(value);
415}
416
417inline void write(BitStreamWriter& writer, VarInt32 value)
418{
419 writer.writeVarInt32(value);
420}
421
422inline void write(BitStreamWriter& writer, VarInt64 value)
423{
424 writer.writeVarInt64(value);
425}
426
427inline void write(BitStreamWriter& writer, VarInt value)
428{
429 writer.writeVarInt(value);
430}
431
432inline void write(BitStreamWriter& writer, VarUInt16 value)
433{
434 writer.writeVarUInt16(value);
435}
436
437inline void write(BitStreamWriter& writer, VarUInt32 value)
438{
439 writer.writeVarUInt32(value);
440}
441
442inline void write(BitStreamWriter& writer, VarUInt64 value)
443{
444 writer.writeVarUInt64(value);
445}
446
447inline void write(BitStreamWriter& writer, VarUInt value)
448{
449 writer.writeVarUInt(value);
450}
451
452inline void write(BitStreamWriter& writer, VarSize value)
453{
454 writer.writeVarSize(value);
455}
456
457inline void write(BitStreamWriter& writer, Float16 value)
458{
459 writer.writeFloat16(value);
460}
461
462inline void write(BitStreamWriter& writer, Float32 value)
463{
464 writer.writeFloat32(value);
465}
466
467inline void write(BitStreamWriter& writer, Float64 value)
468{
469 writer.writeFloat64(value);
470}
471
472inline void write(BitStreamWriter& writer, BytesView value)
473{
474 writer.writeBytes(value);
475}
476
477inline void write(BitStreamWriter& writer, std::string_view value)
478{
479 writer.writeString(value);
480}
481
482template <typename ALLOC>
483inline void write(BitStreamWriter& writer, const BasicBitBufferView<ALLOC>& value)
484{
485 writer.writeBitBuffer(value.get());
486}
487
488} // namespace detail
489
490} // namespace zserio
491
492#endif // ifndef ZSERIO_BIT_STREAM_WRITER_H_INC
void writeVarUInt16(VarUInt16 data)
Span< const uint8_t > getBuffer() const
void writeVarInt32(VarInt32 data)
void writeFloat64(Float64 data)
void writeVarUInt64(VarUInt64 data)
size_t getBufferBitSize() const
BitPosType getBitPosition() const
void writeVarInt16(VarInt16 data)
const uint8_t * getWriteBuffer() const
void writeSignedBits64(int64_t data, uint8_t numBits=64)
BitStreamWriter(const BitStreamWriter &&)=delete
void writeVarInt64(VarInt64 data)
BitStreamWriter(const BitStreamWriter &)=delete
BitStreamWriter & operator=(BitStreamWriter &&)=delete
void writeUnsignedBits32(uint32_t data, uint8_t numBits=32)
void writeFloat32(Float32 data)
void writeSignedBits32(int32_t data, uint8_t numBits=32)
void writeVarUInt(VarUInt data)
void writeBytes(BytesView data)
void writeUnsignedBits64(uint64_t data, uint8_t numBits=64)
void writeBitBuffer(const BasicBitBuffer< ALLOC > &bitBuffer)
BitStreamWriter(BasicBitBuffer< ALLOC > &bitBuffer)
BitStreamWriter & operator=(const BitStreamWriter &)=delete
void writeString(std::string_view data)
void writeFloat16(Float16 data)
void writeVarUInt32(VarUInt32 data)
void writeVarSize(VarSize data)
void writeVarInt(VarInt data)
void setBitPosition(BitPosType position)
void alignTo(size_t alignment)
CppRuntimeException(const char *message="")
pointer iterator
Definition Span.h:68
constexpr pointer data() const noexcept
Definition Span.h:271
Span< const uint8_t > BytesView
Definition Bytes.h:30
detail::BoolWrapper Bool
Definition Types.h:732
detail::VarIntWrapper< uint64_t, detail::VarIntType::VAR > VarUInt
Definition Types.h:888
detail::FloatWrapper< float, detail::FloatType::FLOAT16 > Float16
Definition Types.h:892
detail::FloatWrapper< float, detail::FloatType::FLOAT32 > Float32
Definition Types.h:893
detail::VarIntWrapper< int32_t, detail::VarIntType::VAR32 > VarInt32
Definition Types.h:881
detail::VarIntWrapper< uint16_t, detail::VarIntType::VAR16 > VarUInt16
Definition Types.h:885
detail::VarIntWrapper< uint64_t, detail::VarIntType::VAR64 > VarUInt64
Definition Types.h:887
uint32_t convertSizeToUInt32(size_t value)
detail::VarIntWrapper< int16_t, detail::VarIntType::VAR16 > VarInt16
Definition Types.h:880
detail::FloatWrapper< double, detail::FloatType::FLOAT64 > Float64
Definition Types.h:894
detail::VarIntWrapper< uint32_t, detail::VarIntType::VAR32 > VarUInt32
Definition Types.h:886
detail::VarIntWrapper< int64_t, detail::VarIntType::VAR > VarInt
Definition Types.h:883
detail::VarIntWrapper< int64_t, detail::VarIntType::VAR64 > VarInt64
Definition Types.h:882
detail::VarIntWrapper< uint32_t, detail::VarIntType::VARSIZE > VarSize
Definition Types.h:890