#[derive(Debug)]
pub enum Compression {
None,
#[cfg(feature = "flate2")]
Zlib,
}
#[derive(Debug)]
pub enum Compress {
None,
#[cfg(feature = "flate2")]
Zlib(flate2::Compress),
}
#[derive(Debug)]
pub enum Decompress {
None,
#[cfg(feature = "flate2")]
Zlib(flate2::Decompress),
}
#[cfg(feature = "flate2")]
impl Compression {
pub fn from_string(s: &str) -> Self {
if s == "zlib" || s == "zlib@openssh.com" {
Compression::Zlib
} else {
Compression::None
}
}
pub fn init_compress(&self, comp: &mut Compress) {
if let Compression::Zlib = *self {
if let Compress::Zlib(ref mut c) = *comp {
c.reset()
} else {
*comp = Compress::Zlib(flate2::Compress::new(flate2::Compression::fast(), true))
}
} else {
*comp = Compress::None
}
}
pub fn init_decompress(&self, comp: &mut Decompress) {
if let Compression::Zlib = *self {
if let Decompress::Zlib(ref mut c) = *comp {
c.reset(true)
} else {
*comp = Decompress::Zlib(flate2::Decompress::new(true))
}
} else {
*comp = Decompress::None
}
}
}
#[cfg(not(feature = "flate2"))]
impl Compression {
pub fn from_string(_: &str) -> Self {
Compression::None
}
pub fn init_compress(&self, _: &mut Compress) {}
pub fn init_decompress(&self, _: &mut Decompress) {}
}
#[cfg(not(feature = "flate2"))]
impl Compress {
pub fn compress<'a>(
&mut self,
input: &'a [u8],
_: &'a mut cryptovec::CryptoVec,
) -> Result<&'a [u8], Error> {
Ok(input)
}
}
#[cfg(not(feature = "flate2"))]
impl Decompress {
pub fn decompress<'a>(
&mut self,
input: &'a [u8],
_: &'a mut cryptovec::CryptoVec,
) -> Result<&'a [u8], Error> {
Ok(input)
}
}
#[cfg(feature = "flate2")]
impl Compress {
pub fn compress<'a>(
&mut self,
input: &'a [u8],
output: &'a mut cryptovec::CryptoVec,
) -> Result<&'a [u8], crate::Error> {
match *self {
Compress::None => Ok(input),
Compress::Zlib(ref mut z) => {
output.clear();
let n_in = z.total_in() as usize;
let n_out = z.total_out() as usize;
output.resize(input.len() + 10);
let flush = flate2::FlushCompress::Partial;
loop {
let n_in_ = z.total_in() as usize - n_in;
let n_out_ = z.total_out() as usize - n_out;
let c = z.compress(&input[n_in_..], &mut output[n_out_..], flush)?;
match c {
flate2::Status::BufError => {
output.resize(output.len() * 2);
}
_ => break,
}
}
let n_out_ = z.total_out() as usize - n_out;
Ok(&output[..n_out_])
}
}
}
}
#[cfg(feature = "flate2")]
impl Decompress {
pub fn decompress<'a>(
&mut self,
input: &'a [u8],
output: &'a mut cryptovec::CryptoVec,
) -> Result<&'a [u8], crate::Error> {
match *self {
Decompress::None => Ok(input),
Decompress::Zlib(ref mut z) => {
output.clear();
let n_in = z.total_in() as usize;
let n_out = z.total_out() as usize;
output.resize(input.len());
let flush = flate2::FlushDecompress::None;
loop {
let n_in_ = z.total_in() as usize - n_in;
let n_out_ = z.total_out() as usize - n_out;
let d = z.decompress(&input[n_in_..], &mut output[n_out_..], flush);
match d? {
flate2::Status::Ok => {
output.resize(output.len() * 2);
}
_ => break,
}
}
let n_out_ = z.total_out() as usize - n_out;
Ok(&output[..n_out_])
}
}
}
}