bitinout_ut.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. #include "bitinput.h"
  2. #include "bitoutput.h"
  3. #include <library/cpp/testing/unittest/registar.h>
  4. #include <util/stream/buffer.h>
  5. #include <util/generic/buffer.h>
  6. namespace NBitIO {
  7. static const char BITS_REF[] =
  8. "00100010 01000000 00000000 00100111 11011111 01100111 11010101 00010100 "
  9. "00100010 01100011 11100011 00110000 11011011 11011111 01001100 00110101 "
  10. "10011110 01011111 01010000 00000110 00011011 00100110 00010100 01110011 "
  11. "00001010 10101010 10101010 10101010 10101010 10101010 10101010 10101010 "
  12. "10110101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 "
  13. "01000000";
  14. inline ui64 Bits(ui64 bytes) {
  15. return bytes << 3ULL;
  16. }
  17. inline TString PrintBits(const char* a, const char* b, bool reverse = false) {
  18. TString s;
  19. TStringOutput out(s);
  20. for (const char* it = a; it != b; ++it) {
  21. if (it != a)
  22. out << ' ';
  23. ui8 byte = *it;
  24. if (reverse)
  25. byte = ReverseBits(byte);
  26. for (ui32 mask = 1; mask < 0xff; mask <<= 1) {
  27. out << ((byte & mask) ? '1' : '0');
  28. }
  29. }
  30. return s;
  31. }
  32. template <typename T>
  33. inline TString PrintBits(T t, ui32 bits = Bits(sizeof(T))) {
  34. return PrintBits((char*)&t, ((char*)&t) + BytesUp(bits));
  35. }
  36. }
  37. class TBitIOTest: public TTestBase {
  38. UNIT_TEST_SUITE(TBitIOTest);
  39. UNIT_TEST(TestBitIO)
  40. UNIT_TEST_SUITE_END();
  41. private:
  42. using TBi = NBitIO::TBitInput;
  43. using TVec = TVector<char>;
  44. void static CheckBits(const TVec& v, const TString& ref, const TString& rem) {
  45. UNIT_ASSERT_VALUES_EQUAL_C(NBitIO::PrintBits(v.begin(), v.end()), ref, rem);
  46. }
  47. void DoRead(TBi& b, ui32& t) {
  48. b.Read(t, 1, 0); // 1
  49. b.ReadK<3>(t, 1); // 4
  50. b.Read(t, 5, 4); // 9
  51. b.ReadK<14>(t, 9); // 23
  52. b.Read(t, 1, 23); // 24
  53. b.ReadK<5>(t, 24); // 29
  54. b.Read(t, 3, 29); // 32
  55. }
  56. template <typename TBo>
  57. void DoWrite(TBo& b, ui32 t) {
  58. b.Write(t, 1, 0); //1
  59. b.Write(t, 3, 1); //4
  60. b.Write(t, 5, 4); //9
  61. b.Write(t, 14, 9); //23
  62. b.Write(t, 1, 23); //24
  63. b.Write(t, 5, 24); //29
  64. b.Write(t, 3, 29); //32
  65. }
  66. template <typename TBo>
  67. void DoWrite1(TBo& out, const TString& rem) {
  68. out.Write(0x0C, 3);
  69. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 1u, (rem + ", " + ToString(__LINE__)));
  70. out.Write(0x18, 4);
  71. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 1u, (rem + ", " + ToString(__LINE__)));
  72. out.Write(0x0C, 3);
  73. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 2u, (rem + ", " + ToString(__LINE__)));
  74. out.Write(0x30000, 17);
  75. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 4u, (rem + ", " + ToString(__LINE__)));
  76. out.Write(0x0C, 3);
  77. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 4u, (rem + ", " + ToString(__LINE__)));
  78. }
  79. template <typename TBo>
  80. void DoWrite2(TBo& out, const TString& rem) {
  81. out.Write(0x0C, 3);
  82. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 8u, (rem + ", " + ToString(__LINE__)));
  83. out.Write(0x42, 7);
  84. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 9u, (rem + ", " + ToString(__LINE__)));
  85. DoWrite(out, 1637415112);
  86. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 13u, (rem + ", " + ToString(__LINE__)));
  87. DoWrite(out, 897998715);
  88. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 17u, (rem + ", " + ToString(__LINE__)));
  89. DoWrite(out, 201416527);
  90. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 21u, (rem + ", " + ToString(__LINE__)));
  91. DoWrite(out, 432344219);
  92. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 25u, (rem + ", " + ToString(__LINE__)));
  93. out.Write(0xAAAAAAAAAAAAAAAAULL, 64);
  94. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 33u, (rem + ", " + ToString(__LINE__)));
  95. out.Write(0x5555555555555555ULL, 64);
  96. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 41u, (rem + ", " + ToString(__LINE__)));
  97. }
  98. void DoBitOutput(NBitIO::TBitOutputYVector& out, const TString& rem) {
  99. DoWrite1(out, rem);
  100. out.WriteWords<8>(0xabcdef);
  101. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 8u, (rem + ", " + ToString(__LINE__)));
  102. DoWrite2(out, rem);
  103. }
  104. void DoBitOutput(NBitIO::TBitOutputArray& out, const TString& rem) {
  105. DoWrite1(out, rem);
  106. out.WriteWords<8>(0xabcdef);
  107. UNIT_ASSERT_VALUES_EQUAL_C(out.GetOffset(), 8u, (rem + ", " + ToString(__LINE__)));
  108. DoWrite2(out, rem);
  109. }
  110. void DoBitInput(TBi& in, const TString& rem) {
  111. UNIT_ASSERT(!in.Eof());
  112. {
  113. ui64 val;
  114. val = 0;
  115. UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 0u, (rem + ": " + NBitIO::PrintBits(val)));
  116. UNIT_ASSERT_C(in.Read(val, 3), (rem + ": " + NBitIO::PrintBits(val)).data());
  117. UNIT_ASSERT_VALUES_EQUAL_C(val, 0x4u, (rem + ": " + NBitIO::PrintBits(val)));
  118. UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 1u, (rem + ": " + NBitIO::PrintBits(val)));
  119. UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
  120. val = 0;
  121. UNIT_ASSERT_C(in.Read(val, 4), (rem + ": " + NBitIO::PrintBits(val)).data());
  122. UNIT_ASSERT_VALUES_EQUAL_C(val, 0x8u, (rem + ": " + NBitIO::PrintBits(val)));
  123. UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 1u, (rem + ": " + NBitIO::PrintBits(val)));
  124. UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
  125. val = 0;
  126. UNIT_ASSERT_C(in.Read(val, 3), (rem + ": " + NBitIO::PrintBits(val)).data());
  127. UNIT_ASSERT_VALUES_EQUAL_C(val, 0x4u, (rem + ": " + NBitIO::PrintBits(val)));
  128. UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 2u, (rem + ": " + NBitIO::PrintBits(val)));
  129. UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
  130. val = 0;
  131. UNIT_ASSERT_C(in.Read(val, 17), (rem + ": " + NBitIO::PrintBits(val)).data());
  132. UNIT_ASSERT_VALUES_EQUAL_C(val, 0x10000u, (rem + ": " + NBitIO::PrintBits(val)));
  133. UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 4u, (rem + ": " + NBitIO::PrintBits(val)));
  134. UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
  135. UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 4u, (rem + ": " + NBitIO::PrintBits(val)));
  136. {
  137. ui32 rt = 0;
  138. in.ReadRandom(30, rt, 10, 20);
  139. UNIT_ASSERT_STRINGS_EQUAL(NBitIO::PrintBits(rt).data(), "00000000 00000000 00001111 01111100");
  140. }
  141. val = 0;
  142. UNIT_ASSERT_C(in.Read(val, 3), (rem + ": " + NBitIO::PrintBits(val)).data());
  143. UNIT_ASSERT_VALUES_EQUAL_C(val, 0x4u, (rem + ": " + NBitIO::PrintBits(val)));
  144. UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 4u, (rem + ": " + NBitIO::PrintBits(val)));
  145. UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
  146. val = 0;
  147. UNIT_ASSERT_C(in.ReadWords<8>(val), (rem + ": " + NBitIO::PrintBits(val)).data());
  148. UNIT_ASSERT_VALUES_EQUAL_C(val, 0xabcdefU, (rem + ": " + NBitIO::PrintBits(val)));
  149. UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 8u, (rem + ": " + NBitIO::PrintBits(val)));
  150. UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
  151. val = 0;
  152. UNIT_ASSERT_C(in.Read(val, 3), (rem + ", " + ToString(__LINE__)).data());
  153. UNIT_ASSERT_VALUES_EQUAL_C(val, 0x4u, (rem + ": " + NBitIO::PrintBits(val)));
  154. UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 8u, (rem + ": " + NBitIO::PrintBits(val)));
  155. UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
  156. val = 0;
  157. in.Read(val, 7);
  158. UNIT_ASSERT_VALUES_EQUAL_C(val, 0x42u, (rem + ": " + NBitIO::PrintBits(val)));
  159. }
  160. {
  161. ui32 v = 0;
  162. DoRead(in, v);
  163. UNIT_ASSERT_VALUES_EQUAL_C(v, 1637415112ul, (rem + ": " + NBitIO::PrintBits(v)));
  164. DoRead(in, v);
  165. UNIT_ASSERT_VALUES_EQUAL_C(v, 897998715u, (rem + ": " + NBitIO::PrintBits(v)));
  166. DoRead(in, v);
  167. UNIT_ASSERT_VALUES_EQUAL_C(v, 201416527u, (rem + ": " + NBitIO::PrintBits(v)));
  168. DoRead(in, v);
  169. UNIT_ASSERT_VALUES_EQUAL_C(v, 432344219u, (rem + ": " + NBitIO::PrintBits(v)));
  170. UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 25u, (rem + ": " + NBitIO::PrintBits(v)));
  171. }
  172. {
  173. ui64 v8 = 0;
  174. in.ReadSafe(v8, 64);
  175. UNIT_ASSERT_VALUES_EQUAL_C(v8, 0xAAAAAAAAAAAAAAAAULL, (rem + ": " + NBitIO::PrintBits(v8)));
  176. UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 33u, (rem + ": " + NBitIO::PrintBits(v8)));
  177. v8 = 0;
  178. in.ReadK<64>(v8);
  179. UNIT_ASSERT_VALUES_EQUAL_C(v8, 0x5555555555555555ULL, (rem + ": " + NBitIO::PrintBits(v8)));
  180. UNIT_ASSERT_VALUES_EQUAL_C(in.GetOffset(), 41u, (rem + ": " + NBitIO::PrintBits(v8)));
  181. }
  182. ui32 v = 0;
  183. UNIT_ASSERT_C(!in.Eof(), (rem + ", " + ToString(__LINE__)).data());
  184. UNIT_ASSERT_C(in.Read(v, 5), (rem + ", " + ToString(__LINE__)).data());
  185. UNIT_ASSERT_C(in.Eof(), (rem + ", " + ToString(__LINE__)).data());
  186. }
  187. void TestBitIO() {
  188. {
  189. TVec vec;
  190. {
  191. NBitIO::TBitOutputYVector out(&vec);
  192. DoBitOutput(out, ToString(__LINE__));
  193. }
  194. CheckBits(vec, NBitIO::BITS_REF, ToString(__LINE__).data());
  195. {
  196. TBi in(vec);
  197. DoBitInput(in, ToString(__LINE__));
  198. }
  199. }
  200. {
  201. TVec vec;
  202. vec.resize(41, 0);
  203. {
  204. NBitIO::TBitOutputArray out(vec.begin(), vec.size());
  205. DoBitOutput(out, ToString(__LINE__));
  206. }
  207. CheckBits(vec, NBitIO::BITS_REF, ToString(__LINE__).data());
  208. {
  209. TBi in(vec);
  210. DoBitInput(in, ToString(__LINE__));
  211. }
  212. }
  213. }
  214. };
  215. UNIT_TEST_SUITE_REGISTRATION(TBitIOTest);