Decode the whole `bytes` into a bitmap and check it against `expected`. Decode `chunk_size` values per GetBatch call to check the decoder state between calls. The output starts at bit offset `out_offset`. A non-zero offset makes the output and the encoded `bytes` use different bit alignment.
| 409 | /// calls. The output starts at bit offset `out_offset`. A non-zero offset makes |
| 410 | /// the output and the encoded `bytes` use different bit alignment. |
| 411 | void CheckRleBitPackedDecode(const std::vector<uint8_t>& bytes, |
| 412 | const std::vector<bool>& expected, rle_size_t chunk_size, |
| 413 | rle_size_t out_offset = 0) { |
| 414 | ARROW_SCOPED_TRACE("chunk_size = ", chunk_size, ", out_offset = ", out_offset); |
| 415 | const auto n_vals = static_cast<rle_size_t>(expected.size()); |
| 416 | |
| 417 | RleBitPackedToBitmapDecoder decoder(bytes.data(), |
| 418 | static_cast<rle_size_t>(bytes.size())); |
| 419 | EXPECT_EQ(decoder.exhausted(), n_vals == 0); |
| 420 | |
| 421 | // Output buffer with one guard byte to catch out-of-bounds writes. |
| 422 | std::vector<uint8_t> out( |
| 423 | static_cast<size_t>(bit_util::BytesForBits(out_offset + n_vals)) + 1, 0); |
| 424 | const uint8_t guard = 0xA5; |
| 425 | out.back() = guard; |
| 426 | |
| 427 | rle_size_t read = 0; |
| 428 | while (read < n_vals) { |
| 429 | const auto want = std::min(chunk_size, n_vals - read); |
| 430 | const auto got = decoder.GetBatch( |
| 431 | BitmapSpanMut(out.data(), /*bit_start=*/out_offset + read), want); |
| 432 | EXPECT_EQ(got, want) << "at pos " << read; |
| 433 | ASSERT_GT(got, 0) << "at pos " << read; // break on failure |
| 434 | read += got; |
| 435 | } |
| 436 | |
| 437 | EXPECT_EQ(read, n_vals); |
| 438 | EXPECT_TRUE(decoder.exhausted()); |
| 439 | // Reading past the end yields nothing and leaves the decoder exhausted. |
| 440 | uint8_t scratch = 0; |
| 441 | const auto past_end = decoder.GetBatch(BitmapSpanMut(&scratch), 8); |
| 442 | EXPECT_EQ(past_end, 0); |
| 443 | EXPECT_TRUE(decoder.exhausted()); |
| 444 | |
| 445 | EXPECT_EQ(out.back(), guard) << "decoder wrote past the end of the output"; |
| 446 | CheckDecodedBits({ |
| 447 | .actual = out, |
| 448 | .expected = expected, |
| 449 | .count = n_vals, |
| 450 | .actual_start_bit = out_offset, |
| 451 | }); |
| 452 | } |
| 453 | |
| 454 | /// Run the decode check over a battery of chunk sizes and output offsets. |
| 455 | void CheckRleBitPackedToBitmap(const std::vector<uint8_t>& bytes, |
no test coverage detected