extern crate alloc;
use alloc::vec;
use alloc::vec::Vec;
use crate::{Algorithm, Decoder, Encoder, Error, Status};
const SCRATCH: usize = 64 * 1024;
pub fn compress_to_vec<A: Algorithm>(input: &[u8]) -> Result<Vec<u8>, Error> {
compress_to_vec_with::<A>(input, A::EncoderConfig::default())
}
pub fn compress_to_vec_with<A: Algorithm>(
input: &[u8],
config: A::EncoderConfig,
) -> Result<Vec<u8>, Error> {
let mut enc = A::encoder_with(config);
let mut out: Vec<u8> = Vec::with_capacity(input.len());
let mut scratch: Vec<u8> = vec![0u8; SCRATCH];
let mut consumed = 0usize;
while consumed < input.len() {
let (p, status) = enc.encode(&input[consumed..], &mut scratch)?;
out.extend_from_slice(&scratch[..p.written]);
consumed += p.consumed;
match status {
Status::InputEmpty => break,
Status::OutputFull => continue,
Status::StreamEnd => break,
}
}
loop {
let (p, status) = enc.finish(&mut scratch)?;
out.extend_from_slice(&scratch[..p.written]);
if matches!(status, Status::StreamEnd) {
break;
}
if p.written == 0 {
return Err(Error::Corrupt);
}
}
Ok(out)
}
pub fn decompress_to_vec<A: Algorithm>(input: &[u8]) -> Result<Vec<u8>, Error> {
decompress_to_vec_with::<A>(input, A::DecoderConfig::default())
}
pub fn decompress_to_vec_with<A: Algorithm>(
input: &[u8],
config: A::DecoderConfig,
) -> Result<Vec<u8>, Error> {
let mut dec = A::decoder_with(config);
let mut out: Vec<u8> = Vec::with_capacity(input.len().saturating_mul(2));
let mut scratch: Vec<u8> = vec![0u8; SCRATCH];
let mut consumed = 0usize;
while consumed < input.len() {
let (p, status) = dec.decode(&input[consumed..], &mut scratch)?;
out.extend_from_slice(&scratch[..p.written]);
consumed += p.consumed;
match status {
Status::StreamEnd => return Ok(out),
Status::InputEmpty => break,
Status::OutputFull => continue,
}
}
loop {
let (p, status) = dec.finish(&mut scratch)?;
out.extend_from_slice(&scratch[..p.written]);
if matches!(status, Status::StreamEnd) {
break;
}
if p.written == 0 {
return Err(Error::Corrupt);
}
}
Ok(out)
}