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:
parent
b23200d4a1
commit
804cfea51c
4 changed files with 164 additions and 164 deletions
|
@ -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(())
|
||||
}
|
||||
|
||||
|
|
114
src/read.rs
114
src/read.rs
|
@ -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)?
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
74
src/spec.rs
74
src/spec.rs
|
@ -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
|
||||
{
|
||||
|
|
128
src/write.rs
128
src/write.rs
|
@ -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>
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue