### Get Compression Method Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Returns the compression method used for the zip entry. Returns an error if the method is not supported by the crate. ```rust pub fn compression(&self) -> Result> { Compression::from_raw(self.compression_method) .ok_or(Error::UnsupportedCompression(self.compression_method)) } ``` -------------------------------- ### Find Start of File Name in TinyZip Path Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Scans backwards from the end of a path range to find the starting byte offset of the file name, typically after the last '/'. ```rust fn find_path_file_name_start( archive: &Archive, path_range: Range, ) -> Result> { let mut cursor = path_range.end; let mut scratch = [0u8; PATH_SCAN_CHUNK_LEN]; while cursor > path_range.start { let remaining = cursor .checked_sub(path_range.start) .ok_or(Error::InvalidOffset)?; let chunk_len_u64 = remaining.min(PATH_SCAN_CHUNK_LEN as u64); let chunk_len = usize::try_from(chunk_len_u64).map_err(|_| Error::InvalidOffset)?; let chunk_start = cursor - chunk_len_u64; archive.read_exact_at(chunk_start, &mut scratch[..chunk_len])?; if let Some(index) = scratch[..chunk_len].iter().rposition(|&byte| byte == b'/') { return Ok(chunk_start + index as u64 + 1); } cursor = chunk_start; } Ok(path_range.start) } ``` -------------------------------- ### Get Compression Method Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entry.html Returns the compression method reported by the central directory. Returns an error if the method ID is not recognized by the crate. ```rust pub fn compression(&self) -> Result> ``` -------------------------------- ### Get Entry Count Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Archive.html Returns the number of entries as reported by the central directory of the ZIP archive. ```rust pub fn entry_count(&self) -> u64 ``` -------------------------------- ### Get Archive Size Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Archive.html Retrieves the total size of the ZIP archive in bytes. ```rust pub fn size(&self) -> u64 ``` -------------------------------- ### Get General-Purpose Bit Flags Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entry.html Returns the raw general-purpose bit flags from the central directory. These flags indicate various properties of the entry, such as encryption status and compression details. ```rust pub fn flags(&self) -> u16 ``` -------------------------------- ### Get CRC-32 Checksum Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entry.html Returns the CRC-32 checksum reported by the central directory for the entry. ```rust pub fn crc32(&self) -> u32 ``` -------------------------------- ### Iterator enumerate() Method Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entries.html Creates an iterator that yields pairs of (index, element), where index is the iteration count starting from zero. ```rust fn enumerate(self) -> Enumerate where Self: Sized, ``` -------------------------------- ### Get Entry Reader Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entry.html Returns a Read adapter for the entry's payload bytes. Decompression is the caller's responsibility. Errors can occur if the local header is malformed or data extends past the archive. ```rust pub fn reader(&self) -> Result, Error> ``` -------------------------------- ### Calculate Range Length as usize Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Calculates the length of a u64 range and attempts to convert it to a usize. Returns an error if the range is invalid (end < start) or if the length cannot be represented as a usize. ```rust fn range_len_usize(range: &Range) -> Result> { let len = range .end .checked_sub(range.start) .ok_or(Error::InvalidOffset)?; usize::try_from(len).map_err(|_| Error::InvalidOffset) } ``` -------------------------------- ### UnixFileReader::new Constructor Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/type.FileReader.html Demonstrates how to create a new UnixFileReader instance by wrapping a std::fs::File. This is used for immutable, positioned reads. ```rust pub fn new(inner: File) -> Self ``` -------------------------------- ### take Method for EntryReader Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/struct.EntryReader.html Creates an adapter that reads at most a specified limit of bytes from the EntryReader. This is useful for limiting the amount of data read from an entry. ```rust fn take(self, limit: u64) -> Take where Self: Sized, ``` -------------------------------- ### Get Uncompressed Size Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entry.html Returns the uncompressed payload size in bytes as reported by the central directory. ```rust pub fn uncompressed_size(&self) -> u64 ``` -------------------------------- ### CloneToUninit Implementation (Nightly) Source: https://docs.rs/tinyzip/0.4.0/tinyzip/enum.Compression.html Nightly-only experimental API for copying data to an uninitialized memory location. ```rust unsafe fn clone_to_uninit(&self, dest: *mut u8) ``` -------------------------------- ### Get Compressed Size Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entry.html Returns the compressed payload size in bytes as reported by the central directory. ```rust pub fn compressed_size(&self) -> u64 ``` -------------------------------- ### UnixFileReader From Implementation Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/struct.UnixFileReader.html Provides a convenient way to convert a standard `std::fs::File` into a `UnixFileReader`. This implementation is specific to Unix-based operating systems. ```rust fn from(inner: File) -> Self ``` -------------------------------- ### Open and Read ZIP Entry (no_std) Source: https://docs.rs/tinyzip/0.4.0/tinyzip/index.html Demonstrates opening a ZIP archive, finding a specific file, and decompressing its contents using miniz_oxide in a no_std environment. Handles both Deflated and Stored compression methods. ```Rust use tinyzip::{Archive, Compression}; use miniz_oxide::inflate::stream::{inflate, InflateState}; use miniz_oxide::{DataFormat, MZFlush}; let archive = Archive::open(file_bytes)?; let entry = archive.find_file(b"test.txt")?; let mut decompressed = [0u8; 1024]; let contents = match entry.compression()? { Compression::Deflated => { let mut chunks = entry.read_chunks::<512>()?; let mut state = InflateState::new(DataFormat::Raw); let mut out_pos = 0; while let Some(chunk) = chunks.next() { let result = inflate(&mut state, chunk?, &mut decompressed[out_pos..], MZFlush::None); out_pos += result.bytes_written; } &decompressed[..out_pos] } Compression::Stored => { entry.read_to_slice(&mut decompressed)? } }; assert_eq!(contents, b"This is a test text file.\n"); ``` -------------------------------- ### UnixFileReader for Unix Systems Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/std_io.rs.html An adapter for Unix systems that uses `FileExt::read_exact_at` for efficient, immutable positioned reads directly from a `std::fs::File`. ```rust #[cfg(unix)] /// Adapts a Unix [`std::fs::File`] using `FileExt::read_exact_at`. /// /// Unlike [`ReadSeekReader`], this wrapper performs true immutable positioned /// reads without seeking the file handle. pub struct UnixFileReader { inner: File, } #[cfg(unix)] impl From for UnixFileReader { fn from(inner: File) -> Self { Self::new(inner) } } #[cfg(unix)] impl UnixFileReader { /// Wraps a file for immutable positioned reads. #[must_use] pub fn new(inner: File) -> Self { Self { inner } } /// Returns the wrapped file. #[must_use] pub fn into_inner(self) -> File { self.inner } } #[cfg(unix)] impl Reader for UnixFileReader { type Error = Error; fn size(&self) -> Result { Ok(self.inner.metadata()?.len()) } fn read_exact_at(&self, pos: u64, buf: &mut [u8]) -> Result<(), Self::Error> { use std::os::unix::fs::FileExt; self.inner.read_exact_at(buf, pos) } } ``` -------------------------------- ### by_ref Method for EntryReader Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/struct.EntryReader.html Creates a "by reference" adapter for the EntryReader. This allows borrowing the reader without consuming it. ```rust fn by_ref(&mut self) -> &mut Self ``` -------------------------------- ### Open and Read ZIP Entry (with std) Source: https://docs.rs/tinyzip/0.4.0/tinyzip/index.html Shows how to open a ZIP archive from a std::fs::File and decompress its contents using flate2 in an environment with the 'std' feature enabled. Includes a check for file size to mitigate zip bomb risks. ```Rust use std::fs::File; use std::io::{self, Read}; use tinyzip::{Archive, Compression}; use flate2::read::DeflateDecoder; // switch decompressor lib with crate features let zip_file = File::open(zip_path)?; let archive = Archive::try_from(zip_file)?; let entry = archive.find_file(b"test.txt")?; let mut writer = Vec::new(); // This could be be a `std::fs::File` let size = entry.uncompressed_size(); assert!(size < 1024, "file too large"); // be careful with zip bombs match entry.compression()? { Compression::Deflated => { let mut decoder = DeflateDecoder::new(entry.reader()?).take(size); io::copy(&mut decoder, &mut writer)?; } Compression::Stored => { io::copy(&mut entry.reader()?, &mut writer)?; } } ``` -------------------------------- ### Get Raw ID from Compression Enum Source: https://docs.rs/tinyzip/0.4.0/tinyzip/enum.Compression.html Returns the raw ZIP method ID (u16) for the current Compression enum variant. ```rust pub fn raw(self) -> u16 ``` -------------------------------- ### From for UnixFileReader Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/struct.UnixFileReader.html Provides a conversion from a standard `std::fs::File` to a `UnixFileReader`. This implementation is available only on Unix platforms. ```APIDOC ## From for UnixFileReader ### Description Converts a `std::fs::File` into a `UnixFileReader`. ### Method `from` ### Parameters * `inner` (File) - The `std::fs::File` to convert. ``` -------------------------------- ### Get Uncompressed Size Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Returns the uncompressed size of the zip entry's payload in bytes. This value can be from the central directory or ZIP64 extensions. ```rust pub fn uncompressed_size(&self) -> u64 { self.uncompressed_size } ``` -------------------------------- ### Get Compressed Size Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Returns the compressed size of the zip entry's payload in bytes. This value can be from the central directory or ZIP64 extensions. ```rust pub fn compressed_size(&self) -> u64 { self.compressed_size } ``` -------------------------------- ### Navigate and Decompress ZIP Entry (no_std) Source: https://docs.rs/tinyzip/0.4.0/index.html Opens a ZIP archive, finds a specific file entry, and decompresses its content using miniz_oxide. Suitable for environments without standard library support. Ensure the decompressed buffer is large enough. ```Rust use tinyzip::{Archive, Compression}; use miniz_oxide::inflate::stream::{inflate, InflateState}; use miniz_oxide::{DataFormat, MZFlush}; let archive = Archive::open(file_bytes)?; let entry = archive.find_file(b"test.txt")?; let mut decompressed = [0u8; 1024]; let contents = match entry.compression()? { Compression::Deflated => { let mut chunks = entry.read_chunks::<512>()?; let mut state = InflateState::new(DataFormat::Raw); let mut out_pos = 0; while let Some(chunk) = chunks.next() { let result = inflate(&mut state, chunk?, &mut decompressed[out_pos..], MZFlush::None); out_pos += result.bytes_written; } &decompressed[..out_pos] } Compression::Stored => { entry.read_to_slice(&mut decompressed)? } }; assert_eq!(contents, b"This is a test text file.\n"); ``` -------------------------------- ### Reader for UnixFileReader Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/type.FileReader.html Implements the Reader trait for UnixFileReader, providing methods to get the archive size and read exact byte ranges. This implementation is available only on Unix platforms. ```APIDOC ## Reader for UnixFileReader ### Description Provides reading capabilities for `UnixFileReader`. ### Availability Available on **Unix** only. ### Associated Types #### Error `type Error = Error` - Backend-specific I/O error type. ### Methods #### size ##### Description Returns the total archive size in bytes. ##### Signature `fn size(&self) -> Result` ##### Returns - **Result** - The size of the archive in bytes or an I/O error. #### read_exact_at ##### Description Fills a buffer with data from the archive starting at a specific absolute byte position. ##### Signature `fn read_exact_at(&self, pos: u64, buf: &mut [u8]) -> Result<(), Self::Error>` ##### Parameters - **pos** (u64) - The absolute byte position to start reading from. - **buf** (&mut [u8]) - The mutable byte slice to fill with data. ``` -------------------------------- ### Convert File to Archive Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/std_io.rs.html Implements the `TryFrom` trait to allow direct conversion of a `std::fs::File` into a `tinyzip::Archive` using a `FileReader` adapter. ```rust use crate::{Archive, Entry, Reader}; use core::cell::RefCell; use core::convert::TryFrom; use std::fs::File; use std::io::{Error, Read, Seek, SeekFrom}; impl TryFrom for Archive { type Error = crate::Error; fn try_from(file: File) -> Result { Self::open(FileReader::from(file)) } } ``` -------------------------------- ### UnixFileReader Constructor Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/struct.UnixFileReader.html Creates a new UnixFileReader by wrapping a standard Unix file handle. This is used when you need to perform reads at specific positions without altering the file's current seek position. ```rust pub fn new(inner: File) -> Self ``` -------------------------------- ### chain Method for EntryReader Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/struct.EntryReader.html Creates an adapter that chains the EntryReader with another reader. This allows reading from multiple sources sequentially. ```rust fn chain(self, next: R) -> Chain where R: Read, Self: Sized, ``` -------------------------------- ### Lending Iterator for Data Chunks Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html A lending iterator that reads zip entry data in chunks of a specified size (N). Each call to `next` returns a slice borrowing from an internal buffer, which is invalidated on subsequent calls. Use a `while let` loop for iteration. ```rust pub fn next(&mut self) -> Option>> { if self.pos >= self.end { return None; } let remaining = (self.end - self.pos) as usize; let chunk_len = remaining.min(N); match self .archive .read_exact_at(self.pos, &mut self.buf[..chunk_len]) { Ok(()) => { self.pos += chunk_len as u64; Some(Ok(&self.buf[..chunk_len])) } Err(e) => { Some(Err(e)) } } } ``` -------------------------------- ### Into Implementation Source: https://docs.rs/tinyzip/0.4.0/tinyzip/enum.Compression.html Allows converting a value into another type that can be created from it. ```rust fn into(self) -> U ``` -------------------------------- ### Compare Full Entry Path Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entry.html Returns whether the full stored path of the entry equals the provided path. This is a raw byte comparison and does not decode text or normalize paths. Comparison is optimized for early termination. ```rust pub fn path_is(&self, path: impl AsRef<[u8]>) -> Result> ``` -------------------------------- ### Entry Parsing Logic Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Parses a central directory entry from a given offset. Handles signature validation, flag checks, and calculates the next entry's offset. ```rust fn parse( archive: &'a Archive, header_offset: u64, end_offset: u64, ) -> Result<(Self, u64), Error> { let mut header = [0u8; CENTRAL_HEADER_LEN]; archive.read_exact_at(header_offset, &mut header)?; if le_bytes!(u32, &header[0..4]) != CENTRAL_HEADER_SIGNATURE { return Err(Error::InvalidSignature); } let flags = le_bytes!(u16, &header[8..10]); if flags & (1 << 6) != 0 || flags & (1 << 13) != 0 { return Err(Error::StrongEncryption); } let name_len = u64::from(le_bytes!(u16, &header[28..30])); let extra_len = u64::from(le_bytes!(u16, &header[30..32])); let comment_len = u64::from(le_bytes!(u16, &header[32..34])); let record_len = central_record_len(name_len, extra_len, comment_len).ok_or(Error::InvalidOffset)?; let next_offset = add(header_offset, record_len)?; if next_offset > end_offset { return Err(Error::Truncated); } let name_range = (header_offset + CENTRAL_HEADER_LEN as u64) } ``` -------------------------------- ### impl TryFrom for Archive Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Archive.html Implements the `TryFrom` trait for converting a `File` into an `Archive`, handling potential conversion errors. ```APIDOC ## impl TryFrom for Archive ### Description Performs the conversion from a `File` to an `Archive`. ### Type Alias `type Error = Error` ### Method `try_from(file: File) -> Result` ``` -------------------------------- ### Compare Entry Path Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Checks if the stored path of a zip entry matches a given path. Returns an error if the path length is inconsistent or if underlying reads fail. ```rust pub fn path_is(&self, path: impl AsRef<[u8]>) -> Result> { let path = path.as_ref(); let path_len = u64::try_from(path.len()).map_err(|_| Error::InvalidOffset)?; let stored_len = self .name_range .end .checked_sub(self.name_range.start) .ok_or(Error::InvalidOffset)?; if stored_len != path_len { return Ok(false); } let mut scratch = [0u8; PATH_SCAN_CHUNK_LEN]; let mut remaining = path.len(); while remaining > 0 { let chunk_len = remaining.min(scratch.len()); let offset = remaining - chunk_len; let archive_offset = self.name_range.start + u64::try_from(offset).map_err(|_| Error::InvalidOffset)?; self.archive .read_exact_at(archive_offset, &mut scratch[..chunk_len])?; if scratch[..chunk_len] != path[offset..offset + chunk_len] { return Ok(false); } remaining = offset; } Ok(true) } ``` -------------------------------- ### Compare Entry Filename Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entry.html Returns whether the final component of the entry path equals the provided file name. This is a raw byte comparison and does not perform text decoding or path normalization. ```rust pub fn filename_is(&self, file_name: &[u8]) -> Result> ``` -------------------------------- ### read_buf_exact Method for EntryReader Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/struct.EntryReader.html Reads the exact number of bytes required to fill a BorrowedCursor. This is a nightly-only experimental API. ```rust fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error> ``` -------------------------------- ### TryFrom Implementation Source: https://docs.rs/tinyzip/0.4.0/tinyzip/enum.Compression.html Attempts to convert one type into another, returning a Result. ```rust type Error = Infallible ``` ```rust fn try_from(value: U) -> Result>::Error> ``` -------------------------------- ### Iterator step_by() Method Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entries.html Creates a new iterator that yields elements from the original iterator, but steps by a specified amount. ```rust fn step_by(self, step: usize) -> StepBy where Self: Sized, ``` -------------------------------- ### UnixFileReader::into_inner Method Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/type.FileReader.html Illustrates how to retrieve the original std::fs::File from a UnixFileReader instance, consuming the reader in the process. ```rust pub fn into_inner(self) -> File ``` -------------------------------- ### PartialEq Implementation for Compression Source: https://docs.rs/tinyzip/0.4.0/tinyzip/enum.Compression.html Allows comparison of two Compression enum values for equality. ```rust fn eq(&self, other: &Compression) -> bool ``` ```rust fn ne(&self, other: &Rhs) -> bool ``` -------------------------------- ### Entry::flags Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Returns the raw general-purpose bit flags from the central directory. These flags provide information about the entry's encryption status, compression method specifics, and other attributes. ```APIDOC ## Entry::flags ### Description Returns the raw general-purpose bit flags from the central directory. These flags provide information about the entry's encryption status, compression method specifics, and other attributes. Per PKWARE APPNOTE 6.3.9 section 4.4.4, the bits mean: - Bit 0: entry is encrypted. - Bits 1-2: method-specific; Implode uses them for dictionary/tree choices, Deflate/Deflate64 uses them for compression level, and LZMA uses bit 1 for the EOS marker. - Bit 3: local header CRC-32 and sizes are zero; a data descriptor follows the file data with the real values. - Bit 4: reserved for enhanced deflating. - Bit 5: compressed patched data. - Bit 6: strong encryption; bit 0 must also be set. - Bits 7-10: currently unused. - Bit 11: EFS; file name and comment are UTF-8. - Bit 12: reserved for enhanced compression. - Bit 13: central-directory encryption masking in the local header. - Bit 14: reserved for alternate streams. - Bit 15: reserved by PKWARE. ### Method `pub fn flags(&self) -> u16` ### Returns - `u16`: The general-purpose bit flags. ``` -------------------------------- ### Find File Entry by Path Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Archive.html Finds the first entry in the archive whose full path exactly matches the provided path. Returns `Error::NotFound` if no match is found, or propagates any parse or I/O errors. ```rust pub fn find_file( &self, path: impl AsRef<[u8]>, ) -> Result, Error> ``` -------------------------------- ### read_exact Method for EntryReader Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/struct.EntryReader.html Reads exactly the number of bytes required to fill the provided buffer. Returns an error if EOF is reached before the buffer is filled. ```rust fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error> ``` -------------------------------- ### From Implementation Source: https://docs.rs/tinyzip/0.4.0/tinyzip/enum.Compression.html Allows creating a value of a type from itself. ```rust fn from(t: T) -> T ``` -------------------------------- ### UnixFileReader::new Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/struct.UnixFileReader.html Constructs a new UnixFileReader by wrapping a standard Unix File object. This allows for immutable positioned reads. ```APIDOC ## UnixFileReader::new ### Description Wraps a file for immutable positioned reads. ### Method `new` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters * `inner` (File) - The standard Unix File object to wrap. ``` -------------------------------- ### Entry Struct Methods Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entry.html Provides access to various metadata and data associated with a zip archive entry. ```APIDOC ## Struct Entry Parsed central-directory entry. Variable-length fields remain in the underlying archive and can be read into caller-provided buffers with the `read_*` methods. ### Methods #### `reader()` * **Description**: Returns a `Read` adapter over this entry’s payload bytes. The adapter reads raw stored or compressed bytes from the archive; decompression is the caller’s responsibility. * **Returns**: `Result, Error>` * **Errors**: Returns a structural `crate::Error` if the local header is malformed or the data range extends past the archive. #### `flags()` * **Description**: Returns the raw general-purpose bit flags from the central directory. * **Returns**: `u16` #### `compression()` * **Description**: Returns the compression method reported by the central directory. * **Returns**: `Result>` * **Errors**: Returns `Error::UnsupportedCompression` if the method id is not recognised by this crate. #### `crc32()` * **Description**: Returns the CRC-32 reported by the central directory. * **Returns**: `u32` #### `compressed_size()` * **Description**: Returns the compressed payload size in bytes. * **Returns**: `u64` #### `uncompressed_size()` * **Description**: Returns the uncompressed payload size in bytes. * **Returns**: `u64` #### `read_path(buf: &mut [u8])` * **Description**: Reads the central-directory path bytes into `buf`. ZIP stores a single byte string here rather than a structured path. It may be just a bare file name, a `/`-separated nested path, or a directory marker ending in `/`. Use `Self::path_is_utf8` to check whether the central-directory metadata declares this path as UTF-8. * **Parameters**: `buf` (`&'b mut [u8]`) - The buffer to read the path bytes into. * **Returns**: `Result<&'b [u8], Error>` - A slice of the buffer containing the read path bytes. * **Errors**: Returns `Error::InvalidOffset` if `buf` is too small or the entry range is inconsistent, and `Error::Io` if the underlying read fails. #### `path_is_utf8()` * **Description**: Returns whether the central-directory general-purpose bit flag declares the entry path to be UTF-8 encoded. The result comes from bit 11 of the central-directory general-purpose flag. It does not inspect or validate the path bytes themselves. * **Returns**: `bool` #### `filename_is(file_name: &[u8])` * **Description**: Returns whether the final `/`-separated component of the entry path equals `file_name`. This compares raw bytes only. It does not decode text, normalize path separators, or resolve `.` / `..`. The method reads only the path bytes needed to locate and compare the last component. * **Parameters**: `file_name` (`&[u8]`) - The filename to compare against. * **Returns**: `Result>` * **Errors**: Returns a structural `Error` if the stored path range is inconsistent, and `Error::Io` if the underlying reads fail. #### `data_range()` * **Description**: Resolves the local-header and payload ranges for this entry. This performs an extra local-header read. It does not decompress data; it only reports where the stored or compressed bytes live in the archive. * **Returns**: `Result>` * **Errors**: Returns a structural `Error` if the local header is malformed or uses an unsupported feature, and `Error::Io` if the underlying read fails. #### `path_is(path: impl AsRef<[u8]>)` * **Description**: Returns whether the full stored path equals `path`. This compares raw bytes only. It does not decode text, normalize path separators, or resolve `.` / `..`. Comparison proceeds from the end of the path for early termination when entries share a common prefix. * **Parameters**: `path` (`impl AsRef<[u8]>`) - The path to compare against. * **Returns**: `Result>` * **Errors**: Returns a structural `Error` if the stored path range is inconsistent, and `Error::Io` if the underlying reads fail. ``` -------------------------------- ### Compare Filename Component Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Compares the last component of the entry's path with a given filename. This is a raw byte comparison and does not handle text decoding, path normalization, or special path components like '.' or '..'. It reads only the necessary bytes for comparison. ```rust pub fn filename_is(&self, file_name: &[u8]) -> Result> { let component_start = find_path_file_name_start(self.archive, self.name_range.clone())?; let component_len = self .name_range .end .checked_sub(component_start) .ok_or(Error::InvalidOffset)?; let file_name_len = u64::try_from(file_name.len()).map_err(|_| Error::InvalidOffset)?; if component_len != file_name_len { return Ok(false); } let mut scratch = [0u8; PATH_SCAN_CHUNK_LEN]; let mut compared = 0usize; while compared < file_name.len() { let chunk_len = (file_name.len() - compared).min(scratch.len()); let chunk_offset = component_start + u64::try_from(compared).map_err(|_| Error::InvalidOffset)?; self.archive .read_exact_at(chunk_offset, &mut scratch[..chunk_len])?; if scratch[..chunk_len] != file_name[compared..compared + chunk_len] { return Ok(false); } compared += chunk_len; } Ok(true) } ``` -------------------------------- ### Read Entry Data to Slice Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Reads the entire payload of a zip entry into a provided buffer. The buffer must be large enough to hold the compressed data. Errors can occur if the buffer is too small or if read operations fail. ```rust pub fn read_to_slice<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], Error> { let range = self.data_range()?; let len = range_len_usize(&range.data_range)?; if buf.len() < len { return Err(Error::InvalidOffset); } self.archive .read_exact_at(range.data_range.start, &mut buf[..len])?; Ok(&buf[..len]) } ``` -------------------------------- ### Read Entry Path Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Reads the path of a zip entry into a provided buffer. Returns an error if the path range is inconsistent or if the underlying read fails. ```rust pub fn read_path<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], Error> { read_variable_range(self.archive, self.name_range.clone(), buf) } ``` -------------------------------- ### EntryReader for Reading Archive Entries Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/std_io.rs.html An adapter that provides a `Read` interface over an individual entry's payload bytes within an archive. It performs positioned reads on the underlying archive reader. ```rust /// A [`Read`] adapter over an entry's payload bytes. /// /// Created by [`Entry::reader`]. Each [`read`](Read::read) call performs a /// positioned read on the underlying archive, so the reader is not buffered. pub struct EntryReader<'a, R> { archive: &'a Archive, pos: u64, end: u64, } impl<'a, R: Reader> where R::Error: Into, { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { if self.end <= self.pos { return Ok(0); } let remaining = self.end - self.pos; let to_read = buf.len().min(usize::try_from(remaining).unwrap()); self.archive .reader .read_exact_at(self.pos, &mut buf[..to_read]) .map_err(Into::into)?; self.pos += u64::try_from(to_read).unwrap(); Ok(to_read) } } impl<'a, R: Reader> Entry<'a, R> { /// Returns a [`Read`] adapter over this entry's payload bytes. /// /// The adapter reads raw stored or compressed bytes from the archive; /// decompression is the caller's responsibility. /// /// # Errors /// /// Returns a structural [`crate::Error`] if the local header is malformed /// or the data range extends past the archive. pub fn reader(&self) -> Result, crate::Error> { let range = self.data_range()?; Ok(EntryReader { archive: self.archive, pos: range.data_range.start, end: range.data_range.end, }) } } ``` -------------------------------- ### UnixFileReader Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/std_io.rs.html Adapts a Unix `std::fs::File` using `FileExt::read_exact_at`. Unlike `ReadSeekReader`, this wrapper performs true immutable positioned reads without seeking the file handle. ```APIDOC ## struct UnixFileReader ### Description Adapts a Unix [`std::fs::File`] using `FileExt::read_exact_at`. Unlike [`ReadSeekReader`], this wrapper performs true immutable positioned reads without seeking the file handle. ### Methods * `fn new(inner: File) -> Self` Wraps a file for immutable positioned reads. * `fn into_inner(self) -> File` Returns the wrapped file. ### Implementations * `impl From for UnixFileReader` Creates a `UnixFileReader` from a `std::fs::File`. * `impl Reader for UnixFileReader` * `fn size(&self) -> Result` Returns the size of the file. * `fn read_exact_at(&self, pos: u64, buf: &mut [u8]) -> Result<(), Self::Error>` Reads exactly `buf.len()` bytes from the specified position into `buf` using `FileExt::read_exact_at`. ``` -------------------------------- ### Compression Enum Methods Source: https://docs.rs/tinyzip/0.4.0/tinyzip/enum.Compression.html Provides methods to convert between raw ZIP method identifiers and the `Compression` enum variants, allowing for interoperability with raw ZIP data. ```APIDOC ## impl Compression ### pub fn from_raw(raw: u16) -> Option Converts a raw ZIP method id into the low-level enum used by the crate. ### pub fn raw(self) -> u16 Returns the raw ZIP method id exactly as it appears on disk. ``` -------------------------------- ### read_buf Method for EntryReader Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/struct.EntryReader.html Reads bytes from the EntryReader into a BorrowedCursor. This is a nightly-only experimental API. ```rust fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error> ``` -------------------------------- ### Navigate and Decompress ZIP Entry (std) Source: https://docs.rs/tinyzip/0.4.0/index.html Opens a ZIP archive from a std::fs::File, finds a file entry, and decompresses its content using flate2. This version leverages standard library features and heap allocation for the writer. Be cautious of potential zip bombs by checking file size. ```Rust use std::fs::File; use std::io::{self, Read}; use tinyzip::{Archive, Compression}; use flate2::read::DeflateDecoder; // switch decompressor lib with crate features let zip_file = File::open(zip_path)?; let archive = Archive::try_from(zip_file)?; let entry = archive.find_file(b"test.txt")?; let mut writer = Vec::new(); // This could be be a `std::fs::File` let size = entry.uncompressed_size(); assert!(size < 1024, "file too large"); // be careful with zip bombs match entry.compression()? { Compression::Deflated => { let mut decoder = DeflateDecoder::new(entry.reader()?).take(size); io::copy(&mut decoder, &mut writer)?; } Compression::Stored => { io::copy(&mut entry.reader()?, &mut writer)?; } } ``` -------------------------------- ### TryInto Implementation Source: https://docs.rs/tinyzip/0.4.0/tinyzip/enum.Compression.html Attempts to convert a value into another type, returning a Result. ```rust type Error = >::Error ``` ```rust fn try_into(self) -> Result>::Error> ``` -------------------------------- ### ReadSeekReader::new Constructor Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/struct.ReadSeekReader.html Constructs a new ReadSeekReader by wrapping a given Read + Seek source. ```rust pub fn new(inner: T) -> Self ``` -------------------------------- ### Clone Implementation for Compression Source: https://docs.rs/tinyzip/0.4.0/tinyzip/enum.Compression.html Provides the ability to create a copy of a Compression enum value. ```rust fn clone(&self) -> Compression ``` ```rust fn clone_from(&mut self, source: &Self) ``` -------------------------------- ### Archive::open Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Opens a ZIP archive from a given reader. It performs several checks to validate the archive's structure, including locating the End of Central Directory record, handling ZIP64 extensions, and ensuring the archive is not multi-disk or using unsupported encryption. Errors are returned if the reader fails or if the archive structure is malformed or unsupported. ```APIDOC ## Archive::open ### Description Opens an archive by locating EOCD, resolving ZIP64 metadata, and validating the central directory layout. The parser accepts prefixed archives and trailing junk, but rejects multi-disk archives and several unsupported encrypted forms. ### Method `pub fn open(reader: R) -> Result>` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (Self) - **reader** (R) - The random-access reader for the archive. - **size** (u64) - The total size of the archive. - **base_offset** (u64) - The base offset of the archive. - **directory_end_offset** (u64) - The offset of the end of the directory. - **central_directory_offset** (u64) - The offset of the central directory. - **entry_count** (u64) - The number of entries in the archive. #### Error Response - **Error::Io(E)** - Error returned by the underlying [`Reader`]. - **Error::NotZip** - No EOCD record was found in the allowed scan window. - **Error::Truncated** - A required record or payload extends past the end of the archive. - **Error::InvalidSignature** - A required ZIP signature was missing. - **Error::InvalidOffset** - An archive offset was inconsistent or impossible. - **Error::InvalidRecord** - A record was malformed even though its outer signature matched. - **Error::MultiDisk** - Split or multi-disk archives. - **Error::StrongEncryption** - Strong encryption markers in central or local headers. - **Error::MaskedLocalHeaders** - Masked local headers, which hide required local metadata. - **Error::UnsupportedCompression(u16)** - A compression method the crate does not support. - **Error::NotFound** - No entry matched the requested path. ### Response Example None ``` -------------------------------- ### Iterator zip() Method Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entries.html Combines two iterators into a single iterator of pairs, where each pair contains one element from each of the original iterators. ```rust fn zip(self, other: U) -> Zip::IntoIter> where Self: Sized, U: IntoIterator, ``` -------------------------------- ### TryFrom File for Archive Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Archive.html Implements the `TryFrom` trait for `Archive`, allowing conversion from a `File` to an `Archive`. The associated error type is `Error`. ```rust type Error = Error fn try_from(file: File) -> Result ``` -------------------------------- ### FileReader::new Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/type.FileReader.html Constructs a new FileReader by wrapping a standard file object. This allows for immutable, positioned reads from the file. ```APIDOC ## FileReader::new ### Description Wraps a file for immutable positioned reads. ### Method `new` ### Signature `pub fn new(inner: File) -> Self` ### Parameters #### Path Parameters - **inner** (File) - Description: The standard file object to wrap. ``` -------------------------------- ### Iterator next_chunk() Method (Nightly) Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entries.html Advances the iterator and returns an array of N items. This is an experimental, nightly-only API. ```rust fn next_chunk( &mut self, ) -> Result<[Self::Item; N], IntoIter> where Self: Sized, ``` -------------------------------- ### Entry::compression Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Returns the compression method reported by the central directory. This method translates the raw compression method ID into a `Compression` enum variant. ```APIDOC ## Entry::compression ### Description Returns the compression method reported by the central directory. This method translates the raw compression method ID into a `Compression` enum variant. ### Method `pub fn compression(&self) -> Result>` ### Returns - `Result>`: Ok containing the `Compression` enum variant if the method is recognized, or an `Error::UnsupportedCompression` if the method ID is not recognized. ``` -------------------------------- ### Iterator next() Method Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entries.html Advances the iterator and returns the next archive entry as an Option. This is the fundamental method for consuming the iterator. ```rust fn next(&mut self) -> Option ``` -------------------------------- ### filename_is Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Compares the final component of the entry's path with a given byte slice. This comparison is byte-wise and does not perform text decoding or path normalization. ```APIDOC ## filename_is ### Description Compares the final component of the entry's path with a given byte slice. This comparison is byte-wise and does not perform text decoding or path normalization. It efficiently compares only the necessary bytes. ### Method `filename_is` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **file_name** (`&[u8]`) - Required - The byte slice representing the filename to compare against. ### Request Example ```rust // Example usage (conceptual) let is_match = entry.filename_is(b"example.txt")?; ``` ### Response #### Success Response - `bool` - `true` if the final path component matches `file_name`, `false` otherwise. #### Response Example ```rust // Conceptual success response Ok(true) ``` ### Errors - `Error` - If the stored path range is inconsistent or underlying reads fail. ``` -------------------------------- ### Reader Implementation for Byte Slices Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Provides an implementation of the `Reader` trait for byte slices (`&[u8]`), enabling reading zip archives directly from memory. ```Rust impl Reader for &[u8] { type Error = SliceReaderError; fn size(&self) -> Result { Ok(self.len() as u64) } fn read_exact_at(&self, pos: u64, buf: &mut [u8]) -> Result<(), Self::Error> { let pos = usize::try_from(pos).map_err(|_| SliceReaderError::OutOfBounds)?; let end = pos .checked_add(buf.len()) .ok_or(SliceReaderError::OutOfBounds)?; let src = self.get(pos..end).ok_or(SliceReaderError::OutOfBounds)?; buf.copy_from_slice(src); Ok(()) } } ``` -------------------------------- ### Reading Entry Payload in Chunks Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.DataChunks.html Demonstrates how to use `DataChunks` as a lending iterator to read an entry's payload in chunks of a specified size. This is the primary method for reading chunked data from an archive entry. ```rust let zip_bytes = include_bytes!("../tests/data/manual/go-archive-zip/test.zip"); let archive = tinyzip::Archive::open(zip_bytes.as_slice()).unwrap(); let entry = archive.find_file(b"test.txt").unwrap(); let mut chunks = entry.read_chunks::<512>().unwrap(); while let Some(chunk) = chunks.next() { let _data = chunk.unwrap(); } ``` -------------------------------- ### Check if Entry Path is UTF-8 Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entry.html Returns whether the central-directory general-purpose bit flag declares the entry path to be UTF-8 encoded. This check is based solely on the flag, not the path bytes themselves. ```rust pub fn path_is_utf8(&self) -> bool ``` -------------------------------- ### Borrow Implementation Source: https://docs.rs/tinyzip/0.4.0/tinyzip/enum.Compression.html Provides immutable borrowing capabilities. ```rust fn borrow(&self) -> &T ``` -------------------------------- ### Read Entry Path into Buffer Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entry.html Reads the central-directory path bytes into a provided buffer. The buffer must be large enough to hold the full path. Returns a slice of the buffer containing the read bytes. ```rust pub fn read_path<'b>( &self, buf: &'b mut [u8], ) -> Result<&'b [u8], Error> ``` -------------------------------- ### read_to_string Method for EntryReader Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/struct.EntryReader.html Reads all bytes from the EntryReader until EOF and appends them to a provided String. Returns the total number of bytes read. ```rust fn read_to_string(&mut self, buf: &mut String) -> Result ``` -------------------------------- ### Iterate Over Archive Entries Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Archive.html Provides an iterator over the entries (files) declared in the ZIP archive's central directory. This iterator performs no allocations and stops permanently upon encountering the first parse error. ```rust pub fn entries(&self) -> Entries<'_, R> ``` -------------------------------- ### Debug Implementation for Compression Source: https://docs.rs/tinyzip/0.4.0/tinyzip/enum.Compression.html Enables formatting the Compression enum for debugging purposes. ```rust fn fmt(&self, f: &mut Formatter<'_>) -> Result ``` -------------------------------- ### UnixFileReader into_inner Method Source: https://docs.rs/tinyzip/0.4.0/tinyzip/std_io/struct.UnixFileReader.html Retrieves the original File handle from the UnixFileReader. This is useful when you are finished with the positioned read operations and want to regain ownership of the file. ```rust pub fn into_inner(self) -> File ``` -------------------------------- ### Iterator advance_by() Method (Nightly) Source: https://docs.rs/tinyzip/0.4.0/tinyzip/struct.Entries.html Advances the iterator by a specified number of elements. This is an experimental, nightly-only API. ```rust fn advance_by(&mut self, n: usize) -> Result<(), NonZero> ``` -------------------------------- ### Archive::new Source: https://docs.rs/tinyzip/0.4.0/src/tinyzip/lib.rs.html Constructs a new `Archive` from a reader. This function validates the archive's structure and returns an `Archive` instance if successful. ```APIDOC ## Archive::new ### Description Constructs a new `Archive` from a reader. This function validates the archive's structure and returns an `Archive` instance if successful. ### Method Associated function (constructor) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust let archive = Archive::new(reader)?; ``` ### Response #### Success Response (Ok) - **Archive** (Archive) - An initialized `Archive` struct. #### Response Example ```rust Ok(Self { reader, size, base_offset, directory_end_offset: payload_end, central_directory_offset, entry_count, }) ``` ### Errors - **Error::InvalidOffset**: If the archive offsets are invalid. - **Error::Io**: If an I/O error occurs during reading. ```