Small updates to write module
This commit is contained in:
parent
d9b83af57c
commit
b16da11570
3 changed files with 73 additions and 79 deletions
|
@ -15,7 +15,6 @@ pub use compression::CompressionMethod;
|
|||
|
||||
mod util;
|
||||
mod spec;
|
||||
mod writer_spec;
|
||||
mod crc32;
|
||||
mod types;
|
||||
pub mod read;
|
||||
|
|
78
src/write.rs
78
src/write.rs
|
@ -3,19 +3,22 @@
|
|||
use compression::CompressionMethod;
|
||||
use types::ZipFileData;
|
||||
use spec;
|
||||
use writer_spec;
|
||||
use crc32;
|
||||
use result::{ZipResult, ZipError};
|
||||
use std::default::Default;
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::mem;
|
||||
use std::error::Error;
|
||||
use std::ascii::AsciiExt;
|
||||
use time;
|
||||
use flate2;
|
||||
use flate2::FlateWriteExt;
|
||||
use flate2::write::DeflateEncoder;
|
||||
use bzip2;
|
||||
use bzip2::writer::BzCompressor;
|
||||
use util;
|
||||
use util::WriteIntExt;
|
||||
|
||||
enum GenericZipWriter<W: Write + io::Seek>
|
||||
{
|
||||
|
@ -85,7 +88,7 @@ impl<W: Write+io::Seek> Write for ZipWriter<W>
|
|||
match result {
|
||||
Ok(..) => Ok(()),
|
||||
Err(ZipError::Io(io_err)) => Err(io_err),
|
||||
Err(..) => Err(io::Error::new(io::ErrorKind::Other, "Error occured during finalization", None)),
|
||||
Err(zip_err) => Err(io::Error::new(io::ErrorKind::Other, "A zip error occured", Some(zip_err.description().to_string()))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +139,7 @@ impl<W: Write+io::Seek> ZipWriter<W>
|
|||
header_start: header_start,
|
||||
data_start: 0,
|
||||
};
|
||||
try!(writer_spec::write_local_file_header(writer, &file));
|
||||
try!(write_local_file_header(writer, &file));
|
||||
|
||||
let header_end = try!(writer.seek(io::SeekFrom::Current(0)));
|
||||
self.stats.start = header_end;
|
||||
|
@ -167,7 +170,7 @@ impl<W: Write+io::Seek> ZipWriter<W>
|
|||
file.uncompressed_size = self.stats.bytes_written;
|
||||
file.compressed_size = try!(writer.seek(io::SeekFrom::Current(0))) - self.stats.start;
|
||||
|
||||
try!(writer_spec::update_local_file_header(writer, file));
|
||||
try!(update_local_file_header(writer, file));
|
||||
try!(writer.seek(io::SeekFrom::End(0)));
|
||||
Ok(())
|
||||
}
|
||||
|
@ -193,7 +196,7 @@ impl<W: Write+io::Seek> ZipWriter<W>
|
|||
let central_start = try!(writer.seek(io::SeekFrom::Current(0)));
|
||||
for file in self.files.iter()
|
||||
{
|
||||
try!(writer_spec::write_central_directory_header(writer, file));
|
||||
try!(write_central_directory_header(writer, file));
|
||||
}
|
||||
let central_size = try!(writer.seek(io::SeekFrom::Current(0))) - central_start;
|
||||
|
||||
|
@ -279,3 +282,68 @@ impl<W: Write+io::Seek> GenericZipWriter<W>
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write_local_file_header<T: Write>(writer: &mut T, file: &ZipFileData) -> ZipResult<()>
|
||||
{
|
||||
try!(writer.write_le_u32(spec::LOCAL_FILE_HEADER_SIGNATURE));
|
||||
try!(writer.write_le_u16(20));
|
||||
let flag = if !file.file_name.is_ascii() { 1u16 << 11 } else { 0 };
|
||||
try!(writer.write_le_u16(flag));
|
||||
try!(writer.write_le_u16(file.compression_method as u16));
|
||||
try!(writer.write_le_u16(util::tm_to_msdos_time(file.last_modified_time)));
|
||||
try!(writer.write_le_u16(util::tm_to_msdos_date(file.last_modified_time)));
|
||||
try!(writer.write_le_u32(file.crc32));
|
||||
try!(writer.write_le_u32(file.compressed_size as u32));
|
||||
try!(writer.write_le_u32(file.uncompressed_size as u32));
|
||||
try!(writer.write_le_u16(file.file_name.as_bytes().len() as u16));
|
||||
let extra_field = try!(build_extra_field(file));
|
||||
try!(writer.write_le_u16(extra_field.len() as u16));
|
||||
try!(writer.write_all(file.file_name.as_bytes()));
|
||||
try!(writer.write_all(extra_field.as_slice()));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_local_file_header<T: Write+io::Seek>(writer: &mut T, file: &ZipFileData) -> ZipResult<()>
|
||||
{
|
||||
static CRC32_OFFSET : u64 = 14;
|
||||
try!(writer.seek(io::SeekFrom::Start(file.header_start + CRC32_OFFSET)));
|
||||
try!(writer.write_le_u32(file.crc32));
|
||||
try!(writer.write_le_u32(file.compressed_size as u32));
|
||||
try!(writer.write_le_u32(file.uncompressed_size as u32));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_central_directory_header<T: Write>(writer: &mut T, file: &ZipFileData) -> ZipResult<()>
|
||||
{
|
||||
try!(writer.write_le_u32(spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE));
|
||||
try!(writer.write_le_u16(0x14FF));
|
||||
try!(writer.write_le_u16(20));
|
||||
let flag = if !file.file_name.is_ascii() { 1u16 << 11 } else { 0 };
|
||||
try!(writer.write_le_u16(flag));
|
||||
try!(writer.write_le_u16(file.compression_method as u16));
|
||||
try!(writer.write_le_u16(util::tm_to_msdos_time(file.last_modified_time)));
|
||||
try!(writer.write_le_u16(util::tm_to_msdos_date(file.last_modified_time)));
|
||||
try!(writer.write_le_u32(file.crc32));
|
||||
try!(writer.write_le_u32(file.compressed_size as u32));
|
||||
try!(writer.write_le_u32(file.uncompressed_size as u32));
|
||||
try!(writer.write_le_u16(file.file_name.as_bytes().len() as u16));
|
||||
let extra_field = try!(build_extra_field(file));
|
||||
try!(writer.write_le_u16(extra_field.len() as u16));
|
||||
try!(writer.write_le_u16(0));
|
||||
try!(writer.write_le_u16(0));
|
||||
try!(writer.write_le_u16(0));
|
||||
try!(writer.write_le_u32(0));
|
||||
try!(writer.write_le_u32(file.header_start as u32));
|
||||
try!(writer.write_all(file.file_name.as_bytes()));
|
||||
try!(writer.write_all(extra_field.as_slice()));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build_extra_field(_file: &ZipFileData) -> ZipResult<Vec<u8>>
|
||||
{
|
||||
let writer = Vec::new();
|
||||
// Future work
|
||||
Ok(writer)
|
||||
}
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::ascii::AsciiExt;
|
||||
use types::ZipFileData;
|
||||
use result::ZipResult;
|
||||
use spec;
|
||||
use util;
|
||||
use util::WriteIntExt;
|
||||
|
||||
pub fn write_local_file_header<T: Write>(writer: &mut T, file: &ZipFileData) -> ZipResult<()>
|
||||
{
|
||||
try!(writer.write_le_u32(spec::LOCAL_FILE_HEADER_SIGNATURE));
|
||||
try!(writer.write_le_u16(20));
|
||||
let flag = if !file.file_name.is_ascii() { 1u16 << 11 } else { 0 };
|
||||
try!(writer.write_le_u16(flag));
|
||||
try!(writer.write_le_u16(file.compression_method as u16));
|
||||
try!(writer.write_le_u16(util::tm_to_msdos_time(file.last_modified_time)));
|
||||
try!(writer.write_le_u16(util::tm_to_msdos_date(file.last_modified_time)));
|
||||
try!(writer.write_le_u32(file.crc32));
|
||||
try!(writer.write_le_u32(file.compressed_size as u32));
|
||||
try!(writer.write_le_u32(file.uncompressed_size as u32));
|
||||
try!(writer.write_le_u16(file.file_name.as_bytes().len() as u16));
|
||||
let extra_field = try!(build_extra_field(file));
|
||||
try!(writer.write_le_u16(extra_field.len() as u16));
|
||||
try!(writer.write_all(file.file_name.as_bytes()));
|
||||
try!(writer.write_all(extra_field.as_slice()));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update_local_file_header<T: Write+io::Seek>(writer: &mut T, file: &ZipFileData) -> ZipResult<()>
|
||||
{
|
||||
static CRC32_OFFSET : u64 = 14;
|
||||
try!(writer.seek(io::SeekFrom::Start(file.header_start + CRC32_OFFSET)));
|
||||
try!(writer.write_le_u32(file.crc32));
|
||||
try!(writer.write_le_u32(file.compressed_size as u32));
|
||||
try!(writer.write_le_u32(file.uncompressed_size as u32));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_central_directory_header<T: Write>(writer: &mut T, file: &ZipFileData) -> ZipResult<()>
|
||||
{
|
||||
try!(writer.write_le_u32(spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE));
|
||||
try!(writer.write_le_u16(0x14FF));
|
||||
try!(writer.write_le_u16(20));
|
||||
let flag = if !file.file_name.is_ascii() { 1u16 << 11 } else { 0 };
|
||||
try!(writer.write_le_u16(flag));
|
||||
try!(writer.write_le_u16(file.compression_method as u16));
|
||||
try!(writer.write_le_u16(util::tm_to_msdos_time(file.last_modified_time)));
|
||||
try!(writer.write_le_u16(util::tm_to_msdos_date(file.last_modified_time)));
|
||||
try!(writer.write_le_u32(file.crc32));
|
||||
try!(writer.write_le_u32(file.compressed_size as u32));
|
||||
try!(writer.write_le_u32(file.uncompressed_size as u32));
|
||||
try!(writer.write_le_u16(file.file_name.as_bytes().len() as u16));
|
||||
let extra_field = try!(build_extra_field(file));
|
||||
try!(writer.write_le_u16(extra_field.len() as u16));
|
||||
try!(writer.write_le_u16(0));
|
||||
try!(writer.write_le_u16(0));
|
||||
try!(writer.write_le_u16(0));
|
||||
try!(writer.write_le_u32(0));
|
||||
try!(writer.write_le_u32(file.header_start as u32));
|
||||
try!(writer.write_all(file.file_name.as_bytes()));
|
||||
try!(writer.write_all(extra_field.as_slice()));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build_extra_field(_file: &ZipFileData) -> ZipResult<Vec<u8>>
|
||||
{
|
||||
let writer = Vec::new();
|
||||
// Future work
|
||||
Ok(writer)
|
||||
}
|
Loading…
Add table
Reference in a new issue