mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 04:57:44 +00:00
LibCompress: Move finishing the current XZ block into its own function
This commit is contained in:
parent
0e11e7012d
commit
68984abc43
2 changed files with 51 additions and 44 deletions
|
@ -252,6 +252,55 @@ ErrorOr<bool> XzDecompressor::load_next_stream()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorOr<void> XzDecompressor::finish_current_block()
|
||||||
|
{
|
||||||
|
auto unpadded_size = m_stream->read_bytes() - m_current_block_start_offset;
|
||||||
|
|
||||||
|
// 3.3. Block Padding:
|
||||||
|
// "Block Padding MUST contain 0-3 null bytes to make the size of
|
||||||
|
// the Block a multiple of four bytes. This can be needed when
|
||||||
|
// the size of Compressed Data is not a multiple of four."
|
||||||
|
for (size_t i = 0; (unpadded_size + i) % 4 != 0; i++) {
|
||||||
|
auto padding_byte = TRY(m_stream->read_value<u8>());
|
||||||
|
|
||||||
|
// "If any of the bytes in Block Padding are not null bytes, the decoder
|
||||||
|
// MUST indicate an error."
|
||||||
|
if (padding_byte != 0)
|
||||||
|
return Error::from_string_literal("XZ block contains a non-null padding byte");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3.4. Check:
|
||||||
|
// "The type and size of the Check field depends on which bits
|
||||||
|
// are set in the Stream Flags field (see Section 2.1.1.2).
|
||||||
|
//
|
||||||
|
// The Check, when used, is calculated from the original
|
||||||
|
// uncompressed data. If the calculated Check does not match the
|
||||||
|
// stored one, the decoder MUST indicate an error. If the selected
|
||||||
|
// type of Check is not supported by the decoder, it SHOULD
|
||||||
|
// indicate a warning or error."
|
||||||
|
auto maybe_check_size = size_for_check_type(m_stream_flags->check_type);
|
||||||
|
|
||||||
|
if (!maybe_check_size.has_value())
|
||||||
|
return Error::from_string_literal("XZ stream has an unknown check type");
|
||||||
|
|
||||||
|
// TODO: Block content checks are currently unimplemented as a whole, independent of the check type.
|
||||||
|
// For now, we only make sure to remove the correct amount of bytes from the stream.
|
||||||
|
TRY(m_stream->discard(*maybe_check_size));
|
||||||
|
unpadded_size += *maybe_check_size;
|
||||||
|
|
||||||
|
if (m_current_block_expected_uncompressed_size.has_value()) {
|
||||||
|
if (*m_current_block_expected_uncompressed_size != m_current_block_uncompressed_size)
|
||||||
|
return Error::from_string_literal("Uncompressed size of XZ block does not match the expected value");
|
||||||
|
}
|
||||||
|
|
||||||
|
TRY(m_processed_blocks.try_append({
|
||||||
|
.uncompressed_size = m_current_block_uncompressed_size,
|
||||||
|
.unpadded_size = unpadded_size,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
ErrorOr<Bytes> XzDecompressor::read_some(Bytes bytes)
|
ErrorOr<Bytes> XzDecompressor::read_some(Bytes bytes)
|
||||||
{
|
{
|
||||||
if (!m_stream_flags.has_value()) {
|
if (!m_stream_flags.has_value()) {
|
||||||
|
@ -262,50 +311,7 @@ ErrorOr<Bytes> XzDecompressor::read_some(Bytes bytes)
|
||||||
if (!m_current_block_stream.has_value() || (*m_current_block_stream)->is_eof()) {
|
if (!m_current_block_stream.has_value() || (*m_current_block_stream)->is_eof()) {
|
||||||
if (m_current_block_stream.has_value()) {
|
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.
|
// We have already processed a block, so we weed to clean up trailing data before the next block starts.
|
||||||
|
TRY(finish_current_block());
|
||||||
auto unpadded_size = m_stream->read_bytes() - m_current_block_start_offset;
|
|
||||||
|
|
||||||
// 3.3. Block Padding:
|
|
||||||
// "Block Padding MUST contain 0-3 null bytes to make the size of
|
|
||||||
// the Block a multiple of four bytes. This can be needed when
|
|
||||||
// the size of Compressed Data is not a multiple of four."
|
|
||||||
for (size_t i = 0; (unpadded_size + i) % 4 != 0; i++) {
|
|
||||||
auto padding_byte = TRY(m_stream->read_value<u8>());
|
|
||||||
|
|
||||||
// "If any of the bytes in Block Padding are not null bytes, the decoder
|
|
||||||
// MUST indicate an error."
|
|
||||||
if (padding_byte != 0)
|
|
||||||
return Error::from_string_literal("XZ block contains a non-null padding byte");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3.4. Check:
|
|
||||||
// "The type and size of the Check field depends on which bits
|
|
||||||
// are set in the Stream Flags field (see Section 2.1.1.2).
|
|
||||||
//
|
|
||||||
// The Check, when used, is calculated from the original
|
|
||||||
// uncompressed data. If the calculated Check does not match the
|
|
||||||
// stored one, the decoder MUST indicate an error. If the selected
|
|
||||||
// type of Check is not supported by the decoder, it SHOULD
|
|
||||||
// indicate a warning or error."
|
|
||||||
auto maybe_check_size = size_for_check_type(m_stream_flags->check_type);
|
|
||||||
|
|
||||||
if (!maybe_check_size.has_value())
|
|
||||||
return Error::from_string_literal("XZ stream has an unknown check type");
|
|
||||||
|
|
||||||
// TODO: Block content checks are currently unimplemented as a whole, independent of the check type.
|
|
||||||
// For now, we only make sure to remove the correct amount of bytes from the stream.
|
|
||||||
TRY(m_stream->discard(*maybe_check_size));
|
|
||||||
unpadded_size += *maybe_check_size;
|
|
||||||
|
|
||||||
if (m_current_block_expected_uncompressed_size.has_value()) {
|
|
||||||
if (*m_current_block_expected_uncompressed_size != m_current_block_uncompressed_size)
|
|
||||||
return Error::from_string_literal("Uncompressed size of XZ block does not match the expected value");
|
|
||||||
}
|
|
||||||
|
|
||||||
TRY(m_processed_blocks.try_append({
|
|
||||||
.uncompressed_size = m_current_block_uncompressed_size,
|
|
||||||
.unpadded_size = unpadded_size,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto start_of_current_block = m_stream->read_bytes();
|
auto start_of_current_block = m_stream->read_bytes();
|
||||||
|
|
|
@ -112,6 +112,7 @@ private:
|
||||||
XzDecompressor(NonnullOwnPtr<CountingStream>);
|
XzDecompressor(NonnullOwnPtr<CountingStream>);
|
||||||
|
|
||||||
ErrorOr<bool> load_next_stream();
|
ErrorOr<bool> load_next_stream();
|
||||||
|
ErrorOr<void> finish_current_block();
|
||||||
|
|
||||||
NonnullOwnPtr<CountingStream> m_stream;
|
NonnullOwnPtr<CountingStream> m_stream;
|
||||||
Optional<XzStreamFlags> m_stream_flags;
|
Optional<XzStreamFlags> m_stream_flags;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue