Replace try! macros with ? operator calls

The `?` operator exists since Rust version 1.13.0 and has since become the
standard and recommended variant over the `try!` macro (see
https://doc.rust-lang.org/std/macro.try.html where it is explicitly mentioned to
use the `?` operator instead of the `try!` macro).

I think it is especially useful to replace the `try!` usages throughout the
examples (since new users might not be familiar with the `try!` macro at all).
This commit is contained in:
Benedikt Rascher-Friesenhausen 2018-10-02 23:12:35 +02:00
parent b23200d4a1
commit 804cfea51c
4 changed files with 164 additions and 164 deletions

View file

@ -33,16 +33,16 @@ fn doit(filename: &str) -> zip::result::ZipResult<()>
let mut zip = zip::ZipWriter::new(file);
try!(zip.add_directory("test/", FileOptions::default()));
zip.add_directory("test/", FileOptions::default())?;
let options = FileOptions::default().compression_method(zip::CompressionMethod::Stored).unix_permissions(0o755);
try!(zip.start_file("test/☃.txt", options));
try!(zip.write_all(b"Hello, World!\n"));
zip.start_file("test/☃.txt", options)?;
zip.write_all(b"Hello, World!\n")?;
try!(zip.start_file("test/lorem_ipsum.txt", FileOptions::default()));
try!(zip.write_all(LOREM_IPSUM));
zip.start_file("test/lorem_ipsum.txt", FileOptions::default())?;
zip.write_all(LOREM_IPSUM)?;
try!(zip.finish());
zip.finish()?;
Ok(())
}

View file

