ZipLocator

Struct ZipLocator 

Source
pub struct ZipLocator { /* private fields */ }
Expand description

Locates the End of Central Directory (EOCD) record in a ZIP archive.

The ZipLocator is responsible for finding the EOCD record, which is crucial for reading the contents of a ZIP file.

In the event, that the comment or tailing data contains the EOCD signature, causing the zip locator to fail to parse. One can reparse the data starting from the false EOCD offset using the reported offset Error::eocd_offset()

Implementations§

Source§

impl ZipLocator

Source

pub fn new() -> Self

Creates a new ZipLocator with a default maximum search space of 1 MiB

Source

pub fn max_search_space(self, max_search_space: u64) -> Self

Sets the maximum number of bytes to search for the EOCD signature.

The search is performed backwards from the end of the data source.

use rawzip::ZipLocator;

let locator = ZipLocator::new().max_search_space(1024 * 64); // 64 KiB
Source

pub fn locate_in_slice<T: AsRef<[u8]>>( &self, data: T, ) -> Result<ZipSliceArchive<T>, (T, Error)>

Locates the EOCD record within a byte slice.

On success, returns a ZipSliceArchive which allows reading the archive directly from the slice. On failure, returns the original slice and an Error.

§Examples
use rawzip::ZipLocator;
use std::fs;
use std::io::Read;

let mut file = fs::File::open("assets/readme.zip")?;
let mut data = Vec::new();
file.read_to_end(&mut data)?;

let locator = ZipLocator::new();
match locator.locate_in_slice(&data) {
    Ok(archive) => {
        println!("Found EOCD in slice, archive has {} files.", archive.entries_hint());
    }
    Err((_data, e)) => {
        eprintln!("Failed to locate EOCD in slice: {:?}", e);
    }
}
Source

pub fn locate_in_file( &self, file: File, buffer: &mut [u8], ) -> Result<ZipArchive<FileReader>, (File, Error)>

Locates the EOCD record within a file.

A mutable byte slice to use for reading data from the file. The buffer should be large enough to hold the EOCD record and potentially parts of the ZIP64 EOCD locator if present. A common size might be a few kilobytes.

On failure, returns the original file and an Error.

§Examples
use rawzip::ZipLocator;
use std::fs::File;

let file = File::open("assets/readme.zip")?;
let mut buffer = vec![0; rawzip::RECOMMENDED_BUFFER_SIZE];
let locator = ZipLocator::new();

match locator.locate_in_file(file, &mut buffer) {
    Ok(archive) => {
        println!("Found EOCD in file, archive has {} files.", archive.entries_hint());
    }
    Err((_file, e)) => {
        eprintln!("Failed to locate EOCD in file: {:?}", e);
    }
}
Source

pub fn locate_in_reader<R>( &self, reader: R, buffer: &mut [u8], end_offset: u64, ) -> Result<ZipArchive<R>, (R, Error)>
where R: ReaderAt,

Locates the EOCD record in a reader, treating the specified end offset as the starting point when searching backwards.

This method is useful for several scenarios:

  • Zip archive is nowhere near the end of the reader
  • Zip archives are concatenated

For seekable readers, you can determine the end_offset by seeking to the end of the stream.

Note that the zip locator may request data passed the end offset in order to read the entire end of the central directory record + comment.

§Examples
use rawzip::{ZipLocator, FileReader};
use std::fs::File;
use std::io::Seek;

let file = File::open("assets/test.zip").unwrap();
let mut reader = FileReader::from(file);
let mut buffer = vec![0; rawzip::RECOMMENDED_BUFFER_SIZE];
let locator = ZipLocator::new();

// An example of determining the end offset when you don't
// the length but have a seekable reader.
let end_offset = reader.seek(std::io::SeekFrom::End(0)).unwrap();
let archive = locator.locate_in_reader(reader, &mut buffer, end_offset)
    .map_err(|(_, e)| e)?;

// Maybe there is another zip archive to be found.
// To find where the current archive starts, we need the minimum local header
// offset. Below we are being conservative and iterating through the entire central
// directory for the start offset, but in reality out of order central directories
// are an edge case.
let zip_start = {
    let mut min_offset = u64::MAX;
    let mut entries = archive.entries(&mut buffer);
    while let Ok(Some(entry)) = entries.next_entry() {
        min_offset = min_offset.min(entry.local_header_offset());
    }
    if min_offset == u64::MAX { 0 } else { min_offset }
};
match locator.locate_in_reader(archive.get_ref(), &mut buffer, zip_start) {
   Ok(previous_archive) => {
       println!("Found previous ZIP archive!");
   }
   Err((_, _)) => println!("No previous ZIP archive found"),
}

Trait Implementations§

Source§

impl Debug for ZipLocator

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ZipLocator

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.