aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/bit_io/bitinput.h
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/bit_io/bitinput.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/bit_io/bitinput.h')
-rw-r--r--library/cpp/bit_io/bitinput.h171
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;
+ }
+ };
+}