diff --git a/src/compression.rs b/src/compression.rs index 6e8100b..7697560 100755 --- a/src/compression.rs +++ b/src/compression.rs @@ -1,9 +1,13 @@ use anyhow::{Result}; use strum::IntoEnumIterator; use std::path::PathBuf; -use std::io::Write; +use std::io::{Read,Write}; +use std::io; + +use log::*; use lazy_static::lazy_static; + extern crate enum_map; use enum_map::enum_map; use enum_map::{EnumMap,Enum}; @@ -31,9 +35,38 @@ pub enum CompressionType { pub trait CompressionEngine { - fn is_supported(&self) -> bool; - fn cat(&self, file_path: PathBuf) -> Result<()>; + fn open(&self, file_path: PathBuf) -> Result>; fn create(&self, file_path: PathBuf) -> Result>; + + fn is_supported(&self) -> bool { + true + } + + fn cat(&self, file_path: PathBuf) -> Result<()> { + let mut reader = self.open(file_path)?; + let mut stdout = io::stdout().lock(); + io::copy(&mut reader, &mut stdout)?; + stdout.flush()?; + Ok(()) + } + + fn size(&self, file_path: PathBuf) -> Result { + let mut reader = self.open(file_path)?; + let mut buffer = [0; libc::BUFSIZ as usize]; + let mut size: usize = 0; + + loop { + let n = reader.read(&mut buffer[..libc::BUFSIZ as usize])?; + if n == 0 { + debug!("COMPREESSION: EOF"); + break; + } + + size = size + n; + } + + Ok(size) + } } diff --git a/src/compression/gzip.rs b/src/compression/gzip.rs index b352eaa..97a8245 100644 --- a/src/compression/gzip.rs +++ b/src/compression/gzip.rs @@ -1,7 +1,7 @@ use anyhow::Result; use std::fs::File; use std::io; -use std::io::Write; +use std::io::{Read,Write}; use std::path::PathBuf; use log::*; @@ -25,17 +25,11 @@ impl CompressionEngine for CompressionEngineGZip { true } - fn cat(&self, file_path: PathBuf) -> Result<()> { - debug!("COMPRESSION: Outputting {:?} to STDOUT using {:?}", file_path, *self); + fn open(&self, file_path: PathBuf) -> Result> { + debug!("COMPRESSION: Opening {:?} using {:?}", file_path, *self); - let mut stdout = io::stdout().lock(); let file = File::open(file_path)?; - let mut gzip_read = GzDecoder::new(file); - - io::copy(&mut gzip_read, &mut stdout)?; - stdout.flush()?; - - Ok(()) + Ok(Box::new(GzDecoder::new(file))) } fn create(&self, file_path: PathBuf) -> Result> { diff --git a/src/compression/lz4.rs b/src/compression/lz4.rs index 5df318c..7b1cef3 100644 --- a/src/compression/lz4.rs +++ b/src/compression/lz4.rs @@ -1,7 +1,6 @@ use anyhow::Result; use std::fs::File; -use std::io; -use std::io::Write; +use std::io::{Read,Write}; use std::path::PathBuf; use log::*; @@ -24,17 +23,11 @@ impl CompressionEngine for CompressionEngineLZ4 { true } - fn cat(&self, file_path: PathBuf) -> Result<()> { - debug!("COMPRESSION: Outputting {:?} to STDOUT using {:?}", file_path, *self); + fn open(&self, file_path: PathBuf) -> Result> { + debug!("COMPRESSION: Opening {:?} using {:?}", file_path, *self); - let mut stdout = io::stdout().lock(); let file = File::open(file_path)?; - let mut lz4_read = FrameDecoder::new(file); - - io::copy(&mut lz4_read, &mut stdout)?; - stdout.flush()?; - - Ok(()) + Ok(Box::new(FrameDecoder::new(file))) } fn create(&self, file_path: PathBuf) -> Result> { diff --git a/src/compression/none.rs b/src/compression/none.rs index d95ebad..f359bee 100644 --- a/src/compression/none.rs +++ b/src/compression/none.rs @@ -1,7 +1,6 @@ use anyhow::Result; use std::fs::File; -use std::io; -use std::io::Write; +use std::io::{Read,Write}; use std::path::PathBuf; use log::*; @@ -17,19 +16,14 @@ impl CompressionEngineNone { } impl CompressionEngine for CompressionEngineNone { - fn is_supported(&self) -> bool { - true + fn size(&self, file_path: PathBuf) -> Result { + let item_file_metadata = file_path.metadata()?; + Ok(item_file_metadata.len() as usize) } - fn cat(&self, file_path: PathBuf) -> Result<()> { - debug!("COMPRESSION: Outputting {:?} to STDOUT using {:?}", file_path, *self); - let mut stdout = io::stdout().lock(); - let mut file = File::open(file_path)?; - - io::copy(&mut file, &mut stdout)?; - stdout.flush()?; - - Ok(()) + fn open(&self, file_path: PathBuf) -> Result> { + debug!("COMPRESSION: Opening {:?} using {:?}", file_path, *self); + Ok(Box::new(File::open(file_path)?)) } fn create(&self, file_path: PathBuf) -> Result> { diff --git a/src/compression/program.rs b/src/compression/program.rs index 566c267..809f9ba 100644 --- a/src/compression/program.rs +++ b/src/compression/program.rs @@ -1,6 +1,6 @@ use anyhow::{Context, Result, anyhow}; use std::fs::File; -use std::io::Write; +use std::io::{Read,Write}; use std::process::{Command,Stdio}; use std::path::PathBuf; use std::env; @@ -39,29 +39,23 @@ impl CompressionEngine for CompressionEngineProgram { self.supported } - fn cat(&self, file_path: PathBuf) -> Result<()> { - debug!("COMPRESSION: Outputting {:?} to STDOUT using {:?}", file_path, *self); + fn open(&self, file_path: PathBuf) -> Result> { + debug!("COMPRESSION: Opening {:?} using {:?}", file_path, *self); + let program = self.program.clone(); let args = self.decompress.clone(); - debug!("COMPRESSION: Executing command: {:?} {:?} writing to {:?}", program, args, file_path); + debug!("COMPRESSION: Executing command: {:?} {:?} reading from {:?}", program, args, file_path); let file = File::open(file_path).context("Unable to open file for reading")?; - let mut process = Command::new(program.clone()) + let process = Command::new(program.clone()) .args(args.clone()) .stdin(file) + .stdout(Stdio::piped()) .spawn() .context(anyhow!("Unable to spawn child process: {:?} {:?}", program, args))?; - - let result = process.wait() - .context(anyhow!("Unable to wait for child process: {:?} {:?}", program, args))?; - - if result.success() { - Ok(()) - } else { - Err(anyhow!("Decompression program returned {}", result)) - } + Ok(Box::new(process.stdout.unwrap())) } fn create(&self, file_path: PathBuf) -> Result> {