aboutsummaryrefslogtreecommitdiff
path: root/src/zip
diff options
context:
space:
mode:
authorigorechek06 <me@igorek.dev>2024-08-10 15:11:42 +0900
committerigorechek06 <me@igorek.dev>2024-08-10 15:11:42 +0900
commit51f2737ca7af016e3dd3ad03673f48a754a1642e (patch)
tree5b3ccba6cb3e82eb87b6cf9d9ef5c524b5d285bb /src/zip
parent4c411b76cad9cc735687dc739d2e2db5d00e5eac (diff)
downloadarchivator-51f2737ca7af016e3dd3ad03673f48a754a1642e.tar.gz
archivator-51f2737ca7af016e3dd3ad03673f48a754a1642e.zip
Replace Vec with Iterator
Diffstat (limited to 'src/zip')
-rw-r--r--src/zip/driver.rs41
-rw-r--r--src/zip/structs.rs2
2 files changed, 25 insertions, 18 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;
15use std::fs::File; 15use std::fs::File;
16use std::io::{BufReader, Read, Seek, SeekFrom, Write}; 16use std::io::{BufReader, Read, Seek, SeekFrom, Write};
17 17
18#[inline] 18struct Fields<'b> {
19fn 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)); 23impl<'b> Fields<'b> {
24 pub fn new(bytes: &'b [u8]) -> Self {
25 Self { pointer: 0, bytes }
30 } 26 }
27}
31 28
32 Some(fields) 29impl<'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 {
diff --git a/src/zip/structs.rs b/src/zip/structs.rs
index 8b25400..4b4524f 100644
--- a/src/zip/structs.rs
+++ b/src/zip/structs.rs
@@ -67,7 +67,7 @@ pub struct ExtraHeader {
67#[derive(Serialize, Deserialize)] 67#[derive(Serialize, Deserialize)]
68pub struct AesField { 68pub struct AesField {
69 pub version: u16, 69 pub version: u16,
70 pub id: u16, 70 pub id: [u8; 2],
71 pub strength: u8, 71 pub strength: u8,
72 pub compression_method: u16, 72 pub compression_method: u16,
73} 73}