@ -53,13 +53,13 @@ const TM_1980_01_01 : ::time::Tm = ::time::Tm {
/// let buf: &[u8] = &[0u8; 128];
/// let mut reader = std::io::Cursor::new(buf);
///
/// let mut zip = try!(zip::ZipArchive::new(reader));
/// let mut zip = zip::ZipArchive::new(reader)?;
///
/// for i in 0..zip.len()
/// {
/// let mut file = zip.by_index(i).unwrap();
/// println!("Filename: {}", file.name());
/// let first_byte = try!(file.bytes().next().unwrap());
/// let first_byte = file.bytes().next().unwrap()?;
/// println!("{}", first_byte);
/// }
/// Ok(())
@ -210,7 +210,7 @@ impl<R: Read+io::Seek> ZipArchive<R>
/// Opens a Zip archive and parses the central directory
pub fn new(mut reader: R) -> ZipResult<ZipArchive<R>> {
let (footer, cde_start_pos) = try!(spec::CentralDirectoryEnd::find_and_parse(&mut reader));
let (footer, cde_start_pos) = spec::CentralDirectoryEnd::find_and_parse(&mut reader)?;
if footer.disk_number != footer.disk_with_central_directory
{
@ -218,7 +218,7 @@ impl<R: Read+io::Seek> ZipArchive<R>
}
let (archive_offset, directory_start, number_of_files) =
try!(Self::get_directory_counts(&mut reader, &footer, cde_start_pos));
Self::get_directory_counts(&mut reader, &footer, cde_start_pos)?;
let mut files = Vec::new();
let mut names_map = HashMap::new();
@ -229,7 +229,7 @@ impl<R: Read+io::Seek> ZipArchive<R>
for _ in 0 .. number_of_files
{
let file = try!(central_header_to_zip_file(&mut reader, archive_offset));
let file = central_header_to_zip_file(&mut reader, archive_offset)?;
names_map.insert(file.file_name.clone(), files.len());
files.push(file);
}
@ -290,10 +290,10 @@ impl<R: Read+io::Seek> ZipArchive<R>
return unsupported_zip_error("Encrypted files are not supported")
}
try!(self.reader.seek(io::SeekFrom::Start(pos)));
self.reader.seek(io::SeekFrom::Start(pos))?;
let limit_reader = (self.reader.by_ref() as &mut Read).take(data.compressed_size);
Ok(ZipFile { reader: try!(make_reader(data.compression_method, data.crc32, limit_reader)), data: Cow::Borrowed(data) })
Ok(ZipFile { reader: make_reader(data.compression_method, data.crc32, limit_reader)?, data: Cow::Borrowed(data) })
}
/// Unwrap and return the inner reader object
@ -308,33 +308,33 @@ impl<R: Read+io::Seek> ZipArchive<R>
fn central_header_to_zip_file<R: Read+io::Seek>(reader: &mut R, archive_offset: u64) -> ZipResult<ZipFileData>
{
// Parse central header
let signature = try!(reader.read_u32::<LittleEndian>());
let signature = reader.read_u32::<LittleEndian>()?;
if signature != spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE
{
return Err(ZipError::InvalidArchive("Invalid Central Directory header"))
}
let version_made_by = try!(reader.read_u16::<LittleEndian>());
let _version_to_extract = try!(reader.read_u16::<LittleEndian>());
let flags = try!(reader.read_u16::<LittleEndian>());
let version_made_by = reader.read_u16::<LittleEndian>()?;
let _version_to_extract = reader.read_u16::<LittleEndian>()?;
let flags = reader.read_u16::<LittleEndian>()?;
let encrypted = flags & 1 == 1;
let is_utf8 = flags & (1 << 11) != 0;
let compression_method = try!(reader.read_u16::<LittleEndian>());
let last_mod_time = try!(reader.read_u16::<LittleEndian>());
let last_mod_date = try!(reader.read_u16::<LittleEndian>());
let crc32 = try!(reader.read_u32::<LittleEndian>());
let compressed_size = try!(reader.read_u32::<LittleEndian>());
let uncompressed_size = try!(reader.read_u32::<LittleEndian>());
let file_name_length = try!(reader.read_u16::<LittleEndian>()) as usize;
let extra_field_length = try!(reader.read_u16::<LittleEndian>()) as usize;
let file_comment_length = try!(reader.read_u16::<LittleEndian>()) as usize;
let _disk_number = try!(reader.read_u16::<LittleEndian>());
let _internal_file_attributes = try!(reader.read_u16::<LittleEndian>());
let external_file_attributes = try!(reader.read_u32::<LittleEndian>());
let mut offset = try!(reader.read_u32::<LittleEndian>()) as u64;
let file_name_raw = try!(ReadPodExt::read_exact(reader, file_name_length));
let extra_field = try!(ReadPodExt::read_exact(reader, extra_field_length));
let file_comment_raw = try!(ReadPodExt::read_exact(reader, file_comment_length));
let compression_method = reader.read_u16::<LittleEndian>()?;
let last_mod_time = reader.read_u16::<LittleEndian>()?;
let last_mod_date = reader.read_u16::<LittleEndian>()?;
let crc32 = reader.read_u32::<LittleEndian>()?;
let compressed_size = reader.read_u32::<LittleEndian>()?;
let uncompressed_size = reader.read_u32::<LittleEndian>()?;
let file_name_length = reader.read_u16::<LittleEndian>()? as usize;
let extra_field_length = reader.read_u16::<LittleEndian>()? as usize;
let file_comment_length = reader.read_u16::<LittleEndian>()? as usize;
let _disk_number = reader.read_u16::<LittleEndian>()?;
let _internal_file_attributes = reader.read_u16::<LittleEndian>()?;
let external_file_attributes = reader.read_u32::<LittleEndian>()?;
let mut offset = reader.read_u32::<LittleEndian>()? as u64;
let file_name_raw = ReadPodExt::read_exact(reader, file_name_length)?;
let extra_field = ReadPodExt::read_exact(reader, extra_field_length)?;
let file_comment_raw = ReadPodExt::read_exact(reader, file_comment_length)?;
// Account for shifted zip offsets.
offset += archive_offset;
@ -371,28 +371,28 @@ fn central_header_to_zip_file<R: Read+io::Seek>(reader: &mut R, archive_offset:
match parse_extra_field(&mut result, &*extra_field) {
Ok(..) | Err(ZipError::Io(..)) => {},
Err(e) => try!(Err(e)),
Err(e) => Err(e)?,
}
// Remember end of central header
let return_position = try!(reader.seek(io::SeekFrom::Current(0)));
let return_position = reader.seek(io::SeekFrom::Current(0))?;
// Parse local header
try!(reader.seek(io::SeekFrom::Start(result.header_start)));
let signature = try!(reader.read_u32::<LittleEndian>());
reader.seek(io::SeekFrom::Start(result.header_start))?;
let signature = reader.read_u32::<LittleEndian>()?;
if signature != spec::LOCAL_FILE_HEADER_SIGNATURE
{
return Err(ZipError::InvalidArchive("Invalid local file header"))
}
try!(reader.seek(io::SeekFrom::Current(22)));
let file_name_length = try!(reader.read_u16::<LittleEndian>()) as u64;
let extra_field_length = try!(reader.read_u16::<LittleEndian>()) as u64;
reader.seek(io::SeekFrom::Current(22))?;
let file_name_length = reader.read_u16::<LittleEndian>()? as u64;
let extra_field_length = reader.read_u16::<LittleEndian>()? as u64;
let magic_and_header = 4 + 22 + 2 + 2;
result.data_start = result.header_start + magic_and_header + file_name_length + extra_field_length;
// Go back after the central header
try!(reader.seek(io::SeekFrom::Start(return_position)));
reader.seek(io::SeekFrom::Start(return_position))?;
Ok(result)
}
@ -403,18 +403,18 @@ fn parse_extra_field(file: &mut ZipFileData, data: &[u8]) -> ZipResult<()>
while (reader.position() as usize) < data.len()
{
let kind = try!(reader.read_u16::<LittleEndian>());
let len = try!(reader.read_u16::<LittleEndian>());
let kind = reader.read_u16::<LittleEndian>()?;
let len = reader.read_u16::<LittleEndian>()?;
match kind
{
// Zip64 extended information extra field
0x0001 => {
file.uncompressed_size = try!(reader.read_u64::<LittleEndian>());
file.compressed_size = try!(reader.read_u64::<LittleEndian>());
try!(reader.read_u64::<LittleEndian>()); // relative header offset
try!(reader.read_u32::<LittleEndian>()); // disk start number
file.uncompressed_size = reader.read_u64::<LittleEndian>()?;
file.compressed_size = reader.read_u64::<LittleEndian>()?;
reader.read_u64::<LittleEndian>()?; // relative header offset
reader.read_u32::<LittleEndian>()?; // disk start number
},
_ => { try!(reader.seek(io::SeekFrom::Current(len as i64))); },
_ => { reader.seek(io::SeekFrom::Current(len as i64))?; },
};
}
Ok(())
@ -562,7 +562,7 @@ impl<'a> Drop for ZipFile<'a> {
/// * `data_start`: set to 0
/// * `external_attributes`: `unix_mode()`: will return None
pub fn read_zipfile_from_stream<'a, R: io::Read>(reader: &'a mut R) -> ZipResult<Option<ZipFile>> {
let signature = try!(reader.read_u32::<LittleEndian>());
let signature = reader.read_u32::<LittleEndian>()?;
match signature {
spec::LOCAL_FILE_HEADER_SIGNATURE => (),
@ -570,22 +570,22 @@ pub fn read_zipfile_from_stream<'a, R: io::Read>(reader: &'a mut R) -> ZipResult
_ => return Err(ZipError::InvalidArchive("Invalid local file header")),
}
let version_made_by = try!(reader.read_u16::<LittleEndian>());
let flags = try!(reader.read_u16::<LittleEndian>());
let version_made_by = reader.read_u16::<LittleEndian>()?;
let flags = reader.read_u16::<LittleEndian>()?;
let encrypted = flags & 1 == 1;
let is_utf8 = flags & (1 << 11) != 0;
let using_data_descriptor = flags & (1 << 3) != 0;
let compression_method = CompressionMethod::from_u16(try!(reader.read_u16::<LittleEndian>()));
let last_mod_time = try!(reader.read_u16::<LittleEndian>());
let last_mod_date = try!(reader.read_u16::<LittleEndian>());
let crc32 = try!(reader.read_u32::<LittleEndian>());
let compressed_size = try!(reader.read_u32::<LittleEndian>());
let uncompressed_size = try!(reader.read_u32::<LittleEndian>());
let file_name_length = try!(reader.read_u16::<LittleEndian>()) as usize;
let extra_field_length = try!(reader.read_u16::<LittleEndian>()) as usize;
let compression_method = CompressionMethod::from_u16(reader.read_u16::<LittleEndian>()?);
let last_mod_time = reader.read_u16::<LittleEndian>()?;
let last_mod_date = reader.read_u16::<LittleEndian>()?;
let crc32 = reader.read_u32::<LittleEndian>()?;
let compressed_size = reader.read_u32::<LittleEndian>()?;
let uncompressed_size = reader.read_u32::<LittleEndian>()?;
let file_name_length = reader.read_u16::<LittleEndian>()? as usize;
let extra_field_length = reader.read_u16::<LittleEndian>()? as usize;
let file_name_raw = try!(ReadPodExt::read_exact(reader, file_name_length));
let extra_field = try!(ReadPodExt::read_exact(reader, extra_field_length));
let file_name_raw = ReadPodExt::read_exact(reader, file_name_length)?;
let extra_field = ReadPodExt::read_exact(reader, extra_field_length)?;
let file_name = match is_utf8
{
@ -618,7 +618,7 @@ pub fn read_zipfile_from_stream<'a, R: io::Read>(reader: &'a mut R) -> ZipResult
match parse_extra_field(&mut result, &extra_field) {
Ok(..) | Err(ZipError::Io(..)) => {},
Err(e) => try!(Err(e)),
Err(e) => Err(e)?,
}
if encrypted {
@ -634,7 +634,7 @@ pub fn read_zipfile_from_stream<'a, R: io::Read>(reader: &'a mut R) -> ZipResult
let result_compression_method = result.compression_method;
Ok(Some(ZipFile {
data: Cow::Owned(result),
reader: try!(make_reader(result_compression_method, result_crc32, limit_reader))
reader: make_reader(result_compression_method, result_crc32, limit_reader)?
}))
}

