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,
320 m_buffer(buffer, (bufferBitSize + 7) / 8),
322 m_bufferBitSize(bufferBitSize)
332 m_bufferBitSize(buffer.size() * 8)
338 m_bufferBitSize(bufferBitSize)
340 if (buffer.
size() < (bufferBitSize + 7) / 8)
343 << buffer.
size() <<
"' < '" << (bufferBitSize + 7) / 8 <<
"')!";
352 <<
numBits <<
"-bits value '" << data <<
"' failed!";
355 writeUnsignedBits32Impl(data,
numBits);
363 <<
numBits <<
"-bits value '" << data <<
"' failed!";
366 writeUnsignedBits64Impl(data,
numBits);
372 data > MAX_I32_VALUES[
numBits])
375 <<
numBits <<
"-bits value '" << data <<
"' failed!";
378 writeUnsignedBits32Impl(
static_cast<uint32_t
>(data) & MAX_U32_VALUES[
numBits],
numBits);
384 data > MAX_I64_VALUES[
numBits])
387 <<
numBits <<
"-bits value '" << data <<
"' failed!";
390 writeUnsignedBits64Impl(
static_cast<uint64_t
>(data) & MAX_U64_VALUES[
numBits],
numBits);
395 writeUnsignedBits32Impl((data ? 1 : 0), 1);
400 writeSignedVarNum(data, 2, detail::bitSizeOf(data) / 8);
405 writeSignedVarNum(data, 4, detail::bitSizeOf(data) / 8);
410 writeSignedVarNum(data, 8, detail::bitSizeOf(data) / 8);
415 if (data == INT64_MIN)
417 writeUnsignedBits32Impl(0x80, 8);
421 writeSignedVarNum(data, 9, detail::bitSizeOf(data) / 8);
427 writeUnsignedVarNum(data, 2, detail::bitSizeOf(data) / 8);
432 writeUnsignedVarNum(data, 4, detail::bitSizeOf(data) / 8);
437 writeUnsignedVarNum(data, 8, detail::bitSizeOf(data) / 8);
442 writeUnsignedVarNum(data, 9, detail::bitSizeOf(data) / 8);
447 writeUnsignedVarNum(data, 5, detail::bitSizeOf(data) / 8);
453 writeUnsignedBits32Impl(halfPrecisionFloat, 16);
459 writeUnsignedBits32Impl(singlePrecisionFloat, 32);
474 if ((beginBitPosition & 0x07U) != 0)
477 for (
size_t i = 0; i < len; ++i)
479 writeUnsignedBits32Impl(data[i], 8);
488 (void)std::copy(data.
begin(), data.
end(), m_buffer.
begin() + beginBitPosition / 8);
499 if ((beginBitPosition & 0x07U) != 0)
502 for (
size_t i = 0; i < len; ++i)
505 writeUnsignedBits32(
static_cast<uint8_t
>(std::char_traits<char>::to_int_type(data[i])), 8);
514 (void)std::copy(data.begin(), data.begin() + len, m_buffer.
data() + beginBitPosition / 8);
523 checkCapacity(position);
526 m_bitIndex = position;
534 const uint8_t skip =
static_cast<uint8_t
>(alignment - offset);
541 return m_buffer.
data();
549 void BitStreamWriter::writeUnsignedBits32Impl(uint32_t data, uint8_t
numBits)
557 checkCapacity(m_bitIndex +
numBits);
560 const uint8_t bitsUsed = m_bitIndex & 0x07U;
561 uint8_t bitsFree =
static_cast<uint8_t
>(8 - bitsUsed);
562 size_t byteIndex = m_bitIndex / 8;
564 if (restNumBits > bitsFree)
567 const uint8_t shiftNum =
static_cast<uint8_t
>(restNumBits - bitsFree);
568 const uint8_t maskedByte =
static_cast<uint8_t
>(m_buffer[byteIndex] & ~(0xFFU >> bitsUsed));
569 m_buffer[byteIndex++] =
static_cast<uint8_t
>(maskedByte | (data >> shiftNum));
570 restNumBits =
static_cast<uint8_t
>(restNumBits - bitsFree);
573 while (restNumBits >= 8)
575 restNumBits =
static_cast<uint8_t
>(restNumBits - 8);
576 m_buffer[byteIndex++] =
static_cast<uint8_t
>((data >> restNumBits) & MAX_U32_VALUES[8]);
586 const uint8_t shiftNum =
static_cast<uint8_t
>(bitsFree - restNumBits);
587 const uint32_t mask = MAX_U32_VALUES[restNumBits];
588 const uint8_t maskedByte =
589 m_buffer[byteIndex] &
static_cast<uint8_t
>(~static_cast<uint8_t>(mask << shiftNum));
590 m_buffer[byteIndex] =
static_cast<uint8_t
>(maskedByte | ((data & mask) << shiftNum));
596 inline void BitStreamWriter::writeUnsignedBits64Impl(uint64_t data, uint8_t
numBits)
600 writeUnsignedBits32Impl(
static_cast<uint32_t
>(data),
numBits);
604 writeUnsignedBits32Impl(
static_cast<uint32_t
>(data >> 32U),
static_cast<uint8_t
>(
numBits - 32));
605 writeUnsignedBits32Impl(
static_cast<uint32_t
>(data), 32);
609 inline void BitStreamWriter::writeSignedVarNum(int64_t value,
size_t maxVarBytes,
size_t numVarBytes)
611 const uint64_t absValue =
static_cast<uint64_t
>(value < 0 ? -value : value);
612 writeVarNum(absValue,
true, value < 0, maxVarBytes, numVarBytes);
615 inline void BitStreamWriter::writeUnsignedVarNum(uint64_t value,
size_t maxVarBytes,
size_t numVarBytes)
617 writeVarNum(value,
false,
false, maxVarBytes, numVarBytes);
620 inline void BitStreamWriter::writeVarNum(
621 uint64_t value,
bool hasSign,
bool isNegative,
size_t maxVarBytes,
size_t numVarBytes)
623 static const std::array<uint64_t, 8> bitMasks = {0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
624 const bool hasMaxByteRange = (numVarBytes == maxVarBytes);
626 for (
size_t i = 0; i < numVarBytes; i++)
630 const bool hasNextByte = (i < numVarBytes - 1);
631 const bool hasSignBit = (hasSign && i == 0);
643 const uint8_t add =
static_cast<uint8_t
>(0x01U <<
numBits);
644 byte =
static_cast<uint8_t
>(
byte | add);
648 if (!hasMaxByteRange)
654 const size_t shiftBits = (numVarBytes - (i + 1)) * 7 + ((hasMaxByteRange && hasNextByte) ? 1 : 0);
655 const uint8_t add =
static_cast<uint8_t
>((value >> shiftBits) & bitMasks[
numBits - 1U]);
656 byte =
static_cast<uint8_t
>(
byte | add);
657 writeUnsignedBits32Impl(
byte, 8);
661 inline void BitStreamWriter::throwInsufficientCapacityException()
const
663 throw InsufficientCapacityException(
"BitStreamWriter: Reached end of bit buffer!");
666 inline void BitStreamWriter::checkCapacity(
size_t bitSize)
const
668 if (bitSize > m_bufferBitSize)
670 throwInsufficientCapacityException();
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