15 static const std::array<uint32_t, 33> MAX_U32_VALUES = {
51 static const std::array<int32_t, 33> MIN_I32_VALUES = {
87 static const std::array<int32_t, 33> MAX_I32_VALUES = {
123 static const std::array<uint64_t, 65> MAX_U64_VALUES = {
173 0x0001ffffffffffffULL,
174 0x0003ffffffffffffULL,
175 0x0007ffffffffffffULL,
176 0x000fffffffffffffULL,
177 0x001fffffffffffffULL,
178 0x003fffffffffffffULL,
179 0x007fffffffffffffULL,
180 0x00ffffffffffffffULL,
181 0x01ffffffffffffffULL,
182 0x03ffffffffffffffULL,
183 0x07ffffffffffffffULL,
184 0x0fffffffffffffffULL,
185 0x1fffffffffffffffULL,
186 0x3fffffffffffffffULL,
187 0x7fffffffffffffffULL,
188 0xffffffffffffffffULL,
191 static const std::array<int64_t, 65> MIN_I64_VALUES = {
241 -0x0001000000000000LL,
242 -0x0002000000000000LL,
243 -0x0004000000000000LL,
244 -0x0008000000000000LL,
245 -0x0010000000000000LL,
246 -0x0020000000000000LL,
247 -0x0040000000000000LL,
248 -0x0080000000000000LL,
249 -0x0100000000000000LL,
250 -0x0200000000000000LL,
251 -0x0400000000000000LL,
252 -0x0800000000000000LL,
253 -0x1000000000000000LL,
254 -0x2000000000000000LL,
255 -0x4000000000000000LL,
259 static const std::array<int64_t, 65> MAX_I64_VALUES = {
309 0x0000ffffffffffffLL,
310 0x0001ffffffffffffLL,
311 0x0003ffffffffffffLL,
312 0x0007ffffffffffffLL,
313 0x000fffffffffffffLL,
314 0x001fffffffffffffLL,
315 0x003fffffffffffffLL,
316 0x007fffffffffffffLL,
317 0x00ffffffffffffffLL,
318 0x01ffffffffffffffLL,
319 0x03ffffffffffffffLL,
320 0x07ffffffffffffffLL,
321 0x0fffffffffffffffLL,
322 0x1fffffffffffffffLL,
323 0x3fffffffffffffffLL,
324 0x7fffffffffffffffLL,
328 m_buffer(buffer, (bufferBitSize + 7) / 8),
330 m_bufferBitSize(bufferBitSize)
340 m_bufferBitSize(buffer.size() * 8)
346 m_bufferBitSize(bufferBitSize)
348 if (buffer.
size() < (bufferBitSize + 7) / 8)
351 << buffer.
size() <<
"' < '" << (bufferBitSize + 7) / 8 <<
"')!";
360 <<
numBits <<
"-bits value '" << data <<
"' failed!";
363 writeUnsignedBits(data,
numBits);
371 <<
numBits <<
"-bits value '" << data <<
"' failed!";
374 writeUnsignedBits64(data,
numBits);
380 data > MAX_I32_VALUES[
numBits])
383 <<
numBits <<
"-bits value '" << data <<
"' failed!";
386 writeUnsignedBits(
static_cast<uint32_t
>(data) & MAX_U32_VALUES[
numBits],
numBits);
392 data > MAX_I64_VALUES[
numBits])
395 <<
numBits <<
"-bits value '" << data <<
"' failed!";
398 writeUnsignedBits64(
static_cast<uint64_t
>(data) & MAX_U64_VALUES[
numBits],
numBits);
433 if (data == INT64_MIN)
456 writeUnsignedBits(halfPrecisionFloat, 16);
462 writeUnsignedBits(singlePrecisionFloat, 32);
468 writeUnsignedBits64(doublePrecisionFloat, 64);
473 const size_t len = data.
size();
477 if ((beginBitPosition & 0x07U) != 0)
480 for (
size_t i = 0; i < len; ++i)
491 (void)std::copy(data.
begin(), data.
end(), m_buffer.
begin() + beginBitPosition / 8);
498 const size_t len = data.
size();
502 if ((beginBitPosition & 0x07U) != 0)
505 for (
size_t i = 0; i < len; ++i)
507 writeBits(
static_cast<uint32_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);
530 checkCapacity(position);
533 m_bitIndex = position;
541 const uint8_t skip =
static_cast<uint8_t
>(alignment - offset);
548 return m_buffer.
data();
556 void BitStreamWriter::writeUnsignedBits(uint32_t data, uint8_t
numBits)
564 checkCapacity(m_bitIndex +
numBits);
567 const uint8_t bitsUsed = m_bitIndex & 0x07U;
568 uint8_t bitsFree =
static_cast<uint8_t
>(8 - bitsUsed);
569 size_t byteIndex = m_bitIndex / 8;
571 if (restNumBits > bitsFree)
574 const uint8_t shiftNum =
static_cast<uint8_t
>(restNumBits - bitsFree);
575 const uint8_t maskedByte =
static_cast<uint8_t
>(m_buffer[byteIndex] & ~(0xFFU >> bitsUsed));
576 m_buffer[byteIndex++] =
static_cast<uint8_t
>(maskedByte | (data >> shiftNum));
577 restNumBits =
static_cast<uint8_t
>(restNumBits - bitsFree);
580 while (restNumBits >= 8)
582 restNumBits =
static_cast<uint8_t
>(restNumBits - 8);
583 m_buffer[byteIndex++] =
static_cast<uint8_t
>((data >> restNumBits) & MAX_U32_VALUES[8]);
593 const uint8_t shiftNum =
static_cast<uint8_t
>(bitsFree - restNumBits);
594 const uint32_t mask = MAX_U32_VALUES[restNumBits];
595 const uint8_t maskedByte =
596 m_buffer[byteIndex] &
static_cast<uint8_t
>(~static_cast<uint8_t>(mask << shiftNum));
597 m_buffer[byteIndex] =
static_cast<uint8_t
>(maskedByte | ((data & mask) << shiftNum));
603 inline void BitStreamWriter::writeUnsignedBits64(uint64_t data, uint8_t
numBits)
607 writeUnsignedBits(
static_cast<uint32_t
>(data),
numBits);
611 writeUnsignedBits(
static_cast<uint32_t
>(data >> 32U),
static_cast<uint8_t
>(
numBits - 32));
612 writeUnsignedBits(
static_cast<uint32_t
>(data), 32);
616 inline void BitStreamWriter::writeSignedVarNum(int64_t value,
size_t maxVarBytes,
size_t numVarBytes)
618 const uint64_t absValue =
static_cast<uint64_t
>(value < 0 ? -value : value);
619 writeVarNum(absValue,
true, value < 0, maxVarBytes, numVarBytes);
622 inline void BitStreamWriter::writeUnsignedVarNum(uint64_t value,
size_t maxVarBytes,
size_t numVarBytes)
624 writeVarNum(value,
false,
false, maxVarBytes, numVarBytes);
627 inline void BitStreamWriter::writeVarNum(
628 uint64_t value,
bool hasSign,
bool isNegative,
size_t maxVarBytes,
size_t numVarBytes)
630 static const std::array<uint64_t, 8> bitMasks = {0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
631 const bool hasMaxByteRange = (numVarBytes == maxVarBytes);
633 for (
size_t i = 0; i < numVarBytes; i++)
637 const bool hasNextByte = (i < numVarBytes - 1);
638 const bool hasSignBit = (hasSign && i == 0);
650 const uint8_t add =
static_cast<uint8_t
>(0x01U <<
numBits);
651 byte =
static_cast<uint8_t
>(
byte | add);
655 if (!hasMaxByteRange)
661 const size_t shiftBits = (numVarBytes - (i + 1)) * 7 + ((hasMaxByteRange && hasNextByte) ? 1 : 0);
662 const uint8_t add =
static_cast<uint8_t
>((value >> shiftBits) & bitMasks[
numBits - 1U]);
663 byte =
static_cast<uint8_t
>(
byte | add);
664 writeUnsignedBits(
byte, 8);
668 inline void BitStreamWriter::throwInsufficientCapacityException()
const
670 throw InsufficientCapacityException(
"BitStreamWriter: Reached end of bit buffer!");
673 inline void BitStreamWriter::checkCapacity(
size_t bitSize)
const
675 if (bitSize > m_bufferBitSize)
677 throwInsufficientCapacityException();
constexpr size_type size() const noexcept
constexpr const_iterator begin() const noexcept
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)
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)
void writeVarInt(int64_t data)
void writeFloat16(float data)
void writeBits64(uint64_t data, uint8_t numBits=64)
void writeBytes(Span< const uint8_t > data)
void writeBool(bool data)
BitStreamWriter(uint8_t *buffer, size_t bufferBitSize, BitsTag)
void writeBits(uint32_t data, uint8_t numBits=32)
bool hasWriteBuffer() const
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)
size_t bitSizeOfVarInt32(int32_t value)
uint64_t convertDoubleToUInt64(double float64)
uint32_t convertFloatToUInt32(float float32)
size_t bitSizeOfVarUInt32(uint32_t value)
size_t bitSizeOfVarInt64(int64_t value)
uint16_t convertFloatToUInt16(float float32)
size_t bitSizeOfVarSize(uint32_t value)
size_t bitSizeOfVarUInt64(uint64_t value)
uint32_t convertSizeToUInt32(size_t value)
size_t bitSizeOfVarInt16(int16_t value)
size_t bitSizeOfVarUInt(uint64_t value)
size_t bitSizeOfVarInt(int64_t value)
size_t bitSizeOfVarUInt16(uint16_t value)