2024-05-12 13:14:33 +02:00
|
|
|
#[cfg(feature = "compression")]
|
|
|
|
use std::io::{Read, Write};
|
2024-05-16 21:32:33 +02:00
|
|
|
|
|
|
|
#[cfg(feature = "compression_bzip2")]
|
|
|
|
use bzip2::read::{BzDecoder, BzEncoder};
|
2024-05-16 23:16:05 +02:00
|
|
|
#[cfg(feature = "compression_zlib")]
|
2024-05-16 21:32:33 +02:00
|
|
|
use flate2::{FlushCompress, FlushDecompress, Status};
|
|
|
|
#[cfg(feature = "compression_zstd")]
|
2024-05-11 23:28:08 +02:00
|
|
|
use zstd::{Decoder as ZstdDecoder, Encoder as ZstdEncoder};
|
|
|
|
|
|
|
|
use crate::{CompressionCode, Payload};
|
2024-05-11 23:16:41 +02:00
|
|
|
|
2024-05-11 23:28:08 +02:00
|
|
|
pub(crate) fn into_decompressed(
|
|
|
|
kind: CompressionCode,
|
2024-05-16 23:16:05 +02:00
|
|
|
payload: Payload,
|
2024-05-11 23:28:08 +02:00
|
|
|
) -> Option<Payload> {
|
2024-05-11 23:16:41 +02:00
|
|
|
match kind {
|
2024-05-12 13:11:42 +02:00
|
|
|
CompressionCode::Uncompressed => Some(payload),
|
2024-05-16 21:32:33 +02:00
|
|
|
#[cfg(feature = "compression_zlib")]
|
|
|
|
CompressionCode::Zlib => {
|
|
|
|
let mut decompress = flate2::Decompress::new(true);
|
|
|
|
let mut buffer = [0u8; 10000];
|
|
|
|
|
2024-05-16 23:18:43 +02:00
|
|
|
let status = match decompress.decompress(
|
|
|
|
&payload,
|
|
|
|
&mut buffer,
|
|
|
|
FlushDecompress::Finish,
|
|
|
|
) {
|
2024-05-16 21:32:33 +02:00
|
|
|
Err(_) => return None,
|
|
|
|
Ok(status) => status,
|
|
|
|
};
|
|
|
|
|
|
|
|
match status {
|
|
|
|
Status::Ok => None,
|
|
|
|
Status::BufError => None,
|
2024-05-16 23:18:43 +02:00
|
|
|
Status::StreamEnd => Some(
|
|
|
|
buffer[0..(decompress.total_out() as usize)].to_owned(),
|
|
|
|
),
|
2024-05-11 23:16:41 +02:00
|
|
|
}
|
|
|
|
}
|
2024-05-16 21:32:33 +02:00
|
|
|
#[cfg(feature = "compression_bzip2")]
|
|
|
|
CompressionCode::Bzip2 => {
|
2024-05-11 23:16:41 +02:00
|
|
|
let mut decoder = BzDecoder::new(&*payload);
|
2024-05-11 23:28:08 +02:00
|
|
|
let mut decompressed = vec![];
|
2024-05-11 23:16:41 +02:00
|
|
|
match decoder.read_to_end(&mut decompressed) {
|
|
|
|
Err(_) => None,
|
2024-05-11 23:28:08 +02:00
|
|
|
Ok(_) => Some(decompressed),
|
2024-05-11 23:16:41 +02:00
|
|
|
}
|
|
|
|
}
|
2024-05-16 21:32:33 +02:00
|
|
|
#[cfg(feature = "compression_lzma")]
|
2024-05-17 23:56:20 +02:00
|
|
|
CompressionCode::Lzma => match lzma::decompress(&payload) {
|
|
|
|
Err(_) => None,
|
|
|
|
Ok(decompressed) => Some(decompressed),
|
|
|
|
},
|
2024-05-16 21:32:33 +02:00
|
|
|
#[cfg(feature = "compression_zstd")]
|
|
|
|
CompressionCode::Zstd => {
|
2024-05-11 23:16:41 +02:00
|
|
|
let mut decoder = match ZstdDecoder::new(&*payload) {
|
|
|
|
Err(_) => return None,
|
2024-05-11 23:28:08 +02:00
|
|
|
Ok(value) => value,
|
2024-05-11 23:16:41 +02:00
|
|
|
};
|
2024-05-11 23:28:08 +02:00
|
|
|
let mut decompressed = vec![];
|
2024-05-11 23:16:41 +02:00
|
|
|
match decoder.read_to_end(&mut decompressed) {
|
|
|
|
Err(_) => None,
|
2024-05-11 23:28:08 +02:00
|
|
|
Ok(_) => Some(decompressed),
|
2024-05-11 23:16:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-11 23:28:08 +02:00
|
|
|
pub(crate) fn into_compressed(
|
|
|
|
kind: CompressionCode,
|
|
|
|
payload: Payload,
|
|
|
|
) -> Payload {
|
2024-05-11 23:16:41 +02:00
|
|
|
match kind {
|
2024-05-12 13:11:42 +02:00
|
|
|
CompressionCode::Uncompressed => payload,
|
2024-05-16 21:32:33 +02:00
|
|
|
#[cfg(feature = "compression_zlib")]
|
|
|
|
CompressionCode::Zlib => {
|
2024-05-16 23:18:43 +02:00
|
|
|
let mut compress =
|
|
|
|
flate2::Compress::new(flate2::Compression::fast(), true);
|
2024-05-16 21:32:33 +02:00
|
|
|
let mut buffer = [0u8; 10000];
|
|
|
|
|
2024-05-16 23:18:43 +02:00
|
|
|
match compress
|
|
|
|
.compress(&payload, &mut buffer, FlushCompress::Finish)
|
|
|
|
.expect("compress failed")
|
|
|
|
{
|
2024-05-16 21:32:33 +02:00
|
|
|
Status::Ok => panic!("buffer should be big enough"),
|
|
|
|
Status::BufError => panic!("BufError"),
|
|
|
|
Status::StreamEnd => {}
|
|
|
|
};
|
|
|
|
buffer[..compress.total_out() as usize].to_owned()
|
2024-05-11 23:16:41 +02:00
|
|
|
}
|
2024-05-16 21:32:33 +02:00
|
|
|
#[cfg(feature = "compression_bzip2")]
|
|
|
|
CompressionCode::Bzip2 => {
|
2024-05-11 23:28:08 +02:00
|
|
|
let mut encoder =
|
|
|
|
BzEncoder::new(&*payload, bzip2::Compression::fast());
|
|
|
|
let mut compressed = vec![];
|
2024-05-11 23:16:41 +02:00
|
|
|
match encoder.read_to_end(&mut compressed) {
|
|
|
|
Err(err) => panic!("could not compress payload: {}", err),
|
|
|
|
Ok(_) => compressed,
|
|
|
|
}
|
|
|
|
}
|
2024-05-16 21:32:33 +02:00
|
|
|
#[cfg(feature = "compression_lzma")]
|
2024-05-16 23:18:43 +02:00
|
|
|
CompressionCode::Lzma => lzma::compress(&payload, 6).unwrap(),
|
2024-05-16 21:32:33 +02:00
|
|
|
#[cfg(feature = "compression_zstd")]
|
|
|
|
CompressionCode::Zstd => {
|
2024-05-11 23:28:08 +02:00
|
|
|
let mut encoder =
|
|
|
|
ZstdEncoder::new(vec![], zstd::DEFAULT_COMPRESSION_LEVEL)
|
|
|
|
.expect("could not create encoder");
|
|
|
|
encoder
|
2024-05-15 23:14:38 +02:00
|
|
|
.write_all(&payload)
|
2024-05-11 23:16:41 +02:00
|
|
|
.expect("could not compress payload");
|
2024-05-11 23:28:08 +02:00
|
|
|
encoder.finish().expect("could not finish encoding")
|
2024-05-11 23:16:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|