7 static const std::array<uint32_t, 33> MAX_U32_VALUES = {
43 static const std::array<int32_t, 33> MIN_I32_VALUES = {
79 static const std::array<int32_t, 33> MAX_I32_VALUES = {
115 static 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,
183 static 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,
251 static 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 <<
"')!";
354 <<
numBits <<
"-bits value '" << data <<
"' failed!";
357 writeUnsignedBits32Impl(data,
numBits);
365 <<
numBits <<
"-bits value '" << data <<
"' failed!";
368 writeUnsignedBits64Impl(data,
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);
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);
417 if (data == INT64_MIN)
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);
455 writeUnsignedBits32Impl(halfPrecisionFloat, 16);
461 writeUnsignedBits32Impl(singlePrecisionFloat, 32);
476 if ((beginBitPosition & 0x07U) != 0)
479 for (
size_t i = 0; i < len; ++i)
481 writeUnsignedBits32Impl(data[i], 8);
490 (void)std::copy(data.
begin(), data.
end(), m_buffer.
begin() + beginBitPosition / 8);
501 if ((beginBitPosition & 0x07U) != 0)
504 for (
size_t i = 0; i < len; ++i)
507 writeUnsignedBits32(
static_cast<uint8_t
>(std::char_traits<char>::to_int_type(data[i])), 8);
516 (void)std::copy(data.begin(), data.begin() + len, m_buffer.
data() + beginBitPosition / 8);
525 checkCapacity(position);
528 m_bitIndex = position;
536 const uint8_t skip =
static_cast<uint8_t
>(alignment - offset);
543 return m_buffer.
data();
551 void BitStreamWriter::writeUnsignedBits32Impl(uint32_t data, uint8_t
numBits)
559 checkCapacity(m_bitIndex +
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));
598 inline 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);
611 inline 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);
617 inline void BitStreamWriter::writeUnsignedVarNum(uint64_t value,
size_t maxVarBytes,
size_t numVarBytes)
619 writeVarNum(value,
false,
false, maxVarBytes, numVarBytes);
622 inline 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);
663 inline void BitStreamWriter::throwInsufficientCapacityException()
const
665 throw InsufficientCapacityException(
"BitStreamWriter: Reached end of bit buffer!");
668 inline 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