Skip to content

Commit

Permalink
move pop_n to decompress.cpp
Browse files Browse the repository at this point in the history
Change-Id: I5ec6e616b5ec5d33fb221e196fd9976702175bf8
  • Loading branch information
garymm committed Mar 10, 2024
1 parent f5faa04 commit 58f3d2e
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 31 deletions.
19 changes: 0 additions & 19 deletions huffman/src/bit_span.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,25 +143,6 @@ class bit_span : public std::ranges::view_interface<bit_span>

constexpr auto pop_16() -> std::uint16_t { return pop<std::uint16_t>(); }

/// Removes n bits from the beginning of this and returns them.
///
/// @pre this contains at least n bits.
///
constexpr auto pop_n(std::uint8_t n) -> std::uint16_t
{
assert(n <= 16);
assert(n <= bit_size_);
auto iter = begin();
std::uint16_t res{};
for (std::uint8_t i{}; i < n; i++) {
res |= static_cast<std::uint16_t>(
static_cast<std::uint16_t>(static_cast<bool>(*iter)) << i);
iter += 1;
}
consume(n); // invalidates iter, so must come after the loop
return res;
}

/// Consumes the given number of bits. Advances the start of the view.
///
/// @pre n <= std::ranges::size(*this)
Expand Down
10 changes: 0 additions & 10 deletions huffman/test/bit_span_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <array>
#include <climits>
#include <cstdint>
#include <numeric>
#include <ranges>
#include <vector>

Expand Down Expand Up @@ -175,15 +174,6 @@ auto main() -> int
expect(eq(got_8, expected_8));

expect(aborts([&] { span.pop_8(); }));

span = huffman::bit_span{data};
const std::uint16_t got_5{span.pop_n(5)};
constexpr std::uint16_t expected_5{0b01010};
expect(eq(got_5, expected_5));

const std::uint16_t got_3{span.pop_n(3)};
constexpr std::uint16_t expected_3{0b101};
expect(eq(got_3, expected_3));
// NOLINTEND(readability-magic-numbers)
};
}
27 changes: 25 additions & 2 deletions src/decompress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,28 @@ constexpr auto distance_infos = std::array<LengthInfo, 30>{
{9, 1025}, {9, 1537}, {10, 2049}, {10, 3073}, {11, 4097},
{11, 6145}, {12, 8193}, {12, 12289}, {13, 16385}, {13, 24577}}};

/// Removes n bits from the beginning of bits and returns them.
///
/// @pre bits contains at least n bits.
/// @pre n <= 16
///
/// @returns the n bits removed from the beginning of this.
/// The bits are in the lower (rightmost) part of the return value.
///
auto pop_extra_bits(huffman::bit_span& bits, std::uint8_t n) -> std::uint16_t
{
assert(n <= 16);
auto iter = bits.begin();
std::uint16_t res{};
for (std::uint8_t i{}; i < n; i++) {
res |= static_cast<std::uint16_t>(
static_cast<std::uint16_t>(static_cast<bool>(*iter)) << i);
iter += 1;
}
bits.consume(n); // invalidates iter, so must come after the loop
return res;
}

enum class ParseLitOrLenStatus : std::uint8_t
{
EndOfBlock,
Expand Down Expand Up @@ -100,7 +122,7 @@ auto parse_lit_or_len(
static_cast<size_t>(lit_or_len - detail::lit_or_len_end_of_block - 1);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index)
const auto& len_info = detail::length_infos[len_idx];
const auto extra_len = src_bits.pop_n(len_info.extra_bits);
const auto extra_len = pop_extra_bits(src_bits, len_info.extra_bits);
len = len_info.base + extra_len;
}
return len;
Expand Down Expand Up @@ -136,6 +158,7 @@ auto decompress_block_huffman(
dst[static_cast<size_t>(dst_written++)] = std::get<std::byte>(lit_or_len);
continue;
}
// It's not a literal, so handle length and distance
const auto len = std::get<std::uint16_t>(lit_or_len);
const auto dist_decoded = huffman::decode_one(dist_table, src_bits);
const auto dist_code = dist_decoded.symbol;
Expand All @@ -149,7 +172,7 @@ auto decompress_block_huffman(
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index)
const auto& dist_info = detail::distance_infos[dist_code];
const std::uint16_t distance =
dist_info.base + src_bits.pop_n(dist_info.extra_bits);
dist_info.base + pop_extra_bits(src_bits, dist_info.extra_bits);
if (distance > dst_written) {
return DecompressStatus::InvalidDistance;
}

Check warning on line 178 in src/decompress.cpp

View check run for this annotation

Codecov / codecov/patch

src/decompress.cpp#L177-L178

Added lines #L177 - L178 were not covered by tests
Expand Down

0 comments on commit 58f3d2e

Please sign in to comment.