solana_storage_reader/
compression.rs

1use {
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}