diff options
| author | Igor Tolmachev <me@igorek.dev> | 2024-07-01 19:12:40 +0900 |
|---|---|---|
| committer | Igor Tolmachev <me@igorek.dev> | 2024-07-02 18:59:00 +0900 |
| commit | 5d3d32ded672b67471d9d7c85ebbe691129cc51c (patch) | |
| tree | 1f9a82196d69cfec34af595a659e4d74a80b0c92 /src/zip/file_driver.rs | |
| parent | 6d5f8f046b3b24e50cb1a0e7751c6bc9170ed9d1 (diff) | |
| download | archivator-5d3d32ded672b67471d9d7c85ebbe691129cc51c.tar.gz archivator-5d3d32ded672b67471d9d7c85ebbe691129cc51c.zip | |
Add compression support (lzma and xz are broken)
Diffstat (limited to 'src/zip/file_driver.rs')
| -rw-r--r-- | src/zip/file_driver.rs | 98 |
1 files changed, 0 insertions, 98 deletions
diff --git a/src/zip/file_driver.rs b/src/zip/file_driver.rs deleted file mode 100644 index 51075e4..0000000 --- a/src/zip/file_driver.rs +++ /dev/null | |||
| @@ -1,98 +0,0 @@ | |||
| 1 | use crate::driver::FileDriver; | ||
| 2 | use crate::zip::{ZipError, ZipFileInfo, ZipResult}; | ||
| 3 | use std::io::{ | ||
| 4 | Error as IoError, ErrorKind as IoErrorKind, Read, Result as IoResult, Seek, SeekFrom, Write, | ||
| 5 | }; | ||
| 6 | |||
| 7 | pub struct ZipFile<'d, Io> { | ||
| 8 | io: &'d mut Io, | ||
| 9 | info: &'d ZipFileInfo, | ||
| 10 | |||
| 11 | bounds: (u64, u64), | ||
| 12 | cursor: u64, | ||
| 13 | } | ||
| 14 | |||
| 15 | impl<'d, Io> FileDriver for ZipFile<'d, Io> { | ||
| 16 | type Io = Io; | ||
| 17 | type FileInfo = ZipFileInfo; | ||
| 18 | |||
| 19 | fn info(&self) -> &Self::FileInfo { | ||
| 20 | self.info | ||
| 21 | } | ||
| 22 | } | ||
| 23 | |||
| 24 | impl<'d, Io: Read + Seek> ZipFile<'d, Io> { | ||
| 25 | pub fn new(io: &'d mut Io, info: &'d ZipFileInfo) -> ZipResult<Self> { | ||
| 26 | io.seek(SeekFrom::Start(info.header_pointer))?; | ||
| 27 | let buf = { | ||
| 28 | let mut buf = [0; 30]; | ||
| 29 | io.read(&mut buf)?; | ||
| 30 | buf | ||
| 31 | }; | ||
| 32 | if u32::from_le_bytes(buf[..4].try_into().unwrap()) != 0x04034b50 { | ||
| 33 | return Err(ZipError::InvalidFileHeaderSignature.into()); | ||
| 34 | } | ||
| 35 | let data_pointer = info.header_pointer | ||
| 36 | + 30 | ||
| 37 | + u16::from_le_bytes(buf[26..28].try_into().unwrap()) as u64 | ||
| 38 | + u16::from_le_bytes(buf[28..30].try_into().unwrap()) as u64; | ||
| 39 | io.seek(SeekFrom::Start(data_pointer))?; | ||
| 40 | |||
| 41 | Ok(Self { | ||
| 42 | io, | ||
| 43 | info, | ||
| 44 | |||
| 45 | bounds: (data_pointer, data_pointer + info.compressed_size), | ||
| 46 | cursor: data_pointer, | ||
| 47 | }) | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | impl<'d, Io: Read> Read for ZipFile<'d, Io> { | ||
| 52 | fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> { | ||
| 53 | let upper = buf.len().min((self.bounds.1 - self.cursor) as usize); | ||
| 54 | self.cursor += upper as u64; | ||
| 55 | self.io.read(&mut buf[..upper]) | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | impl<'d, Io: Write> Write for ZipFile<'d, Io> { | ||
| 60 | fn write(&mut self, buf: &[u8]) -> IoResult<usize> { | ||
| 61 | todo!() | ||
| 62 | } | ||
| 63 | |||
| 64 | fn flush(&mut self) -> IoResult<()> { | ||
| 65 | todo!() | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | impl<'d, Io: Seek> Seek for ZipFile<'d, Io> { | ||
| 70 | fn seek(&mut self, pos: SeekFrom) -> IoResult<u64> { | ||
| 71 | self.cursor = match pos { | ||
| 72 | SeekFrom::Start(offset) => self.bounds.0 + offset, | ||
| 73 | SeekFrom::End(offset) => { | ||
| 74 | let cursor = self.bounds.1.saturating_add_signed(offset); | ||
| 75 | if cursor < self.bounds.0 { | ||
| 76 | return Err(IoError::new( | ||
| 77 | IoErrorKind::InvalidInput, | ||
| 78 | ZipError::NegativeFileOffset, | ||
| 79 | )); | ||
| 80 | } | ||
| 81 | cursor | ||
| 82 | } | ||
| 83 | SeekFrom::Current(offset) => { | ||
| 84 | let cursor = self.cursor.saturating_add_signed(offset); | ||
| 85 | if cursor < self.bounds.0 { | ||
| 86 | return Err(IoError::new( | ||
| 87 | IoErrorKind::InvalidInput, | ||
| 88 | ZipError::NegativeFileOffset, | ||
| 89 | )); | ||
| 90 | } | ||
| 91 | cursor | ||
| 92 | } | ||
| 93 | } | ||
| 94 | .min(self.bounds.1); | ||
| 95 | |||
| 96 | Ok(self.io.seek(SeekFrom::Start(self.cursor))? - self.bounds.0) | ||
| 97 | } | ||
| 98 | } | ||
