diff --git a/src/lib.rs b/src/lib.rs index baf29a1c4..efc2f0411 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,6 +29,7 @@ pub use crate::compression::{CompressionMethod, SUPPORTED_COMPRESSION_METHODS}; pub use crate::read::ZipArchive; +pub use crate::spec::{ZIP64_BYTES_THR, ZIP64_ENTRY_THR}; pub use crate::types::DateTime; pub use crate::write::ZipWriter; diff --git a/src/spec.rs b/src/spec.rs index b620c01e7..18c8c1252 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -1,4 +1,6 @@ use crate::result::{ZipError, ZipResult}; +#[cfg(doc)] +use crate::write::{FileOptions, ZipWriter}; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use std::borrow::Cow; use std::io; @@ -11,7 +13,47 @@ pub(crate) const CENTRAL_DIRECTORY_END_SIGNATURE: u32 = 0x06054b50; pub const ZIP64_CENTRAL_DIRECTORY_END_SIGNATURE: u32 = 0x06064b50; pub(crate) const ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE: u32 = 0x07064b50; +/// The number of bytes necessary to allocate a zip64 record for an individual file. +/// +/// If a file larger than this threshold attempts to be written, and [`FileOptions::large_file()`] +/// was not true, then [`ZipWriter`] will raise an [`io::Error`] with [`io::ErrorKind::Other`]. +/// +/// If the zip file itself is larger than this value, then a zip64 central directory record will be +/// written to the end of the file. +/// +///``` +/// # fn main() -> Result<(), zip::result::ZipError> { +/// use std::io::{self, Cursor, prelude::*}; +/// use zip::{ZipWriter, write::SimpleFileOptions}; +/// +/// let mut zip = ZipWriter::new(Cursor::new(Vec::new())); +/// // Writing an extremely large file for this test is faster without compression. +/// let options = SimpleFileOptions::default().compression_method(zip::CompressionMethod::Stored); +/// +/// let big_len: usize = (zip::ZIP64_BYTES_THR as usize) + 1; +/// let big_buf = vec![0u8; big_len]; +/// zip.start_file("zero.dat", options)?; +/// // This is too big! +/// assert!(zip.write_all(&big_buf[..]).is_err()); +/// // Attempting to write anything further to the same zip will fail. +/// assert!(zip.start_file("one.dat", options).is_err()); +/// +/// // Create a new zip output. +/// let mut zip = ZipWriter::new(Cursor::new(Vec::new())); +/// // This time, create a zip64 record for the file. +/// let options = options.large_file(true); +/// zip.start_file("zero.dat", options)?; +/// // This succeeds because we specified that it could be a large file. +/// assert!(zip.write_all(&big_buf[..]).is_ok()); +/// # Ok(()) +/// # } +///``` pub const ZIP64_BYTES_THR: u64 = u32::MAX as u64; +/// The number of entries within a single zip necessary to allocate a zip64 central +/// directory record. +/// +/// If more than this number of entries is written to a [`ZipWriter`], then [`ZipWriter::finish()`] +/// will write out extra zip64 data to the end of the zip file. pub const ZIP64_ENTRY_THR: usize = u16::MAX as usize; pub struct CentralDirectoryEnd {