123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- #include "bitinput.h"
- #include "bitoutput.h"
- #include <library/cpp/testing/unittest/registar.h>
- #include <util/stream/buffer.h>
- #include <util/generic/buffer.h>
- namespace NBitIO {
- static const char BITS_REF[] =
- "00100010 01000000 00000000 00100111 11011111 01100111 11010101 00010100 "
- "00100010 01100011 11100011 00110000 11011011 11011111 01001100 00110101 "
- "10011110 01011111 01010000 00000110 00011011 00100110 00010100 01110011 "
- "00001010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 "
- "10110101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 "
- "01000000";
- inline ui64 Bits(ui64 bytes) {
- return bytes << 3ULL;
- }
- inline TString PrintBits(const char* a, const char* b, bool reverse = false) {
- TString s;
- TStringOutput out(s);
- for (const char* it = a; it != b; ++it) {
- if (it != a)
- out << ' ';
- ui8 byte = *it;
- if (reverse)
- byte = ReverseBits(byte);
- for (ui32 mask = 1; mask < 0xff; mask <<= 1) {
- out << ((byte & mask) ? '1' : '0');
- }
- }
- return s;
- }
- template <typename T>
- inline TString PrintBits(T t, ui32 bits = Bits(sizeof(T))) {
- return PrintBits((char*)&t, ((char*)&t) + BytesUp(bits));
- }
- }
- class TBitIOTest: public TTestBase {
- UNIT_TEST_SUITE(TBitIOTest);
- UNIT_TEST(TestBitIO)
- UNIT_TEST_SUITE_END();
- private:
- using TBi = NBitIO::TBitInput;
- using TVec = TVector<char>;
- void static CheckBits(const TVec& v, const TString& ref, const TString& rem) {
- UNIT_ASSERT_VALUES_EQUAL_C(NBitIO::PrintBits(v.begin(), v.end()), ref, rem);
- }
- void DoRead(TBi& b, ui32& t) {
- b.Read(t, 1, 0); // 1
- b.ReadK<3>(t, 1); // 4
- b.Read(t, 5, 4); // 9
- b.ReadK<14>(t, 9); // 23
- b.Read(t, 1, 23); // 24
- b.ReadK<5>(t, 24); // 29
- b.Read(t, 3, 29); // 32
- }
- template <typename TBo>
- void DoWrite(TBo& b, ui32 t) {
- b.Write(t, 1, 0); //1
- b.Write(t, 3, 1); //4
- b.Write(t, 5, 4); //9
- b.Write(t, 14, 9); //23
- b.Write(t, 1, 23); //24
- b.Write(t, 5, 24); //29
- b.Write(t, 3, 29); //32
- }
- template <typename TBo>
- void DoWrite1(TBo& out, const TString& rem) {
- out.Write(0x0C, 3);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 1u, (rem + ", " + ToString(__LINE__)));
- out.Write(0x18, 4);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 1u, (rem + ", " + ToString(__LINE__)));
- out.Write(0x0C, 3);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 2u, (rem + ", " + ToString(__LINE__)));
- out.Write(0x30000, 17);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 4u, (rem + ", " + ToString(__LINE__)));
- out.Write(0x0C, 3);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 4u, (rem + ", " + ToString(__LINE__)));
- }
- template <typename TBo>
- void DoWrite2(TBo& out, const TString& rem) {
- out.Write(0x0C, 3);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 8u, (rem + ", " + ToString(__LINE__)));
- out.Write(0x42, 7);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 9u, (rem + ", " + ToString(__LINE__)));
- DoWrite(out, 1637415112);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 13u, (rem + ", " + ToString(__LINE__)));
- DoWrite(out, 897998715);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 17u, (rem + ", " + ToString(__LINE__)));
- DoWrite(out, 201416527);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 21u, (rem + ", " + ToString(__LINE__)));
- DoWrite(out, 432344219);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 25u, (rem + ", " + ToString(__LINE__)));
- out.Write(0xAAAAAAAAAAAAAAAAULL, 64);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 33u, (rem + ", " + ToString(__LINE__)));
- out.Write(0x5555555555555555ULL, 64);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 41u, (rem + ", " + ToString(__LINE__)));
- }
- void DoBitOutput(NBitIO::TBitOutputYVector& out, const TString& rem) {
- DoWrite1(out, rem);
- out.WriteWords<8>(0xabcdef);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 8u, (rem + ", " + ToString(__LINE__)));
- DoWrite2(out, rem);
- }
- void DoBitOutput(NBitIO::TBitOutputArray& out, const TString& rem) {
- DoWrite1(out, rem);
- out.WriteWords<8>(0xabcdef);
- UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 8u, (rem + ", " + ToString(__LINE__)));
- DoWrite2(out, rem);
- }
- void DoBitInput(TBi& in, const TString& rem) {
- UNIT_ASSERT(!in.Eof());
- {
- ui64 val;
- val = 0;
- UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 0u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_C(in.Read(val, 3), (rem + ": " + NBitIO::PrintBits(val)).data());
- UNIT_ASSERT_VALUES_EQUAL_C(val, 0x4u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 1u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
- val = 0;
- UNIT_ASSERT_C(in.Read(val, 4), (rem + ": " + NBitIO::PrintBits(val)).data());
- UNIT_ASSERT_VALUES_EQUAL_C(val, 0x8u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 1u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
- val = 0;
- UNIT_ASSERT_C(in.Read(val, 3), (rem + ": " + NBitIO::PrintBits(val)).data());
- UNIT_ASSERT_VALUES_EQUAL_C(val, 0x4u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 2u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
- val = 0;
- UNIT_ASSERT_C(in.Read(val, 17), (rem + ": " + NBitIO::PrintBits(val)).data());
- UNIT_ASSERT_VALUES_EQUAL_C(val, 0x10000u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 4u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
- UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 4u, (rem + ": " + NBitIO::PrintBits(val)));
- {
- ui32 rt = 0;
- in.ReadRandom(30, rt, 10, 20);
- UNIT_ASSERT_STRINGS_EQUAL(NBitIO::PrintBits(rt).data(), "00000000 00000000 00001111 01111100");
- }
- val = 0;
- UNIT_ASSERT_C(in.Read(val, 3), (rem + ": " + NBitIO::PrintBits(val)).data());
- UNIT_ASSERT_VALUES_EQUAL_C(val, 0x4u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 4u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
- val = 0;
- UNIT_ASSERT_C(in.ReadWords<8>(val), (rem + ": " + NBitIO::PrintBits(val)).data());
- UNIT_ASSERT_VALUES_EQUAL_C(val, 0xabcdefU, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 8u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
- val = 0;
- UNIT_ASSERT_C(in.Read(val, 3), (rem + ", " + ToString(__LINE__)).data());
- UNIT_ASSERT_VALUES_EQUAL_C(val, 0x4u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 8u, (rem + ": " + NBitIO::PrintBits(val)));
- UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
- val = 0;
- in.Read(val, 7);
- UNIT_ASSERT_VALUES_EQUAL_C(val, 0x42u, (rem + ": " + NBitIO::PrintBits(val)));
- }
- {
- ui32 v = 0;
- DoRead(in, v);
- UNIT_ASSERT_VALUES_EQUAL_C(v, 1637415112ul, (rem + ": " + NBitIO::PrintBits(v)));
- DoRead(in, v);
- UNIT_ASSERT_VALUES_EQUAL_C(v, 897998715u, (rem + ": " + NBitIO::PrintBits(v)));
- DoRead(in, v);
- UNIT_ASSERT_VALUES_EQUAL_C(v, 201416527u, (rem + ": " + NBitIO::PrintBits(v)));
- DoRead(in, v);
- UNIT_ASSERT_VALUES_EQUAL_C(v, 432344219u, (rem + ": " + NBitIO::PrintBits(v)));
- UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 25u, (rem + ": " + NBitIO::PrintBits(v)));
- }
- {
- ui64 v8 = 0;
- in.ReadSafe(v8, 64);
- UNIT_ASSERT_VALUES_EQUAL_C(v8, 0xAAAAAAAAAAAAAAAAULL, (rem + ": " + NBitIO::PrintBits(v8)));
- UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 33u, (rem + ": " + NBitIO::PrintBits(v8)));
- v8 = 0;
- in.ReadK<64>(v8);
- UNIT_ASSERT_VALUES_EQUAL_C(v8, 0x5555555555555555ULL, (rem + ": " + NBitIO::PrintBits(v8)));
- UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 41u, (rem + ": " + NBitIO::PrintBits(v8)));
- }
- ui32 v = 0;
- UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
- UNIT_ASSERT_C(in.Read(v, 5), (rem + ", " + ToString(__LINE__)).data());
- UNIT_ASSERT_C(in.Eof(), (rem + ", " + ToString(__LINE__)).data());
- }
- void TestBitIO() {
- {
- TVec vec;
- {
- NBitIO::TBitOutputYVector out(&vec);
- DoBitOutput(out, ToString(__LINE__));
- }
- CheckBits(vec, NBitIO::BITS_REF, ToString(__LINE__).data());
- {
- TBi in(vec);
- DoBitInput(in, ToString(__LINE__));
- }
- }
- {
- TVec vec;
- vec.resize(41, 0);
- {
- NBitIO::TBitOutputArray out(vec.begin(), vec.size());
- DoBitOutput(out, ToString(__LINE__));
- }
- CheckBits(vec, NBitIO::BITS_REF, ToString(__LINE__).data());
- {
- TBi in(vec);
- DoBitInput(in, ToString(__LINE__));
- }
- }
- }
- };
- UNIT_TEST_SUITE_REGISTRATION(TBitIOTest);
|