Convert writer_spec to new IO

This commit is contained in:
Mathijs van de Nes 2015-02-24 14:36:00 +01:00
parent 2e8baed799
commit af22baf13b
3 changed files with 44 additions and 22 deletions

View file

@ -70,3 +70,31 @@ impl<'a, R: Reader> Reader for RefMutReader<'a, R>
self.inner.read(buf) self.inner.read(buf)
} }
} }
/// Additional integer write methods for a io::Read
pub trait WriteIntExt {
/// Write a u32 in little-endian mode
fn write_le_u32(&mut self, u32) -> io::Result<()>;
/// Write a u16 in little-endian mode
fn write_le_u16(&mut self, u16) -> io::Result<()>;
}
impl<W: Write> WriteIntExt for W {
fn write_le_u32(&mut self, val: u32) -> io::Result<()> {
let mut buf = [0u8; 4];
let v = val;
buf[0] = ((v >> 0) & 0xFF) as u8;
buf[1] = ((v >> 8) & 0xFF) as u8;
buf[2] = ((v >> 16) & 0xFF) as u8;
buf[3] = ((v >> 24) & 0xFF) as u8;
self.write_all(&buf)
}
fn write_le_u16(&mut self, val: u16) -> io::Result<()> {
let mut buf = [0u8; 2];
let v = val;
buf[0] = ((v >> 0) & 0xFF) as u8;
buf[1] = ((v >> 8) & 0xFF) as u8;
self.write_all(&buf)
}
}

View file

