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 <<
"')!";
356 if (
numBits >
sizeof(uint32_t) * 8 || data > MAX_U32_VALUES[
numBits])
359 <<
numBits <<
"-bits value '" << data <<
"' failed!";
362 writeUnsignedBits(data,
numBits);
367 if (
numBits >
sizeof(uint64_t) * 8 || data > MAX_U64_VALUES[
numBits])
370 <<
numBits <<
"-bits value '" << data <<
"' failed!";
373 writeUnsignedBits64(data,
numBits);
378 if (
numBits >
sizeof(int32_t) * 8 || data < MIN_I32_VALUES[
numBits] || data > MAX_I32_VALUES[
numBits])
381 <<
numBits <<
"-bits value '" << data <<
"' failed!";
384 writeUnsignedBits(
static_cast<uint32_t
>(data) & MAX_U32_VALUES[
numBits],
numBits);
389 if (
numBits >
sizeof(int64_t) * 8 || data < MIN_I64_VALUES[
numBits] || data > MAX_I64_VALUES[
numBits])
392 <<
numBits <<
"-bits value '" << data <<
"' failed!";
395 writeUnsignedBits64(
static_cast<uint64_t
>(data) & MAX_U64_VALUES[
numBits],
numBits);
430 if (data == INT64_MIN)
449 writeUnsignedBits(halfPrecisionFloat, 16);
455 writeUnsignedBits(singlePrecisionFloat, 32);
461 writeUnsignedBits64(doublePrecisionFloat, 64);
466 const size_t len = data.
size();
470 if ((beginBitPosition & 0x07U) != 0)
473 for (
size_t i = 0; i < len; ++i)
481 std::copy(data.
begin(), data.
end(), m_buffer.
begin() + beginBitPosition / 8);
487 const size_t len = data.
size();
491 if ((beginBitPosition & 0x07U) != 0)
494 for (
size_t i = 0; i < len; ++i)
495 writeBits(
static_cast<uint8_t
>(data[i]), 8);
502 std::copy(data.
begin(), data.
begin() + len, m_buffer.
data() + beginBitPosition / 8);
514 checkCapacity(position);
516 m_bitIndex = position;
524 const uint8_t skip =
static_cast<uint8_t
>(alignment - offset);
531 return m_buffer.
data();
539 void BitStreamWriter::writeUnsignedBits(uint32_t data, uint8_t
numBits)
547 checkCapacity(m_bitIndex +
numBits);
550 const uint8_t bitsUsed = m_bitIndex & 0x07U;
551 uint8_t bitsFree =
static_cast<uint8_t
>(8 - bitsUsed);
552 size_t byteIndex = m_bitIndex / 8;
554 if (restNumBits > bitsFree)
557 const uint8_t shiftNum =
static_cast<uint8_t
>(restNumBits - bitsFree);
558 const uint8_t maskedByte =
static_cast<uint8_t
>(m_buffer[byteIndex] & ~(0xFFU >> bitsUsed));
559 m_buffer[byteIndex++] =
static_cast<uint8_t
>(maskedByte | (data >> shiftNum));
560 restNumBits =
static_cast<uint8_t
>(restNumBits - bitsFree);
563 while (restNumBits >= 8)
565 restNumBits =
static_cast<uint8_t
>(restNumBits - 8);
566 m_buffer[byteIndex++] =
static_cast<uint8_t
>((data >> restNumBits) & MAX_U32_VALUES[8]);
576 const uint8_t shiftNum =
static_cast<uint8_t
>(bitsFree - restNumBits);
577 const uint32_t mask = MAX_U32_VALUES[restNumBits];
578 const uint8_t maskedByte =
579 m_buffer[byteIndex] &
static_cast<uint8_t
>(~static_cast<uint8_t>(mask << shiftNum));
580 m_buffer[byteIndex] =
static_cast<uint8_t
>(maskedByte | ((data & mask) << shiftNum));
586 inline void BitStreamWriter::writeUnsignedBits64(uint64_t data, uint8_t
numBits)
590 writeUnsignedBits(
static_cast<uint32_t
>(data),
numBits);
594 writeUnsignedBits(
static_cast<uint32_t
>(data >> 32U),
static_cast<uint8_t
>(
numBits - 32));
595 writeUnsignedBits(
static_cast<uint32_t
>(data), 32);
599 inline void BitStreamWriter::writeSignedVarNum(int64_t value,
size_t maxVarBytes,
size_t numVarBytes)
601 const uint64_t absValue =
static_cast<uint64_t
>(value < 0 ? -value : value);
602 writeVarNum(absValue,
true, value < 0, maxVarBytes, numVarBytes);
605 inline void BitStreamWriter::writeUnsignedVarNum(uint64_t value,
size_t maxVarBytes,
size_t numVarBytes)
607 writeVarNum(value,
false,
false, maxVarBytes, numVarBytes);
610 inline void BitStreamWriter::writeVarNum(
611 uint64_t value,
bool hasSign,
bool isNegative,
size_t maxVarBytes,
size_t numVarBytes)
613 static const std::array<uint64_t, 8> bitMasks = {0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
614 const bool hasMaxByteRange = (numVarBytes == maxVarBytes);
616 for (
size_t i = 0; i < numVarBytes; i++)
620 const bool hasNextByte = (i < numVarBytes - 1);
621 const bool hasSignBit = (hasSign && i == 0);
631 const uint8_t add =
static_cast<uint8_t
>(0x01U <<
numBits);
632 byte =
static_cast<uint8_t
>(
byte | add);
636 if (!hasMaxByteRange)
640 const size_t shiftBits = (numVarBytes - (i + 1)) * 7 + ((hasMaxByteRange && hasNextByte) ? 1 : 0);
641 const uint8_t add =
static_cast<uint8_t
>((value >> shiftBits) & bitMasks[
numBits - 1]);
642 byte =
static_cast<uint8_t
>(
byte | add);
643 writeUnsignedBits(
byte, 8);
647 inline void BitStreamWriter::throwInsufficientCapacityException()
const
649 throw InsufficientCapacityException(
"BitStreamWriter: Reached end of bit buffer!");
652 inline void BitStreamWriter::checkCapacity(
size_t bitSize)
const
654 if (bitSize > m_bufferBitSize)
655 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)