use crate::raw::{
ArchiveExtraDataRecord, ArchiveExtraDataRecordFixed, CentralDirectoryHeader, CentralDirectoryHeaderFixed,
DataDescriptor, DataDescriptorSignature, DataDescriptorZip64Signature, DigitalSignature, DigitalSignatureFixed,
EndOfCentralDirectory, EndOfCentralDirectoryFixed, LocalFileHeader, LocalFileHeaderFixed,
Zip64EndOfCentralDirectory, Zip64EndOfCentralDirectoryFixed, Zip64EndOfCentralDirectoryLocator,
};
pub trait PartialRecord {
type Partial;
fn get_partial(&self) -> &Self::Partial;
fn is_valid_sizes(&self) -> bool;
}
pub trait Signature {
fn is_valid_signature(&self) -> bool;
}
impl<T> Signature for T
where
T: PartialRecord,
T::Partial: Signature,
{
fn is_valid_signature(&self) -> bool { self.get_partial().is_valid_signature() }
}
impl Signature for LocalFileHeaderFixed {
fn is_valid_signature(&self) -> bool { self.local_file_header_signature == Self::LOCAL_FILE_HEADER_SIGNATURE }
}
impl PartialRecord for LocalFileHeader {
type Partial = LocalFileHeaderFixed;
fn get_partial(&self) -> &Self::Partial { &self.fixed }
fn is_valid_sizes(&self) -> bool {
self.file_name.len() == self.fixed.file_name_length as usize
&& self.extra_field.len() == self.fixed.extra_field_length as usize
}
}
impl Signature for DataDescriptorSignature {
fn is_valid_signature(&self) -> bool { self.signature == DataDescriptor::SIGNATURE }
}
impl Signature for DataDescriptorZip64Signature {
fn is_valid_signature(&self) -> bool { self.signature == DataDescriptor::SIGNATURE }
}
impl Signature for ArchiveExtraDataRecordFixed {
fn is_valid_signature(&self) -> bool { self.archive_extra_data_signature == Self::ARCHIVE_EXTRA_DATE_SIGNATURE }
}
impl PartialRecord for ArchiveExtraDataRecord {
type Partial = ArchiveExtraDataRecordFixed;
fn get_partial(&self) -> &Self::Partial { &self.fixed }
fn is_valid_sizes(&self) -> bool { self.extra_field_data.len() == self.fixed.extra_field_length as usize }
}
impl Signature for CentralDirectoryHeaderFixed {
fn is_valid_signature(&self) -> bool { self.central_file_header_signature == Self::CENTRAL_FILE_HEADER_SIGNATURE }
}
impl PartialRecord for CentralDirectoryHeader {
type Partial = CentralDirectoryHeaderFixed;
fn get_partial(&self) -> &Self::Partial { &self.fixed }
fn is_valid_sizes(&self) -> bool {
self.file_name.len() == self.fixed.file_name_length as usize
&& self.extra_field.len() == self.fixed.extra_field_length as usize
&& self.file_comment.len() == self.fixed.file_comment_length as usize
}
}
impl Signature for DigitalSignatureFixed {
fn is_valid_signature(&self) -> bool { self.header_signature == Self::HEADER_SIGNATURE }
}
impl PartialRecord for DigitalSignature {
type Partial = DigitalSignatureFixed;
fn get_partial(&self) -> &Self::Partial { &self.fixed }
fn is_valid_sizes(&self) -> bool { self.signature_data.len() == self.fixed.size_of_data as usize }
}
impl Signature for Zip64EndOfCentralDirectoryFixed {
fn is_valid_signature(&self) -> bool {
self.zip64_end_of_central_dir_signature == Self::ZIP64_END_OF_CENTRAL_DIR_SIGNATURE
}
}
impl PartialRecord for Zip64EndOfCentralDirectory {
type Partial = Zip64EndOfCentralDirectoryFixed;
fn get_partial(&self) -> &Self::Partial { &self.fixed }
fn is_valid_sizes(&self) -> bool {
if (self.fixed.size_of_zip64_end_of_central_directory_record as usize)
< Zip64EndOfCentralDirectoryFixed::SIZE_IN_BYTES - 12
{
return false;
}
let length = self.fixed.size_of_zip64_end_of_central_directory_record as usize + 12
- Zip64EndOfCentralDirectoryFixed::SIZE_IN_BYTES;
self.zip64_extensible_data_sector.len() == length
}
}
impl Signature for Zip64EndOfCentralDirectoryLocator {
fn is_valid_signature(&self) -> bool {
self.zip64_end_of_central_dir_locator_signature == Self::ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE
}
}
impl Signature for EndOfCentralDirectoryFixed {
fn is_valid_signature(&self) -> bool { self.end_of_central_dir_signature == Self::END_OF_CENTRAL_DIR_SIGNATURE }
}
impl PartialRecord for EndOfCentralDirectory {
type Partial = EndOfCentralDirectoryFixed;
fn get_partial(&self) -> &Self::Partial { &self.fixed }
fn is_valid_sizes(&self) -> bool { self.zip_file_comment.len() == self.fixed.zip_file_comment_length as usize }
}