Skip to content

Commit

Permalink
copy_n to copy_from_before
Browse files Browse the repository at this point in the history
Change-Id: I9322af2674ab583f3cdb286ea06385587bacf670
  • Loading branch information
garymm committed Mar 10, 2024
1 parent 6943db7 commit 6983463
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 18 deletions.
12 changes: 6 additions & 6 deletions src/decompress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,19 @@ auto decompress_block_huffman(
if (dst.size() - static_cast<std::size_t>(dst_written) < len) {
return DecompressStatus::DstTooSmall;
}
starflate::detail::copy_n(
dst.begin() + (dst_written - distance), len, dst.begin() + dst_written);
starflate::detail::copy_from_before(
dst.begin() + dst_written, distance, len);
dst_written += len;
}
return DecompressStatus::Success;
}

void copy_n(
std::span<const std::byte>::iterator src,
std::uint16_t n,
std::span<std::byte>::iterator dst)
/// Copy n bytes from distance bytes before dst to dst.
void copy_from_before(
std::span<std::byte>::iterator dst, std::uint16_t distance, std::uint16_t n)
{
std::ptrdiff_t n_signed{n};
const auto src = dst - distance;
while (n_signed > 0) {
const auto n_to_copy = std::min(n_signed, dst - src);
dst = std::copy_n(src, n_to_copy, dst);
Expand Down
19 changes: 10 additions & 9 deletions src/decompress.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,18 @@ constexpr auto lit_or_len_end_of_block = std::uint16_t{256};
constexpr auto lit_or_len_max = std::uint16_t{285};
constexpr auto lit_or_len_max_decoded = std::uint16_t{258};

/// Copies n bytes from src to dst, repeating the source data if necessary.
/// Copies n bytes from (dst - distance) to dst, handling overlap by repeating.
///
/// From the standard section 3.2.3:
/// "Note also that the referenced string may overlap the current
/// position; for example, if the last 2 bytes decoded have values
/// X and Y, a string reference with <length = 5, distance = 2>
/// adds X,Y,X,Y,X to the output stream."
void copy_n(
std::span<const std::byte>::iterator src,
std::uint16_t n,
std::span<std::byte>::iterator dst);
/// the referenced string may overlap the current position; for example, if the
/// last 2 bytes decoded have values X and Y, a string reference with
/// <length = 5, distance = 2> adds X,Y,X,Y,X to the output stream.
///
/// @pre dst - distance is valid.
void copy_from_before(
std::span<std::byte>::iterator dst,
std::uint16_t distance,
std::uint16_t n);
} // namespace detail

/// Decompresses the given source data into the destination buffer.
Expand Down
5 changes: 2 additions & 3 deletions src/test/decompress_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,10 @@ auto main(int, char* argv[]) -> int
expect(header->type == detail::BlockType::DynamicHuffman);
};

test("copy_n") = [] {
test("copy_from_before") = [] {
auto src_and_dst = huffman::byte_array(1, 2, 0, 0, 0, 0);
const auto src_span = std::span<const std::byte>{src_and_dst};
const auto dst_span = std::span<std::byte>{src_and_dst}.subspan(2);
detail::copy_n(src_span.begin(), 3, dst_span.begin());
detail::copy_from_before(dst_span.begin(), 2, 3);
expect(eq(src_and_dst, huffman::byte_array(1, 2, 1, 2, 1, 0)));
};
};

0 comments on commit 6983463

Please sign in to comment.