7static const std::array<uint32_t, 33> MAX_U32_VALUES = {
43static const std::array<int32_t, 33> MIN_I32_VALUES = {
79static const std::array<int32_t, 33> MAX_I32_VALUES = {
115static const std::array<uint64_t, 65> MAX_U64_VALUES = {
165 0x0001ffffffffffffULL,
166 0x0003ffffffffffffULL,
167 0x0007ffffffffffffULL,
168 0x000fffffffffffffULL,
169 0x001fffffffffffffULL,
170 0x003fffffffffffffULL,
171 0x007fffffffffffffULL,
172 0x00ffffffffffffffULL,
173 0x01ffffffffffffffULL,
174 0x03ffffffffffffffULL,
175 0x07ffffffffffffffULL,
176 0x0fffffffffffffffULL,
177 0x1fffffffffffffffULL,
178 0x3fffffffffffffffULL,
179 0x7fffffffffffffffULL,
180 0xffffffffffffffffULL,
183static const std::array<int64_t, 65> MIN_I64_VALUES = {
233 -0x0001000000000000LL,
234 -0x0002000000000000LL,
235 -0x0004000000000000LL,
236 -0x0008000000000000LL,
237 -0x0010000000000000LL,
238 -0x0020000000000000LL,
239 -0x0040000000000000LL,
240 -0x0080000000000000LL,
241 -0x0100000000000000LL,
242 -0x0200000000000000LL,
243 -0x0400000000000000LL,
244 -0x0800000000000000LL,
245 -0x1000000000000000LL,
246 -0x2000000000000000LL,
247 -0x4000000000000000LL,
251static const std::array<int64_t, 65> MAX_I64_VALUES = {
301 0x0000ffffffffffffLL,
302 0x0001ffffffffffffLL,
303 0x0003ffffffffffffLL,
304 0x0007ffffffffffffLL,
305 0x000fffffffffffffLL,
306 0x001fffffffffffffLL,
307 0x003fffffffffffffLL,
308 0x007fffffffffffffLL,
309 0x00ffffffffffffffLL,
310 0x01ffffffffffffffLL,
311 0x03ffffffffffffffLL,
312 0x07ffffffffffffffLL,
313 0x0fffffffffffffffLL,
314 0x1fffffffffffffffLL,
315 0x3fffffffffffffffLL,
316 0x7fffffffffffffffLL,
322 m_buffer(buffer, (bufferBitSize + 7) / 8),
324 m_bufferBitSize(bufferBitSize)
334 m_bufferBitSize(buffer.size() * 8)
340 m_bufferBitSize(bufferBitSize)
342 if (buffer.size() < (bufferBitSize + 7) / 8)
345 << buffer.size() <<
"' < '" << (bufferBitSize + 7) / 8 <<
"')!";
351 if (numBits == 0 || numBits >
sizeof(
uint32_t) * 8 || data > MAX_U32_VALUES[numBits])
354 << numBits <<
"-bits value '" << data <<
"' failed!";
357 writeUnsignedBits32Impl(data, numBits);
362 if (numBits == 0 || numBits >
sizeof(
uint64_t) * 8 || data > MAX_U64_VALUES[numBits])
365 << numBits <<
"-bits value '" << data <<
"' failed!";
368 writeUnsignedBits64Impl(data, numBits);
373 if (numBits == 0 || numBits >
sizeof(
int32_t) * 8 || data < MIN_I32_VALUES[numBits] ||
374 data > MAX_I32_VALUES[numBits])
377 << numBits <<
"-bits value '" << data <<
"' failed!";
380 writeUnsignedBits32Impl(
static_cast<uint32_t>(data) & MAX_U32_VALUES[numBits], numBits);
385 if (numBits == 0 || numBits >
sizeof(
int64_t) * 8 || data < MIN_I64_VALUES[numBits] ||
386 data > MAX_I64_VALUES[numBits])
389 << numBits <<
"-bits value '" << data <<
"' failed!";
392 writeUnsignedBits64Impl(
static_cast<uint64_t>(data) & MAX_U64_VALUES[numBits], numBits);
397 writeUnsignedBits32Impl((data ? 1 : 0), 1);
402 writeSignedVarNum(data, 2, detail::bitSizeOf(data) / 8);
407 writeSignedVarNum(data, 4, detail::bitSizeOf(data) / 8);
412 writeSignedVarNum(data, 8, detail::bitSizeOf(data) / 8);
419 writeUnsignedBits32Impl(0x80, 8);
423 writeSignedVarNum(data, 9, detail::bitSizeOf(data) / 8);
429 writeUnsignedVarNum(data, 2, detail::bitSizeOf(data) / 8);
434 writeUnsignedVarNum(data, 4, detail::bitSizeOf(data) / 8);
439 writeUnsignedVarNum(data, 8, detail::bitSizeOf(data) / 8);
444 writeUnsignedVarNum(data, 9, detail::bitSizeOf(data) / 8);
449 writeUnsignedVarNum(data, 5, detail::bitSizeOf(data) / 8);
479 for (
size_t i = 0;
i <
len; ++
i)
481 writeUnsignedBits32Impl(data[
i], 8);
504 for (
size_t i = 0;
i <
len; ++
i)
543 return m_buffer.
data();
551void BitStreamWriter::writeUnsignedBits32Impl(
uint32_t data,
uint8_t numBits)
555 m_bitIndex += numBits;
559 checkCapacity(m_bitIndex + numBits);
561 uint8_t restNumBits = numBits;
562 const uint8_t bitsUsed = m_bitIndex & 0x07U;
563 uint8_t bitsFree =
static_cast<uint8_t
>(8 - bitsUsed);
564 size_t byteIndex = m_bitIndex / 8;
566 if (restNumBits > bitsFree)
569 const uint8_t shiftNum =
static_cast<uint8_t
>(restNumBits - bitsFree);
570 const uint8_t maskedByte =
static_cast<uint8_t
>(m_buffer[byteIndex] & ~(0xFFU >> bitsUsed));
571 m_buffer[byteIndex++] =
static_cast<uint8_t
>(maskedByte | (data >> shiftNum));
572 restNumBits =
static_cast<uint8_t
>(restNumBits - bitsFree);
575 while (restNumBits >= 8)
577 restNumBits =
static_cast<uint8_t
>(restNumBits - 8);
578 m_buffer[byteIndex++] =
static_cast<uint8_t
>((data >> restNumBits) & MAX_U32_VALUES[8]);
588 const uint8_t shiftNum =
static_cast<uint8_t
>(bitsFree - restNumBits);
589 const uint32_t mask = MAX_U32_VALUES[restNumBits];
590 const uint8_t maskedByte =
591 m_buffer[byteIndex] &
static_cast<uint8_t
>(~static_cast<uint8_t>(mask << shiftNum));
592 m_buffer[byteIndex] =
static_cast<uint8_t
>(maskedByte | ((data & mask) << shiftNum));
598inline void BitStreamWriter::writeUnsignedBits64Impl(uint64_t data, uint8_t numBits)
602 writeUnsignedBits32Impl(
static_cast<uint32_t
>(data), numBits);
606 writeUnsignedBits32Impl(
static_cast<uint32_t
>(data >> 32U),
static_cast<uint8_t
>(numBits - 32));
607 writeUnsignedBits32Impl(
static_cast<uint32_t
>(data), 32);
611inline void BitStreamWriter::writeSignedVarNum(int64_t value,
size_t maxVarBytes,
size_t numVarBytes)
613 const uint64_t absValue =
static_cast<uint64_t
>(value < 0 ? -value : value);
614 writeVarNum(absValue,
true, value < 0, maxVarBytes, numVarBytes);
617inline void BitStreamWriter::writeUnsignedVarNum(uint64_t value,
size_t maxVarBytes,
size_t numVarBytes)
619 writeVarNum(value,
false,
false, maxVarBytes, numVarBytes);
622inline void BitStreamWriter::writeVarNum(
623 uint64_t value,
bool hasSign,
bool isNegative,
size_t maxVarBytes,
size_t numVarBytes)
625 static const std::array<uint64_t, 8> bitMasks = {0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
626 const bool hasMaxByteRange = (numVarBytes == maxVarBytes);
628 for (
size_t i = 0; i < numVarBytes; i++)
632 const bool hasNextByte = (i < numVarBytes - 1);
633 const bool hasSignBit = (hasSign && i == 0);
645 const uint8_t add =
static_cast<uint8_t
>(0x01U <<
numBits);
646 byte =
static_cast<uint8_t
>(
byte | add);
650 if (!hasMaxByteRange)
656 const size_t shiftBits = (numVarBytes - (i + 1)) * 7 + ((hasMaxByteRange && hasNextByte) ? 1 : 0);
657 const uint8_t add =
static_cast<uint8_t
>((value >> shiftBits) & bitMasks[numBits - 1U]);
658 byte =
static_cast<uint8_t
>(
byte | add);
659 writeUnsignedBits32Impl(
byte, 8);
663inline void BitStreamWriter::throwInsufficientCapacityException()
const
665 throw InsufficientCapacityException(
"BitStreamWriter: Reached end of bit buffer!");
668inline void BitStreamWriter::checkCapacity(
size_t bitSize)
const
670 if (bitSize > m_bufferBitSize)
672 throwInsufficientCapacityException();
~InsufficientCapacityException() override
void writeBool(Bool data)
void writeVarUInt16(VarUInt16 data)
Span< const uint8_t > getBuffer() const
void writeVarInt32(VarInt32 data)
void writeFloat64(Float64 data)
void writeVarUInt64(VarUInt64 data)
BitPosType getBitPosition() const
void writeVarInt16(VarInt16 data)
const uint8_t * getWriteBuffer() const
void writeSignedBits64(int64_t data, uint8_t numBits=64)
void writeVarInt64(VarInt64 data)
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)
BitStreamWriter(uint8_t *buffer, size_t bufferBitSize, BitsTag)
void writeString(std::string_view data)
void writeFloat16(Float16 data)
void writeVarUInt32(VarUInt32 data)
void writeVarSize(VarSize data)
bool hasWriteBuffer() const
void writeVarInt(VarInt data)
void setBitPosition(BitPosType position)
void alignTo(size_t alignment)
constexpr size_type size() const noexcept
constexpr pointer data() const noexcept
constexpr iterator end() const noexcept
constexpr iterator begin() const noexcept
uint8_t numBits(uint64_t numValues)
uint64_t convertDoubleToUInt64(double float64)
detail::VarIntWrapper< uint64_t, detail::VarIntType::VAR > VarUInt
detail::FloatWrapper< float, detail::FloatType::FLOAT16 > Float16
detail::FloatWrapper< float, detail::FloatType::FLOAT32 > Float32
detail::VarIntWrapper< int32_t, detail::VarIntType::VAR32 > VarInt32
uint32_t convertFloatToUInt32(float float32)
detail::VarIntWrapper< uint16_t, detail::VarIntType::VAR16 > VarUInt16
detail::VarIntWrapper< uint64_t, detail::VarIntType::VAR64 > VarUInt64
uint16_t convertFloatToUInt16(float float32)
uint32_t convertSizeToUInt32(size_t value)
detail::VarIntWrapper< int16_t, detail::VarIntType::VAR16 > VarInt16
detail::FloatWrapper< double, detail::FloatType::FLOAT64 > Float64
detail::VarIntWrapper< uint32_t, detail::VarIntType::VAR32 > VarUInt32
detail::VarIntWrapper< int64_t, detail::VarIntType::VAR > VarInt
detail::VarIntWrapper< int64_t, detail::VarIntType::VAR64 > VarInt64
detail::VarIntWrapper< uint32_t, detail::VarIntType::VARSIZE > VarSize