1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 10:17:35 +00:00

LibCompress: Move finishing the current XZ stream into its own function

This commit is contained in:
Tim Schumacher 2023-04-05 16:41:05 +02:00 committed by Brian Gianforcaro
parent 68984abc43
commit e6b1e1bb33
2 changed files with 106 additions and 96 deletions

View file

@ -301,30 +301,10 @@ ErrorOr<void> XzDecompressor::finish_current_block()
return {};
}
ErrorOr<Bytes> XzDecompressor::read_some(Bytes bytes)
ErrorOr<void> XzDecompressor::finish_current_stream()
{
if (!m_stream_flags.has_value()) {
if (!TRY(load_next_stream()))
return bytes.trim(0);
}
if (!m_current_block_stream.has_value() || (*m_current_block_stream)->is_eof()) {
if (m_current_block_stream.has_value()) {
// We have already processed a block, so we weed to clean up trailing data before the next block starts.
TRY(finish_current_block());
}
auto start_of_current_block = m_stream->read_bytes();
// Ensure that the start of the block is aligned to a multiple of four (in theory, everything in XZ is).
VERIFY(start_of_current_block % 4 == 0);
// The first byte between Block Header (3.1.1. Block Header Size) and Index (4.1. Index Indicator) overlap.
// Block header sizes have valid values in the range of [0x01, 0xFF], the only valid value for an Index Indicator is therefore 0x00.
auto encoded_block_header_size_or_index_indicator = TRY(m_stream->read_value<u8>());
if (encoded_block_header_size_or_index_indicator == 0x00) {
// This is an Index.
// We already read the Index Indicator (one byte) to determine that this is an Index.
auto start_of_current_block = m_stream->read_bytes() - 1;
// 4.2. Number of Records:
// "This field indicates how many Records there are in the List
@ -421,6 +401,35 @@ ErrorOr<Bytes> XzDecompressor::read_some(Bytes bytes)
if (Bytes { &*m_stream_flags, sizeof(XzStreamFlags) } != Bytes { &stream_footer.flags, sizeof(stream_footer.flags) })
return Error::from_string_literal("XZ stream header flags don't match the stream footer");
return {};
}
ErrorOr<Bytes> XzDecompressor::read_some(Bytes bytes)
{
if (!m_stream_flags.has_value()) {
if (!TRY(load_next_stream()))
return bytes.trim(0);
}
if (!m_current_block_stream.has_value() || (*m_current_block_stream)->is_eof()) {
if (m_current_block_stream.has_value()) {
// We have already processed a block, so we weed to clean up trailing data before the next block starts.
TRY(finish_current_block());
}
auto start_of_current_block = m_stream->read_bytes();
// Ensure that the start of the block is aligned to a multiple of four (in theory, everything in XZ is).
VERIFY(start_of_current_block % 4 == 0);
// The first byte between Block Header (3.1.1. Block Header Size) and Index (4.1. Index Indicator) overlap.
// Block header sizes have valid values in the range of [0x01, 0xFF], the only valid value for an Index Indicator is therefore 0x00.
auto encoded_block_header_size_or_index_indicator = TRY(m_stream->read_value<u8>());
if (encoded_block_header_size_or_index_indicator == 0x00) {
// This is an Index, which is the last element before the stream footer.
TRY(finish_current_stream());
// Another XZ Stream might follow, so we just unset the current information and continue on the next read.
m_stream_flags.clear();
m_processed_blocks.clear();

View file

@ -113,6 +113,7 @@ private:
ErrorOr<bool> load_next_stream();
ErrorOr<void> finish_current_block();
ErrorOr<void> finish_current_stream();
NonnullOwnPtr<CountingStream> m_stream;
Optional<XzStreamFlags> m_stream_flags;