29#include <jau/test/catch2_ext.hpp>
43 REQUIRE(
true ==
true );
55 for(
size_t i=0; i<bitCount; ) {
56 for(
size_t j=64; i<bitCount && j-- > 0; ++i) {
57 REQUIRE(
true == source.
put(i, in[j] ==
'1'));
68 const nsize_t bitCount = preBits + skipBits + postBits;
69 const nsize_t byteCount = (bitCount + 7) / 8;
72 fprintf(stderr,
"TestStream.0: bitOrder[data %s], bits[pre %zu, skip %zu, post %zu = %zu]: %s\n",
74 (
size_t)preBits, (
size_t)skipBits, (
size_t)postBits, (
size_t)bitCount, bsTest.
toString().c_str());
75 std::cerr << source <<
"\n";
77 for(
nsize_t i = 0; i < bitCount; i++ ) {
78 REQUIRE(
true == bsTest.
writeBit(source[i]) );
81 CHECK(preBits + skipBits + postBits == bsTest.
position());
84 fprintf(stderr,
"TestData.X: %s\n", bsTest.
toString().c_str());
85 REQUIRE(0 == bsTest.
seek(0));
93 fprintf(stderr,
"TestString: bitOrder %s, preBits %zu, skipBits %zu, postBits %zu, totalBits %zu\n",
94 jau::to_string(dataBitOrder).c_str(), (
size_t)preBits, (
size_t)skipBits, (
size_t)postBits, (
size_t)totalBits);
97 std::cerr << source <<
"\n";
98 const auto [pre, preOK] = source.
subbits(0, preBits);
99 const auto [post, postOK] = source.
subbits(preBits+skipBits, postBits);
100 REQUIRE(
true == preOK);
101 REQUIRE(
true == postOK);
104 REQUIRE(
true == r.
put(0, pre));
105 REQUIRE(
true == r.
put(preBits, post));
106 std::cerr <<
"ResultExp: <" << pre <<
"> + <" << post <<
"> = <" << r <<
">\n";
107 REQUIRE(totalBits == r.
size());
113 fprintf(stderr,
"ReadBits.0: count[pre %zu, actual %zu]: %s\n", (
size_t)preCount, (
size_t)count, input.
toString().c_str());
115 fprintf(stderr,
"ReadBits.0c: %s\n", copy->toString().c_str());
120 const int bit = input.
readBit();
125 const char c = ( 0 != bit ) ?
'1' :
'0';
126 sbRead.insert(0, 1, c);
129 REQUIRE(i+preCount == input.
position());
131 REQUIRE(
true == copy->writeBit(bit));
133 REQUIRE(i+preCount == copy->position());
137 fprintf(stderr,
"ReadBits.2: %s\n", input.
toString().c_str());
138 REQUIRE(i+preCount == input.
position());
140 fprintf(stderr,
"ReadBits.2c: %s\n", copy->toString().c_str());
141 REQUIRE(i+preCount == copy->position());
147 const nsize_t totalBits = preBits+skipBits+postBits;
148 fprintf(stderr,
"XXX TestLinearBits: bitOrder %s, preBits %zu, skipBits %zu, postBits %zu, totalBits %zu\n",
149 jau::to_string(bitOrder).c_str(), (
size_t)preBits, (
size_t)skipBits, (
size_t)postBits, (
size_t)totalBits);
152 std::cerr <<
"Prepare bitstream\n";
157 const nsize_t byteCount = ( totalBits + 7 ) / 8;
161 std::cerr <<
"Reading bitstream: <" << sTest <<
"> from " << bsTest <<
"\n";
163 const std::string sReadPre =
readBits(&bsCopy, bsTest, 0, preBits);
164 REQUIRE(skipBits == bsTest.
skip(skipBits));
165 REQUIRE(skipBits == bsCopy.
skip(skipBits));
167 const std::string sReadPost =
readBits(&bsCopy, bsTest, preBits+skipBits, postBits);
168 const std::string sRead = sReadPost + sReadPre;
169 std::cerr <<
"Read.Test: <" << sTest <<
"> == <" << sReadPre <<
"> + <" << sReadPost <<
"> = <" << sRead <<
">\n";
170 REQUIRE(sTest == sRead);
171 REQUIRE(totalBits == bsTest.
position());
172 REQUIRE(totalBits == bsCopy.
position());
178 REQUIRE(0 == bsTest.
seek(0));
180 std::cerr <<
"Reading copy-bitstream: " << bsCopy <<
"\n";
181 REQUIRE(
true == bsCopy.
setMark(0));
184 const std::string sReadPre1 =
readBits(
nullptr, bsCopy, 0, preBits);
185 REQUIRE(skipBits == bsCopy.
skip(skipBits));
187 const std::string sReadPost1 =
readBits(
nullptr, bsCopy, preBits+skipBits, postBits);
188 const std::string sRead1 = sReadPost1 + sReadPre1;
189 REQUIRE(sTest == sRead1);
192 const std::string sReadPre2 =
readBits(
nullptr, bsCopy, 0, preBits);
193 REQUIRE(sReadPre1 == sReadPre2);
194 REQUIRE(skipBits == bsCopy.
skip(skipBits));
196 const std::string sReadPost2 =
readBits(
nullptr, bsCopy, preBits+skipBits, postBits);
197 REQUIRE(sReadPost1 == sReadPost2);
198 const std::string sRead2 = sReadPost2 + sReadPre2;
199 REQUIRE(sTest == sRead2);
200 REQUIRE(totalBits == bsCopy.
position());
242TEST_CASE(
"Bitstream Test 01 LinearBitsMSBFirst",
"[bitstream]" ) {
246TEST_CASE(
"Bitstream Test 02 LinearBitsLSBFirst",
"[bitstream]" ) {
255 const nsize_t totalBits = preBits+skipBits+postBits;
256 fprintf(stderr,
"XXX TestBulkBits: preBits %zu, skipBits %zu, postBits %zu, totalBits %zu\n",
257 (
size_t)preBits, (
size_t)skipBits, (
size_t)postBits, (
size_t)totalBits);
260 std::cerr <<
"Prepare bitstream\n";
265 const nsize_t byteCount = ( totalBits + 7 ) / 8;
269 std::cerr <<
"Reading bitstream: <" << sTest <<
"> from " << bsTest <<
"\n";
271 uint64_t readBitsPre;
272 REQUIRE(preBits == bsTest.
readBits64(preBits, readBitsPre));
273 REQUIRE(preBits == bsCopy.
writeBits64(preBits, readBitsPre));
275 REQUIRE(skipBits == bsTest.
skip(skipBits));
276 REQUIRE(skipBits == bsCopy.
skip(skipBits));
278 uint64_t readBitsPost;
279 REQUIRE(postBits == bsTest.
readBits64(postBits, readBitsPost));
280 REQUIRE(postBits == bsCopy.
writeBits64(postBits, readBitsPost));
284 const std::string sRead = sReadPostHi + sReadPreLo;
285 std::cerr <<
"Read.Test: <" << sTest <<
"> == <" << sReadPreLo <<
"> + <" << sReadPostHi <<
"> = <" << sRead <<
">\n";
287 REQUIRE(sTest == sRead);
288 REQUIRE(totalBits == bsTest.
position());
289 REQUIRE(totalBits == bsCopy.
position());
296 std::cerr <<
"Reading copy-bitstream: " << bsCopy <<
"\n";
297 REQUIRE(
true == bsCopy.
setMark(0));
300 uint64_t copyBitsPre;
301 REQUIRE(preBits == bsCopy.
readBits64(preBits, copyBitsPre));
302 REQUIRE(skipBits == bsCopy.
skip(skipBits));
304 uint64_t copyBitsPost;
305 REQUIRE(postBits == bsCopy.
readBits64(postBits, copyBitsPost));
309 const std::string sRead = sReadPostHi + sReadPreLo;
310 std::cerr <<
"Copy.Test: <" << sTest <<
"> == <" << sReadPreLo <<
"> + <" << sReadPostHi <<
"> = <" << sRead <<
">\n";
312 REQUIRE(sTest == sRead);
313 REQUIRE(totalBits == bsCopy.
position());
317TEST_CASE(
"Bitstream Test 11 BulkBitsLSBFirst",
"[bitstream]" ) {
351TEST_CASE(
"Bitstream Test 21 ErrorHandling",
"[bitstream]" ) {
353 std::cerr <<
"x0 " << bsTest <<
"\n";
354 std::cerr <<
"x0 " << bsTest.
byteStream() <<
"\n";
357 REQUIRE(-1 == bsTest.
readBit());
360 REQUIRE(
false == bsTest.
canWrite());
361 REQUIRE(
false == bsTest.
writeBit(1));
365 REQUIRE(
true == bsTest.
writeBit(1));
368 REQUIRE(
false == bsTest.
canWrite());
369 REQUIRE(1 == bsTest.
readBit());
static void dumpData(const std::string &prefix, const uint8_t *data, size_t len)
static constexpr std::string_view testStringMSB64_be
Simple dynamically heap-sized bitheap for efficient bit storage access in O(1).
std::string toString(size_type bitpos, size_type length, PrefixOpt prefix=PrefixOpt::none) const noexcept
std::pair< bitheap, bool > subbits(size_type bitpos, size_type length) const noexcept
constexpr size_type size() const noexcept
Returns storage size in bits.
constexpr bool put(size_type bitpos, bool v) noexcept
Writes the bit value v to position bitpos into this storage.
constexpr bitheap & reverse() noexcept
Versatile Bitstream implementation supporting:
size_type seek(size_type newPos) noexcept
Sets this stream's bit position.
std::string toString() const
bool setAccess(ioaccess_t access) noexcept
Changes the access-mode to write or read and resets position and cache to zero.
bool setImmutable() noexcept
Changes the write-mode to read, sets the underlying ByteStream to read-only and resets position and c...
constexpr bool canWrite() const noexcept
Returns true in case stream is in write mode, false if in read mode.
bool writeBit(uint8_t bit) noexcept
Write given bit in least-significant-bit (LSB) first order.
bool setMark(size_type readLimit) noexcept
Set markpos to current bit-position, allowing the stream to be seekMark().
ByteStream & byteStream()
Returns the used underlying ByteStream.
size_type skip(size_type n) noexcept
Skip given number of bits.
jau::nsize_t readBits64(jau::nsize_t n, data_type &r) noexcept
Read incoming bits in least-significant-bit (LSB) first order.
int readBit() noexcept
Read incoming bit in least-significant-bit (LSB) first order.
bool seekMark() noexcept
Seeks stream bit-position to markpos as set via setMark().
jau::nsize_t writeBits64(jau::nsize_t n, data_type bits) noexcept
Write given bits in least-significant-bit (LSB) first order.
size_type position() const noexcept
Returns the bit position in the stream.
@ rw
Read and write capabilities, i.e.
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
std::string toBitString(const void *data, const nsize_t length, const bit_order_t bitOrder=bit_order_t::msb, const PrefixOpt prefix=PrefixOpt::prefix, size_t bit_len=0) noexcept
Produce a binary string representation of the given lsb-first byte values.
bit_order_t
Bit order type, i.e.
@ lsb
Identifier for least-significant-bit (lsb) first.
@ msb
Identifier for most-significant-bit (msb) first.
std::string to_string(const bit_order_t v) noexcept
Return std::string representation of the given bit_order_t.
static void testBulkBitsImpl(const nsize_t preBits, const nsize_t skipBits, const nsize_t postBits)
static std::string getTestStreamResultAsString(const jau::bit_order_t dataBitOrder, const jau::nsize_t preBits, const jau::nsize_t skipBits, const jau::nsize_t postBits)
static void testLinearBitsImpl(const jau::bit_order_t bitOrder, const nsize_t preBits, const nsize_t skipBits, const nsize_t postBits)
static jau::io::Bitstream getTestStream(const jau::bit_order_t dataBitOrder, const nsize_t preBits, const nsize_t skipBits, const nsize_t postBits)
static std::string readBits(jau::io::Bitstream *copy, jau::io::Bitstream &input, const nsize_t preCount, const nsize_t count)
TEST_CASE("Bitstream Test 00", "[bitstream]")
static jau::bitheap getBitfield(const jau::nsize_t bitCount, const jau::bit_order_t bitOrder)