mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-26 01:31:06 +00:00
Remove unused bit stream methods. (#1807)
This CL deletes methods from bit stream which are never used and moves several to the anonymous namespace in the bit_stream test file.
This commit is contained in:
parent
e3ea909ebe
commit
508df9a387
@ -197,41 +197,6 @@ bool ReadVariableWidthSigned(BitReaderInterface* reader, T* val,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
size_t Log2U64(uint64_t val) {
|
|
||||||
size_t res = 0;
|
|
||||||
|
|
||||||
if (val & 0xFFFFFFFF00000000) {
|
|
||||||
val >>= 32;
|
|
||||||
res |= 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val & 0xFFFF0000) {
|
|
||||||
val >>= 16;
|
|
||||||
res |= 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val & 0xFF00) {
|
|
||||||
val >>= 8;
|
|
||||||
res |= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val & 0xF0) {
|
|
||||||
val >>= 4;
|
|
||||||
res |= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val & 0xC) {
|
|
||||||
val >>= 2;
|
|
||||||
res |= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val & 0x2) {
|
|
||||||
res |= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BitWriterInterface::WriteVariableWidthU64(uint64_t val,
|
void BitWriterInterface::WriteVariableWidthU64(uint64_t val,
|
||||||
size_t chunk_length) {
|
size_t chunk_length) {
|
||||||
WriteVariableWidthUnsigned(this, val, chunk_length);
|
WriteVariableWidthUnsigned(this, val, chunk_length);
|
||||||
@ -247,41 +212,11 @@ void BitWriterInterface::WriteVariableWidthU16(uint16_t val,
|
|||||||
WriteVariableWidthUnsigned(this, val, chunk_length);
|
WriteVariableWidthUnsigned(this, val, chunk_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitWriterInterface::WriteVariableWidthU8(uint8_t val,
|
|
||||||
size_t chunk_length) {
|
|
||||||
WriteVariableWidthUnsigned(this, val, chunk_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BitWriterInterface::WriteVariableWidthS64(int64_t val, size_t chunk_length,
|
void BitWriterInterface::WriteVariableWidthS64(int64_t val, size_t chunk_length,
|
||||||
size_t zigzag_exponent) {
|
size_t zigzag_exponent) {
|
||||||
WriteVariableWidthSigned(this, val, chunk_length, zigzag_exponent);
|
WriteVariableWidthSigned(this, val, chunk_length, zigzag_exponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitWriterInterface::WriteVariableWidthS32(int32_t val, size_t chunk_length,
|
|
||||||
size_t zigzag_exponent) {
|
|
||||||
WriteVariableWidthSigned(this, val, chunk_length, zigzag_exponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BitWriterInterface::WriteVariableWidthS16(int16_t val, size_t chunk_length,
|
|
||||||
size_t zigzag_exponent) {
|
|
||||||
WriteVariableWidthSigned(this, val, chunk_length, zigzag_exponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BitWriterInterface::WriteVariableWidthS8(int8_t val, size_t chunk_length,
|
|
||||||
size_t zigzag_exponent) {
|
|
||||||
WriteVariableWidthSigned(this, val, chunk_length, zigzag_exponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BitWriterInterface::WriteFixedWidth(uint64_t val, uint64_t max_val) {
|
|
||||||
if (val > max_val) {
|
|
||||||
assert(0 && "WriteFixedWidth: value too wide");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t num_bits = 1 + Log2U64(max_val);
|
|
||||||
WriteBits(val, num_bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
BitWriterWord64::BitWriterWord64(size_t reserve_bits) : end_(0) {
|
BitWriterWord64::BitWriterWord64(size_t reserve_bits) : end_(0) {
|
||||||
buffer_.reserve(NumBitsToNumWords<64>(reserve_bits));
|
buffer_.reserve(NumBitsToNumWords<64>(reserve_bits));
|
||||||
}
|
}
|
||||||
@ -340,36 +275,11 @@ bool BitReaderInterface::ReadVariableWidthU16(uint16_t* val,
|
|||||||
return ReadVariableWidthUnsigned(this, val, chunk_length);
|
return ReadVariableWidthUnsigned(this, val, chunk_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitReaderInterface::ReadVariableWidthU8(uint8_t* val,
|
|
||||||
size_t chunk_length) {
|
|
||||||
return ReadVariableWidthUnsigned(this, val, chunk_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BitReaderInterface::ReadVariableWidthS64(int64_t* val, size_t chunk_length,
|
bool BitReaderInterface::ReadVariableWidthS64(int64_t* val, size_t chunk_length,
|
||||||
size_t zigzag_exponent) {
|
size_t zigzag_exponent) {
|
||||||
return ReadVariableWidthSigned(this, val, chunk_length, zigzag_exponent);
|
return ReadVariableWidthSigned(this, val, chunk_length, zigzag_exponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitReaderInterface::ReadVariableWidthS32(int32_t* val, size_t chunk_length,
|
|
||||||
size_t zigzag_exponent) {
|
|
||||||
return ReadVariableWidthSigned(this, val, chunk_length, zigzag_exponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BitReaderInterface::ReadVariableWidthS16(int16_t* val, size_t chunk_length,
|
|
||||||
size_t zigzag_exponent) {
|
|
||||||
return ReadVariableWidthSigned(this, val, chunk_length, zigzag_exponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BitReaderInterface::ReadVariableWidthS8(int8_t* val, size_t chunk_length,
|
|
||||||
size_t zigzag_exponent) {
|
|
||||||
return ReadVariableWidthSigned(this, val, chunk_length, zigzag_exponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BitReaderInterface::ReadFixedWidth(uint64_t* val, uint64_t max_val) {
|
|
||||||
const size_t num_bits = 1 + Log2U64(max_val);
|
|
||||||
return ReadBits(val, num_bits) == num_bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
BitReaderWord64::BitReaderWord64(std::vector<uint64_t>&& buffer)
|
BitReaderWord64::BitReaderWord64(std::vector<uint64_t>&& buffer)
|
||||||
: buffer_(std::move(buffer)), pos_(0) {}
|
: buffer_(std::move(buffer)), pos_(0) {}
|
||||||
|
|
||||||
|
@ -29,9 +29,6 @@
|
|||||||
namespace spvtools {
|
namespace spvtools {
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
// Returns rounded down log2(val). log2(0) is considered 0.
|
|
||||||
size_t Log2U64(uint64_t val);
|
|
||||||
|
|
||||||
// Terminology:
|
// Terminology:
|
||||||
// Bits - usually used for a uint64 word, first bit is the lowest.
|
// Bits - usually used for a uint64 word, first bit is the lowest.
|
||||||
// Stream - std::string of '0' and '1', read left-to-right,
|
// Stream - std::string of '0' and '1', read left-to-right,
|
||||||
@ -54,33 +51,6 @@ inline T GetLowerBits(T in, size_t num_bits) {
|
|||||||
return sizeof(T) * 8 == num_bits ? in : in & T((T(1) << num_bits) - T(1));
|
return sizeof(T) * 8 == num_bits ? in : in & T((T(1) << num_bits) - T(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encodes signed integer as unsigned in zigzag order:
|
|
||||||
// 0 -> 0
|
|
||||||
// -1 -> 1
|
|
||||||
// 1 -> 2
|
|
||||||
// -2 -> 3
|
|
||||||
// 2 -> 4
|
|
||||||
// Motivation: -1 is 0xFF...FF what doesn't work very well with
|
|
||||||
// WriteVariableWidth which prefers to have as many 0 bits as possible.
|
|
||||||
inline uint64_t EncodeZigZag(int64_t val) { return (val << 1) ^ (val >> 63); }
|
|
||||||
|
|
||||||
// Decodes signed integer encoded with EncodeZigZag.
|
|
||||||
inline int64_t DecodeZigZag(uint64_t val) {
|
|
||||||
if (val & 1) {
|
|
||||||
// Negative.
|
|
||||||
// 1 -> -1
|
|
||||||
// 3 -> -2
|
|
||||||
// 5 -> -3
|
|
||||||
return -1 - (val >> 1);
|
|
||||||
} else {
|
|
||||||
// Non-negative.
|
|
||||||
// 0 -> 0
|
|
||||||
// 2 -> 1
|
|
||||||
// 4 -> 2
|
|
||||||
return val >> 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encodes signed integer as unsigned. This is a generalized version of
|
// Encodes signed integer as unsigned. This is a generalized version of
|
||||||
// EncodeZigZag, designed to favor small positive numbers.
|
// EncodeZigZag, designed to favor small positive numbers.
|
||||||
// Values are transformed in blocks of 2^|block_exponent|.
|
// Values are transformed in blocks of 2^|block_exponent|.
|
||||||
@ -113,111 +83,24 @@ inline int64_t DecodeZigZag(uint64_t val, size_t block_exponent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts |buffer| to a stream of '0' and '1'.
|
|
||||||
template <typename T>
|
|
||||||
std::string BufferToStream(const std::vector<T>& buffer) {
|
|
||||||
std::stringstream ss;
|
|
||||||
for (auto it = buffer.begin(); it != buffer.end(); ++it) {
|
|
||||||
std::string str = std::bitset<sizeof(T) * 8>(*it).to_string();
|
|
||||||
// Strings generated by std::bitset::to_string are read right to left.
|
|
||||||
// Reversing to left to right.
|
|
||||||
std::reverse(str.begin(), str.end());
|
|
||||||
ss << str;
|
|
||||||
}
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts a left-to-right input string of '0' and '1' to a buffer of |T|
|
|
||||||
// words.
|
|
||||||
template <typename T>
|
|
||||||
std::vector<T> StreamToBuffer(std::string str) {
|
|
||||||
// The input string is left-to-right, the input argument of std::bitset needs
|
|
||||||
// to right-to-left. Instead of reversing tokens, reverse the entire string
|
|
||||||
// and iterate tokens from end to begin.
|
|
||||||
std::reverse(str.begin(), str.end());
|
|
||||||
const int word_size = static_cast<int>(sizeof(T) * 8);
|
|
||||||
const int str_length = static_cast<int>(str.length());
|
|
||||||
std::vector<T> buffer;
|
|
||||||
buffer.reserve(NumBitsToNumWords<sizeof(T)>(str.length()));
|
|
||||||
for (int index = str_length - word_size; index >= 0; index -= word_size) {
|
|
||||||
buffer.push_back(static_cast<T>(
|
|
||||||
std::bitset<sizeof(T) * 8>(str, index, word_size).to_ullong()));
|
|
||||||
}
|
|
||||||
const size_t suffix_length = str.length() % word_size;
|
|
||||||
if (suffix_length != 0) {
|
|
||||||
buffer.push_back(static_cast<T>(
|
|
||||||
std::bitset<sizeof(T) * 8>(str, 0, suffix_length).to_ullong()));
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds '0' chars at the end of the string until the size is a multiple of N.
|
|
||||||
template <size_t N>
|
|
||||||
inline std::string PadToWord(std::string&& str) {
|
|
||||||
const size_t tail_length = str.size() % N;
|
|
||||||
if (tail_length != 0) str += std::string(N - tail_length, '0');
|
|
||||||
return std::move(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds '0' chars at the end of the string until the size is a multiple of N.
|
|
||||||
template <size_t N>
|
|
||||||
inline std::string PadToWord(const std::string& str) {
|
|
||||||
return PadToWord<N>(std::string(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts a left-to-right stream of bits to std::bitset.
|
|
||||||
template <size_t N>
|
|
||||||
inline std::bitset<N> StreamToBitset(std::string str) {
|
|
||||||
std::reverse(str.begin(), str.end());
|
|
||||||
return std::bitset<N>(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts first |num_bits| of std::bitset to a left-to-right stream of bits.
|
|
||||||
template <size_t N>
|
|
||||||
inline std::string BitsetToStream(const std::bitset<N>& bits,
|
|
||||||
size_t num_bits = N) {
|
|
||||||
std::string str = bits.to_string().substr(N - num_bits);
|
|
||||||
std::reverse(str.begin(), str.end());
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts a left-to-right stream of bits to uint64.
|
|
||||||
inline uint64_t StreamToBits(std::string str) {
|
|
||||||
std::reverse(str.begin(), str.end());
|
|
||||||
return std::bitset<64>(str).to_ullong();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts first |num_bits| stored in uint64 to a left-to-right stream of bits.
|
// Converts first |num_bits| stored in uint64 to a left-to-right stream of bits.
|
||||||
inline std::string BitsToStream(uint64_t bits, size_t num_bits = 64) {
|
inline std::string BitsToStream(uint64_t bits, size_t num_bits = 64) {
|
||||||
std::bitset<64> bitset(bits);
|
std::bitset<64> bitset(bits);
|
||||||
return BitsetToStream(bitset, num_bits);
|
std::string str = bitset.to_string().substr(64 - num_bits);
|
||||||
|
std::reverse(str.begin(), str.end());
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base class for writing sequences of bits.
|
// Base class for writing sequences of bits.
|
||||||
class BitWriterInterface {
|
class BitWriterInterface {
|
||||||
public:
|
public:
|
||||||
BitWriterInterface() {}
|
BitWriterInterface() = default;
|
||||||
virtual ~BitWriterInterface() {}
|
virtual ~BitWriterInterface() = default;
|
||||||
|
|
||||||
// Writes lower |num_bits| in |bits| to the stream.
|
// Writes lower |num_bits| in |bits| to the stream.
|
||||||
// |num_bits| must be no greater than 64.
|
// |num_bits| must be no greater than 64.
|
||||||
virtual void WriteBits(uint64_t bits, size_t num_bits) = 0;
|
virtual void WriteBits(uint64_t bits, size_t num_bits) = 0;
|
||||||
|
|
||||||
// Writes left-to-right string of '0' and '1' to stream.
|
|
||||||
// String length must be no greater than 64.
|
|
||||||
// Note: "01" will be writen as 0x2, not 0x1. The string doesn't represent
|
|
||||||
// numbers but a stream of bits in the order they come from encoder.
|
|
||||||
virtual void WriteStream(const std::string& bits) {
|
|
||||||
WriteBits(StreamToBits(bits), bits.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Writes lower |num_bits| in |bits| to the stream.
|
|
||||||
// |num_bits| must be no greater than 64.
|
|
||||||
template <size_t N>
|
|
||||||
void WriteBitset(const std::bitset<N>& bits, size_t num_bits = N) {
|
|
||||||
WriteBits(bits.to_ullong(), num_bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Writes bits from value of type |T| to the stream. No encoding is done.
|
// Writes bits from value of type |T| to the stream. No encoding is done.
|
||||||
// Always writes 8 * sizeof(T) bits.
|
// Always writes 8 * sizeof(T) bits.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -237,27 +120,8 @@ class BitWriterInterface {
|
|||||||
void WriteVariableWidthU64(uint64_t val, size_t chunk_length);
|
void WriteVariableWidthU64(uint64_t val, size_t chunk_length);
|
||||||
void WriteVariableWidthU32(uint32_t val, size_t chunk_length);
|
void WriteVariableWidthU32(uint32_t val, size_t chunk_length);
|
||||||
void WriteVariableWidthU16(uint16_t val, size_t chunk_length);
|
void WriteVariableWidthU16(uint16_t val, size_t chunk_length);
|
||||||
void WriteVariableWidthU8(uint8_t val, size_t chunk_length);
|
|
||||||
void WriteVariableWidthS64(int64_t val, size_t chunk_length,
|
void WriteVariableWidthS64(int64_t val, size_t chunk_length,
|
||||||
size_t zigzag_exponent);
|
size_t zigzag_exponent);
|
||||||
void WriteVariableWidthS32(int32_t val, size_t chunk_length,
|
|
||||||
size_t zigzag_exponent);
|
|
||||||
void WriteVariableWidthS16(int16_t val, size_t chunk_length,
|
|
||||||
size_t zigzag_exponent);
|
|
||||||
void WriteVariableWidthS8(int8_t val, size_t chunk_length,
|
|
||||||
size_t zigzag_exponent);
|
|
||||||
|
|
||||||
// Writes |val| using fixed bit width. Bit width is determined by |max_val|:
|
|
||||||
// max_val 0 -> bit width 1
|
|
||||||
// max_val 1 -> bit width 1
|
|
||||||
// max_val 2 -> bit width 2
|
|
||||||
// max_val 3 -> bit width 2
|
|
||||||
// max_val 4 -> bit width 3
|
|
||||||
// max_val 5 -> bit width 3
|
|
||||||
// max_val 8 -> bit width 4
|
|
||||||
// max_val n -> bit width 1 + floor(log2(n))
|
|
||||||
// |val| needs to be <= |max_val|.
|
|
||||||
void WriteFixedWidth(uint64_t val, uint64_t max_val);
|
|
||||||
|
|
||||||
// Returns number of bits written.
|
// Returns number of bits written.
|
||||||
virtual size_t GetNumBits() const = 0;
|
virtual size_t GetNumBits() const = 0;
|
||||||
@ -293,10 +157,6 @@ class BitWriterWord64 : public BitWriterInterface {
|
|||||||
return std::vector<uint8_t>(GetData(), GetData() + GetDataSizeBytes());
|
return std::vector<uint8_t>(GetData(), GetData() + GetDataSizeBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns written stream as std::string, padded with zeroes so that the
|
|
||||||
// length is a multiple of 64.
|
|
||||||
std::string GetStreamPadded64() const { return BufferToStream(buffer_); }
|
|
||||||
|
|
||||||
// Sets callback to emit bit sequences after every write.
|
// Sets callback to emit bit sequences after every write.
|
||||||
void SetCallback(std::function<void(const std::string&)> callback) {
|
void SetCallback(std::function<void(const std::string&)> callback) {
|
||||||
callback_ = callback;
|
callback_ = callback;
|
||||||
@ -328,27 +188,6 @@ class BitReaderInterface {
|
|||||||
// Returns number of read bits. |num_bits| must be no greater than 64.
|
// Returns number of read bits. |num_bits| must be no greater than 64.
|
||||||
virtual size_t ReadBits(uint64_t* bits, size_t num_bits) = 0;
|
virtual size_t ReadBits(uint64_t* bits, size_t num_bits) = 0;
|
||||||
|
|
||||||
// Reads |num_bits| from the stream, stores them in |bits|.
|
|
||||||
// Returns number of read bits. |num_bits| must be no greater than 64.
|
|
||||||
template <size_t N>
|
|
||||||
size_t ReadBitset(std::bitset<N>* bits, size_t num_bits = N) {
|
|
||||||
uint64_t val = 0;
|
|
||||||
size_t num_read = ReadBits(&val, num_bits);
|
|
||||||
if (num_read) {
|
|
||||||
*bits = std::bitset<N>(val);
|
|
||||||
}
|
|
||||||
return num_read;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reads |num_bits| from the stream, returns string in left-to-right order.
|
|
||||||
// The length of the returned string may be less than |num_bits| if end was
|
|
||||||
// reached.
|
|
||||||
std::string ReadStream(size_t num_bits) {
|
|
||||||
uint64_t bits = 0;
|
|
||||||
size_t num_read = ReadBits(&bits, num_bits);
|
|
||||||
return BitsToStream(bits, num_read);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reads 8 * sizeof(T) bits and stores them in |val|.
|
// Reads 8 * sizeof(T) bits and stores them in |val|.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool ReadUnencoded(T* val) {
|
bool ReadUnencoded(T* val) {
|
||||||
@ -383,19 +222,8 @@ class BitReaderInterface {
|
|||||||
bool ReadVariableWidthU64(uint64_t* val, size_t chunk_length);
|
bool ReadVariableWidthU64(uint64_t* val, size_t chunk_length);
|
||||||
bool ReadVariableWidthU32(uint32_t* val, size_t chunk_length);
|
bool ReadVariableWidthU32(uint32_t* val, size_t chunk_length);
|
||||||
bool ReadVariableWidthU16(uint16_t* val, size_t chunk_length);
|
bool ReadVariableWidthU16(uint16_t* val, size_t chunk_length);
|
||||||
bool ReadVariableWidthU8(uint8_t* val, size_t chunk_length);
|
|
||||||
bool ReadVariableWidthS64(int64_t* val, size_t chunk_length,
|
bool ReadVariableWidthS64(int64_t* val, size_t chunk_length,
|
||||||
size_t zigzag_exponent);
|
size_t zigzag_exponent);
|
||||||
bool ReadVariableWidthS32(int32_t* val, size_t chunk_length,
|
|
||||||
size_t zigzag_exponent);
|
|
||||||
bool ReadVariableWidthS16(int16_t* val, size_t chunk_length,
|
|
||||||
size_t zigzag_exponent);
|
|
||||||
bool ReadVariableWidthS8(int8_t* val, size_t chunk_length,
|
|
||||||
size_t zigzag_exponent);
|
|
||||||
|
|
||||||
// Reads value written by WriteFixedWidth (|max_val| needs to be the same).
|
|
||||||
// Returns true on success, false if the bit stream ends prematurely.
|
|
||||||
bool ReadFixedWidth(uint64_t* val, uint64_t max_val);
|
|
||||||
|
|
||||||
BitReaderInterface(const BitReaderInterface&) = delete;
|
BitReaderInterface(const BitReaderInterface&) = delete;
|
||||||
BitReaderInterface& operator=(const BitReaderInterface&) = delete;
|
BitReaderInterface& operator=(const BitReaderInterface&) = delete;
|
||||||
|
@ -25,12 +25,75 @@ namespace spvtools {
|
|||||||
namespace utils {
|
namespace utils {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
// Converts |buffer| to a stream of '0' and '1'.
|
||||||
|
template <typename T>
|
||||||
|
std::string BufferToStream(const std::vector<T>& buffer) {
|
||||||
|
std::stringstream ss;
|
||||||
|
for (auto it = buffer.begin(); it != buffer.end(); ++it) {
|
||||||
|
std::string str = std::bitset<sizeof(T) * 8>(*it).to_string();
|
||||||
|
// Strings generated by std::bitset::to_string are read right to left.
|
||||||
|
// Reversing to left to right.
|
||||||
|
std::reverse(str.begin(), str.end());
|
||||||
|
ss << str;
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts a left-to-right input string of '0' and '1' to a buffer of |T|
|
||||||
|
// words.
|
||||||
|
template <typename T>
|
||||||
|
std::vector<T> StreamToBuffer(std::string str) {
|
||||||
|
// The input string is left-to-right, the input argument of std::bitset needs
|
||||||
|
// to right-to-left. Instead of reversing tokens, reverse the entire string
|
||||||
|
// and iterate tokens from end to begin.
|
||||||
|
std::reverse(str.begin(), str.end());
|
||||||
|
const int word_size = static_cast<int>(sizeof(T) * 8);
|
||||||
|
const int str_length = static_cast<int>(str.length());
|
||||||
|
std::vector<T> buffer;
|
||||||
|
buffer.reserve(NumBitsToNumWords<sizeof(T)>(str.length()));
|
||||||
|
for (int index = str_length - word_size; index >= 0; index -= word_size) {
|
||||||
|
buffer.push_back(static_cast<T>(
|
||||||
|
std::bitset<sizeof(T) * 8>(str, index, word_size).to_ullong()));
|
||||||
|
}
|
||||||
|
const size_t suffix_length = str.length() % word_size;
|
||||||
|
if (suffix_length != 0) {
|
||||||
|
buffer.push_back(static_cast<T>(
|
||||||
|
std::bitset<sizeof(T) * 8>(str, 0, suffix_length).to_ullong()));
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds '0' chars at the end of the string until the size is a multiple of N.
|
||||||
|
template <size_t N>
|
||||||
|
std::string PadToWord(std::string&& str) {
|
||||||
|
const size_t tail_length = str.size() % N;
|
||||||
|
if (tail_length != 0) str += std::string(N - tail_length, '0');
|
||||||
|
return std::move(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds '0' chars at the end of the string until the size is a multiple of N.
|
||||||
|
template <size_t N>
|
||||||
|
std::string PadToWord(const std::string& str) {
|
||||||
|
return PadToWord<N>(std::string(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts a left-to-right stream of bits to std::bitset.
|
||||||
|
template <size_t N>
|
||||||
|
std::bitset<N> StreamToBitset(std::string str) {
|
||||||
|
std::reverse(str.begin(), str.end());
|
||||||
|
return std::bitset<N>(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts a left-to-right stream of bits to uint64.
|
||||||
|
uint64_t StreamToBits(std::string str) {
|
||||||
|
std::reverse(str.begin(), str.end());
|
||||||
|
return std::bitset<64>(str).to_ullong();
|
||||||
|
}
|
||||||
|
|
||||||
// A simple and inefficient implementatition of BitWriterInterface,
|
// A simple and inefficient implementatition of BitWriterInterface,
|
||||||
// using std::stringstream. Intended for tests only.
|
// using std::stringstream. Intended for tests only.
|
||||||
class BitWriterStringStream : public BitWriterInterface {
|
class BitWriterStringStream : public BitWriterInterface {
|
||||||
public:
|
public:
|
||||||
void WriteStream(const std::string& bits) override { ss_ << bits; }
|
|
||||||
|
|
||||||
void WriteBits(uint64_t bits, size_t num_bits) override {
|
void WriteBits(uint64_t bits, size_t num_bits) override {
|
||||||
assert(num_bits <= 64);
|
assert(num_bits <= 64);
|
||||||
ss_ << BitsToStream(bits, num_bits);
|
ss_ << BitsToStream(bits, num_bits);
|
||||||
@ -73,52 +136,11 @@ class BitReaderFromString : public BitReaderInterface {
|
|||||||
|
|
||||||
bool ReachedEnd() const override { return pos_ >= str_.length(); }
|
bool ReachedEnd() const override { return pos_ >= str_.length(); }
|
||||||
|
|
||||||
const std::string& GetStreamPadded64() const { return str_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string str_;
|
std::string str_;
|
||||||
size_t pos_;
|
size_t pos_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(Log2U16, Test) {
|
|
||||||
EXPECT_EQ(0u, Log2U64(0));
|
|
||||||
EXPECT_EQ(0u, Log2U64(1));
|
|
||||||
EXPECT_EQ(1u, Log2U64(2));
|
|
||||||
EXPECT_EQ(1u, Log2U64(3));
|
|
||||||
EXPECT_EQ(2u, Log2U64(4));
|
|
||||||
EXPECT_EQ(2u, Log2U64(5));
|
|
||||||
EXPECT_EQ(2u, Log2U64(6));
|
|
||||||
EXPECT_EQ(2u, Log2U64(7));
|
|
||||||
EXPECT_EQ(3u, Log2U64(8));
|
|
||||||
EXPECT_EQ(3u, Log2U64(9));
|
|
||||||
EXPECT_EQ(3u, Log2U64(10));
|
|
||||||
EXPECT_EQ(3u, Log2U64(11));
|
|
||||||
EXPECT_EQ(3u, Log2U64(12));
|
|
||||||
EXPECT_EQ(3u, Log2U64(13));
|
|
||||||
EXPECT_EQ(3u, Log2U64(14));
|
|
||||||
EXPECT_EQ(3u, Log2U64(15));
|
|
||||||
EXPECT_EQ(4u, Log2U64(16));
|
|
||||||
EXPECT_EQ(4u, Log2U64(17));
|
|
||||||
EXPECT_EQ(5u, Log2U64(35));
|
|
||||||
EXPECT_EQ(6u, Log2U64(72));
|
|
||||||
EXPECT_EQ(7u, Log2U64(255));
|
|
||||||
EXPECT_EQ(8u, Log2U64(256));
|
|
||||||
EXPECT_EQ(15u, Log2U64(65535));
|
|
||||||
EXPECT_EQ(16u, Log2U64(65536));
|
|
||||||
EXPECT_EQ(19u, Log2U64(0xFFFFF));
|
|
||||||
EXPECT_EQ(23u, Log2U64(0xFFFFFF));
|
|
||||||
EXPECT_EQ(27u, Log2U64(0xFFFFFFF));
|
|
||||||
EXPECT_EQ(31u, Log2U64(0xFFFFFFFF));
|
|
||||||
EXPECT_EQ(35u, Log2U64(0xFFFFFFFFF));
|
|
||||||
EXPECT_EQ(39u, Log2U64(0xFFFFFFFFFF));
|
|
||||||
EXPECT_EQ(43u, Log2U64(0xFFFFFFFFFFF));
|
|
||||||
EXPECT_EQ(47u, Log2U64(0xFFFFFFFFFFFF));
|
|
||||||
EXPECT_EQ(51u, Log2U64(0xFFFFFFFFFFFFF));
|
|
||||||
EXPECT_EQ(55u, Log2U64(0xFFFFFFFFFFFFFF));
|
|
||||||
EXPECT_EQ(59u, Log2U64(0xFFFFFFFFFFFFFFF));
|
|
||||||
EXPECT_EQ(63u, Log2U64(0xFFFFFFFFFFFFFFFF));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(NumBitsToNumWords, Word8) {
|
TEST(NumBitsToNumWords, Word8) {
|
||||||
EXPECT_EQ(0u, NumBitsToNumWords<8>(0));
|
EXPECT_EQ(0u, NumBitsToNumWords<8>(0));
|
||||||
EXPECT_EQ(1u, NumBitsToNumWords<8>(1));
|
EXPECT_EQ(1u, NumBitsToNumWords<8>(1));
|
||||||
@ -141,34 +163,6 @@ TEST(NumBitsToNumWords, Word64) {
|
|||||||
EXPECT_EQ(3u, NumBitsToNumWords<64>(129));
|
EXPECT_EQ(3u, NumBitsToNumWords<64>(129));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ZigZagCoding, Encode) {
|
|
||||||
EXPECT_EQ(0u, EncodeZigZag(0));
|
|
||||||
EXPECT_EQ(1u, EncodeZigZag(-1));
|
|
||||||
EXPECT_EQ(2u, EncodeZigZag(1));
|
|
||||||
EXPECT_EQ(3u, EncodeZigZag(-2));
|
|
||||||
EXPECT_EQ(4u, EncodeZigZag(2));
|
|
||||||
EXPECT_EQ(5u, EncodeZigZag(-3));
|
|
||||||
EXPECT_EQ(6u, EncodeZigZag(3));
|
|
||||||
EXPECT_EQ(std::numeric_limits<uint64_t>::max() - 1,
|
|
||||||
EncodeZigZag(std::numeric_limits<int64_t>::max()));
|
|
||||||
EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
|
|
||||||
EncodeZigZag(std::numeric_limits<int64_t>::min()));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(ZigZagCoding, Decode) {
|
|
||||||
EXPECT_EQ(0, DecodeZigZag(0));
|
|
||||||
EXPECT_EQ(-1, DecodeZigZag(1));
|
|
||||||
EXPECT_EQ(1, DecodeZigZag(2));
|
|
||||||
EXPECT_EQ(-2, DecodeZigZag(3));
|
|
||||||
EXPECT_EQ(2, DecodeZigZag(4));
|
|
||||||
EXPECT_EQ(-3, DecodeZigZag(5));
|
|
||||||
EXPECT_EQ(3, DecodeZigZag(6));
|
|
||||||
EXPECT_EQ(std::numeric_limits<int64_t>::min(),
|
|
||||||
DecodeZigZag(std::numeric_limits<uint64_t>::max()));
|
|
||||||
EXPECT_EQ(std::numeric_limits<int64_t>::max(),
|
|
||||||
DecodeZigZag(std::numeric_limits<uint64_t>::max() - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(ZigZagCoding, Encode0) {
|
TEST(ZigZagCoding, Encode0) {
|
||||||
EXPECT_EQ(0u, EncodeZigZag(0, 0));
|
EXPECT_EQ(0u, EncodeZigZag(0, 0));
|
||||||
EXPECT_EQ(1u, EncodeZigZag(-1, 0));
|
EXPECT_EQ(1u, EncodeZigZag(-1, 0));
|
||||||
@ -191,18 +185,6 @@ TEST(ZigZagCoding, Decode0) {
|
|||||||
DecodeZigZag(std::numeric_limits<uint64_t>::max() - 1, 0));
|
DecodeZigZag(std::numeric_limits<uint64_t>::max() - 1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ZigZagCoding, Decode0SameAsNormalZigZag) {
|
|
||||||
for (int32_t i = -10000; i < 10000; i += 123) {
|
|
||||||
ASSERT_EQ(DecodeZigZag(i), DecodeZigZag(i, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(ZigZagCoding, Encode0SameAsNormalZigZag) {
|
|
||||||
for (uint32_t i = 0; i < 10000; i += 123) {
|
|
||||||
ASSERT_EQ(EncodeZigZag(i), EncodeZigZag(i, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(ZigZagCoding, Encode1) {
|
TEST(ZigZagCoding, Encode1) {
|
||||||
EXPECT_EQ(0u, EncodeZigZag(0, 1));
|
EXPECT_EQ(0u, EncodeZigZag(0, 1));
|
||||||
EXPECT_EQ(1u, EncodeZigZag(1, 1));
|
EXPECT_EQ(1u, EncodeZigZag(1, 1));
|
||||||
@ -428,30 +410,6 @@ TEST(BitWriterStringStream, Empty) {
|
|||||||
EXPECT_EQ("", writer.GetStreamRaw());
|
EXPECT_EQ("", writer.GetStreamRaw());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitWriterStringStream, WriteStream) {
|
|
||||||
BitWriterStringStream writer;
|
|
||||||
const std::string bits1 = "1011111111111111111";
|
|
||||||
writer.WriteStream(bits1);
|
|
||||||
EXPECT_EQ(19u, writer.GetNumBits());
|
|
||||||
EXPECT_EQ(3u, writer.GetDataSizeBytes());
|
|
||||||
EXPECT_EQ(bits1, writer.GetStreamRaw());
|
|
||||||
|
|
||||||
const std::string bits2 = "10100001010101010000111111111111111111111111111";
|
|
||||||
writer.WriteStream(bits2);
|
|
||||||
EXPECT_EQ(66u, writer.GetNumBits());
|
|
||||||
EXPECT_EQ(9u, writer.GetDataSizeBytes());
|
|
||||||
EXPECT_EQ(bits1 + bits2, writer.GetStreamRaw());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(BitWriterStringStream, WriteBitSet) {
|
|
||||||
BitWriterStringStream writer;
|
|
||||||
const std::string bits1 = "10101";
|
|
||||||
writer.WriteBitset(StreamToBitset<16>(bits1));
|
|
||||||
EXPECT_EQ(16u, writer.GetNumBits());
|
|
||||||
EXPECT_EQ(2u, writer.GetDataSizeBytes());
|
|
||||||
EXPECT_EQ(PadToWord<16>(bits1), writer.GetStreamRaw());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(BitWriterStringStream, WriteBits) {
|
TEST(BitWriterStringStream, WriteBits) {
|
||||||
BitWriterStringStream writer;
|
BitWriterStringStream writer;
|
||||||
const uint64_t bits1 = 0x1 | 0x2 | 0x10;
|
const uint64_t bits1 = 0x1 | 0x2 | 0x10;
|
||||||
@ -482,20 +440,19 @@ TEST(BitWriterStringStream, WriteMultiple) {
|
|||||||
BitWriterStringStream writer;
|
BitWriterStringStream writer;
|
||||||
|
|
||||||
std::string expected_result;
|
std::string expected_result;
|
||||||
const std::string bits1 = "101001111111001100010000001110001111111100";
|
|
||||||
writer.WriteStream(bits1);
|
|
||||||
|
|
||||||
const std::string bits2 = "10100011000010010101";
|
const uint64_t b2_val = 0x4 | 0x2 | 0x40;
|
||||||
writer.WriteBitset(StreamToBitset<20>(bits2));
|
const std::string bits2 = BitsToStream(b2_val, 8);
|
||||||
|
writer.WriteBits(b2_val, 8);
|
||||||
|
|
||||||
const uint64_t val = 0x1 | 0x2 | 0x10;
|
const uint64_t val = 0x1 | 0x2 | 0x10;
|
||||||
const std::string bits3 = BitsToStream(val, 8);
|
const std::string bits3 = BitsToStream(val, 8);
|
||||||
writer.WriteBits(val, 8);
|
writer.WriteBits(val, 8);
|
||||||
|
|
||||||
const std::string expected = bits1 + bits2 + bits3;
|
const std::string expected = bits2 + bits3;
|
||||||
|
|
||||||
EXPECT_EQ(expected.length(), writer.GetNumBits());
|
EXPECT_EQ(expected.length(), writer.GetNumBits());
|
||||||
EXPECT_EQ(9u, writer.GetDataSizeBytes());
|
EXPECT_EQ(2u, writer.GetDataSizeBytes());
|
||||||
EXPECT_EQ(expected, writer.GetStreamRaw());
|
EXPECT_EQ(expected, writer.GetStreamRaw());
|
||||||
|
|
||||||
EXPECT_EQ(PadToWord<8>(expected), BufferToStream(writer.GetDataCopy()));
|
EXPECT_EQ(PadToWord<8>(expected), BufferToStream(writer.GetDataCopy()));
|
||||||
@ -505,46 +462,6 @@ TEST(BitWriterWord64, Empty) {
|
|||||||
BitWriterWord64 writer;
|
BitWriterWord64 writer;
|
||||||
EXPECT_EQ(0u, writer.GetNumBits());
|
EXPECT_EQ(0u, writer.GetNumBits());
|
||||||
EXPECT_EQ(0u, writer.GetDataSizeBytes());
|
EXPECT_EQ(0u, writer.GetDataSizeBytes());
|
||||||
EXPECT_EQ("", writer.GetStreamPadded64());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(BitWriterWord64, WriteStream) {
|
|
||||||
BitWriterWord64 writer;
|
|
||||||
std::string expected;
|
|
||||||
|
|
||||||
{
|
|
||||||
const std::string bits = "101";
|
|
||||||
expected += bits;
|
|
||||||
writer.WriteStream(bits);
|
|
||||||
EXPECT_EQ(expected.length(), writer.GetNumBits());
|
|
||||||
EXPECT_EQ(1u, writer.GetDataSizeBytes());
|
|
||||||
EXPECT_EQ(PadToWord<64>(expected), writer.GetStreamPadded64());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const std::string bits = "10000111111111110000000";
|
|
||||||
expected += bits;
|
|
||||||
writer.WriteStream(bits);
|
|
||||||
EXPECT_EQ(expected.length(), writer.GetNumBits());
|
|
||||||
EXPECT_EQ(PadToWord<64>(expected), writer.GetStreamPadded64());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const std::string bits = "101001111111111100000111111111111100";
|
|
||||||
expected += bits;
|
|
||||||
writer.WriteStream(bits);
|
|
||||||
EXPECT_EQ(expected.length(), writer.GetNumBits());
|
|
||||||
EXPECT_EQ(PadToWord<64>(expected), writer.GetStreamPadded64());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(BitWriterWord64, WriteBitset) {
|
|
||||||
BitWriterWord64 writer;
|
|
||||||
const std::string bits1 = "10101";
|
|
||||||
writer.WriteBitset(StreamToBitset<16>(bits1), 12);
|
|
||||||
EXPECT_EQ(12u, writer.GetNumBits());
|
|
||||||
EXPECT_EQ(2u, writer.GetDataSizeBytes());
|
|
||||||
EXPECT_EQ(PadToWord<64>(bits1), writer.GetStreamPadded64());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitWriterWord64, WriteBits) {
|
TEST(BitWriterWord64, WriteBits) {
|
||||||
@ -555,7 +472,6 @@ TEST(BitWriterWord64, WriteBits) {
|
|||||||
writer.WriteBits(bits1, 5);
|
writer.WriteBits(bits1, 5);
|
||||||
EXPECT_EQ(15u, writer.GetNumBits());
|
EXPECT_EQ(15u, writer.GetNumBits());
|
||||||
EXPECT_EQ(2u, writer.GetDataSizeBytes());
|
EXPECT_EQ(2u, writer.GetDataSizeBytes());
|
||||||
EXPECT_EQ(PadToWord<64>("110011100111001"), writer.GetStreamPadded64());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitWriterWord64, WriteZeroBits) {
|
TEST(BitWriterWord64, WriteZeroBits) {
|
||||||
@ -565,18 +481,11 @@ TEST(BitWriterWord64, WriteZeroBits) {
|
|||||||
EXPECT_EQ(0u, writer.GetNumBits());
|
EXPECT_EQ(0u, writer.GetNumBits());
|
||||||
writer.WriteBits(1, 1);
|
writer.WriteBits(1, 1);
|
||||||
writer.WriteBits(0, 0);
|
writer.WriteBits(0, 0);
|
||||||
EXPECT_EQ(PadToWord<64>("1"), writer.GetStreamPadded64());
|
|
||||||
writer.WriteBits(0, 63);
|
writer.WriteBits(0, 63);
|
||||||
EXPECT_EQ(64u, writer.GetNumBits());
|
EXPECT_EQ(64u, writer.GetNumBits());
|
||||||
writer.WriteBits(0, 0);
|
writer.WriteBits(0, 0);
|
||||||
writer.WriteBits(7, 3);
|
writer.WriteBits(7, 3);
|
||||||
writer.WriteBits(0, 0);
|
writer.WriteBits(0, 0);
|
||||||
EXPECT_EQ(
|
|
||||||
PadToWord<64>(
|
|
||||||
"1"
|
|
||||||
"000000000000000000000000000000000000000000000000000000000000000"
|
|
||||||
"111"),
|
|
||||||
writer.GetStreamPadded64());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitWriterWord64, ComparisonTestWriteLotsOfBits) {
|
TEST(BitWriterWord64, ComparisonTestWriteLotsOfBits) {
|
||||||
@ -588,42 +497,6 @@ TEST(BitWriterWord64, ComparisonTestWriteLotsOfBits) {
|
|||||||
writer2.WriteBits(i, 16);
|
writer2.WriteBits(i, 16);
|
||||||
ASSERT_EQ(writer1.GetNumBits(), writer2.GetNumBits());
|
ASSERT_EQ(writer1.GetNumBits(), writer2.GetNumBits());
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_EQ(PadToWord<64>(writer1.GetStreamRaw()), writer2.GetStreamPadded64());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(BitWriterWord64, ComparisonTestWriteLotsOfStreams) {
|
|
||||||
BitWriterStringStream writer1;
|
|
||||||
BitWriterWord64 writer2(16384);
|
|
||||||
|
|
||||||
for (int i = 0; i < 1000; ++i) {
|
|
||||||
std::string bits = "1111100000";
|
|
||||||
if (i % 2) bits += "101010";
|
|
||||||
if (i % 3) bits += "1110100";
|
|
||||||
if (i % 5) bits += "1110100111111111111";
|
|
||||||
writer1.WriteStream(bits);
|
|
||||||
writer2.WriteStream(bits);
|
|
||||||
ASSERT_EQ(writer1.GetNumBits(), writer2.GetNumBits());
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_EQ(PadToWord<64>(writer1.GetStreamRaw()), writer2.GetStreamPadded64());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(BitWriterWord64, ComparisonTestWriteLotsOfBitsets) {
|
|
||||||
BitWriterStringStream writer1;
|
|
||||||
BitWriterWord64 writer2(16384);
|
|
||||||
|
|
||||||
for (uint64_t i = 0; i < 65000; i += 25) {
|
|
||||||
std::bitset<16> bits1(i);
|
|
||||||
std::bitset<24> bits2(i);
|
|
||||||
writer1.WriteBitset(bits1);
|
|
||||||
writer1.WriteBitset(bits2);
|
|
||||||
writer2.WriteBitset(bits1);
|
|
||||||
writer2.WriteBitset(bits2);
|
|
||||||
ASSERT_EQ(writer1.GetNumBits(), writer2.GetNumBits());
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_EQ(PadToWord<64>(writer1.GetStreamRaw()), writer2.GetStreamPadded64());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(GetLowerBits, Test) {
|
TEST(GetLowerBits, Test) {
|
||||||
@ -661,7 +534,6 @@ TEST(BitReaderFromString, FromU8) {
|
|||||||
"10111011";
|
"10111011";
|
||||||
|
|
||||||
BitReaderFromString reader(buffer);
|
BitReaderFromString reader(buffer);
|
||||||
EXPECT_EQ(PadToWord<64>(total_stream), reader.GetStreamPadded64());
|
|
||||||
|
|
||||||
uint64_t bits = 0;
|
uint64_t bits = 0;
|
||||||
EXPECT_EQ(2u, reader.ReadBits(&bits, 2));
|
EXPECT_EQ(2u, reader.ReadBits(&bits, 2));
|
||||||
@ -690,7 +562,6 @@ TEST(BitReaderFromString, FromU64) {
|
|||||||
"1011101110111011101110111011101110111011101110111011101110111011";
|
"1011101110111011101110111011101110111011101110111011101110111011";
|
||||||
|
|
||||||
BitReaderFromString reader(buffer);
|
BitReaderFromString reader(buffer);
|
||||||
EXPECT_EQ(total_stream, reader.GetStreamPadded64());
|
|
||||||
|
|
||||||
uint64_t bits = 0;
|
uint64_t bits = 0;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
@ -728,40 +599,6 @@ TEST(BitReaderWord64, ReadBitsSingleByte) {
|
|||||||
EXPECT_TRUE(reader.ReachedEnd());
|
EXPECT_TRUE(reader.ReachedEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitReaderWord64, ReadBitsetSingleByte) {
|
|
||||||
BitReaderWord64 reader(std::vector<uint8_t>({uint8_t(0xCC)}));
|
|
||||||
std::bitset<4> bits;
|
|
||||||
EXPECT_EQ(2u, reader.ReadBitset(&bits, 2));
|
|
||||||
EXPECT_EQ(0u, bits.to_ullong());
|
|
||||||
EXPECT_EQ(2u, reader.ReadBitset(&bits, 2));
|
|
||||||
EXPECT_EQ(3u, bits.to_ullong());
|
|
||||||
EXPECT_FALSE(reader.OnlyZeroesLeft());
|
|
||||||
EXPECT_EQ(4u, reader.ReadBitset(&bits, 4));
|
|
||||||
EXPECT_EQ(12u, bits.to_ullong());
|
|
||||||
EXPECT_TRUE(reader.OnlyZeroesLeft());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(BitReaderWord64, ReadStreamSingleByte) {
|
|
||||||
BitReaderWord64 reader(std::vector<uint8_t>({uint8_t(0xAA)}));
|
|
||||||
EXPECT_EQ("", reader.ReadStream(0));
|
|
||||||
EXPECT_EQ("0", reader.ReadStream(1));
|
|
||||||
EXPECT_EQ("101", reader.ReadStream(3));
|
|
||||||
EXPECT_EQ("01010000", reader.ReadStream(8));
|
|
||||||
EXPECT_TRUE(reader.OnlyZeroesLeft());
|
|
||||||
EXPECT_EQ("0000000000000000000000000000000000000000000000000000",
|
|
||||||
reader.ReadStream(64));
|
|
||||||
EXPECT_TRUE(reader.ReachedEnd());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(BitReaderWord64, ReadStreamEmpty) {
|
|
||||||
std::vector<uint64_t> buffer;
|
|
||||||
BitReaderWord64 reader(std::move(buffer));
|
|
||||||
EXPECT_TRUE(reader.OnlyZeroesLeft());
|
|
||||||
EXPECT_TRUE(reader.ReachedEnd());
|
|
||||||
EXPECT_EQ("", reader.ReadStream(10));
|
|
||||||
EXPECT_TRUE(reader.ReachedEnd());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(BitReaderWord64, ReadBitsTwoWords) {
|
TEST(BitReaderWord64, ReadBitsTwoWords) {
|
||||||
std::vector<uint64_t> buffer = {0x0000000000000001, 0x0000000000FFFFFF};
|
std::vector<uint64_t> buffer = {0x0000000000000001, 0x0000000000FFFFFF};
|
||||||
|
|
||||||
@ -934,37 +771,6 @@ TEST(VariableWidthWrite, Write0U) {
|
|||||||
"000"
|
"000"
|
||||||
"000",
|
"000",
|
||||||
writer.GetStreamRaw());
|
writer.GetStreamRaw());
|
||||||
writer.WriteVariableWidthU8(0, 2);
|
|
||||||
EXPECT_EQ(
|
|
||||||
"000"
|
|
||||||
"000"
|
|
||||||
"000"
|
|
||||||
"000",
|
|
||||||
writer.GetStreamRaw());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VariableWidthWrite, Write0S) {
|
|
||||||
BitWriterStringStream writer;
|
|
||||||
writer.WriteVariableWidthS64(0, 2, 0);
|
|
||||||
EXPECT_EQ("000", writer.GetStreamRaw());
|
|
||||||
writer.WriteVariableWidthS32(0, 2, 0);
|
|
||||||
EXPECT_EQ(
|
|
||||||
"000"
|
|
||||||
"000",
|
|
||||||
writer.GetStreamRaw());
|
|
||||||
writer.WriteVariableWidthS16(0, 2, 0);
|
|
||||||
EXPECT_EQ(
|
|
||||||
"000"
|
|
||||||
"000"
|
|
||||||
"000",
|
|
||||||
writer.GetStreamRaw());
|
|
||||||
writer.WriteVariableWidthS8(0, 2, 0);
|
|
||||||
EXPECT_EQ(
|
|
||||||
"000"
|
|
||||||
"000"
|
|
||||||
"000"
|
|
||||||
"000",
|
|
||||||
writer.GetStreamRaw());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VariableWidthWrite, WriteSmallUnsigned) {
|
TEST(VariableWidthWrite, WriteSmallUnsigned) {
|
||||||
@ -982,13 +788,6 @@ TEST(VariableWidthWrite, WriteSmallUnsigned) {
|
|||||||
"010"
|
"010"
|
||||||
"110",
|
"110",
|
||||||
writer.GetStreamRaw());
|
writer.GetStreamRaw());
|
||||||
writer.WriteVariableWidthU8(4, 2);
|
|
||||||
EXPECT_EQ(
|
|
||||||
"100"
|
|
||||||
"010"
|
|
||||||
"110"
|
|
||||||
"001100",
|
|
||||||
writer.GetStreamRaw());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VariableWidthWrite, WriteSmallSigned) {
|
TEST(VariableWidthWrite, WriteSmallSigned) {
|
||||||
@ -1000,19 +799,6 @@ TEST(VariableWidthWrite, WriteSmallSigned) {
|
|||||||
"010"
|
"010"
|
||||||
"100",
|
"100",
|
||||||
writer.GetStreamRaw());
|
writer.GetStreamRaw());
|
||||||
writer.WriteVariableWidthS16(3, 2, 0);
|
|
||||||
EXPECT_EQ(
|
|
||||||
"010"
|
|
||||||
"100"
|
|
||||||
"011100",
|
|
||||||
writer.GetStreamRaw());
|
|
||||||
writer.WriteVariableWidthS8(-4, 2, 0);
|
|
||||||
EXPECT_EQ(
|
|
||||||
"010"
|
|
||||||
"100"
|
|
||||||
"011100"
|
|
||||||
"111100",
|
|
||||||
writer.GetStreamRaw());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VariableWidthWrite, U64Val127ChunkLength7) {
|
TEST(VariableWidthWrite, U64Val127ChunkLength7) {
|
||||||
@ -1044,16 +830,6 @@ TEST(VariableWidthWrite, U16Val2ChunkLength4) {
|
|||||||
writer.GetStreamRaw());
|
writer.GetStreamRaw());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VariableWidthWrite, U8Val128ChunkLength7) {
|
|
||||||
BitWriterStringStream writer;
|
|
||||||
writer.WriteVariableWidthU8(128, 7);
|
|
||||||
EXPECT_EQ(
|
|
||||||
"0000000"
|
|
||||||
"1"
|
|
||||||
"1",
|
|
||||||
writer.GetStreamRaw());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VariableWidthWrite, U64ValAAAAChunkLength2) {
|
TEST(VariableWidthWrite, U64ValAAAAChunkLength2) {
|
||||||
BitWriterStringStream writer;
|
BitWriterStringStream writer;
|
||||||
writer.WriteVariableWidthU64(0xAAAA, 2);
|
writer.WriteVariableWidthU64(0xAAAA, 2);
|
||||||
@ -1077,16 +853,6 @@ TEST(VariableWidthWrite, U64ValAAAAChunkLength2) {
|
|||||||
writer.GetStreamRaw());
|
writer.GetStreamRaw());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VariableWidthWrite, S8ValM128ChunkLength7) {
|
|
||||||
BitWriterStringStream writer;
|
|
||||||
writer.WriteVariableWidthS8(-128, 7, 0);
|
|
||||||
EXPECT_EQ(
|
|
||||||
"1111111"
|
|
||||||
"1"
|
|
||||||
"1",
|
|
||||||
writer.GetStreamRaw());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VariableWidthRead, U64Val127ChunkLength7) {
|
TEST(VariableWidthRead, U64Val127ChunkLength7) {
|
||||||
BitReaderFromString reader(
|
BitReaderFromString reader(
|
||||||
"1111111"
|
"1111111"
|
||||||
@ -1116,16 +882,6 @@ TEST(VariableWidthRead, U16Val2ChunkLength4) {
|
|||||||
EXPECT_EQ(2u, val);
|
EXPECT_EQ(2u, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VariableWidthRead, U8Val128ChunkLength7) {
|
|
||||||
BitReaderFromString reader(
|
|
||||||
"0000000"
|
|
||||||
"1"
|
|
||||||
"1");
|
|
||||||
uint8_t val = 0;
|
|
||||||
ASSERT_TRUE(reader.ReadVariableWidthU8(&val, 7));
|
|
||||||
EXPECT_EQ(128u, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VariableWidthRead, U64ValAAAAChunkLength2) {
|
TEST(VariableWidthRead, U64ValAAAAChunkLength2) {
|
||||||
BitReaderFromString reader(
|
BitReaderFromString reader(
|
||||||
"01"
|
"01"
|
||||||
@ -1149,16 +905,6 @@ TEST(VariableWidthRead, U64ValAAAAChunkLength2) {
|
|||||||
EXPECT_EQ(0xAAAAu, val);
|
EXPECT_EQ(0xAAAAu, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VariableWidthRead, S8ValM128ChunkLength7) {
|
|
||||||
BitReaderFromString reader(
|
|
||||||
"1111111"
|
|
||||||
"1"
|
|
||||||
"1");
|
|
||||||
int8_t val = 0;
|
|
||||||
ASSERT_TRUE(reader.ReadVariableWidthS8(&val, 7, 0));
|
|
||||||
EXPECT_EQ(-128, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VariableWidthRead, FailTooShort) {
|
TEST(VariableWidthRead, FailTooShort) {
|
||||||
BitReaderFromString reader("00000001100000");
|
BitReaderFromString reader("00000001100000");
|
||||||
uint64_t val = 0;
|
uint64_t val = 0;
|
||||||
@ -1215,24 +961,6 @@ TEST(VariableWidthWriteRead, SingleWriteReadU32) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VariableWidthWriteRead, SingleWriteReadS32) {
|
|
||||||
for (int32_t i = 0; i < 100000; i += 123) {
|
|
||||||
const int32_t val = i * (i % 2 ? -i : i);
|
|
||||||
const size_t chunk_length = i % 16 + 1;
|
|
||||||
const size_t zigzag_exponent = i % 11;
|
|
||||||
|
|
||||||
BitWriterWord64 writer;
|
|
||||||
writer.WriteVariableWidthS32(val, chunk_length, zigzag_exponent);
|
|
||||||
|
|
||||||
BitReaderWord64 reader(writer.GetDataCopy());
|
|
||||||
int32_t read_val = 0;
|
|
||||||
ASSERT_TRUE(
|
|
||||||
reader.ReadVariableWidthS32(&read_val, chunk_length, zigzag_exponent));
|
|
||||||
|
|
||||||
ASSERT_EQ(val, read_val) << "Chunk length " << chunk_length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VariableWidthWriteRead, SingleWriteReadU16) {
|
TEST(VariableWidthWriteRead, SingleWriteReadU16) {
|
||||||
for (int i = 0; i < 65536; i += 123) {
|
for (int i = 0; i < 65536; i += 123) {
|
||||||
const uint16_t val = static_cast<int16_t>(i);
|
const uint16_t val = static_cast<int16_t>(i);
|
||||||
@ -1249,58 +977,6 @@ TEST(VariableWidthWriteRead, SingleWriteReadU16) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VariableWidthWriteRead, SingleWriteReadS16) {
|
|
||||||
for (int i = -32768; i < 32768; i += 123) {
|
|
||||||
const int16_t val = static_cast<int16_t>(i);
|
|
||||||
const size_t chunk_length = std::abs(i) % 10 + 1;
|
|
||||||
const size_t zigzag_exponent = std::abs(i) % 7;
|
|
||||||
|
|
||||||
BitWriterWord64 writer;
|
|
||||||
writer.WriteVariableWidthS16(val, chunk_length, zigzag_exponent);
|
|
||||||
|
|
||||||
BitReaderWord64 reader(writer.GetDataCopy());
|
|
||||||
int16_t read_val = 0;
|
|
||||||
ASSERT_TRUE(
|
|
||||||
reader.ReadVariableWidthS16(&read_val, chunk_length, zigzag_exponent));
|
|
||||||
|
|
||||||
ASSERT_EQ(val, read_val) << "Chunk length " << chunk_length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VariableWidthWriteRead, SingleWriteReadU8) {
|
|
||||||
for (int i = 0; i < 256; ++i) {
|
|
||||||
const uint8_t val = static_cast<uint8_t>(i);
|
|
||||||
const size_t chunk_length = val % 5 + 1;
|
|
||||||
|
|
||||||
BitWriterWord64 writer;
|
|
||||||
writer.WriteVariableWidthU8(val, chunk_length);
|
|
||||||
|
|
||||||
BitReaderWord64 reader(writer.GetDataCopy());
|
|
||||||
uint8_t read_val = 0;
|
|
||||||
ASSERT_TRUE(reader.ReadVariableWidthU8(&read_val, chunk_length));
|
|
||||||
|
|
||||||
ASSERT_EQ(val, read_val) << "Chunk length " << chunk_length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VariableWidthWriteRead, SingleWriteReadS8) {
|
|
||||||
for (int i = -128; i < 128; ++i) {
|
|
||||||
const int8_t val = static_cast<int8_t>(i);
|
|
||||||
const size_t chunk_length = std::abs(i) % 5 + 1;
|
|
||||||
const size_t zigzag_exponent = std::abs(i) % 3;
|
|
||||||
|
|
||||||
BitWriterWord64 writer;
|
|
||||||
writer.WriteVariableWidthS8(val, chunk_length, zigzag_exponent);
|
|
||||||
|
|
||||||
BitReaderWord64 reader(writer.GetDataCopy());
|
|
||||||
int8_t read_val = 0;
|
|
||||||
ASSERT_TRUE(
|
|
||||||
reader.ReadVariableWidthS8(&read_val, chunk_length, zigzag_exponent));
|
|
||||||
|
|
||||||
ASSERT_EQ(val, read_val) << "Chunk length " << chunk_length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(VariableWidthWriteRead, SmallNumbersChunkLength4) {
|
TEST(VariableWidthWriteRead, SmallNumbersChunkLength4) {
|
||||||
const std::vector<uint64_t> expected_values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
const std::vector<uint64_t> expected_values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
|
|
||||||
@ -1344,70 +1020,6 @@ TEST(VariableWidthWriteRead, VariedNumbersChunkLength8) {
|
|||||||
EXPECT_EQ(expected_values, actual_values);
|
EXPECT_EQ(expected_values, actual_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FixedWidthWrite, Val0Max3) {
|
|
||||||
BitWriterStringStream writer;
|
|
||||||
writer.WriteFixedWidth(0, 3);
|
|
||||||
EXPECT_EQ("00", writer.GetStreamRaw());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FixedWidthWrite, Val0Max5) {
|
|
||||||
BitWriterStringStream writer;
|
|
||||||
writer.WriteFixedWidth(0, 5);
|
|
||||||
EXPECT_EQ("000", writer.GetStreamRaw());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FixedWidthWrite, Val0Max255) {
|
|
||||||
BitWriterStringStream writer;
|
|
||||||
writer.WriteFixedWidth(0, 255);
|
|
||||||
EXPECT_EQ("00000000", writer.GetStreamRaw());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FixedWidthWrite, Val3Max8) {
|
|
||||||
BitWriterStringStream writer;
|
|
||||||
writer.WriteFixedWidth(3, 8);
|
|
||||||
EXPECT_EQ("1100", writer.GetStreamRaw());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FixedWidthWrite, Val15Max127) {
|
|
||||||
BitWriterStringStream writer;
|
|
||||||
writer.WriteFixedWidth(15, 127);
|
|
||||||
EXPECT_EQ("1111000", writer.GetStreamRaw());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FixedWidthRead, Val0Max3) {
|
|
||||||
BitReaderFromString reader("0011111");
|
|
||||||
uint64_t val = 0;
|
|
||||||
ASSERT_TRUE(reader.ReadFixedWidth(&val, 3));
|
|
||||||
EXPECT_EQ(0u, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FixedWidthRead, Val0Max5) {
|
|
||||||
BitReaderFromString reader("0001010101");
|
|
||||||
uint64_t val = 0;
|
|
||||||
ASSERT_TRUE(reader.ReadFixedWidth(&val, 5));
|
|
||||||
EXPECT_EQ(0u, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FixedWidthRead, Val3Max8) {
|
|
||||||
BitReaderFromString reader("11001010101");
|
|
||||||
uint64_t val = 0;
|
|
||||||
ASSERT_TRUE(reader.ReadFixedWidth(&val, 8));
|
|
||||||
EXPECT_EQ(3u, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FixedWidthRead, Val15Max127) {
|
|
||||||
BitReaderFromString reader("111100010101");
|
|
||||||
uint64_t val = 0;
|
|
||||||
ASSERT_TRUE(reader.ReadFixedWidth(&val, 127));
|
|
||||||
EXPECT_EQ(15u, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FixedWidthRead, Fail) {
|
|
||||||
BitReaderFromString reader("111100");
|
|
||||||
uint64_t val = 0;
|
|
||||||
ASSERT_FALSE(reader.ReadFixedWidth(&val, 127));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
} // namespace spvtools
|
} // namespace spvtools
|
||||||
|
Loading…
Reference in New Issue
Block a user