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); 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); let options = FileOptions::default().compression_method(zip::CompressionMethod::Stored).unix_permissions(0o755);
try!(zip.start_file("test/☃.txt", options)); zip.start_file("test/☃.txt", options)?;
try!(zip.write_all(b"Hello, World!\n")); zip.write_all(b"Hello, World!\n")?;
try!(zip.start_file("test/lorem_ipsum.txt", FileOptions::default())); zip.start_file("test/lorem_ipsum.txt", FileOptions::default())?;
try!(zip.write_all(LOREM_IPSUM)); zip.write_all(LOREM_IPSUM)?;
try!(zip.finish()); zip.finish()?;
Ok(()) Ok(())
} }

View file

@ -53,13 +53,13 @@ const TM_1980_01_01 : ::time::Tm = ::time::Tm {
/// let buf: &[u8] = &[0u8; 128]; /// let buf: &[u8] = &[0u8; 128];
/// let mut reader = std::io::Cursor::new(buf); /// 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() /// for i in 0..zip.len()
/// { /// {
/// let mut file = zip.by_index(i).unwrap(); /// let mut file = zip.by_index(i).unwrap();
/// println!("Filename: {}", file.name()); /// println!("Filename: {}", file.name());
/// let first_byte = try!(file.bytes().next().unwrap()); /// let first_byte = file.bytes().next().unwrap()?;
/// println!("{}", first_byte); /// println!("{}", first_byte);
/// } /// }
/// Ok(()) /// Ok(())
@ -210,7 +210,7 @@ impl<R: Read+io::Seek> ZipArchive<R>
/// Opens a Zip archive and parses the central directory /// Opens a Zip archive and parses the central directory
pub fn new(mut reader: R) -> ZipResult<ZipArchive<R>> { 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 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) = 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 files = Vec::new();
let mut names_map = HashMap::new(); let mut names_map = HashMap::new();
@ -229,7 +229,7 @@ impl<R: Read+io::Seek> ZipArchive<R>
for _ in 0 .. number_of_files 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()); names_map.insert(file.file_name.clone(), files.len());
files.push(file); files.push(file);
} }
@ -290,10 +290,10 @@ impl<R: Read+io::Seek> ZipArchive<R>
return unsupported_zip_error("Encrypted files are not supported") 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); 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 /// 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> fn central_header_to_zip_file<R: Read+io::Seek>(reader: &mut R, archive_offset: u64) -> ZipResult<ZipFileData>
{ {
// Parse central header // Parse central header
let signature = try!(reader.read_u32::<LittleEndian>()); let signature = reader.read_u32::<LittleEndian>()?;
if signature != spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE if signature != spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE
{ {
return Err(ZipError::InvalidArchive("Invalid Central Directory header")) return Err(ZipError::InvalidArchive("Invalid Central Directory header"))
} }
let version_made_by = try!(reader.read_u16::<LittleEndian>()); let version_made_by = reader.read_u16::<LittleEndian>()?;
let _version_to_extract = try!(reader.read_u16::<LittleEndian>()); let _version_to_extract = reader.read_u16::<LittleEndian>()?;
let flags = try!(reader.read_u16::<LittleEndian>()); let flags = reader.read_u16::<LittleEndian>()?;
let encrypted = flags & 1 == 1; let encrypted = flags & 1 == 1;
let is_utf8 = flags & (1 << 11) != 0; let is_utf8 = flags & (1 << 11) != 0;
let compression_method = try!(reader.read_u16::<LittleEndian>()); let compression_method = reader.read_u16::<LittleEndian>()?;
let last_mod_time = try!(reader.read_u16::<LittleEndian>()); let last_mod_time = reader.read_u16::<LittleEndian>()?;
let last_mod_date = try!(reader.read_u16::<LittleEndian>()); let last_mod_date = reader.read_u16::<LittleEndian>()?;
let crc32 = try!(reader.read_u32::<LittleEndian>()); let crc32 = reader.read_u32::<LittleEndian>()?;
let compressed_size = try!(reader.read_u32::<LittleEndian>()); let compressed_size = reader.read_u32::<LittleEndian>()?;
let uncompressed_size = try!(reader.read_u32::<LittleEndian>()); let uncompressed_size = reader.read_u32::<LittleEndian>()?;
let file_name_length = try!(reader.read_u16::<LittleEndian>()) as usize; let file_name_length = reader.read_u16::<LittleEndian>()? as usize;
let extra_field_length = try!(reader.read_u16::<LittleEndian>()) as usize; let extra_field_length = reader.read_u16::<LittleEndian>()? as usize;
let file_comment_length = try!(reader.read_u16::<LittleEndian>()) as usize; let file_comment_length = reader.read_u16::<LittleEndian>()? as usize;
let _disk_number = try!(reader.read_u16::<LittleEndian>()); let _disk_number = reader.read_u16::<LittleEndian>()?;
let _internal_file_attributes = try!(reader.read_u16::<LittleEndian>()); let _internal_file_attributes = reader.read_u16::<LittleEndian>()?;
let external_file_attributes = try!(reader.read_u32::<LittleEndian>()); let external_file_attributes = reader.read_u32::<LittleEndian>()?;
let mut offset = try!(reader.read_u32::<LittleEndian>()) as u64; let mut offset = reader.read_u32::<LittleEndian>()? as u64;
let file_name_raw = try!(ReadPodExt::read_exact(reader, file_name_length)); let file_name_raw = ReadPodExt::read_exact(reader, file_name_length)?;
let extra_field = try!(ReadPodExt::read_exact(reader, extra_field_length)); let extra_field = ReadPodExt::read_exact(reader, extra_field_length)?;
let file_comment_raw = try!(ReadPodExt::read_exact(reader, file_comment_length)); let file_comment_raw = ReadPodExt::read_exact(reader, file_comment_length)?;
// Account for shifted zip offsets. // Account for shifted zip offsets.
offset += archive_offset; 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) { match parse_extra_field(&mut result, &*extra_field) {
Ok(..) | Err(ZipError::Io(..)) => {}, Ok(..) | Err(ZipError::Io(..)) => {},
Err(e) => try!(Err(e)), Err(e) => Err(e)?,
} }
// Remember end of central header // 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 // Parse local header
try!(reader.seek(io::SeekFrom::Start(result.header_start))); reader.seek(io::SeekFrom::Start(result.header_start))?;
let signature = try!(reader.read_u32::<LittleEndian>()); let signature = reader.read_u32::<LittleEndian>()?;
if signature != spec::LOCAL_FILE_HEADER_SIGNATURE if signature != spec::LOCAL_FILE_HEADER_SIGNATURE
{ {
return Err(ZipError::InvalidArchive("Invalid local file header")) return Err(ZipError::InvalidArchive("Invalid local file header"))
} }
try!(reader.seek(io::SeekFrom::Current(22))); reader.seek(io::SeekFrom::Current(22))?;
let file_name_length = try!(reader.read_u16::<LittleEndian>()) as u64; let file_name_length = reader.read_u16::<LittleEndian>()? as u64;
let extra_field_length = try!(reader.read_u16::<LittleEndian>()) as u64; let extra_field_length = reader.read_u16::<LittleEndian>()? as u64;
let magic_and_header = 4 + 22 + 2 + 2; let magic_and_header = 4 + 22 + 2 + 2;
result.data_start = result.header_start + magic_and_header + file_name_length + extra_field_length; result.data_start = result.header_start + magic_and_header + file_name_length + extra_field_length;
// Go back after the central header // Go back after the central header
try!(reader.seek(io::SeekFrom::Start(return_position))); reader.seek(io::SeekFrom::Start(return_position))?;
Ok(result) Ok(result)
} }
@ -403,18 +403,18 @@ fn parse_extra_field(file: &mut ZipFileData, data: &[u8]) -> ZipResult<()>
while (reader.position() as usize) < data.len() while (reader.position() as usize) < data.len()
{ {
let kind = try!(reader.read_u16::<LittleEndian>()); let kind = reader.read_u16::<LittleEndian>()?;
let len = try!(reader.read_u16::<LittleEndian>()); let len = reader.read_u16::<LittleEndian>()?;
match kind match kind
{ {
// Zip64 extended information extra field // Zip64 extended information extra field
0x0001 => { 0x0001 => {
file.uncompressed_size = try!(reader.read_u64::<LittleEndian>()); file.uncompressed_size = reader.read_u64::<LittleEndian>()?;
file.compressed_size = try!(reader.read_u64::<LittleEndian>()); file.compressed_size = reader.read_u64::<LittleEndian>()?;
try!(reader.read_u64::<LittleEndian>()); // relative header offset reader.read_u64::<LittleEndian>()?; // relative header offset
try!(reader.read_u32::<LittleEndian>()); // disk start number 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(()) Ok(())
@ -562,7 +562,7 @@ impl<'a> Drop for ZipFile<'a> {
/// * `data_start`: set to 0 /// * `data_start`: set to 0
/// * `external_attributes`: `unix_mode()`: will return None /// * `external_attributes`: `unix_mode()`: will return None
pub fn read_zipfile_from_stream<'a, R: io::Read>(reader: &'a mut R) -> ZipResult<Option<ZipFile>> { 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 { match signature {
spec::LOCAL_FILE_HEADER_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")), _ => return Err(ZipError::InvalidArchive("Invalid local file header")),
} }
let version_made_by = try!(reader.read_u16::<LittleEndian>()); let version_made_by = reader.read_u16::<LittleEndian>()?;
let flags = try!(reader.read_u16::<LittleEndian>()); let flags = reader.read_u16::<LittleEndian>()?;
let encrypted = flags & 1 == 1; let encrypted = flags & 1 == 1;
let is_utf8 = flags & (1 << 11) != 0; let is_utf8 = flags & (1 << 11) != 0;
let using_data_descriptor = flags & (1 << 3) != 0; let using_data_descriptor = flags & (1 << 3) != 0;
let compression_method = CompressionMethod::from_u16(try!(reader.read_u16::<LittleEndian>())); let compression_method = CompressionMethod::from_u16(reader.read_u16::<LittleEndian>()?);
let last_mod_time = try!(reader.read_u16::<LittleEndian>()); let last_mod_time = reader.read_u16::<LittleEndian>()?;
let last_mod_date = try!(reader.read_u16::<LittleEndian>()); let last_mod_date = reader.read_u16::<LittleEndian>()?;
let crc32 = try!(reader.read_u32::<LittleEndian>()); let crc32 = reader.read_u32::<LittleEndian>()?;
let compressed_size = try!(reader.read_u32::<LittleEndian>()); let compressed_size = reader.read_u32::<LittleEndian>()?;
let uncompressed_size = try!(reader.read_u32::<LittleEndian>()); let uncompressed_size = reader.read_u32::<LittleEndian>()?;
let file_name_length = try!(reader.read_u16::<LittleEndian>()) as usize; let file_name_length = reader.read_u16::<LittleEndian>()? as usize;
let extra_field_length = try!(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 file_name_raw = ReadPodExt::read_exact(reader, file_name_length)?;
let extra_field = try!(ReadPodExt::read_exact(reader, extra_field_length)); let extra_field = ReadPodExt::read_exact(reader, extra_field_length)?;
let file_name = match is_utf8 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) { match parse_extra_field(&mut result, &extra_field) {
Ok(..) | Err(ZipError::Io(..)) => {}, Ok(..) | Err(ZipError::Io(..)) => {},
Err(e) => try!(Err(e)), Err(e) => Err(e)?,
} }
if encrypted { 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; let result_compression_method = result.compression_method;
Ok(Some(ZipFile { Ok(Some(ZipFile {
data: Cow::Owned(result), 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> 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 if magic != CENTRAL_DIRECTORY_END_SIGNATURE
{ {
return Err(ZipError::InvalidArchive("Invalid digital signature header")) return Err(ZipError::InvalidArchive("Invalid digital signature header"))
} }
let disk_number = try!(reader.read_u16::<LittleEndian>()); let disk_number = reader.read_u16::<LittleEndian>()?;
let disk_with_central_directory = try!(reader.read_u16::<LittleEndian>()); let disk_with_central_directory = reader.read_u16::<LittleEndian>()?;
let number_of_files_on_this_disk = try!(reader.read_u16::<LittleEndian>()); let number_of_files_on_this_disk = reader.read_u16::<LittleEndian>()?;
let number_of_files = try!(reader.read_u16::<LittleEndian>()); let number_of_files = reader.read_u16::<LittleEndian>()?;
let central_directory_size = try!(reader.read_u32::<LittleEndian>()); let central_directory_size = reader.read_u32::<LittleEndian>()?;
let central_directory_offset = try!(reader.read_u32::<LittleEndian>()); let central_directory_offset = reader.read_u32::<LittleEndian>()?;
let zip_file_comment_length = try!(reader.read_u16::<LittleEndian>()) as usize; let zip_file_comment_length = reader.read_u16::<LittleEndian>()? as usize;
let zip_file_comment = try!(ReadPodExt::read_exact(reader, zip_file_comment_length)); let zip_file_comment = ReadPodExt::read_exact(reader, zip_file_comment_length)?;
Ok(CentralDirectoryEnd Ok(CentralDirectoryEnd
{ {
@ -54,7 +54,7 @@ impl CentralDirectoryEnd
{ {
const HEADER_SIZE: u64 = 22; const HEADER_SIZE: u64 = 22;
const BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE: u64 = HEADER_SIZE - 6; 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); 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; let mut pos = file_length - HEADER_SIZE;
while pos >= search_upper_bound while pos >= search_upper_bound
{ {
try!(reader.seek(io::SeekFrom::Start(pos as u64))); reader.seek(io::SeekFrom::Start(pos as u64))?;
if try!(reader.read_u32::<LittleEndian>()) == CENTRAL_DIRECTORY_END_SIGNATURE if reader.read_u32::<LittleEndian>()? == CENTRAL_DIRECTORY_END_SIGNATURE
{ {
try!(reader.seek(io::SeekFrom::Current(BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64))); reader.seek(io::SeekFrom::Current(BYTES_BETWEEN_MAGIC_AND_COMMENT_SIZE as i64))?;
let comment_length = try!(reader.read_u16::<LittleEndian>()) as u64; let comment_length = reader.read_u16::<LittleEndian>()? as u64;
if file_length - pos - HEADER_SIZE == comment_length 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)); 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<()> pub fn write<T: Write>(&self, writer: &mut T) -> ZipResult<()>
{ {
try!(writer.write_u32::<LittleEndian>(CENTRAL_DIRECTORY_END_SIGNATURE)); writer.write_u32::<LittleEndian>(CENTRAL_DIRECTORY_END_SIGNATURE)?;
try!(writer.write_u16::<LittleEndian>(self.disk_number)); writer.write_u16::<LittleEndian>(self.disk_number)?;
try!(writer.write_u16::<LittleEndian>(self.disk_with_central_directory)); writer.write_u16::<LittleEndian>(self.disk_with_central_directory)?;
try!(writer.write_u16::<LittleEndian>(self.number_of_files_on_this_disk)); writer.write_u16::<LittleEndian>(self.number_of_files_on_this_disk)?;
try!(writer.write_u16::<LittleEndian>(self.number_of_files)); writer.write_u16::<LittleEndian>(self.number_of_files)?;
try!(writer.write_u32::<LittleEndian>(self.central_directory_size)); writer.write_u32::<LittleEndian>(self.central_directory_size)?;
try!(writer.write_u32::<LittleEndian>(self.central_directory_offset)); writer.write_u32::<LittleEndian>(self.central_directory_offset)?;
try!(writer.write_u16::<LittleEndian>(self.zip_file_comment.len() as u16)); writer.write_u16::<LittleEndian>(self.zip_file_comment.len() as u16)?;
try!(writer.write_all(&self.zip_file_comment)); writer.write_all(&self.zip_file_comment)?;
Ok(()) Ok(())
} }
} }
@ -110,14 +110,14 @@ impl Zip64CentralDirectoryEndLocator
{ {
pub fn parse<T: Read>(reader: &mut T) -> ZipResult<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 if magic != ZIP64_CENTRAL_DIRECTORY_END_LOCATOR_SIGNATURE
{ {
return Err(ZipError::InvalidArchive("Invalid zip64 locator digital signature header")) return Err(ZipError::InvalidArchive("Invalid zip64 locator digital signature header"))
} }
let disk_with_central_directory = try!(reader.read_u32::<LittleEndian>()); let disk_with_central_directory = reader.read_u32::<LittleEndian>()?;
let end_of_central_directory_offset = try!(reader.read_u64::<LittleEndian>()); let end_of_central_directory_offset = reader.read_u64::<LittleEndian>()?;
let number_of_disks = try!(reader.read_u32::<LittleEndian>()); let number_of_disks = reader.read_u32::<LittleEndian>()?;
Ok(Zip64CentralDirectoryEndLocator Ok(Zip64CentralDirectoryEndLocator
{ {
@ -157,17 +157,17 @@ impl Zip64CentralDirectoryEnd
{ {
let archive_offset = pos - nominal_offset; 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". // 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_made_by = reader.read_u16::<LittleEndian>()?;
let version_needed_to_extract = try!(reader.read_u16::<LittleEndian>()); let version_needed_to_extract = reader.read_u16::<LittleEndian>()?;
let disk_number = try!(reader.read_u32::<LittleEndian>()); let disk_number = reader.read_u32::<LittleEndian>()?;
let disk_with_central_directory = try!(reader.read_u32::<LittleEndian>()); let disk_with_central_directory = reader.read_u32::<LittleEndian>()?;
let number_of_files_on_this_disk = try!(reader.read_u64::<LittleEndian>()); let number_of_files_on_this_disk = reader.read_u64::<LittleEndian>()?;
let number_of_files = try!(reader.read_u64::<LittleEndian>()); let number_of_files = reader.read_u64::<LittleEndian>()?;
let central_directory_size = try!(reader.read_u64::<LittleEndian>()); let central_directory_size = reader.read_u64::<LittleEndian>()?;
let central_directory_offset = try!(reader.read_u64::<LittleEndian>()); let central_directory_offset = reader.read_u64::<LittleEndian>()?;
return Ok((Zip64CentralDirectoryEnd return Ok((Zip64CentralDirectoryEnd
{ {

View file

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