From 33cda194d3bbbb5257e9e80c1b837312da000b57 Mon Sep 17 00:00:00 2001 From: Amos Wenger Date: Mon, 5 Feb 2024 19:27:43 +0100 Subject: [PATCH] More unification --- rc-zip-sync/src/entry_reader.rs | 6 +++--- rc-zip-sync/src/read_zip.rs | 15 +++++++------ rc-zip/src/fsm/archive.rs | 3 +-- rc-zip/src/fsm/entry/mod.rs | 21 ++++++++++--------- .../parse/central_directory_file_header.rs | 5 ++--- rc-zip/src/parse/version.rs | 12 +++-------- 6 files changed, 29 insertions(+), 33 deletions(-) diff --git a/rc-zip-sync/src/entry_reader.rs b/rc-zip-sync/src/entry_reader.rs index 0032d79..5a276f6 100644 --- a/rc-zip-sync/src/entry_reader.rs +++ b/rc-zip-sync/src/entry_reader.rs @@ -1,6 +1,6 @@ use rc_zip::{ fsm::{EntryFsm, FsmResult}, - parse::StoredEntry, + parse::Entry, }; use std::io; use tracing::trace; @@ -17,10 +17,10 @@ impl EntryReader where R: io::Read, { - pub(crate) fn new(entry: &StoredEntry, rd: R) -> Self { + pub(crate) fn new(entry: &Entry, rd: R) -> Self { Self { rd, - fsm: Some(EntryFsm::new(Some(entry.inner))), + fsm: Some(EntryFsm::new(Some(entry.clone()))), } } } diff --git a/rc-zip-sync/src/read_zip.rs b/rc-zip-sync/src/read_zip.rs index 16ade0b..951884c 100644 --- a/rc-zip-sync/src/read_zip.rs +++ b/rc-zip-sync/src/read_zip.rs @@ -1,8 +1,11 @@ -use rc_zip::chrono::{DateTime, TimeZone, Utc}; +use rc_zip::{ + chrono::{DateTime, TimeZone, Utc}, + parse::Entry, +}; use rc_zip::{ error::{Error, FormatError}, fsm::{ArchiveFsm, FsmResult}, - parse::{Archive, ExtraField, ExtraFieldSettings, LocalFileHeader, NtfsAttr, StoredEntry}, + parse::{Archive, ExtraField, ExtraFieldSettings, LocalFileHeader, NtfsAttr}, }; use tracing::trace; use winnow::{ @@ -96,7 +99,7 @@ impl ReadZip for Vec { /// /// This only contains metadata for the archive and its entries. Separate /// readers can be created for arbitraries entries on-demand using -/// [SyncStoredEntry::reader]. +/// [SyncEntry::reader]. pub struct SyncArchive<'a, F> where F: HasCursor, @@ -133,7 +136,7 @@ where pub fn by_name>(&self, name: N) -> Option> { self.archive .entries() - .find(|&x| x.name() == name.as_ref()) + .find(|&x| x.name == name.as_ref()) .map(|entry| SyncEntry { file: self.file, entry, @@ -144,11 +147,11 @@ where /// A zip entry, read synchronously from a file or other I/O resource. pub struct SyncEntry<'a, F> { file: &'a F, - entry: &'a StoredEntry, + entry: &'a Entry, } impl Deref for SyncEntry<'_, F> { - type Target = StoredEntry; + type Target = Entry; fn deref(&self) -> &Self::Target { self.entry diff --git a/rc-zip/src/fsm/archive.rs b/rc-zip/src/fsm/archive.rs index 080994c..92a833b 100644 --- a/rc-zip/src/fsm/archive.rs +++ b/rc-zip/src/fsm/archive.rs @@ -334,11 +334,10 @@ impl ArchiveFsm { } }; - let is_zip64 = eocd.dir64.is_some(); let global_offset = eocd.global_offset as u64; let entries: Result, Error> = directory_headers .iter() - .map(|x| x.as_entry(is_zip64, encoding, global_offset)) + .map(|x| x.as_entry(encoding, global_offset)) .collect(); let entries = entries?; diff --git a/rc-zip/src/fsm/entry/mod.rs b/rc-zip/src/fsm/entry/mod.rs index 90f1ca3..5d36659 100644 --- a/rc-zip/src/fsm/entry/mod.rs +++ b/rc-zip/src/fsm/entry/mod.rs @@ -160,11 +160,12 @@ impl EntryFsm { self.buffer.consume(consumed); let decompressor = AnyDecompressor::new( header.method, - self.entry.map(|entry| entry.uncompressed_size), + self.entry.as_ref().map(|entry| entry.uncompressed_size), )?; let compressed_size = match &self.entry { Some(entry) => entry.compressed_size, None => { + // FIXME: the zip64 extra field is here for that if header.compressed_size == u32::MAX { return Err(Error::Decompression { method: header.method, @@ -258,14 +259,11 @@ impl EntryFsm { Ok(FsmResult::Continue((self, outcome))) } - S::ReadDataDescriptor { .. } => { + S::ReadDataDescriptor { header, .. } => { let mut input = Partial::new(self.buffer.data()); - // if we don't have entry info, we're dangerously assuming the - // file isn't zip64. oh well. - // FIXME: we can just read until the next local file header and - // determine whether the file is zip64 or not from there? - let is_zip64 = self.entry.as_ref().map(|e| e.is_zip64).unwrap_or(false); + let is_zip64 = + header.compressed_size == u32::MAX || header.uncompressed_size == u32::MAX; match DataDescriptorRecord::mk_parser(is_zip64).parse_next(&mut input) { Ok(descriptor) => { @@ -288,7 +286,7 @@ impl EntryFsm { metrics, descriptor, } => { - let entry_crc32 = self.entry.map(|e| e.crc32).unwrap_or_default(); + let entry_crc32 = self.entry.as_ref().map(|e| e.crc32).unwrap_or_default(); let expected_crc32 = if entry_crc32 != 0 { entry_crc32 } else if let Some(descriptor) = descriptor.as_ref() { @@ -297,8 +295,11 @@ impl EntryFsm { header.crc32 }; - let entry_uncompressed_size = - self.entry.map(|e| e.uncompressed_size).unwrap_or_default(); + let entry_uncompressed_size = self + .entry + .as_ref() + .map(|e| e.uncompressed_size) + .unwrap_or_default(); let expected_size = if entry_uncompressed_size != 0 { entry_uncompressed_size } else if let Some(descriptor) = descriptor.as_ref() { diff --git a/rc-zip/src/parse/central_directory_file_header.rs b/rc-zip/src/parse/central_directory_file_header.rs index 4a03735..07c4f1b 100644 --- a/rc-zip/src/parse/central_directory_file_header.rs +++ b/rc-zip/src/parse/central_directory_file_header.rs @@ -1,4 +1,3 @@ -use chrono::{offset::TimeZone, DateTime, Utc}; use tracing::trace; use winnow::{ binary::{le_u16, le_u32}, @@ -13,11 +12,11 @@ use crate::{ error::{Error, FormatError}, parse::{ zero_datetime, Entry, ExtraField, ExtraFieldSettings, HostSystem, Mode, MsdosMode, - MsdosTimestamp, NtfsAttr, UnixMode, Version, ZipBytes, ZipString, + MsdosTimestamp, UnixMode, Version, ZipBytes, ZipString, }, }; -use super::{EntryCdFields, Method}; +use super::Method; /// 4.3.12 Central directory structure: File header pub struct CentralDirectoryFileHeader { diff --git a/rc-zip/src/parse/version.rs b/rc-zip/src/parse/version.rs index 2348bdf..4e5b2a6 100644 --- a/rc-zip/src/parse/version.rs +++ b/rc-zip/src/parse/version.rs @@ -8,7 +8,7 @@ use winnow::{binary::le_u8, seq, PResult, Parser, Partial}; /// which features are required when reading a file. /// /// For more information, see the [.ZIP Application Note](https://support.pkware.com/display/PKZIP/APPNOTE), section 4.4.2. -#[derive(Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Clone, Copy)] pub struct Version { /// The host system on which pub host_system: HostSystem, @@ -20,13 +20,7 @@ pub struct Version { impl fmt::Debug for Version { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "{:?} v{}.{}", - self.host_system(), - self.major(), - self.minor() - ) + write!(f, "{:?} v{}", self.host_system, self.version) } } @@ -34,7 +28,7 @@ impl Version { /// Parse a version from a byte slice pub fn parser(i: &mut Partial<&'_ [u8]>) -> PResult { seq! {Self { - host_system: le_u8.map(HostSystem::from_u8), + host_system: le_u8.map(HostSystem::from), version: le_u8, }} .parse_next(i)