Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impl Deflate read/write::Encoder/Decoders #17

Merged
merged 9 commits into from
Sep 25, 2024
7 changes: 6 additions & 1 deletion examples/compress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ fn get_data() -> std::result::Result<Vec<u8>, std::io::Error> {
fn main() {
let data = get_data().unwrap();
for _ in 0..1000 {
let _v = igzip::compress(Cursor::new(&data), igzip::CompressionLevel::Three, true).unwrap();
let _v = igzip::compress(
Cursor::new(&data),
igzip::CompressionLevel::Three,
isal::igzip::Codec::Gzip,
)
.unwrap();
}
}
44 changes: 30 additions & 14 deletions src/igzip/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,27 @@ use isal_sys::igzip_lib as isal;
/// Buffer size
pub const BUF_SIZE: usize = 16 * 1024;

/// Flavor of De/Compression to use if using the `isal::igzip::Encoder/Decoder` directly
/// and not the thin wrappers like `GzDecoder/GzEncoder` and similar.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum Codec {
Gzip = isal::IGZIP_GZIP,
Deflate = isal::IGZIP_DEFLATE,
}

/// Compress `input` directly into `output`. This is the fastest possible compression available.
#[inline(always)]
pub fn compress_into(
input: &[u8],
output: &mut [u8],
level: CompressionLevel,
is_gzip: bool,
codec: Codec,
) -> Result<usize> {
let mut zstream = ZStream::new(level, ZStreamKind::Stateless);

zstream.stream.flush = FlushFlags::NoFlush as _;
zstream.stream.gzip_flag = is_gzip as _;
zstream.stream.gzip_flag = codec as _;
zstream.stream.end_of_stream = 1;

// read input into buffer
Expand All @@ -42,10 +51,10 @@ pub fn compress_into(
pub fn compress<R: std::io::Read>(
input: R,
level: CompressionLevel,
is_gzip: bool,
codec: Codec,
) -> Result<Vec<u8>> {
let mut out = vec![];
let mut encoder = read::Encoder::new(input, level, is_gzip);
let mut encoder = read::Encoder::new(input, level, codec);
io::copy(&mut encoder, &mut out)?;
Ok(out)
}
Expand All @@ -54,7 +63,7 @@ pub fn compress<R: std::io::Read>(
#[inline(always)]
pub fn decompress<R: std::io::Read>(input: R) -> Result<Vec<u8>> {
let mut out = vec![];
let mut decoder = read::Decoder::new(input);
let mut decoder = read::Decoder::new(input, Codec::Gzip);
io::copy(&mut decoder, &mut out)?;
Ok(out)
}
Expand Down Expand Up @@ -313,7 +322,7 @@ pub mod tests {

// Default testing data
pub fn gen_large_data() -> Vec<u8> {
(0..(BUF_SIZE * 2) + 1)
(0..(BUF_SIZE * 20) + 1)
.map(|_| b"oh what a beautiful morning, oh what a beautiful day!!".to_vec())
.flat_map(|v| v)
.collect()
Expand All @@ -334,7 +343,12 @@ pub mod tests {
fn basic_compress_into() -> Result<()> {
let data = get_data()?;
let mut output = vec![0_u8; data.len()]; // assume compression isn't worse than input len.
let n_bytes = compress_into(data.as_slice(), &mut output, CompressionLevel::Three, true)?;
let n_bytes = compress_into(
data.as_slice(),
&mut output,
CompressionLevel::Three,
Codec::Gzip,
)?;
println!(
"n_bytes: {} - {:?}",
n_bytes,
Expand All @@ -346,7 +360,7 @@ pub mod tests {
#[test]
fn basic_compress() -> Result<()> {
let data = get_data()?;
let output = compress(Cursor::new(data), CompressionLevel::Three, true)?;
let output = compress(Cursor::new(data), CompressionLevel::Three, Codec::Gzip)?;
println!(
"n_bytes: {:?}",
&output[..std::cmp::min(output.len() - 1, 100)]
Expand Down Expand Up @@ -384,7 +398,7 @@ pub mod tests {
fn larger_decompress() -> Result<()> {
/* Decompress data which is larger than BUF_SIZE */
let data = get_data()?;
let compressed = compress(Cursor::new(&data), CompressionLevel::Three, true)?;
let compressed = compress(Cursor::new(&data), CompressionLevel::Three, Codec::Gzip)?;
let decompressed = decompress(Cursor::new(compressed))?;
assert!(same_same(&data, &decompressed));
Ok(())
Expand All @@ -407,7 +421,7 @@ pub mod tests {
#[test]
fn basic_round_trip() -> Result<()> {
let data = b"hello, world!";
let compressed = compress(Cursor::new(&data), CompressionLevel::Three, true)?;
let compressed = compress(Cursor::new(&data), CompressionLevel::Three, Codec::Gzip)?;
let decompressed = decompress(Cursor::new(compressed))?;
assert_eq!(decompressed, data);
Ok(())
Expand All @@ -417,14 +431,15 @@ pub mod tests {
fn basic_round_trip_into() -> Result<()> {
let data = b"hello, world!".to_vec();

let compressed_len = compress(Cursor::new(&data), CompressionLevel::Three, true)?.len();
let compressed_len =
compress(Cursor::new(&data), CompressionLevel::Three, Codec::Gzip)?.len();
let decompressed_len = data.len();

let mut compressed = vec![0; compressed_len];
let mut decompressed = vec![0; decompressed_len];

// compress_into
let n_bytes = compress_into(&data, &mut compressed, CompressionLevel::Three, true)?;
let n_bytes = compress_into(&data, &mut compressed, CompressionLevel::Three, Codec::Gzip)?;
assert_eq!(n_bytes, compressed_len);

// decompress_into
Expand All @@ -440,14 +455,15 @@ pub mod tests {
fn large_round_trip_into() -> Result<()> {
let data = gen_large_data();

let compressed_len = compress(Cursor::new(&data), CompressionLevel::Three, true)?.len();
let compressed_len =
compress(Cursor::new(&data), CompressionLevel::Three, Codec::Gzip)?.len();
let decompressed_len = data.len();

let mut compressed = vec![0; compressed_len];
let mut decompressed = vec![0; decompressed_len];

// compress_into
let n_bytes = compress_into(&data, &mut compressed, CompressionLevel::Three, true)?;
let n_bytes = compress_into(&data, &mut compressed, CompressionLevel::Three, Codec::Gzip)?;
assert!(n_bytes < data.len());

// decompress_into
Expand Down
Loading
Loading