diff --git a/Cargo.toml b/Cargo.toml index ee5b1ed2..66f882bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "zip" -version = "0.0.2" +version = "0.0.3" authors = ["Mathijs van de Nes "] license = "MIT" repository = "https://github.com/mvdnes/zip-rs.git" @@ -19,6 +19,11 @@ name = "extract" test = false doc = false +[[bin]] +name = "extract_lorem" +test = false +doc = false + [[bin]] name = "write_sample" test = false diff --git a/src/bin/extract_lorem.rs b/src/bin/extract_lorem.rs new file mode 100644 index 00000000..57b8a271 --- /dev/null +++ b/src/bin/extract_lorem.rs @@ -0,0 +1,25 @@ +extern crate zip; + +fn main() +{ + let args = std::os::args(); + if args.len() < 2 { + println!("Usage: {} ", args[0]); + std::os::set_exit_status(1); + return; + } + let fname = Path::new(args[1].as_slice()); + let file = std::io::File::open(&fname).unwrap(); + + let zipcontainer = zip::ZipReader::new(file).unwrap(); + + let file = match zipcontainer.get("test/lorem_ipsum.txt") + { + Some(file) => file, + None => { println!("File test/lorem_ipsum.txt not found"); return } + }; + + let data = zipcontainer.read_file(file).unwrap().read_to_end().unwrap(); + let contents = String::from_utf8(data).unwrap(); + println!("{}", contents); +} diff --git a/src/reader.rs b/src/reader.rs index 2600c399..f71d082c 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -6,6 +6,7 @@ use reader_spec; use result::{ZipResult, ZipError}; use std::io; use std::cell::RefCell; +use std::collections::HashMap; use flate2::FlateReader; use bzip2::reader::BzDecompressor; @@ -37,6 +38,7 @@ pub struct ZipReader { inner: RefCell, files: Vec, + names_map: HashMap, } fn unsupported_zip_error(detail: &'static str) -> ZipResult @@ -57,14 +59,17 @@ impl ZipReader let number_of_files = footer.number_of_files_on_this_disk as uint; let mut files = Vec::with_capacity(number_of_files); + let mut names_map = HashMap::new(); try!(reader.seek(directory_start, io::SeekSet)); for _ in range(0, number_of_files) { - files.push(try!(reader_spec::central_header_to_zip_file(&mut reader))); + let file = try!(reader_spec::central_header_to_zip_file(&mut reader)); + names_map.insert(file.file_name.clone(), files.len()); + files.push(file); } - Ok(ZipReader { inner: RefCell::new(reader), files: files }) + Ok(ZipReader { inner: RefCell::new(reader), files: files, names_map: names_map }) } /// An iterator over the information of all contained files. @@ -73,6 +78,12 @@ impl ZipReader self.files.as_slice().iter() } + /// Search for a file entry by name + pub fn get(&self, name: &str) -> Option<&ZipFile> + { + self.names_map.get(name).map(|index| &self.files[*index]) + } + /// Gets a reader for a contained zipfile. /// /// May return `ReaderUnavailable` if there is another reader borrowed. diff --git a/src/types.rs b/src/types.rs index 4a06a4bb..893372bc 100644 --- a/src/types.rs +++ b/src/types.rs @@ -2,6 +2,7 @@ use time; +#[deriving(Clone)] /// Structure representing a ZIP file. pub struct ZipFile {