use crate::Signature; use androscalpel_serializer::{ReadSeek, Result, Serializable}; use std::io::{SeekFrom, Write}; #[derive(Debug, Clone, PartialEq, Eq)] pub enum DataDescriptor { Zip32(DataDescriptor32), Zip64(DataDescriptor64), } /// DataDescriptor for 32bit zip format. #[derive(Debug, Clone, PartialEq, Eq)] pub struct DataDescriptor32 { // signature: Option pub crc_32: u32, pub compressed_size: u32, pub uncompressed_size: u32, /// For reproducibility. This should be true when writting a zip, but can be false when /// reading one. If we want to stick to the original, we need to keep this information. pub use_signature: bool, } /// DataDescriptor for 64bit zip format. #[derive(Debug, Clone, PartialEq, Eq)] pub struct DataDescriptor64 { // signature: Option pub crc_32: u32, pub compressed_size: u64, pub uncompressed_size: u64, /// For reproducibility. This should be true when writting a zip, but can be false when /// reading one. If we want to stick to the original, we need to keep this information. pub use_signature: bool, } impl DataDescriptor32 { const SIGNATURE: Signature = Signature(0x02014b50); } impl Serializable for DataDescriptor32 { fn serialize(&self, output: &mut dyn Write) -> Result<()> { if self.use_signature { Self::SIGNATURE.serialize(output)?; } self.crc_32.serialize(output)?; self.compressed_size.serialize(output)?; self.uncompressed_size.serialize(output) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let pos = input.stream_position().unwrap(); //TODO let signature = Signature::deserialize(input)?; let use_signature = if signature != Self::SIGNATURE { input.seek(SeekFrom::Start(pos)).unwrap(); //TODO false } else { true }; let crc_32 = u32::deserialize(input)?; let compressed_size = u32::deserialize(input)?; let uncompressed_size = u32::deserialize(input)?; Ok(Self { crc_32, compressed_size, uncompressed_size, use_signature, }) } fn size(&self) -> usize { 12 + if self.use_signature { Self::SIGNATURE.size() } else { 0 } } } impl DataDescriptor64 { const SIGNATURE: Signature = Signature(0x02014b50); } impl Serializable for DataDescriptor64 { fn serialize(&self, output: &mut dyn Write) -> Result<()> { if self.use_signature { Self::SIGNATURE.serialize(output)?; } self.crc_32.serialize(output)?; self.compressed_size.serialize(output)?; self.uncompressed_size.serialize(output) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let pos = input.stream_position().unwrap(); //TODO let signature = Signature::deserialize(input)?; let use_signature = if signature != Self::SIGNATURE { input.seek(SeekFrom::Start(pos)).unwrap(); //TODO false } else { true }; let crc_32 = u32::deserialize(input)?; let compressed_size = u64::deserialize(input)?; let uncompressed_size = u64::deserialize(input)?; Ok(Self { crc_32, compressed_size, uncompressed_size, use_signature, }) } fn size(&self) -> usize { 20 + if self.use_signature { Self::SIGNATURE.size() } else { 0 } } }