14 static const std::array<uint32_t, 33> MAX_U32_VALUES =
17 0x0001U, 0x0003U, 0x0007U, 0x000fU,
18 0x001fU, 0x003fU, 0x007fU, 0x00ffU,
19 0x01ffU, 0x03ffU, 0x07ffU, 0x0fffU,
20 0x1fffU, 0x3fffU, 0x7fffU, 0xffffU,
21 0x0001ffffU, 0x0003ffffU, 0x0007ffffU, 0x000fffffU,
22 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
23 0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU,
24 0x1fffffffU, 0x3fffffffU, 0x7fffffffU, 0xffffffffU,
27 static const std::array<int32_t, 33> MIN_I32_VALUES =
30 -0x0001, -0x0002, -0x0004, -0x0008,
31 -0x0010, -0x0020, -0x0040, -0x0080,
32 -0x0100, -0x0200, -0x0400, -0x0800,
33 -0x1000, -0x2000, -0x4000, -0x8000,
34 -0x00010000, -0x00020000, -0x00040000, -0x00080000,
35 -0x00100000, -0x00200000, -0x00400000, -0x00800000,
36 -0x01000000, -0x02000000, -0x04000000, -0x08000000,
37 -0x10000000, -0x20000000, -0x40000000, INT32_MIN
40 static const std::array<int32_t, 33> MAX_I32_VALUES =
43 0x0000, 0x0001, 0x0003, 0x0007,
44 0x000f, 0x001f, 0x003f, 0x007f,
45 0x00ff, 0x01ff, 0x03ff, 0x07ff,
46 0x0fff, 0x1fff, 0x3fff, 0x7fff,
47 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
48 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
49 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
50 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff
53 static const std::array<uint64_t, 65> MAX_U64_VALUES =
56 0x0001ULL, 0x0003ULL, 0x0007ULL, 0x000fULL,
57 0x001fULL, 0x003fULL, 0x007fULL, 0x00ffULL,
58 0x01ffULL, 0x03ffULL, 0x07ffULL, 0x0fffULL,
59 0x1fffULL, 0x3fffULL, 0x7fffULL, 0xffffULL,
60 0x0001ffffULL, 0x0003ffffULL, 0x0007ffffULL, 0x000fffffULL,
61 0x001fffffULL, 0x003fffffULL, 0x007fffffULL, 0x00ffffffULL,
62 0x01ffffffULL, 0x03ffffffULL, 0x07ffffffULL, 0x0fffffffULL,
63 0x1fffffffULL, 0x3fffffffULL, 0x7fffffffULL, 0xffffffffULL,
64 0x0001ffffffffULL, 0x0003ffffffffULL, 0x0007ffffffffULL, 0x000fffffffffULL,
65 0x001fffffffffULL, 0x003fffffffffULL, 0x007fffffffffULL, 0x00ffffffffffULL,
66 0x01ffffffffffULL, 0x03ffffffffffULL, 0x07ffffffffffULL, 0x0fffffffffffULL,
67 0x1fffffffffffULL, 0x3fffffffffffULL, 0x7fffffffffffULL, 0xffffffffffffULL,
68 0x0001ffffffffffffULL, 0x0003ffffffffffffULL, 0x0007ffffffffffffULL, 0x000fffffffffffffULL,
69 0x001fffffffffffffULL, 0x003fffffffffffffULL, 0x007fffffffffffffULL, 0x00ffffffffffffffULL,
70 0x01ffffffffffffffULL, 0x03ffffffffffffffULL, 0x07ffffffffffffffULL, 0x0fffffffffffffffULL,
71 0x1fffffffffffffffULL, 0x3fffffffffffffffULL, 0x7fffffffffffffffULL, 0xffffffffffffffffULL
74 static const std::array<int64_t, 65> MIN_I64_VALUES =
77 -0x0001LL, -0x0002LL, -0x0004LL, -0x0008LL,
78 -0x0010LL, -0x0020LL, -0x0040LL, -0x0080LL,
79 -0x0100LL, -0x0200LL, -0x0400LL, -0x0800LL,
80 -0x1000LL, -0x2000LL, -0x4000LL, -0x8000LL,
81 -0x00010000LL, -0x00020000LL, -0x00040000LL, -0x00080000LL,
82 -0x00100000LL, -0x00200000LL, -0x00400000LL, -0x00800000LL,
83 -0x01000000LL, -0x02000000LL, -0x04000000LL, -0x08000000LL,
84 -0x10000000LL, -0x20000000LL, -0x40000000LL, -0x80000000LL,
85 -0x000100000000LL, -0x000200000000LL, -0x000400000000LL, -0x000800000000LL,
86 -0x001000000000LL, -0x002000000000LL, -0x004000000000LL, -0x008000000000LL,
87 -0x010000000000LL, -0x020000000000LL, -0x040000000000LL, -0x080000000000LL,
88 -0x100000000000LL, -0x200000000000LL, -0x400000000000LL, -0x800000000000LL,
89 -0x0001000000000000LL, -0x0002000000000000LL, -0x0004000000000000LL, -0x0008000000000000LL,
90 -0x0010000000000000LL, -0x0020000000000000LL, -0x0040000000000000LL, -0x0080000000000000LL,
91 -0x0100000000000000LL, -0x0200000000000000LL, -0x0400000000000000LL, -0x0800000000000000LL,
92 -0x1000000000000000LL, -0x2000000000000000LL, -0x4000000000000000LL, INT64_MIN
95 static const std::array<int64_t, 65> MAX_I64_VALUES =
98 0x0000LL, 0x0001LL, 0x0003LL, 0x0007LL,
99 0x000fLL, 0x001fLL, 0x003fLL, 0x007fLL,
100 0x00ffLL, 0x01ffLL, 0x03ffLL, 0x07ffLL,
101 0x0fffLL, 0x1fffLL, 0x3fffLL, 0x7fffLL,
102 0x0000ffffLL, 0x0001ffffLL, 0x0003ffffLL, 0x0007ffffLL,
103 0x000fffffLL, 0x001fffffLL, 0x003fffffLL, 0x007fffffLL,
104 0x00ffffffLL, 0x01ffffffLL, 0x03ffffffLL, 0x07ffffffLL,
105 0x0fffffffLL, 0x1fffffffLL, 0x3fffffffLL, 0x7fffffffLL,
106 0x0000ffffffffLL, 0x0001ffffffffLL, 0x0003ffffffffLL, 0x0007ffffffffLL,
107 0x000fffffffffLL, 0x001fffffffffLL, 0x003fffffffffLL, 0x007fffffffffLL,
108 0x00ffffffffffLL, 0x01ffffffffffLL, 0x03ffffffffffLL, 0x07ffffffffffLL,
109 0x0fffffffffffLL, 0x1fffffffffffLL, 0x3fffffffffffLL, 0x7fffffffffffLL,
110 0x0000ffffffffffffLL, 0x0001ffffffffffffLL, 0x0003ffffffffffffLL, 0x0007ffffffffffffLL,
111 0x000fffffffffffffLL, 0x001fffffffffffffLL, 0x003fffffffffffffLL, 0x007fffffffffffffLL,
112 0x00ffffffffffffffLL, 0x01ffffffffffffffLL, 0x03ffffffffffffffLL, 0x07ffffffffffffffLL,
113 0x0fffffffffffffffLL, 0x1fffffffffffffffLL, 0x3fffffffffffffffLL, 0x7fffffffffffffffLL
117 m_buffer(buffer, (bufferBitSize + 7) / 8),
119 m_bufferBitSize(bufferBitSize)
129 m_bufferBitSize(buffer.size() * 8)
135 m_bufferBitSize(bufferBitSize)
137 if (buffer.
size() < (bufferBitSize + 7) / 8)
140 "' < '" << (bufferBitSize + 7) / 8 <<
"')!";
146 if (numBits >
sizeof(uint32_t) * 8 || data > MAX_U32_VALUES[numBits])
148 throw CppRuntimeException(
"BitStreamWriter: Writing of ") << numBits <<
"-bits value '" << data <<
152 writeUnsignedBits(data, numBits);
157 if (numBits >
sizeof(uint64_t) * 8 || data > MAX_U64_VALUES[numBits])
159 throw CppRuntimeException(
"BitStreamWriter: Writing of ") << numBits <<
"-bits value '" << data <<
163 writeUnsignedBits64(data, numBits);
168 if (numBits >
sizeof(int32_t) * 8 || data < MIN_I32_VALUES[numBits] || data > MAX_I32_VALUES[numBits])
170 throw CppRuntimeException(
"BitStreamWriter: Writing of ") << numBits <<
"-bits value '" << data <<
174 writeUnsignedBits(static_cast<uint32_t>(data) & MAX_U32_VALUES[numBits], numBits);
179 if (numBits >
sizeof(int64_t) * 8 || data < MIN_I64_VALUES[numBits] || data > MAX_I64_VALUES[numBits])
181 throw CppRuntimeException(
"BitStreamWriter: Writing of ") << numBits <<
"-bits value '" << data <<
185 writeUnsignedBits64(static_cast<uint64_t>(data) & MAX_U64_VALUES[numBits], numBits);
220 if (data == INT64_MIN)
239 writeUnsignedBits(halfPrecisionFloat, 16);
245 writeUnsignedBits(singlePrecisionFloat, 32);
251 writeUnsignedBits64(doublePrecisionFloat, 64);
256 const size_t len = data.
size();
260 if ((beginBitPosition & 0x07U) != 0)
263 for (
size_t i = 0; i < len; ++i)
271 std::copy(data.
begin(), data.
end(), m_buffer.
begin() + beginBitPosition / 8);
277 const size_t len = data.
size();
281 if ((beginBitPosition & 0x07U) != 0)
284 for (
size_t i = 0; i < len; ++i)
285 writeBits(static_cast<uint8_t>(data[i]), 8);
292 std::copy(data.
begin(), data.
begin() + len, m_buffer.
data() + beginBitPosition / 8);
304 checkCapacity(position);
306 m_bitIndex = position;
314 const uint8_t skip =
static_cast<uint8_t
>(alignment - offset);
321 return m_buffer.
data();
329 void BitStreamWriter::writeUnsignedBits(uint32_t data, uint8_t
numBits)
337 checkCapacity(m_bitIndex + numBits);
340 const uint8_t bitsUsed = m_bitIndex & 0x07U;
341 uint8_t bitsFree = 8 - bitsUsed;
342 size_t byteIndex = m_bitIndex / 8;
344 if (restNumBits > bitsFree)
347 const uint8_t shiftNum = restNumBits - bitsFree;
348 const uint8_t maskedByte = m_buffer[byteIndex] & ~(0xFFU >> bitsUsed);
349 m_buffer[byteIndex++] = maskedByte |
static_cast<uint8_t
>(data >> shiftNum);
350 restNumBits -= bitsFree;
353 while (restNumBits >= 8)
356 m_buffer[byteIndex++] =
static_cast<uint8_t
>((data >> restNumBits) & MAX_U32_VALUES[8]);
366 const uint8_t shiftNum = bitsFree - restNumBits;
367 const uint32_t mask = MAX_U32_VALUES[restNumBits];
368 const uint8_t maskedByte = m_buffer[byteIndex] &
369 static_cast<uint8_t
>(~static_cast<uint8_t>(mask << shiftNum));
370 m_buffer[byteIndex] = maskedByte |
static_cast<uint8_t
>((data & mask) << shiftNum);
376 inline void BitStreamWriter::writeUnsignedBits64(uint64_t data, uint8_t numBits)
380 writeUnsignedBits(static_cast<uint32_t>(data), numBits);
384 writeUnsignedBits(static_cast<uint32_t>(data >> 32U), numBits - 32);
385 writeUnsignedBits(static_cast<uint32_t>(data), 32);
389 inline void BitStreamWriter::writeSignedVarNum(int64_t value,
size_t maxVarBytes,
size_t numVarBytes)
391 const uint64_t absValue =
static_cast<uint64_t
>(value < 0 ? -value : value);
392 writeVarNum(absValue,
true, value < 0, maxVarBytes, numVarBytes);
395 inline void BitStreamWriter::writeUnsignedVarNum(uint64_t value,
size_t maxVarBytes,
size_t numVarBytes)
397 writeVarNum(value,
false,
false, maxVarBytes, numVarBytes);
400 inline void BitStreamWriter::writeVarNum(uint64_t value,
bool hasSign,
bool isNegative,
size_t maxVarBytes,
403 static const std::array<uint64_t, 8> bitMasks = { 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF };
404 const bool hasMaxByteRange = (numVarBytes == maxVarBytes);
406 for (
size_t i = 0; i < numVarBytes; i++)
410 const bool hasNextByte = (i < numVarBytes - 1);
411 const bool hasSignBit = (hasSign && i == 0);
425 if (!hasMaxByteRange)
429 const size_t shiftBits = (numVarBytes - (i + 1)) * 7 + ((hasMaxByteRange && hasNextByte) ? 1 : 0);
430 byte |=
static_cast<uint8_t
>((value >> shiftBits) & bitMasks[numBits - 1]);
431 writeUnsignedBits(byte, 8);
435 inline void BitStreamWriter::throwInsufficientCapacityException()
const 440 inline void BitStreamWriter::checkCapacity(
size_t bitSize)
const 442 if (bitSize > m_bufferBitSize)
443 throwInsufficientCapacityException();
void writeVarInt64(int64_t data)
void alignTo(size_t alignment)
void writeVarUInt16(uint16_t data)
constexpr size_type size() const noexcept
void writeBytes(Span< const uint8_t > data)
void writeFloat16(float data)
void writeVarUInt64(uint64_t data)
void writeVarInt16(int16_t data)
size_t bitSizeOfVarUInt64(uint64_t value)
uint8_t numBits(uint64_t numValues)
const uint8_t * getWriteBuffer() const
BitStreamWriter(uint8_t *buffer, size_t bufferBitSize, BitsTag)
void writeFloat32(float data)
void writeVarInt(int64_t data)
void writeVarInt32(int32_t data)
void writeVarUInt32(uint32_t data)
void writeString(StringView data)
void writeVarSize(uint32_t data)
void writeSignedBits(int32_t data, uint8_t numBits=32)
size_t bitSizeOfVarSize(uint32_t value)
size_t bitSizeOfVarInt64(int64_t value)
size_t bitSizeOfVarInt16(int16_t value)
uint32_t convertSizeToUInt32(size_t value)
bool hasWriteBuffer() const
size_t bitSizeOfVarUInt16(uint16_t value)
constexpr size_type size() const noexcept
Span< const uint8_t > getBuffer() const
void writeFloat64(double data)
void setBitPosition(BitPosType position)
size_t bitSizeOfVarUInt32(uint32_t value)
BitPosType getBitPosition() const
void writeBits(uint32_t data, uint8_t numBits=32)
void writeVarUInt(uint64_t data)
size_t bitSizeOfVarUInt(uint64_t value)
uint32_t convertFloatToUInt32(float float32)
size_t bitSizeOfVarInt(int64_t value)
constexpr pointer data() const noexcept
constexpr iterator begin() const noexcept
constexpr const_iterator begin() const noexcept
void writeBool(bool data)
constexpr iterator end() const noexcept
void writeSignedBits64(int64_t data, uint8_t numBits=64)
size_t bitSizeOfVarInt32(int32_t value)
uint64_t convertDoubleToUInt64(double float64)
void writeBits64(uint64_t data, uint8_t numBits=64)
uint16_t convertFloatToUInt16(float float32)