aboutsummaryrefslogtreecommitdiff
path: root/src/zip
diff options
context:
space:
mode:
Diffstat (limited to 'src/zip')
-rw-r--r--src/zip/driver.rs75
-rw-r--r--src/zip/error.rs2
-rw-r--r--src/zip/file_driver.rs3
-rw-r--r--src/zip/file_info.rs6
4 files changed, 42 insertions, 44 deletions
diff --git a/src/zip/driver.rs b/src/zip/driver.rs
index 0db845d..a280dc7 100644
--- a/src/zip/driver.rs
+++ b/src/zip/driver.rs
@@ -2,13 +2,12 @@ use crate::driver::{ArchiveRead, ArchiveWrite, Driver};
2use crate::zip::structs::{deserialize, EOCDR64Locator, ExtraHeader, CDR, EOCDR, EOCDR64}; 2use crate::zip::structs::{deserialize, EOCDR64Locator, ExtraHeader, CDR, EOCDR, EOCDR64};
3use crate::zip::{BitFlag, CompressionMethod, ZipError, ZipFile, ZipFileInfo, ZipResult}; 3use crate::zip::{BitFlag, CompressionMethod, ZipError, ZipFile, ZipFileInfo, ZipResult};
4use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime}; 4use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime};
5use std::collections::HashMap as Map;
6use std::io::{Read, Seek, SeekFrom, Write}; 5use std::io::{Read, Seek, SeekFrom, Write};
7 6
8pub struct Zip<Io> { 7pub struct Zip<Io> {
9 io: Io, 8 io: Io,
10 9
11 files: Map<String, ZipFileInfo>, 10 files: Vec<ZipFileInfo>,
12 comment: String, 11 comment: String,
13} 12}
14 13
@@ -80,7 +79,7 @@ impl<Io: Read + Seek> ArchiveRead for Zip<Io> {
80 }; 79 };
81 80
82 // Read cd records 81 // Read cd records
83 let mut files = Map::with_capacity(cd_records as usize); 82 let mut files = Vec::with_capacity(cd_records as usize);
84 io.seek(SeekFrom::Start(cd_pointer))?; 83 io.seek(SeekFrom::Start(cd_pointer))?;
85 let buf = { 84 let buf = {
86 let mut buf = vec![0; cd_size as usize]; 85 let mut buf = vec![0; cd_size as usize];
@@ -135,52 +134,50 @@ impl<Io: Read + Seek> ArchiveRead for Zip<Io> {
135 } 134 }
136 } 135 }
137 136
138 files.insert( 137 files.push(ZipFileInfo::new(
139 name.clone(), 138 CompressionMethod::from_struct_id(cdr.compression_method)?,
140 ZipFileInfo::new( 139 BitFlag::new(cdr.bit_flag),
141 CompressionMethod::from_struct_id(cdr.compression_method)?, 140 NaiveDateTime::new(
142 BitFlag::new(cdr.bit_flag), 141 NaiveDate::from_ymd_opt(
143 NaiveDateTime::new( 142 (cdr.dos_date as i32 >> 9 & 0x7F) + 1980,
144 NaiveDate::from_ymd_opt( 143 cdr.dos_date as u32 >> 5 & 0xF,
145 (cdr.dos_date as i32 >> 9 & 0x7F) + 1980, 144 cdr.dos_date as u32 & 0x1F,
146 cdr.dos_date as u32 >> 5 & 0xF,
147 cdr.dos_date as u32 & 0x1F,
148 )
149 .ok_or(ZipError::InvalidDate)?,
150 NaiveTime::from_hms_opt(
151 (cdr.dos_time as u32 >> 11) & 0x1F,
152 (cdr.dos_time as u32 >> 5) & 0x3F,
153 (cdr.dos_time as u32 & 0x1F) * 2,
154 )
155 .ok_or(ZipError::InvalidTime)?,
156 ) 145 )
157 .and_local_timezone(Local) 146 .ok_or(ZipError::InvalidDate)?,
158 .unwrap(), 147 NaiveTime::from_hms_opt(
159 cdr.crc, 148 (cdr.dos_time as u32 >> 11) & 0x1F,
160 compressed_size, 149 (cdr.dos_time as u32 >> 5) & 0x3F,
161 size, 150 (cdr.dos_time as u32 & 0x1F) * 2,
162 header_pointer, 151 )
163 name, 152 .ok_or(ZipError::InvalidTime)?,
164 comment, 153 )
165 ), 154 .and_local_timezone(Local)
166 ); 155 .unwrap(),
156 cdr.crc,
157 compressed_size,
158 size,
159 header_pointer,
160 name,
161 comment,
162 ));
167 } 163 }
168 164
169 Ok(Self { io, files, comment }) 165 Ok(Self { io, files, comment })
170 } 166 }
171 167
172 fn files(&self) -> Vec<&Self::FileInfo> { 168 fn files(&self) -> &Vec<Self::FileInfo> {
173 let mut files: Vec<&Self::FileInfo> = self.files.values().collect(); 169 &self.files
174 files.sort_by_key(|f| &f.name);
175 files
176 } 170 }
177 171
178 fn get_file_info(&self, name: &str) -> Option<&Self::FileInfo> { 172 fn get_file_info(&self, index: usize) -> ZipResult<&Self::FileInfo> {
179 self.files.get(name) 173 self.files.get(index).ok_or(ZipError::FileNotFound.into())
180 } 174 }
181 175
182 fn get_file_reader<'d>(&'d mut self, name: &str) -> Option<Self::FileDriver<'d>> { 176 fn get_file_reader<'d>(&'d mut self, index: usize) -> ZipResult<Self::FileDriver<'d>> {
183 Some(ZipFile::new(&mut self.io, self.files.get(name)?).unwrap()) 177 Ok(ZipFile::new(
178 &mut self.io,
179 self.files.get(index).ok_or(ZipError::FileNotFound)?,
180 )?)
184 } 181 }
185} 182}
186 183
diff --git a/src/zip/error.rs b/src/zip/error.rs
index d82de78..3acbf8c 100644
--- a/src/zip/error.rs
+++ b/src/zip/error.rs
@@ -20,6 +20,7 @@ pub enum ZipError {
20 InvalidFileComment, 20 InvalidFileComment,
21 21
22 NegativeFileOffset, 22 NegativeFileOffset,
23 FileNotFound,
23} 24}
24 25
25impl From<ZipError> for ArchiveError<ZipError> { 26impl From<ZipError> for ArchiveError<ZipError> {
@@ -57,6 +58,7 @@ impl Display for ZipError {
57 Self::InvalidFileComment => write!(f, "Invalid file comment"), 58 Self::InvalidFileComment => write!(f, "Invalid file comment"),
58 59
59 Self::NegativeFileOffset => write!(f, "Negative file offset"), 60 Self::NegativeFileOffset => write!(f, "Negative file offset"),
61 Self::FileNotFound => write!(f, "File not found"),
60 } 62 }
61 } 63 }
62} 64}
diff --git a/src/zip/file_driver.rs b/src/zip/file_driver.rs
index 47b4242..51075e4 100644
--- a/src/zip/file_driver.rs
+++ b/src/zip/file_driver.rs
@@ -1,8 +1,7 @@
1use crate::driver::FileDriver; 1use crate::driver::FileDriver;
2use crate::zip::{ZipError, ZipFileInfo, ZipResult}; 2use crate::zip::{ZipError, ZipFileInfo, ZipResult};
3use std::io::{ 3use std::io::{
4 Error as IoError, ErrorKind as IoErrorKind, Read, Result as IoResult, Seek, SeekFrom, Take, 4 Error as IoError, ErrorKind as IoErrorKind, Read, Result as IoResult, Seek, SeekFrom, Write,
5 Write,
6}; 5};
7 6
8pub struct ZipFile<'d, Io> { 7pub struct ZipFile<'d, Io> {
diff --git a/src/zip/file_info.rs b/src/zip/file_info.rs
index 88322be..92d52f7 100644
--- a/src/zip/file_info.rs
+++ b/src/zip/file_info.rs
@@ -2,7 +2,7 @@ use crate::driver::ArchiveFileInfo;
2use crate::zip::{ZipError, ZipResult}; 2use crate::zip::{ZipError, ZipResult};
3use chrono::{DateTime, Local}; 3use chrono::{DateTime, Local};
4 4
5#[derive(Debug)] 5#[derive(Debug, Clone)]
6pub enum CompressionMethod { 6pub enum CompressionMethod {
7 Store, 7 Store,
8 Deflate, 8 Deflate,
@@ -29,7 +29,7 @@ impl CompressionMethod {
29 } 29 }
30} 30}
31 31
32#[derive(Debug)] 32#[derive(Debug, Clone)]
33pub struct BitFlag { 33pub struct BitFlag {
34 flag: u16, 34 flag: u16,
35} 35}
@@ -121,7 +121,7 @@ impl BitFlag {
121 } 121 }
122} 122}
123 123
124#[derive(Debug)] 124#[derive(Debug, Clone)]
125pub struct ZipFileInfo { 125pub struct ZipFileInfo {
126 pub compression_method: CompressionMethod, 126 pub compression_method: CompressionMethod,
127 pub bit_flag: BitFlag, 127 pub bit_flag: BitFlag,