View file

@ -24,19 +24,19 @@ impl CentralDirectoryEnd
{
pub fn parse<T: Read>(reader: &mut T) -> ZipResult<CentralDirectoryEnd>
{
let magic = try!(reader.read_u32::<LittleEndian>());
let magic = reader.read_u32::<LittleEndian>()?;
if magic != CENTRAL_DIRECTORY_END_SIGNATURE
{
return Err(ZipError::InvalidArchive("Invalid digital signature header"))
}
let disk_number = try!(reader.read_u16::<LittleEndian>());
let disk_with_central_directory = try!(reader.read_u16::<LittleEndian>());
let number_of_files_on_this_disk = try!(reader.read_u16::<LittleEndian>());
let number_of_files = try!(reader.read_u16::<LittleEndian>());
let central_directory_size = try!(reader.read_u32::<LittleEndian>());
let central_directory_offset = try!(reader.read_u32::<LittleEndian>());
let zip_file_comment_length = try!(reader.read_u16::<LittleEndian>()) as usize;
let zip_file_comment = try!(ReadPodExt::read_exact(reader, zip_file_comment_length));
let disk_number = reader.read_u16::<LittleEndian>()?;
let disk_with_central_directory = reader.read_u16::<LittleEndian>()?;
let number_of_files_on_this_disk = reader.read_u16::<LittleEndian>()?;
let number_of_files = reader.read_u16::<LittleEndian>()?;
let central_directory_size = reader.read_u32::<LittleEndian>()?;
let central_directory_offset = reader.read_u32::<LittleEndian>()?;
let zip_file_comment_length = reader.read_u16::<LittleEndian>()? as usize;
let zip_file_comment = ReadPodExt::read_exact(reader, zip_file_comment_length)?;
Ok(CentralDirectoryEnd
{
@ -54,7 +54,7 @@ impl CentralDirectoryEnd
{
const HEADER_SIZE: u64 = 22;
const BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE: u64 = HEADER_SIZE - 6;
let file_length = try!(reader.seek(io::SeekFrom::End(0)));
let file_length = reader.seek(io::SeekFrom::End(0))?;
let search_upper_bound = file_length.checked_sub(HEADER_SIZE + ::std::u16::MAX as u64).unwrap_or(0);
@ -65,14 +65,14 @@ impl CentralDirectoryEnd
let mut pos = file_length - HEADER_SIZE;
while pos >= search_upper_bound
{
try!(reader.seek(io::SeekFrom::Start(pos as u64)));
if try!(reader.read_u32::<LittleEndian>()) == CENTRAL_DIRECTORY_END_SIGNATURE
reader.seek(io::SeekFrom::Start(pos as u64))?;
if reader.read_u32::<LittleEndian>()? == CENTRAL_DIRECTORY_END_SIGNATURE
{
try!(reader.seek(io::SeekFrom::Current(BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64)));
let comment_length = try!(reader.read_u16::<LittleEndian>()) as u64;
reader.seek(io::SeekFrom::Current(BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64))?;
let comment_length = reader.read_u16::<LittleEndian>()? as u64;
if file_length - pos - HEADER_SIZE == comment_length
{
let cde_start_pos = try!(reader.seek(io::SeekFrom::Start(pos as u64)));
let cde_start_pos = reader.seek(io::SeekFrom::Start(pos as u64))?;
return CentralDirectoryEnd::parse(reader).map(|cde| (cde, cde_start_pos));
}
}
@ -86,15 +86,15 @@ impl CentralDirectoryEnd
pub fn write<T: Write>(&self, writer: &mut T) -> ZipResult<()>
{
try!(writer.write_u32::<LittleEndian>(CENTRAL_DIRECTORY_END_SIGNATURE));
try!(writer.write_u16::<LittleEndian>(self.disk_number));
try!(writer.write_u16::<LittleEndian>(self.disk_with_central_directory));
try!(writer.write_u16::<LittleEndian>(self.number_of_files_on_this_disk));
try!(writer.write_u16::<LittleEndian>(self.number_of_files));
try!(writer.write_u32::<LittleEndian>(self.central_directory_size));
try!(writer.write_u32::<LittleEndian>(self.central_directory_offset));
try!(writer.write_u16::<LittleEndian>(self.zip_file_comment.len() as u16));
try!(writer.write_all(&self.zip_file_comment));
writer.write_u32::<LittleEndian>(CENTRAL_DIRECTORY_END_SIGNATURE)?;
writer.write_u16::<LittleEndian>(self.disk_number)?;
writer.write_u16::<LittleEndian>(self.disk_with_central_directory)?;
writer.write_u16::<LittleEndian>(self.number_of_files_on_this_disk)?;
writer.write_u16::<LittleEndian>(self.number_of_files)?;
writer.write_u32::<LittleEndian>(self.central_directory_size)?;
writer.write_u32::<LittleEndian>(self.central_directory_offset)?;
writer.write_u16::<LittleEndian>(self.zip_file_comment.len() as u16)?;
writer.write_all(&self.zip_file_comment)?;
Ok(())
}
}
@ -110,14 +110,14 @@ impl Zip64CentralDirectoryEndLocator
{
pub fn parse<T: Read>(reader: &mut T) -> ZipResult<Zip64CentralDirectoryEndLocator>
{
let magic = try!(reader.read_u32::<LittleEndian>());
let magic = reader.read_u32::<LittleEndian>()?;
if magic != ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE
{
return Err(ZipError::InvalidArchive("Invalid zip64 locator digital signature header"))
}
let disk_with_central_directory = try!(reader.read_u32::<LittleEndian>());
let end_of_central_directory_offset = try!(reader.read_u64::<LittleEndian>());
let number_of_disks = try!(reader.read_u32::<LittleEndian>());
let disk_with_central_directory = reader.read_u32::<LittleEndian>()?;
let end_of_central_directory_offset = reader.read_u64::<LittleEndian>()?;
let number_of_disks = reader.read_u32::<LittleEndian>()?;
Ok(Zip64CentralDirectoryEndLocator
{
@ -157,17 +157,17 @@ impl Zip64CentralDirectoryEnd
{
let archive_offset = pos - nominal_offset;
let _record_size = try!(reader.read_u64::<LittleEndian>());
let _record_size = reader.read_u64::<LittleEndian>()?;
// We would use this value if we did anything with the "zip64 extensible data sector".
let version_made_by = try!(reader.read_u16::<LittleEndian>());
let version_needed_to_extract = try!(reader.read_u16::<LittleEndian>());
let disk_number = try!(reader.read_u32::<LittleEndian>());
let disk_with_central_directory = try!(reader.read_u32::<LittleEndian>());
let number_of_files_on_this_disk = try!(reader.read_u64::<LittleEndian>());
let number_of_files = try!(reader.read_u64::<LittleEndian>());
let central_directory_size = try!(reader.read_u64::<LittleEndian>());
let central_directory_offset = try!(reader.read_u64::<LittleEndian>());
let version_made_by = reader.read_u16::<LittleEndian>()?;
let version_needed_to_extract = reader.read_u16::<LittleEndian>()?;
let disk_number = reader.read_u32::<LittleEndian>()?;
let disk_with_central_directory = reader.read_u32::<LittleEndian>()?;
let number_of_files_on_this_disk = reader.read_u64::<LittleEndian>()?;
let number_of_files = reader.read_u64::<LittleEndian>()?;
let central_directory_size = reader.read_u64::<LittleEndian>()?;
let central_directory_offset = reader.read_u64::<LittleEndian>()?;
return Ok((Zip64CentralDirectoryEnd
{

View file

@ -48,11 +48,11 @@ enum GenericZipWriter<W: Write + io::Seek>
/// let mut zip = zip::ZipWriter::new(w);
///
/// let options = zip::write::FileOptions::default().compression_method(zip::CompressionMethod::Stored);
/// try!(zip.start_file("hello_world.txt", options));
/// try!(zip.write(b"Hello, World!"));
/// zip.start_file("hello_world.txt", options)?;
/// zip.write(b"Hello, World!")?;
///
/// // Optionally finish the zip. (this is also done on drop)
/// try!(zip.finish());
/// zip.finish()?;
///
/// Ok(())
/// }
@ -189,11 +189,11 @@ impl<W: Write+io::Seek> ZipWriter<W>
fn start_entry<S>(&mut self, name: S, options: FileOptions) -> ZipResult<()>
where S: Into<String>
{
try!(self.finish_file());
self.finish_file()?;
{
let writer = self.inner.get_plain();
let header_start = try!(writer.seek(io::SeekFrom::Current(0)));
let header_start = writer.seek(io::SeekFrom::Current(0))?;
let permissions = options.permissions.unwrap_or(0o100644);
let file_name = name.into();
@ -215,9 +215,9 @@ impl<W: Write+io::Seek> ZipWriter<W>
data_start: 0,
external_attributes: permissions << 16,
};
try!(write_local_file_header(writer, &file));
write_local_file_header(writer, &file)?;
let header_end = try!(writer.seek(io::SeekFrom::Current(0)));
let header_end = writer.seek(io::SeekFrom::Current(0))?;
self.stats.start = header_end;
file.data_start = header_end;
@ -227,14 +227,14 @@ impl<W: Write+io::Seek> ZipWriter<W>
self.files.push(file);
}
try!(self.inner.switch_to(options.compression_method));
self.inner.switch_to(options.compression_method)?;
Ok(())
}
fn finish_file(&mut self) -> ZipResult<()>
{
try!(self.inner.switch_to(CompressionMethod::Stored));
self.inner.switch_to(CompressionMethod::Stored)?;
let writer = self.inner.get_plain();
let file = match self.files.last_mut()
@ -245,11 +245,11 @@ impl<W: Write+io::Seek> ZipWriter<W>
file.crc32 = self.stats.crc32;
file.uncompressed_size = self.stats.bytes_written;
let file_end = try!(writer.seek(io::SeekFrom::Current(0)));
let file_end = writer.seek(io::SeekFrom::Current(0))?;
file.compressed_size = file_end - self.stats.start;
try!(update_local_file_header(writer, file));
try!(writer.seek(io::SeekFrom::Start(file_end)));
update_local_file_header(writer, file)?;
writer.seek(io::SeekFrom::Start(file_end))?;
Ok(())
}
@ -261,7 +261,7 @@ impl<W: Write+io::Seek> ZipWriter<W>
options.permissions = Some(0o644);
}
*options.permissions.as_mut().unwrap() |= 0o100000;
try!(self.start_entry(name, options));
self.start_entry(name, options)?;
Ok(())
}
@ -285,7 +285,7 @@ impl<W: Write+io::Seek> ZipWriter<W>
_ => name_as_string + "/",
};
try!(self.start_entry(name_with_slash, options));
self.start_entry(name_with_slash, options)?;
Ok(())
}
@ -295,24 +295,24 @@ impl<W: Write+io::Seek> ZipWriter<W>
/// Note that the zipfile will also be finished on drop.
pub fn finish(&mut self) -> ZipResult<W>
{
try!(self.finalize());
self.finalize()?;
let inner = mem::replace(&mut self.inner, GenericZipWriter::Closed);
Ok(inner.unwrap())
}
fn finalize(&mut self) -> ZipResult<()>
{
try!(self.finish_file());
self.finish_file()?;
{
let writer = self.inner.get_plain();
let central_start = try!(writer.seek(io::SeekFrom::Current(0)));
let central_start = writer.seek(io::SeekFrom::Current(0))?;
for file in self.files.iter()
{
try!(write_central_directory_header(writer, file));
write_central_directory_header(writer, file)?;
}
let central_size = try!(writer.seek(io::SeekFrom::Current(0))) - central_start;
let central_size = writer.seek(io::SeekFrom::Current(0))? - central_start;
let footer = spec::CentralDirectoryEnd
{
@ -325,7 +325,7 @@ impl<W: Write+io::Seek> ZipWriter<W>
zip_file_comment: b"zip-rs".to_vec(),
};
try!(footer.write(writer));
footer.write(writer)?;
}
Ok(())
@ -351,7 +351,7 @@ impl<W: Write+io::Seek> GenericZipWriter<W>
{
match self.current_compression() {
Some(method) if method == compression => return Ok(()),
None => try!(Err(io::Error::new(io::ErrorKind::BrokenPipe, "ZipWriter was already closed"))),
None => Err(io::Error::new(io::ErrorKind::BrokenPipe, "ZipWriter was already closed"))?,
_ => {},
}
@ -359,10 +359,10 @@ impl<W: Write+io::Seek> GenericZipWriter<W>
{
GenericZipWriter::Storer(w) => w,
#[cfg(feature = "flate2")]
GenericZipWriter::Deflater(w) => try!(w.finish()),
GenericZipWriter::Deflater(w) => w.finish()?,
#[cfg(feature = "bzip2")]
GenericZipWriter::Bzip2(w) => try!(w.finish()),
GenericZipWriter::Closed => try!(Err(io::Error::new(io::ErrorKind::BrokenPipe, "ZipWriter was already closed"))),
GenericZipWriter::Bzip2(w) => w.finish()?,
GenericZipWriter::Closed => Err(io::Error::new(io::ErrorKind::BrokenPipe, "ZipWriter was already closed"))?,
};
*self = match compression
@ -431,33 +431,33 @@ impl<W: Write+io::Seek> GenericZipWriter<W>
fn write_local_file_header<T: Write>(writer: &mut T, file: &ZipFileData) -> ZipResult<()>
{
// local file header signature
try!(writer.write_u32::<LittleEndian>(spec::LOCAL_FILE_HEADER_SIGNATURE));
writer.write_u32::<LittleEndian>(spec::LOCAL_FILE_HEADER_SIGNATURE)?;
// version needed to extract
try!(writer.write_u16::<LittleEndian>(file.version_needed()));
writer.write_u16::<LittleEndian>(file.version_needed())?;
// general purpose bit flag
let flag = if !file.file_name.is_ascii() { 1u16 << 11 } else { 0 };
try!(writer.write_u16::<LittleEndian>(flag));
writer.write_u16::<LittleEndian>(flag)?;
// Compression method
try!(writer.write_u16::<LittleEndian>(file.compression_method.to_u16()));
writer.write_u16::<LittleEndian>(file.compression_method.to_u16())?;
// last mod file time and last mod file date
let msdos_datetime = try!(file.last_modified_time.to_msdos());
try!(writer.write_u16::<LittleEndian>(msdos_datetime.timepart));
try!(writer.write_u16::<LittleEndian>(msdos_datetime.datepart));
let msdos_datetime = file.last_modified_time.to_msdos()?;
writer.write_u16::<LittleEndian>(msdos_datetime.timepart)?;
writer.write_u16::<LittleEndian>(msdos_datetime.datepart)?;
// crc-32
try!(writer.write_u32::<LittleEndian>(file.crc32));
writer.write_u32::<LittleEndian>(file.crc32)?;
// compressed size
try!(writer.write_u32::<LittleEndian>(file.compressed_size as u32));
writer.write_u32::<LittleEndian>(file.compressed_size as u32)?;
// uncompressed size
try!(writer.write_u32::<LittleEndian>(file.uncompressed_size as u32));
writer.write_u32::<LittleEndian>(file.uncompressed_size as u32)?;
// file name length
try!(writer.write_u16::<LittleEndian>(file.file_name.as_bytes().len() as u16));
writer.write_u16::<LittleEndian>(file.file_name.as_bytes().len() as u16)?;
// extra field length
let extra_field = try!(build_extra_field(file));
try!(writer.write_u16::<LittleEndian>(extra_field.len() as u16));
let extra_field = build_extra_field(file)?;
writer.write_u16::<LittleEndian>(extra_field.len() as u16)?;
// file name
try!(writer.write_all(file.file_name.as_bytes()));
writer.write_all(file.file_name.as_bytes())?;
// extra field
try!(writer.write_all(&extra_field));
writer.write_all(&extra_field)?;
Ok(())
}
@ -465,56 +465,56 @@ fn write_local_file_header<T: Write>(writer: &mut T, file: &ZipFileData) -> ZipR
fn update_local_file_header<T: Write+io::Seek>(writer: &mut T, file: &ZipFileData) -> ZipResult<()>
{
const CRC32_OFFSET : u64 = 14;
try!(writer.seek(io::SeekFrom::Start(file.header_start + CRC32_OFFSET)));
try!(writer.write_u32::<LittleEndian>(file.crc32));
try!(writer.write_u32::<LittleEndian>(file.compressed_size as u32));
try!(writer.write_u32::<LittleEndian>(file.uncompressed_size as u32));
writer.seek(io::SeekFrom::Start(file.header_start + CRC32_OFFSET))?;
writer.write_u32::<LittleEndian>(file.crc32)?;
writer.write_u32::<LittleEndian>(file.compressed_size as u32)?;
writer.write_u32::<LittleEndian>(file.uncompressed_size as u32)?;
Ok(())
}
fn write_central_directory_header<T: Write>(writer: &mut T, file: &ZipFileData) -> ZipResult<()>
{
// central file header signature
try!(writer.write_u32::<LittleEndian>(spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE));
writer.write_u32::<LittleEndian>(spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE)?;
// version made by
let version_made_by = (file.system as u16) << 8 | (file.version_made_by as u16);
try!(writer.write_u16::<LittleEndian>(version_made_by));
writer.write_u16::<LittleEndian>(version_made_by)?;
// version needed to extract
try!(writer.write_u16::<LittleEndian>(file.version_needed()));
writer.write_u16::<LittleEndian>(file.version_needed())?;
// general puprose bit flag
let flag = if !file.file_name.is_ascii() { 1u16 << 11 } else { 0 };
try!(writer.write_u16::<LittleEndian>(flag));
writer.write_u16::<LittleEndian>(flag)?;
// compression method
try!(writer.write_u16::<LittleEndian>(file.compression_method.to_u16()));
writer.write_u16::<LittleEndian>(file.compression_method.to_u16())?;
// last mod file time + date
let msdos_datetime = try!(file.last_modified_time.to_msdos());
try!(writer.write_u16::<LittleEndian>(msdos_datetime.timepart));
try!(writer.write_u16::<LittleEndian>(msdos_datetime.datepart));
let msdos_datetime = file.last_modified_time.to_msdos()?;
writer.write_u16::<LittleEndian>(msdos_datetime.timepart)?;
writer.write_u16::<LittleEndian>(msdos_datetime.datepart)?;
// crc-32
try!(writer.write_u32::<LittleEndian>(file.crc32));
writer.write_u32::<LittleEndian>(file.crc32)?;
// compressed size
try!(writer.write_u32::<LittleEndian>(file.compressed_size as u32));
writer.write_u32::<LittleEndian>(file.compressed_size as u32)?;
// uncompressed size
try!(writer.write_u32::<LittleEndian>(file.uncompressed_size as u32));
writer.write_u32::<LittleEndian>(file.uncompressed_size as u32)?;
// file name length
try!(writer.write_u16::<LittleEndian>(file.file_name.as_bytes().len() as u16));
writer.write_u16::<LittleEndian>(file.file_name.as_bytes().len() as u16)?;
// extra field length
let extra_field = try!(build_extra_field(file));
try!(writer.write_u16::<LittleEndian>(extra_field.len() as u16));
let extra_field = build_extra_field(file)?;
writer.write_u16::<LittleEndian>(extra_field.len() as u16)?;
// file comment length
try!(writer.write_u16::<LittleEndian>(0));
writer.write_u16::<LittleEndian>(0)?;
// disk number start
try!(writer.write_u16::<LittleEndian>(0));
writer.write_u16::<LittleEndian>(0)?;
// internal file attribytes
try!(writer.write_u16::<LittleEndian>(0));
writer.write_u16::<LittleEndian>(0)?;
// external file attributes
try!(writer.write_u32::<LittleEndian>(file.external_attributes));
writer.write_u32::<LittleEndian>(file.external_attributes)?;
// relative offset of local header
try!(writer.write_u32::<LittleEndian>(file.header_start as u32));
writer.write_u32::<LittleEndian>(file.header_start as u32)?;
// file name
try!(writer.write_all(file.file_name.as_bytes()));
writer.write_all(file.file_name.as_bytes())?;
// extra field
try!(writer.write_all(&extra_field));
writer.write_all(&extra_field)?;
// file comment
// <none>