@ -6,7 +6,6 @@ use crc32;
use result::{ZipResult, ZipError}; use result::{ZipResult, ZipError};
use std::default::Default; use std::default::Default;
use std::io; use std::io;
use std::io::Seek;
use std::io::prelude::*; use std::io::prelude::*;
use std::old_io::Writer; use std::old_io::Writer;
use std::mem; use std::mem;
@ -64,7 +63,7 @@ struct ZipWriterStats
bytes_written: u64, bytes_written: u64,
} }
impl<W: Write+Seek> Write for ZipWriter<W> impl<W: Write+io::Seek> Write for ZipWriter<W>
{ {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> fn write(&mut self, buf: &[u8]) -> io::Result<usize>
{ {
@ -98,7 +97,7 @@ impl ZipWriterStats
} }
} }
impl<W: Write+Seek> ZipWriter<W> impl<W: Write+io::Seek> ZipWriter<W>
{ {
/// Initializes the ZipWriter. /// Initializes the ZipWriter.
/// ///
@ -135,9 +134,7 @@ impl<W: Write+Seek> ZipWriter<W>
header_start: header_start, header_start: header_start,
data_start: 0, data_start: 0,
}; };
let mut conv_w = IoConverter::new(writer); try!(writer_spec::write_local_file_header(writer, &file));
try!(writer_spec::write_local_file_header(&mut conv_w, &file));
let writer = conv_w.into_inner();
let header_end = try!(writer.seek(io::SeekFrom::Current(0))); let header_end = try!(writer.seek(io::SeekFrom::Current(0)));
self.stats.start = header_end; self.stats.start = header_end;
@ -168,9 +165,7 @@ impl<W: Write+Seek> ZipWriter<W>
file.uncompressed_size = self.stats.bytes_written; file.uncompressed_size = self.stats.bytes_written;
file.compressed_size = try!(writer.seek(io::SeekFrom::Current(0))) - self.stats.start; file.compressed_size = try!(writer.seek(io::SeekFrom::Current(0))) - self.stats.start;
let mut conv_w = IoConverter::new(writer); try!(writer_spec::update_local_file_header(writer, file));
try!(writer_spec::update_local_file_header(&mut conv_w, file));
let writer = conv_w.into_inner();
try!(writer.seek(io::SeekFrom::End(0))); try!(writer.seek(io::SeekFrom::End(0)));
Ok(()) Ok(())
} }
@ -194,12 +189,10 @@ impl<W: Write+Seek> ZipWriter<W>
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 = try!(writer.seek(io::SeekFrom::Current(0)));
let mut conv_w = IoConverter::new(writer);
for file in self.files.iter() for file in self.files.iter()
{ {
try!(writer_spec::write_central_directory_header(&mut conv_w, file)); try!(writer_spec::write_central_directory_header(writer, file));
} }
let writer = conv_w.into_inner();
let central_size = try!(writer.seek(io::SeekFrom::Current(0))) - central_start; let central_size = try!(writer.seek(io::SeekFrom::Current(0))) - central_start;
let footer = spec::CentralDirectoryEnd let footer = spec::CentralDirectoryEnd
@ -221,7 +214,7 @@ impl<W: Write+Seek> ZipWriter<W>
} }
#[unsafe_destructor] #[unsafe_destructor]
impl<W: Write+Seek> Drop for ZipWriter<W> impl<W: Write+io::Seek> Drop for ZipWriter<W>
{ {
fn drop(&mut self) fn drop(&mut self)
{ {
@ -234,7 +227,7 @@ impl<W: Write+Seek> Drop for ZipWriter<W>
} }
} }
impl<W: Write+Seek> GenericZipWriter<W> impl<W: Write+io::Seek> GenericZipWriter<W>
{ {
fn switch_to(&mut self, compression: CompressionMethod) -> ZipResult<()> fn switch_to(&mut self, compression: CompressionMethod) -> ZipResult<()>
{ {

View file

@ -1,12 +1,13 @@
use std::old_io; use std::io;
use std::io::prelude::*; use std::io::prelude::*;
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use types::ZipFile; use types::ZipFile;
use result::ZipResult; use result::ZipResult;
use spec; use spec;
use util; use util;
use util::WriteIntExt;
pub fn write_local_file_header<T: Writer>(writer: &mut T, file: &ZipFile) -> ZipResult<()> pub fn write_local_file_header<T: Write>(writer: &mut T, file: &ZipFile) -> ZipResult<()>
{ {
try!(writer.write_le_u32(spec::LOCAL_FILE_HEADER_SIGNATURE)); try!(writer.write_le_u32(spec::LOCAL_FILE_HEADER_SIGNATURE));
try!(writer.write_le_u16(20)); try!(writer.write_le_u16(20));
@ -27,17 +28,17 @@ pub fn write_local_file_header<T: Writer>(writer: &mut T, file: &ZipFile) -> Zip
Ok(()) Ok(())
} }
pub fn update_local_file_header<T: Writer+Seek>(writer: &mut T, file: &ZipFile) -> ZipResult<()> pub fn update_local_file_header<T: Write+io::Seek>(writer: &mut T, file: &ZipFile) -> ZipResult<()>
{ {
static CRC32_OFFSET : i64 = 14; static CRC32_OFFSET : u64 = 14;
try!(writer.seek(file.header_start as i64 + CRC32_OFFSET, old_io::SeekSet)); try!(writer.seek(io::SeekFrom::Start(file.header_start + CRC32_OFFSET)));
try!(writer.write_le_u32(file.crc32)); try!(writer.write_le_u32(file.crc32));
try!(writer.write_le_u32(file.compressed_size as u32)); try!(writer.write_le_u32(file.compressed_size as u32));
try!(writer.write_le_u32(file.uncompressed_size as u32)); try!(writer.write_le_u32(file.uncompressed_size as u32));
Ok(()) Ok(())
} }
pub fn write_central_directory_header<T: Writer>(writer: &mut T, file: &ZipFile) -> ZipResult<()> pub fn write_central_directory_header<T: Write>(writer: &mut T, file: &ZipFile) -> ZipResult<()>
{ {
try!(writer.write_le_u32(spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE)); try!(writer.write_le_u32(spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE));
try!(writer.write_le_u16(0x14FF)); try!(writer.write_le_u16(0x14FF));
@ -66,7 +67,7 @@ pub fn write_central_directory_header<T: Writer>(writer: &mut T, file: &ZipFile)
fn build_extra_field(_file: &ZipFile) -> ZipResult<Vec<u8>> fn build_extra_field(_file: &ZipFile) -> ZipResult<Vec<u8>>
{ {
let writer = old_io::MemWriter::new(); let writer = Vec::new();
// Future work // Future work
Ok(writer.into_inner()) Ok(writer)
} }