aboutsummaryrefslogtreecommitdiff
path: root/src/zip/driver.rs
diff options
context:
space:
mode:
authorIgor Tolmachev <me@igorek.dev>2024-06-29 22:53:47 +0900
committerIgor Tolmachev <me@igorek.dev>2024-06-30 21:53:11 +0900
commit6d5f8f046b3b24e50cb1a0e7751c6bc9170ed9d1 (patch)
tree2ab77965a7c54b64e024a0fc3405b065ad54ea96 /src/zip/driver.rs
parent51694e1f0b2730915e0a57ec6d8de503cf06ef9a (diff)
downloadarchivator-6d5f8f046b3b24e50cb1a0e7751c6bc9170ed9d1.tar.gz
archivator-6d5f8f046b3b24e50cb1a0e7751c6bc9170ed9d1.zip
Add `Clone` derive and edit trait types
Diffstat (limited to 'src/zip/driver.rs')
-rw-r--r--src/zip/driver.rs75
1 files changed, 36 insertions, 39 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