Made deflate compression into separate feature

This commit is contained in:
jhwgh1968 2018-01-07 00:47:11 -06:00
parent f2e5cad539
commit 19274b497a
6 changed files with 71 additions and 14 deletions

View file

@ -12,7 +12,7 @@ Library to support the reading and writing of zip files.
""" """
[dependencies] [dependencies]
flate2 = { version = "1.0", default-features = false, features = ["rust_backend"]} flate2 = { version = "1.0", default-features = false, features = ["rust_backend"], optional = true}
time = "0.1" time = "0.1"
podio = "0.1" podio = "0.1"
msdos_time = "0.1" msdos_time = "0.1"
@ -22,4 +22,4 @@ bzip2 = { version = "0.3", optional = true }
walkdir = "1.0" walkdir = "1.0"
[features] [features]
default = ["bzip2"] default = ["bzip2", "flate2"]

View file

@ -12,6 +12,18 @@ fn main() {
std::process::exit(real_main()); std::process::exit(real_main());
} }
const METHOD_STORED : Option<zip::CompressionMethod> = Some(zip::CompressionMethod::Stored);
#[cfg(feature = "flate2")]
const METHOD_DEFLATED : Option<zip::CompressionMethod> = Some(zip::CompressionMethod::Deflated);
#[cfg(not(feature = "flate2"))]
const METHOD_DEFLATED : Option<zip::CompressionMethod> = None;
#[cfg(feature = "bzip2")]
const METHOD_BZIP2 : Option<zip::CompressionMethod> = Some(zip::CompressionMethod::Bzip2);
#[cfg(not(feature = "bzip2"))]
const METHOD_BZIP2 : Option<zip::CompressionMethod> = None;
fn real_main() -> i32 { fn real_main() -> i32 {
let args: Vec<_> = std::env::args().collect(); let args: Vec<_> = std::env::args().collect();
if args.len() < 3 { if args.len() < 3 {
@ -22,15 +34,18 @@ fn real_main() -> i32 {
let src_dir = &*args[1]; let src_dir = &*args[1];
let dst_file = &*args[2]; let dst_file = &*args[2];
match doit(src_dir, dst_file) { for &method in [METHOD_STORED, METHOD_DEFLATED, METHOD_BZIP2].iter() {
if method.is_none() { continue }
match doit(src_dir, dst_file, method.unwrap()) {
Ok(_) => println!("done: {} written to {}", src_dir, dst_file), Ok(_) => println!("done: {} written to {}", src_dir, dst_file),
Err(e) => println!("Error: {:?}", e), Err(e) => println!("Error: {:?}", e),
} }
}
return 0; return 0;
} }
fn doit(src_dir: &str, dst_file: &str) -> zip::result::ZipResult<()> { fn doit(src_dir: &str, dst_file: &str, method: zip::CompressionMethod) -> zip::result::ZipResult<()> {
if !Path::new(src_dir).is_dir() { if !Path::new(src_dir).is_dir() {
return Ok(()); return Ok(());
} }
@ -41,7 +56,7 @@ fn doit(src_dir: &str, dst_file: &str) -> zip::result::ZipResult<()> {
let mut zip = zip::ZipWriter::new(file); let mut zip = zip::ZipWriter::new(file);
let options = FileOptions::default() let options = FileOptions::default()
.compression_method(zip::CompressionMethod::Deflated) .compression_method(method)
.unix_permissions(0o755); .unix_permissions(0o755);
let walkdir = WalkDir::new(src_dir.to_string()); let walkdir = WalkDir::new(src_dir.to_string());

View file

@ -9,6 +9,7 @@ pub enum CompressionMethod
/// The file is stored (no compression) /// The file is stored (no compression)
Stored, Stored,
/// The file is Deflated /// The file is Deflated
#[cfg(feature = "flate2")]
Deflated, Deflated,
/// File is compressed using BZIP2 algorithm /// File is compressed using BZIP2 algorithm
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
@ -22,6 +23,7 @@ impl CompressionMethod {
pub fn from_u16(val: u16) -> CompressionMethod { pub fn from_u16(val: u16) -> CompressionMethod {
match val { match val {
0 => CompressionMethod::Stored, 0 => CompressionMethod::Stored,
#[cfg(feature = "flate2")]
8 => CompressionMethod::Deflated, 8 => CompressionMethod::Deflated,
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
12 => CompressionMethod::Bzip2, 12 => CompressionMethod::Bzip2,
@ -33,6 +35,7 @@ impl CompressionMethod {
pub fn to_u16(self) -> u16 { pub fn to_u16(self) -> u16 {
match self { match self {
CompressionMethod::Stored => 0, CompressionMethod::Stored => 0,
#[cfg(feature = "flate2")]
CompressionMethod::Deflated => 8, CompressionMethod::Deflated => 8,
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
CompressionMethod::Bzip2 => 12, CompressionMethod::Bzip2 => 12,
@ -62,16 +65,26 @@ mod test {
} }
} }
#[cfg(not(feature = "bzip2"))] #[cfg(all(not(feature = "bzip2"), feature = "flate2"))]
fn methods() -> Vec<CompressionMethod> { fn methods() -> Vec<CompressionMethod> {
vec![CompressionMethod::Stored, CompressionMethod::Deflated] vec![CompressionMethod::Stored, CompressionMethod::Deflated]
} }
#[cfg(feature = "bzip2")] #[cfg(all(not(feature = "flate2"), feature = "bzip2"))]
fn methods() -> Vec<CompressionMethod> {
vec![CompressionMethod::Stored, CompressionMethod::Bzip2]
}
#[cfg(all(feature = "bzip2", feature = "flate2"))]
fn methods() -> Vec<CompressionMethod> { fn methods() -> Vec<CompressionMethod> {
vec![CompressionMethod::Stored, CompressionMethod::Deflated, CompressionMethod::Bzip2] vec![CompressionMethod::Stored, CompressionMethod::Deflated, CompressionMethod::Bzip2]
} }
#[cfg(all(not(feature = "bzip2"), not(feature = "flate2")))]
fn methods() -> Vec<CompressionMethod> {
vec![CompressionMethod::Stored]
}
#[test] #[test]
fn to_eq_from() { fn to_eq_from() {
fn check_match(method: CompressionMethod) { fn check_match(method: CompressionMethod) {

View file

@ -4,6 +4,7 @@
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
extern crate bzip2; extern crate bzip2;
#[cfg(feature = "flate2")]
extern crate flate2; extern crate flate2;
extern crate msdos_time; extern crate msdos_time;
extern crate podio; extern crate podio;

View file

@ -7,13 +7,17 @@ use result::{ZipResult, ZipError};
use std::io; use std::io;
use std::io::prelude::*; use std::io::prelude::*;
use std::collections::HashMap; use std::collections::HashMap;
use flate2;
use flate2::read::DeflateDecoder;
use podio::{ReadPodExt, LittleEndian}; use podio::{ReadPodExt, LittleEndian};
use types::{ZipFileData, System}; use types::{ZipFileData, System};
use cp437::FromCp437; use cp437::FromCp437;
use msdos_time::{TmMsDosExt, MsDosDateTime}; use msdos_time::{TmMsDosExt, MsDosDateTime};
#[cfg(feature = "flate2")]
use flate2;
#[cfg(feature = "flate2")]
use flate2::read::DeflateDecoder;
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
use bzip2::read::BzDecoder; use bzip2::read::BzDecoder;
@ -59,6 +63,7 @@ pub struct ZipArchive<R: Read + io::Seek>
enum ZipFileReader<'a> { enum ZipFileReader<'a> {
Stored(Crc32Reader<io::Take<&'a mut Read>>), Stored(Crc32Reader<io::Take<&'a mut Read>>),
#[cfg(feature = "flate2")]
Deflated(Crc32Reader<flate2::read::DeflateDecoder<io::Take<&'a mut Read>>>), Deflated(Crc32Reader<flate2::read::DeflateDecoder<io::Take<&'a mut Read>>>),
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
Bzip2(Crc32Reader<BzDecoder<io::Take<&'a mut Read>>>), Bzip2(Crc32Reader<BzDecoder<io::Take<&'a mut Read>>>),
@ -235,6 +240,7 @@ impl<R: Read+io::Seek> ZipArchive<R>
limit_reader, limit_reader,
data.crc32)) data.crc32))
}, },
#[cfg(feature = "flate2")]
CompressionMethod::Deflated => CompressionMethod::Deflated =>
{ {
let deflate_reader = DeflateDecoder::new(limit_reader); let deflate_reader = DeflateDecoder::new(limit_reader);
@ -377,6 +383,7 @@ impl<'a> ZipFile<'a> {
fn get_reader(&mut self) -> &mut Read { fn get_reader(&mut self) -> &mut Read {
match self.reader { match self.reader {
ZipFileReader::Stored(ref mut r) => r as &mut Read, ZipFileReader::Stored(ref mut r) => r as &mut Read,
#[cfg(feature = "flate2")]
ZipFileReader::Deflated(ref mut r) => r as &mut Read, ZipFileReader::Deflated(ref mut r) => r as &mut Read,
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
ZipFileReader::Bzip2(ref mut r) => r as &mut Read, ZipFileReader::Bzip2(ref mut r) => r as &mut Read,

View file

@ -10,11 +10,14 @@ use std::io;
use std::io::prelude::*; use std::io::prelude::*;
use std::mem; use std::mem;
use time; use time;
use flate2;
use flate2::write::DeflateEncoder;
use podio::{WritePodExt, LittleEndian}; use podio::{WritePodExt, LittleEndian};
use msdos_time::TmMsDosExt; use msdos_time::TmMsDosExt;
#[cfg(feature = "flate2")]
use flate2;
#[cfg(feature = "flate2")]
use flate2::write::DeflateEncoder;
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
use bzip2; use bzip2;
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
@ -24,6 +27,7 @@ enum GenericZipWriter<W: Write + io::Seek>
{ {
Closed, Closed,
Storer(W), Storer(W),
#[cfg(feature = "flate2")]
Deflater(DeflateEncoder<W>), Deflater(DeflateEncoder<W>),
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
Bzip2(BzEncoder<W>), Bzip2(BzEncoder<W>),
@ -77,6 +81,7 @@ pub struct FileOptions {
} }
impl FileOptions { impl FileOptions {
#[cfg(feature = "flate2")]
/// Construct a new FileOptions object /// Construct a new FileOptions object
pub fn default() -> FileOptions { pub fn default() -> FileOptions {
FileOptions { FileOptions {
@ -86,9 +91,21 @@ impl FileOptions {
} }
} }
#[cfg(not(feature = "flate2"))]
/// Construct a new FileOptions object
pub fn default() -> FileOptions {
FileOptions {
compression_method: CompressionMethod::Stored,
last_modified_time: time::now(),
permissions: None,
}
}
/// Set the compression method for the new file /// Set the compression method for the new file
/// ///
/// The default is `CompressionMethod::Deflated` /// The default is `CompressionMethod::Deflated`. If the deflate compression feature is
/// disabled, `CompressionMethod::Stored` becomes the default.
/// otherwise.
pub fn compression_method(mut self, method: CompressionMethod) -> FileOptions { pub fn compression_method(mut self, method: CompressionMethod) -> FileOptions {
self.compression_method = method; self.compression_method = method;
self self
@ -330,6 +347,7 @@ impl<W: Write+io::Seek> GenericZipWriter<W>
let bare = match mem::replace(self, GenericZipWriter::Closed) let bare = match mem::replace(self, GenericZipWriter::Closed)
{ {
GenericZipWriter::Storer(w) => w, GenericZipWriter::Storer(w) => w,
#[cfg(feature = "flate2")]
GenericZipWriter::Deflater(w) => try!(w.finish()), GenericZipWriter::Deflater(w) => try!(w.finish()),
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
GenericZipWriter::Bzip2(w) => try!(w.finish()), GenericZipWriter::Bzip2(w) => try!(w.finish()),
@ -339,6 +357,7 @@ impl<W: Write+io::Seek> GenericZipWriter<W>
*self = match compression *self = match compression
{ {
CompressionMethod::Stored => GenericZipWriter::Storer(bare), CompressionMethod::Stored => GenericZipWriter::Storer(bare),
#[cfg(feature = "flate2")]
CompressionMethod::Deflated => GenericZipWriter::Deflater(DeflateEncoder::new(bare, flate2::Compression::default())), CompressionMethod::Deflated => GenericZipWriter::Deflater(DeflateEncoder::new(bare, flate2::Compression::default())),
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
CompressionMethod::Bzip2 => GenericZipWriter::Bzip2(BzEncoder::new(bare, bzip2::Compression::Default)), CompressionMethod::Bzip2 => GenericZipWriter::Bzip2(BzEncoder::new(bare, bzip2::Compression::Default)),
@ -351,6 +370,7 @@ impl<W: Write+io::Seek> GenericZipWriter<W>
fn ref_mut(&mut self) -> Option<&mut Write> { fn ref_mut(&mut self) -> Option<&mut Write> {
match *self { match *self {
GenericZipWriter::Storer(ref mut w) => Some(w as &mut Write), GenericZipWriter::Storer(ref mut w) => Some(w as &mut Write),
#[cfg(feature = "flate2")]
GenericZipWriter::Deflater(ref mut w) => Some(w as &mut Write), GenericZipWriter::Deflater(ref mut w) => Some(w as &mut Write),
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
GenericZipWriter::Bzip2(ref mut w) => Some(w as &mut Write), GenericZipWriter::Bzip2(ref mut w) => Some(w as &mut Write),
@ -379,6 +399,7 @@ impl<W: Write+io::Seek> GenericZipWriter<W>
fn current_compression(&self) -> Option<CompressionMethod> { fn current_compression(&self) -> Option<CompressionMethod> {
match *self { match *self {
GenericZipWriter::Storer(..) => Some(CompressionMethod::Stored), GenericZipWriter::Storer(..) => Some(CompressionMethod::Stored),
#[cfg(feature = "flate2")]
GenericZipWriter::Deflater(..) => Some(CompressionMethod::Deflated), GenericZipWriter::Deflater(..) => Some(CompressionMethod::Deflated),
#[cfg(feature = "bzip2")] #[cfg(feature = "bzip2")]
GenericZipWriter::Bzip2(..) => Some(CompressionMethod::Bzip2), GenericZipWriter::Bzip2(..) => Some(CompressionMethod::Bzip2),