mirror of
https://github.com/ouch-org/ouch.git
synced 2025-06-07 12:05:46 +00:00
Add support for Gzip compression (includes .tar.gz)
This commit is contained in:
parent
bdc16fdb17
commit
3fa939ac90
@ -1,4 +1,4 @@
|
|||||||
use std::{fs, io::{self, Read, Write}, path::PathBuf};
|
use std::{fs, io::Write, path::PathBuf};
|
||||||
|
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
|
|
||||||
@ -9,38 +9,6 @@ use super::{Compressor, Entry};
|
|||||||
|
|
||||||
pub struct BzipCompressor {}
|
pub struct BzipCompressor {}
|
||||||
|
|
||||||
struct CompressorToMemory {}
|
|
||||||
|
|
||||||
// impl CompressorToMemory {
|
|
||||||
// pub fn compress_files(files: Vec<PathBuf>, format: CompressionFormat) -> OuchResult<Vec<u8>> {
|
|
||||||
// let mut buffer = vec![];
|
|
||||||
|
|
||||||
// if files.len() != 1 {
|
|
||||||
// eprintln!("{}: cannot compress multiple files directly to {:#?}.\n Try using an intermediate archival method such as Tar.\n Example: filename.tar{}", "error".red(), format, format);
|
|
||||||
// return Err(Error::InvalidInput);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let mut contents = Vec::new();
|
|
||||||
// let path = &files[0];
|
|
||||||
// ensure_exists(path)?;
|
|
||||||
|
|
||||||
// let bytes_read = {
|
|
||||||
// let bytes = fs::read(path)?;
|
|
||||||
// let mut encoder = get_encoder(&format, Box::new(&mut buffer));
|
|
||||||
// encoder.write_all(&*bytes)?;
|
|
||||||
// bytes.as_slice().read_to_end(&mut contents)?
|
|
||||||
// };
|
|
||||||
|
|
||||||
// println!("{}: compressed {:?} into memory ({} bytes)", "info".yellow(), &path, bytes_read);
|
|
||||||
|
|
||||||
// Ok(contents)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn compress_bytes(file: File) {
|
|
||||||
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
impl BzipCompressor {
|
impl BzipCompressor {
|
||||||
fn compress_files(files: Vec<PathBuf>, format: CompressionFormat) -> OuchResult<Vec<u8>> {
|
fn compress_files(files: Vec<PathBuf>, format: CompressionFormat) -> OuchResult<Vec<u8>> {
|
||||||
if files.len() != 1 {
|
if files.len() != 1 {
|
||||||
@ -82,13 +50,6 @@ impl BzipCompressor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: customizable compression level
|
// TODO: customizable compression level
|
||||||
fn get_encoder<'a>(format: &CompressionFormat, buffer: Box<dyn io::Write + Send + 'a>) -> Box<dyn io::Write + Send + 'a> {
|
|
||||||
match format {
|
|
||||||
CompressionFormat::Bzip => Box::new(bzip2::write::BzEncoder::new(buffer, bzip2::Compression::new(4))),
|
|
||||||
_other => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Compressor for BzipCompressor {
|
impl Compressor for BzipCompressor {
|
||||||
fn compress(&self, from: Entry) -> OuchResult<Vec<u8>> {
|
fn compress(&self, from: Entry) -> OuchResult<Vec<u8>> {
|
||||||
match from {
|
match from {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
mod tar;
|
mod tar;
|
||||||
mod zip;
|
mod zip;
|
||||||
mod bzip;
|
mod bzip;
|
||||||
|
mod tomemory;
|
||||||
mod compressor;
|
mod compressor;
|
||||||
|
|
||||||
pub use compressor::Compressor;
|
pub use compressor::Compressor;
|
||||||
@ -8,3 +9,4 @@ pub use self::compressor::Entry;
|
|||||||
pub use self::tar::TarCompressor;
|
pub use self::tar::TarCompressor;
|
||||||
pub use self::zip::ZipCompressor;
|
pub use self::zip::ZipCompressor;
|
||||||
pub use self::bzip::BzipCompressor;
|
pub use self::bzip::BzipCompressor;
|
||||||
|
pub use self::tomemory::GzipCompressor;
|
@ -23,25 +23,8 @@ impl TarCompressor {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// let ok = EntryType::
|
println!("todo");
|
||||||
|
|
||||||
|
|
||||||
// let mut b = Builder::new(Vec::new());
|
|
||||||
// let mut header = Header::new_gnu();
|
|
||||||
// let name = b"././@LongLink";
|
|
||||||
// header.as_gnu_mut().unwrap().name[..name.len()].clone_from_slice(&name[..]);
|
|
||||||
// header.set_mode(0o644);
|
|
||||||
// header.set_uid(0);
|
|
||||||
// header.set_gid(0);
|
|
||||||
// header.set_mtime(0);
|
|
||||||
// // + 1 to be compliant with GNU tar
|
|
||||||
// header.set_size(size + 1);
|
|
||||||
// header.set_entry_type(EntryType::new(entry_type));
|
|
||||||
// header.set_cksum();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Ok(b.into_inner()?)
|
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
97
src/compressors/tomemory.rs
Normal file
97
src/compressors/tomemory.rs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
use std::{fs, io::{self, Read}, path::PathBuf};
|
||||||
|
|
||||||
|
use colored::Colorize;
|
||||||
|
|
||||||
|
use crate::{error::{Error, OuchResult}, extension::CompressionFormat, file::File};
|
||||||
|
use crate::utils::ensure_exists;
|
||||||
|
|
||||||
|
use super::{Compressor, Entry};
|
||||||
|
|
||||||
|
pub struct GzipCompressor {}
|
||||||
|
|
||||||
|
struct CompressorToMemory {}
|
||||||
|
|
||||||
|
impl CompressorToMemory {
|
||||||
|
pub fn compress_files(files: Vec<PathBuf>, format: CompressionFormat) -> OuchResult<Vec<u8>> {
|
||||||
|
|
||||||
|
|
||||||
|
if files.len() != 1 {
|
||||||
|
eprintln!("{}: cannot compress multiple files directly to {:#?}.\n Try using an intermediate archival method such as Tar.\n Example: filename.tar{}", "error".red(), format, format);
|
||||||
|
return Err(Error::InvalidInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut contents = Vec::new();
|
||||||
|
let path = &files[0];
|
||||||
|
ensure_exists(path)?;
|
||||||
|
|
||||||
|
let bytes_written = {
|
||||||
|
let bytes = fs::read(path)?;
|
||||||
|
|
||||||
|
// let mut buffer = vec![];
|
||||||
|
// let mut encoder = get_encoder(&format, Box::new(&mut buffer));
|
||||||
|
// encoder.write_all(&*bytes)?;
|
||||||
|
// bytes.as_slice().read_to_end(&mut contents)?
|
||||||
|
Self::compress_bytes(&mut contents, bytes, format)?
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"{}: compressed {:?} into memory ({} bytes)",
|
||||||
|
"info".yellow(),
|
||||||
|
&path,
|
||||||
|
bytes_written
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compress_file_in_memory(file: File, format:CompressionFormat ) -> OuchResult<Vec<u8>> {
|
||||||
|
let mut compressed_contents = Vec::new();
|
||||||
|
let file_contents = match file.contents_in_memory {
|
||||||
|
Some(bytes) => bytes,
|
||||||
|
None => {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let _bytes_written = Self::compress_bytes(&mut compressed_contents, file_contents, format);
|
||||||
|
|
||||||
|
Ok(compressed_contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compress_bytes(mut contents: &mut Vec<u8>, bytes_to_compress: Vec<u8>, format: CompressionFormat) -> OuchResult<usize> {
|
||||||
|
let mut buffer = vec![];
|
||||||
|
let mut encoder = get_encoder(&format, Box::new(&mut buffer));
|
||||||
|
encoder.write_all(&*bytes_to_compress)?;
|
||||||
|
|
||||||
|
Ok(bytes_to_compress.as_slice().read_to_end(&mut contents)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_encoder<'a>(
|
||||||
|
format: &CompressionFormat,
|
||||||
|
buffer: Box<dyn io::Write + Send + 'a>,
|
||||||
|
) -> Box<dyn io::Write + Send + 'a> {
|
||||||
|
match format {
|
||||||
|
CompressionFormat::Gzip => Box::new(flate2::write::GzEncoder::new(
|
||||||
|
buffer,
|
||||||
|
flate2::Compression::default(),
|
||||||
|
)),
|
||||||
|
_other => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Compressor for GzipCompressor {
|
||||||
|
fn compress(&self, from: Entry) -> OuchResult<Vec<u8>> {
|
||||||
|
let format = CompressionFormat::Gzip;
|
||||||
|
match from {
|
||||||
|
Entry::Files(files) => Ok(
|
||||||
|
CompressorToMemory::compress_files(files, format)?
|
||||||
|
),
|
||||||
|
Entry::InMemory(file) => Ok(
|
||||||
|
CompressorToMemory::compress_file_in_memory(file, format)?
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ use crate::compressors::{
|
|||||||
Compressor,
|
Compressor,
|
||||||
TarCompressor,
|
TarCompressor,
|
||||||
ZipCompressor,
|
ZipCompressor,
|
||||||
|
GzipCompressor,
|
||||||
BzipCompressor,
|
BzipCompressor,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,6 +72,7 @@ impl Evaluator {
|
|||||||
CompressionFormat::Tar => Box::new(TarCompressor {}),
|
CompressionFormat::Tar => Box::new(TarCompressor {}),
|
||||||
CompressionFormat::Zip => Box::new(ZipCompressor {}),
|
CompressionFormat::Zip => Box::new(ZipCompressor {}),
|
||||||
CompressionFormat::Bzip => Box::new(BzipCompressor {}),
|
CompressionFormat::Bzip => Box::new(BzipCompressor {}),
|
||||||
|
CompressionFormat::Gzip => Box::new(GzipCompressor {}),
|
||||||
_other => todo!()
|
_other => todo!()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user