diff options
| author | Igor Tolmachev <me@igorek.dev> | 2024-06-29 22:53:47 +0900 |
|---|---|---|
| committer | Igor Tolmachev <me@igorek.dev> | 2024-06-30 21:53:11 +0900 |
| commit | 6d5f8f046b3b24e50cb1a0e7751c6bc9170ed9d1 (patch) | |
| tree | 2ab77965a7c54b64e024a0fc3405b065ad54ea96 /src/zip/driver.rs | |
| parent | 51694e1f0b2730915e0a57ec6d8de503cf06ef9a (diff) | |
| download | archivator-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.rs | 75 |
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}; | |||
| 2 | use crate::zip::structs::{deserialize, EOCDR64Locator, ExtraHeader, CDR, EOCDR, EOCDR64}; | 2 | use crate::zip::structs::{deserialize, EOCDR64Locator, ExtraHeader, CDR, EOCDR, EOCDR64}; |
| 3 | use crate::zip::{BitFlag, CompressionMethod, ZipError, ZipFile, ZipFileInfo, ZipResult}; | 3 | use crate::zip::{BitFlag, CompressionMethod, ZipError, ZipFile, ZipFileInfo, ZipResult}; |
| 4 | use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime}; | 4 | use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime}; |
| 5 | use std::collections::HashMap as Map; | ||
| 6 | use std::io::{Read, Seek, SeekFrom, Write}; | 5 | use std::io::{Read, Seek, SeekFrom, Write}; |
| 7 | 6 | ||
| 8 | pub struct Zip<Io> { | 7 | pub 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 | ||
