solana_storage_reader/
compression.rs1use {
2 enum_iterator::{Sequence},
3 std::io::{self, BufReader, Read},
4};
5
6#[derive(Debug, Serialize, Deserialize, Sequence)]
7pub enum CompressionMethod {
8 NoCompression,
9 Bzip2,
10 Gzip,
11 Zstd,
12}
13
14fn decompress_reader<'a, R: Read + 'a>(
15 method: CompressionMethod,
16 stream: R,
17) -> Result<Box<dyn Read + 'a>, io::Error> {
18 let buf_reader = BufReader::new(stream);
19 let decompress_reader: Box<dyn Read> = match method {
20 CompressionMethod::Bzip2 => Box::new(bzip2::bufread::BzDecoder::new(buf_reader)),
21 CompressionMethod::Gzip => Box::new(flate2::read::GzDecoder::new(buf_reader)),
22 CompressionMethod::Zstd => Box::new(zstd::stream::read::Decoder::new(buf_reader)?),
23 CompressionMethod::NoCompression => Box::new(buf_reader),
24 };
25 Ok(decompress_reader)
26}
27
28pub fn decompress(data: &[u8]) -> Result<Vec<u8>, io::Error> {
29 let method_size = bincode::serialized_size(&CompressionMethod::NoCompression).unwrap();
30 if (data.len() as u64) < method_size {
31 return Err(io::Error::new(
32 io::ErrorKind::Other,
33 format!("data len too small: {}", data.len()),
34 ));
35 }
36 let method = bincode::deserialize(&data[..method_size as usize]).map_err(|err| {
37 io::Error::new(
38 io::ErrorKind::Other,
39 format!("method deserialize failed: {err}"),
40 )
41 })?;
42
43 let mut reader = decompress_reader(method, &data[method_size as usize..])?;
44 let mut uncompressed_data = vec![];
45 reader.read_to_end(&mut uncompressed_data)?;
46 Ok(uncompressed_data)
47}