14 static const std::array<uint32_t, 33> MAX_U32_VALUES = {
50 static const std::array<int32_t, 33> MIN_I32_VALUES = {
86 static const std::array<int32_t, 33> MAX_I32_VALUES = {
122 static const std::array<uint64_t, 65> MAX_U64_VALUES = {
172 0x0001ffffffffffffULL,
173 0x0003ffffffffffffULL,
174 0x0007ffffffffffffULL,
175 0x000fffffffffffffULL,
176 0x001fffffffffffffULL,
177 0x003fffffffffffffULL,
178 0x007fffffffffffffULL,
179 0x00ffffffffffffffULL,
180 0x01ffffffffffffffULL,
181 0x03ffffffffffffffULL,
182 0x07ffffffffffffffULL,
183 0x0fffffffffffffffULL,
184 0x1fffffffffffffffULL,
185 0x3fffffffffffffffULL,
186 0x7fffffffffffffffULL,
187 0xffffffffffffffffULL,
190 static const std::array<int64_t, 65> MIN_I64_VALUES = {
240 -0x0001000000000000LL,
241 -0x0002000000000000LL,
242 -0x0004000000000000LL,
243 -0x0008000000000000LL,
244 -0x0010000000000000LL,
245 -0x0020000000000000LL,
246 -0x0040000000000000LL,
247 -0x0080000000000000LL,
248 -0x0100000000000000LL,
249 -0x0200000000000000LL,
250 -0x0400000000000000LL,
251 -0x0800000000000000LL,
252 -0x1000000000000000LL,
253 -0x2000000000000000LL,
254 -0x4000000000000000LL,
258 static const std::array<int64_t, 65> MAX_I64_VALUES = {
308 0x0000ffffffffffffLL,
309 0x0001ffffffffffffLL,
310 0x0003ffffffffffffLL,
311 0x0007ffffffffffffLL,
312 0x000fffffffffffffLL,
313 0x001fffffffffffffLL,
314 0x003fffffffffffffLL,
315 0x007fffffffffffffLL,
316 0x00ffffffffffffffLL,
317 0x01ffffffffffffffLL,
318 0x03ffffffffffffffLL,
319 0x07ffffffffffffffLL,
320 0x0fffffffffffffffLL,
321 0x1fffffffffffffffLL,
322 0x3fffffffffffffffLL,
323 0x7fffffffffffffffLL,
327 m_buffer(buffer, (bufferBitSize + 7) / 8),
329 m_bufferBitSize(bufferBitSize)
339 m_bufferBitSize(buffer.size() * 8)
345 m_bufferBitSize(bufferBitSize)
347 if (buffer.
size() < (bufferBitSize + 7) / 8)
350 << buffer.
size() <<
"' < '" << (bufferBitSize + 7) / 8 <<
"')!";
359 <<
numBits <<
"-bits value '" << data <<
"' failed!";
362 writeUnsignedBits(data,
numBits);
370 <<
numBits <<
"-bits value '" << data <<
"' failed!";
373 writeUnsignedBits64(data,
numBits);
379 data > MAX_I32_VALUES[
numBits])
382 <<
numBits <<
"-bits value '" << data <<
"' failed!";
385 writeUnsignedBits(
static_cast<uint32_t
>(data) & MAX_U32_VALUES[
numBits],
numBits);
391 data > MAX_I64_VALUES[
numBits])
394 <<
numBits <<
"-bits value '" << data <<
"' failed!";
397 writeUnsignedBits64(
static_cast<uint64_t
>(data) & MAX_U64_VALUES[
numBits],
numBits);
432 if (data == INT64_MIN)
455 writeUnsignedBits(halfPrecisionFloat, 16);
461 writeUnsignedBits(singlePrecisionFloat, 32);
467 writeUnsignedBits64(doublePrecisionFloat, 64);
472 const size_t len = data.
size();
476 if ((beginBitPosition & 0x07U) != 0)
479 for (
size_t i = 0; i < len; ++i)
490 std::copy(data.
begin(), data.
end(), m_buffer.
begin() + beginBitPosition / 8);
497 const size_t len = data.
size();
501 if ((beginBitPosition & 0x07U) != 0)
504 for (
size_t i = 0; i < len; ++i)
506 writeBits(
static_cast<uint8_t
>(data[i]), 8);
515 std::copy(data.
begin(), data.
begin() + len, m_buffer.
data() + beginBitPosition / 8);
529 checkCapacity(position);
532 m_bitIndex = position;
540 const uint8_t skip =
static_cast<uint8_t
>(alignment - offset);
547 return m_buffer.
data();
555 void BitStreamWriter::writeUnsignedBits(uint32_t data, uint8_t
numBits)
563 checkCapacity(m_bitIndex +
numBits);
566 const uint8_t bitsUsed = m_bitIndex & 0x07U;
567 uint8_t bitsFree =
static_cast<uint8_t
>(8 - bitsUsed);
568 size_t byteIndex = m_bitIndex / 8;
570 if (restNumBits > bitsFree)
573 const uint8_t shiftNum =
static_cast<uint8_t
>(restNumBits - bitsFree);
574 const uint8_t maskedByte =
static_cast<uint8_t
>(m_buffer[byteIndex] & ~(0xFFU >> bitsUsed));
575 m_buffer[byteIndex++] =
static_cast<uint8_t
>(maskedByte | (data >> shiftNum));
576 restNumBits =
static_cast<uint8_t
>(restNumBits - bitsFree);
579 while (restNumBits >= 8)
581 restNumBits =
static_cast<uint8_t
>(restNumBits - 8);
582 m_buffer[byteIndex++] =
static_cast<uint8_t
>((data >> restNumBits) & MAX_U32_VALUES[8]);
592 const uint8_t shiftNum =
static_cast<uint8_t
>(bitsFree - restNumBits);
593 const uint32_t mask = MAX_U32_VALUES[restNumBits];
594 const uint8_t maskedByte =
595 m_buffer[byteIndex] &
static_cast<uint8_t
>(~static_cast<uint8_t>(mask << shiftNum));
596 m_buffer[byteIndex] =
static_cast<uint8_t
>(maskedByte | ((data & mask) << shiftNum));
602 inline void BitStreamWriter::writeUnsignedBits64(uint64_t data, uint8_t
numBits)
606 writeUnsignedBits(
static_cast<uint32_t
>(data),
numBits);
610 writeUnsignedBits(
static_cast<uint32_t
>(data >> 32U),
static_cast<uint8_t
>(
numBits - 32));
611 writeUnsignedBits(
static_cast<uint32_t
>(data), 32);
615 inline void BitStreamWriter::writeSignedVarNum(int64_t value,
size_t maxVarBytes,
size_t numVarBytes)
617 const uint64_t absValue =
static_cast<uint64_t
>(value < 0 ? -value : value);
618 writeVarNum(absValue,
true, value < 0, maxVarBytes, numVarBytes);
621 inline void BitStreamWriter::writeUnsignedVarNum(uint64_t value,
size_t maxVarBytes,
size_t numVarBytes)
623 writeVarNum(value,
false,
false, maxVarBytes, numVarBytes);
626 inline void BitStreamWriter::writeVarNum(
627 uint64_t value,
bool hasSign,
bool isNegative,
size_t maxVarBytes,
size_t numVarBytes)
629 static const std::array<uint64_t, 8> bitMasks = {0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
630 const bool hasMaxByteRange = (numVarBytes == maxVarBytes);
632 for (
size_t i = 0; i < numVarBytes; i++)
636 const bool hasNextByte = (i < numVarBytes - 1);
637 const bool hasSignBit = (hasSign && i == 0);
649 const uint8_t add =
static_cast<uint8_t
>(0x01U <<
numBits);
650 byte =
static_cast<uint8_t
>(
byte | add);
654 if (!hasMaxByteRange)
660 const size_t shiftBits = (numVarBytes - (i + 1)) * 7 + ((hasMaxByteRange && hasNextByte) ? 1 : 0);
661 const uint8_t add =
static_cast<uint8_t
>((value >> shiftBits) & bitMasks[
numBits - 1U]);
662 byte =
static_cast<uint8_t
>(
byte | add);
663 writeUnsignedBits(
byte, 8);
667 inline void BitStreamWriter::throwInsufficientCapacityException()
const
669 throw InsufficientCapacityException(
"BitStreamWriter: Reached end of bit buffer!");
672 inline void BitStreamWriter::checkCapacity(
size_t bitSize)
const
674 if (bitSize > m_bufferBitSize)
676 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)