diff options
| author | igorechek06 <me@igorek.dev> | 2024-08-10 15:11:42 +0900 |
|---|---|---|
| committer | igorechek06 <me@igorek.dev> | 2024-08-10 15:11:42 +0900 |
| commit | 51f2737ca7af016e3dd3ad03673f48a754a1642e (patch) | |
| tree | 5b3ccba6cb3e82eb87b6cf9d9ef5c524b5d285bb /src/zip/driver.rs | |
| parent | 4c411b76cad9cc735687dc739d2e2db5d00e5eac (diff) | |
| download | archivator-51f2737ca7af016e3dd3ad03673f48a754a1642e.tar.gz archivator-51f2737ca7af016e3dd3ad03673f48a754a1642e.zip | |
Replace Vec with Iterator
Diffstat (limited to 'src/zip/driver.rs')
| -rw-r--r-- | src/zip/driver.rs | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/src/zip/driver.rs b/src/zip/driver.rs index 8dc902f..b4217c8 100644 --- a/src/zip/driver.rs +++ b/src/zip/driver.rs | |||
| @@ -15,21 +15,30 @@ use std::collections::HashMap as Map; | |||
| 15 | use std::fs::File; | 15 | use std::fs::File; |
| 16 | use std::io::{BufReader, Read, Seek, SeekFrom, Write}; | 16 | use std::io::{BufReader, Read, Seek, SeekFrom, Write}; |
| 17 | 17 | ||
| 18 | #[inline] | 18 | struct Fields<'b> { |
| 19 | fn split_fields(bytes: &[u8]) -> Option<Vec<(u16, &[u8])>> { | 19 | pointer: usize, |
| 20 | let mut fields = Vec::new(); | 20 | bytes: &'b [u8], |
| 21 | 21 | } | |
| 22 | let mut p = 0; | ||
| 23 | while p < bytes.len() { | ||
| 24 | let header: ExtraHeader = deserialize(bytes.get(p..p + 4)?).unwrap(); | ||
| 25 | p += 4; | ||
| 26 | let data = bytes.get(p..p + header.size as usize)?; | ||
| 27 | p += header.size as usize; | ||
| 28 | 22 | ||
| 29 | fields.push((header.id, data)); | 23 | impl<'b> Fields<'b> { |
| 24 | pub fn new(bytes: &'b [u8]) -> Self { | ||
| 25 | Self { pointer: 0, bytes } | ||
| 30 | } | 26 | } |
| 27 | } | ||
| 31 | 28 | ||
| 32 | Some(fields) | 29 | impl<'b> Iterator for Fields<'b> { |
| 30 | type Item = (u16, &'b [u8]); | ||
| 31 | |||
| 32 | fn next(&mut self) -> Option<Self::Item> { | ||
| 33 | let header: ExtraHeader = | ||
| 34 | deserialize(self.bytes.get(self.pointer..self.pointer + 4)?).unwrap(); | ||
| 35 | self.pointer += 4; | ||
| 36 | let data = self | ||
| 37 | .bytes | ||
| 38 | .get(self.pointer..self.pointer + header.size as usize)?; | ||
| 39 | self.pointer += header.size as usize; | ||
| 40 | Some((header.id, data)) | ||
| 41 | } | ||
| 33 | } | 42 | } |
| 34 | 43 | ||
| 35 | #[inline] | 44 | #[inline] |
| @@ -159,7 +168,7 @@ impl<Io: Read + Seek> ArchiveRead for Zip<Io> { | |||
| 159 | let mut ctime = None; | 168 | let mut ctime = None; |
| 160 | 169 | ||
| 161 | // Parse extensible data fields | 170 | // Parse extensible data fields |
| 162 | for (id, mut data) in split_fields(&extra_fields).ok_or(ZipError::InvalidExtraFields)? { | 171 | for (id, mut data) in Fields::new(&extra_fields) { |
| 163 | match id { | 172 | match id { |
| 164 | // Zip64 | 173 | // Zip64 |
| 165 | 0x0001 => { | 174 | 0x0001 => { |
| @@ -175,9 +184,7 @@ impl<Io: Read + Seek> ArchiveRead for Zip<Io> { | |||
| 175 | } | 184 | } |
| 176 | // NTFS | 185 | // NTFS |
| 177 | 0x000a => { | 186 | 0x000a => { |
| 178 | for (id, mut data) in | 187 | for (id, mut data) in Fields::new(&data[4..]) { |
| 179 | split_fields(&data).ok_or(ZipError::InvalidExtraFields)? | ||
| 180 | { | ||
| 181 | match id { | 188 | match id { |
| 182 | 0x0001 => { | 189 | 0x0001 => { |
| 183 | mtime = ntfs_to_local(u64::from_le_bytes(data.read_arr()?)) | 190 | mtime = ntfs_to_local(u64::from_le_bytes(data.read_arr()?)) |
| @@ -198,7 +205,7 @@ impl<Io: Read + Seek> ArchiveRead for Zip<Io> { | |||
| 198 | // AES | 205 | // AES |
| 199 | 0x9901 => { | 206 | 0x9901 => { |
| 200 | let aes: AesField = deserialize(&data.read_arr::<7>()?).unwrap(); | 207 | let aes: AesField = deserialize(&data.read_arr::<7>()?).unwrap(); |
| 201 | if aes.id != 0x4541 { | 208 | if aes.id != [0x41, 0x45] { |
| 202 | return Err(ZipError::InvalidExtraFields); | 209 | return Err(ZipError::InvalidExtraFields); |
| 203 | } | 210 | } |
| 204 | encryption_method = match aes.strength { | 211 | encryption_method = match aes.strength { |
