#[cfg(feature = "lzma2")]
use std::io::Write;
#[cfg(feature = "lzma2")]
use crate::Result;
#[cfg(feature = "lzma2")]
use crate::format::property_id;
#[cfg(feature = "lzma2")]
use crate::format::reader::write_variable_u64;
#[cfg(feature = "lzma2")]
const COMPRESSION_THRESHOLD: usize = 512;
#[cfg(feature = "lzma2")]
pub(crate) fn encode_compressed_header(
plain_header: &[u8],
pack_pos: u64,
) -> Result<Option<(Vec<u8>, Vec<u8>)>> {
use crate::codec::method;
use crate::write::header_encryption::lzma2_dictionary_property;
if plain_header.len() < COMPRESSION_THRESHOLD {
return Ok(None);
}
let compressed = {
use lzma_rust2::{Lzma2Options, Lzma2Writer};
let mut compressed = Vec::new();
let options = Lzma2Options::with_preset(5);
let mut encoder = Lzma2Writer::new(&mut compressed, options);
encoder.write_all(plain_header).map_err(crate::Error::Io)?;
encoder.finish().map_err(crate::Error::Io)?;
compressed
};
if compressed.len() >= plain_header.len() {
return Ok(None);
}
let mut encoded = Vec::new();
encoded.push(property_id::ENCODED_HEADER);
encoded.push(property_id::PACK_INFO);
write_variable_u64(&mut encoded, pack_pos)?;
write_variable_u64(&mut encoded, 1)?;
encoded.push(property_id::SIZE);
write_variable_u64(&mut encoded, compressed.len() as u64)?;
encoded.push(property_id::END);
encoded.push(property_id::UNPACK_INFO);
encoded.push(property_id::FOLDER);
write_variable_u64(&mut encoded, 1)?;
encoded.push(0);
encoded.push(0x01); let lzma2_props = [lzma2_dictionary_property(plain_header.len() as u64)];
encoded.push((method::LZMA2.len() as u8) | 0x20);
encoded.extend_from_slice(method::LZMA2);
write_variable_u64(&mut encoded, lzma2_props.len() as u64)?;
encoded.extend_from_slice(&lzma2_props);
encoded.push(property_id::CODERS_UNPACK_SIZE);
write_variable_u64(&mut encoded, plain_header.len() as u64)?;
encoded.push(property_id::CRC);
encoded.push(1); encoded.extend_from_slice(&crc32fast::hash(plain_header).to_le_bytes());
encoded.push(property_id::END); encoded.push(property_id::END);
Ok(Some((compressed, encoded)))
}