use crate::Signature; use androscalpel_serializer::{ReadSeek, Result, Serializable}; use std::io::Write; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Zip64EndCentralDirectory { // signature: Signature // size_zip64_edf_record: u64 pub version_made_by: u16, pub version_needed_to_extract: u16, pub number_of_this_disk: u32, pub disk_number_of_central_directory_start: u32, pub number_entry_in_central_directory_on_this_disk: u64, pub number_entry_in_central_directory: u64, pub size_of_central_directory: u64, pub offset_central_directory: u64, pub extensible_data: Vec, } impl Zip64EndCentralDirectory { const SIGNATURE: Signature = Signature(0x06064b50); const MIN_SIZE: usize = 4 + 8 + 2 + 2 + 4 + 4 + 8 + 8 + 8 + 8; // + 0; } impl Serializable for Zip64EndCentralDirectory { fn serialize(&self, output: &mut dyn Write) -> Result<()> { Self::SIGNATURE.serialize(output)?; ((self.size() - 12) as u64).serialize(output)?; self.version_made_by.serialize(output)?; self.version_needed_to_extract.serialize(output)?; self.number_of_this_disk.serialize(output)?; self.disk_number_of_central_directory_start .serialize(output)?; self.number_entry_in_central_directory_on_this_disk .serialize(output)?; self.number_entry_in_central_directory.serialize(output)?; self.size_of_central_directory.serialize(output)?; self.offset_central_directory.serialize(output)?; for d in &self.extensible_data { d.serialize(output)?; } Ok(()) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let signature = Signature::deserialize(input)?; assert_eq!(signature, Self::SIGNATURE); // TODO let size_zip64_edf_record = u64::deserialize(input)?; let version_made_by = u16::deserialize(input)?; let version_needed_to_extract = u16::deserialize(input)?; let number_of_this_disk = u32::deserialize(input)?; let disk_number_of_central_directory_start = u32::deserialize(input)?; let number_entry_in_central_directory_on_this_disk = u64::deserialize(input)?; let number_entry_in_central_directory = u64::deserialize(input)?; let size_of_central_directory = u64::deserialize(input)?; let offset_central_directory = u64::deserialize(input)?; let mut extensible_data = vec![]; for _ in 0..(size_zip64_edf_record as usize + 12 - Self::MIN_SIZE) { extensible_data.push(u8::deserialize(input)?); } Ok(Self { version_made_by, version_needed_to_extract, number_of_this_disk, disk_number_of_central_directory_start, number_entry_in_central_directory_on_this_disk, number_entry_in_central_directory, size_of_central_directory, offset_central_directory, extensible_data, }) } fn size(&self) -> usize { Self::MIN_SIZE + self.extensible_data.len() } } #[derive(Debug, Clone, PartialEq, Eq, Serializable)] pub struct Zip64EndCentralDirectoryLocator { #[prefix(Self::SIGNATURE.0.to_le_bytes())] pub disk_number_of_zip64_end_central_directory_start: u32, pub offset_zip64_end_of_central_directory_record: u64, pub total_number_of_disks: u32, } impl Zip64EndCentralDirectoryLocator { pub const SIGNATURE: Signature = Signature(0x07064b50); pub const SIZE: usize = 4 + 4 + 8 + 4; } #[derive(Debug, Clone, PartialEq, Eq)] pub struct EndCentralDirectory { //signature: Self::SIGNATURE, pub disk_number: u16, pub disk_number_of_central_directory_start: u16, pub number_of_entries_in_central_directory_on_disk: u16, pub number_of_entries_in_central_directory: u16, pub size_central_directory: u32, pub offset_central_directory: u32, //file_comment_length: u16, pub comment: Vec, } impl EndCentralDirectory { pub const SIGNATURE: Signature = Signature(0x06054b50); //Signature([0x06, 0x05, 0x4b, 0x50]); pub const MIN_SIZE: usize = 4 + 4 * 2 + 2 * 4 + 2; // + 0; } impl Serializable for EndCentralDirectory { fn serialize(&self, output: &mut dyn Write) -> Result<()> { Self::SIGNATURE.serialize(output)?; self.disk_number.serialize(output)?; self.disk_number_of_central_directory_start .serialize(output)?; self.number_of_entries_in_central_directory_on_disk .serialize(output)?; self.number_of_entries_in_central_directory .serialize(output)?; self.size_central_directory.serialize(output)?; self.offset_central_directory.serialize(output)?; (self.comment.len() as u16).serialize(output)?; for c in &self.comment { c.serialize(output)?; } Ok(()) } fn deserialize(input: &mut dyn ReadSeek) -> Result { let signature = Signature::deserialize(input)?; let disk_number = u16::deserialize(input)?; let disk_number_of_central_directory_start = u16::deserialize(input)?; let number_of_entries_in_central_directory_on_disk = u16::deserialize(input)?; let number_of_entries_in_central_directory = u16::deserialize(input)?; let size_central_directory = u32::deserialize(input)?; let offset_central_directory = u32::deserialize(input)?; let file_comment_length = u16::deserialize(input)?; let mut comment = vec![]; for _ in 0..file_comment_length { comment.push(u8::deserialize(input)?); } assert_eq!(signature, Self::SIGNATURE); // TODO Ok(Self { disk_number, disk_number_of_central_directory_start, number_of_entries_in_central_directory_on_disk, number_of_entries_in_central_directory, size_central_directory, offset_central_directory, comment, }) } fn size(&self) -> usize { Self::MIN_SIZE + self.comment.len() } }