diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/bit_io/bitinput.h | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/bit_io/bitinput.h')
-rw-r--r-- | library/cpp/bit_io/bitinput.h | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/library/cpp/bit_io/bitinput.h b/library/cpp/bit_io/bitinput.h new file mode 100644 index 0000000000..85711eb7f9 --- /dev/null +++ b/library/cpp/bit_io/bitinput.h @@ -0,0 +1,171 @@ +#pragma once + +#include "bitinput_impl.h" + +#include <util/system/yassert.h> +#include <util/generic/vector.h> +#include <util/generic/yexception.h> + +#include <iterator> + +namespace NBitIO { + // Based on junk/solar/codecs/bitstream.h + + class TBitInput: protected TBitInputImpl { + public: + template <typename TVec> + explicit TBitInput(const TVec& vec) + : TBitInputImpl(std::begin(vec), std::end(vec)) + { + } + + TBitInput(const char* start, const char* end) + : TBitInputImpl(start, end) + { + } + + bool Eof() const { + return EofImpl(); + } + + ui64 GetOffset() const { + ui64 bo = BitOffset(); + return bo / 8 + !!(bo % 8); + } + + using TBitInputImpl::GetBitLength; + + ui64 GetBitOffset() const { + return BitOffset() % 8; + } + + public: + // Read with static number of bits. + // Preserves what's in result. + template <ui64 bits, typename T> + Y_FORCE_INLINE bool ReadK(T& result, ui64 skipbits) { + ui64 r64 = 0; + bool ret = bits <= 56 ? ReadKImpl<bits>(r64) : ReadSafe(r64, bits); + CopyToResultK<bits>(result, r64, skipbits); + return ret; + } + + // Read with static number of bits. + // Zeroes other bits in result. + template <ui64 bits, typename T> + Y_FORCE_INLINE bool ReadK(T& result) { + ui64 r = 0; + bool res = ReadK<bits>(r); + result = r; + return res; + } + + // Shortcut to impl. + template <ui64 bits> + Y_FORCE_INLINE bool ReadK(ui64& result) { + if (bits <= 56) + return ReadKImpl<bits>(result); + + ui64 r1 = 0ULL; + ui64 r2 = 0ULL; + + bool ret1 = ReadKImpl<56ULL>(r1); + bool ret2 = ReadKImpl<(bits > 56ULL ? bits - 56ULL : 0) /*or else we get negative param in template*/>(r2); + + result = (r2 << 56ULL) | r1; + + return ret1 & ret2; + } + + // It's safe to read up to 64 bits. + // Zeroes other bits in result. + template <typename T> + Y_FORCE_INLINE bool ReadSafe(T& result, ui64 bits) { + if (bits <= 56ULL) + return Read(result, bits); + + ui64 r1 = 0ULL; + ui64 r2 = 0ULL; + + bool ret1 = ReadKImpl<56ULL>(r1); + bool ret2 = ReadImpl(r2, bits - 56ULL); + + result = (r2 << 56ULL) | r1; + + return ret1 & ret2; + } + + // It's safe to read up to 64 bits. + // Preserves what's in result. + template <typename T> + Y_FORCE_INLINE bool ReadSafe(T& result, ui64 bits, ui64 skipbits) { + ui64 r64 = 0; + bool ret = ReadSafe(r64, bits); + CopyToResult(result, r64, bits, skipbits); + return ret; + } + + // Do not try to read more than 56 bits at once. Split in two reads or use ReadSafe. + // Zeroes other bits in result. + template <typename T> + Y_FORCE_INLINE bool Read(T& result, ui64 bits) { + ui64 r64 = 0; + bool ret = ReadImpl(r64, bits); + result = r64; + return ret; + } + + // Shortcut to impl. + Y_FORCE_INLINE bool Read(ui64& result, ui64 bits) { + return ReadImpl(result, bits); + } + + // Do not try to read more than 56 bits at once. Split in two reads or use ReadSafe. + // Preserves what's in result. + template <typename T> + Y_FORCE_INLINE bool Read(T& result, ui64 bits, ui64 skipbits) { + ui64 r64 = 0; + bool ret = ReadImpl(r64, bits); + CopyToResult(result, r64, bits, skipbits); + return ret; + } + + // Unsigned wordwise read. Underlying data is splitted in "words" of "bits(data) + 1(flag)" bits. + // Like this: (unsigned char)0x2E<3> (0010 1110) <=> 1110 0101 + // fddd fddd + template <ui64 bits, typename T> + Y_FORCE_INLINE bool ReadWords(T& result) { + ui64 r64 = 0; + + bool retCode = ReadWordsImpl<bits>(r64); + result = r64; + + return retCode; + } + + // Shortcut to impl. + template <ui64 bits> + Y_FORCE_INLINE bool ReadWords(ui64& result) { + return ReadWordsImpl<bits>(result); + } + + Y_FORCE_INLINE bool Back(int bits) { + return Seek(BitOffset() - bits); + } + + Y_FORCE_INLINE bool Seek(int bitoffset) { + return TBitInputImpl::Seek(bitoffset); + } + + // A way to read a portion of bits at random location. + // Didn't want to complicate sequential read, neither to copypaste. + template <typename T> + Y_FORCE_INLINE bool ReadRandom(ui64 bitoffset, T& result, ui64 bits, ui64 skipbits) { + const ui64 curr = BitOffset(); + Seek(bitoffset); + bool ret = ReadSafe<T>(result, bits, skipbits); + Seek(curr); + return ret; + } + }; +} |