1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
use crate::decompress::lzf::LzfReader; use crate::decompress::zst::ZstReader; use crate::error::{CliResult, Error}; use crate::util::preview::Preview; use byteorder::{BigEndian, ReadBytesExt}; use flate2::read::GzDecoder; use lz_fear::LZ4FrameReader; use std::io; use std::io::{BufReader, Read}; static GZ: &str = ".gz"; static LZ4: &str = ".lz4"; static LZF: &str = ".lzf"; static ZST: &str = ".zst"; pub enum DecompressionFormat { GZ, LZ4, LZF, ZST, } pub fn is_compressed_using_format(format: &str) -> Option<(DecompressionFormat, String)> { if format.ends_with(GZ) { return Some(( DecompressionFormat::GZ, format[..(format.len() - GZ.len())].to_owned(), )); } if format.ends_with(LZ4) { return Some(( DecompressionFormat::LZ4, format[..(format.len() - LZ4.len())].to_owned(), )); } if format.ends_with(LZF) { return Some(( DecompressionFormat::LZF, format[..(format.len() - LZF.len())].to_owned(), )); } if format.ends_with(ZST) { return Some(( DecompressionFormat::ZST, format[..(format.len() - ZST.len())].to_owned(), )); } None } pub fn is_compressed_using_previewer(previewer: &dyn Preview) -> Option<DecompressionFormat> { let buf = previewer.get_buf(); let mut reader = BufReader::new(buf.as_ref()); let first_four_bytes_big_endian = reader.read_u32::<BigEndian>(); if let Ok(header32be) = first_four_bytes_big_endian { let header24be = header32be & 0xFFFFFF00; if header24be == 0x1F8B0800 { return Some(DecompressionFormat::GZ); } if header32be == 0x04224D18 { return Some(DecompressionFormat::LZ4); } if header24be == 0x5A560100 || header24be == 0x5A560000 { return Some(DecompressionFormat::LZF); } if header32be == 0x28B52FFD { return Some(DecompressionFormat::ZST); } } None } pub fn decompress( decompression_format: DecompressionFormat, reader: Box<dyn Read>, ) -> CliResult<Box<dyn Read>> { match decompression_format { DecompressionFormat::GZ => decompress_gz(reader), DecompressionFormat::LZ4 => decompress_lz4(reader), DecompressionFormat::LZF => decompress_lzf(reader), DecompressionFormat::ZST => decompress_zst(reader), } } pub fn decompress_gz(reader: Box<dyn Read>) -> CliResult<Box<dyn Read>> { let decoder = GzDecoder::new(reader); Ok(Box::new(decoder)) } pub fn decompress_lz4(reader: Box<dyn Read>) -> CliResult<Box<dyn Read>> { let frame_reader = match LZ4FrameReader::new(reader) { Ok(frame_reader) => frame_reader, Err(e) => { return CliResult::Err(Error::Io(io::Error::new(io::ErrorKind::Other, e))); } }; Ok(Box::new(frame_reader.into_read())) } pub fn decompress_lzf(reader: Box<dyn Read>) -> CliResult<Box<dyn Read>> { let decoder = LzfReader::new(reader); Ok(Box::new(decoder)) } pub fn decompress_zst(reader: Box<dyn Read>) -> CliResult<Box<dyn Read>> { let decoder = ZstReader::new(reader)?; Ok(Box::new(decoder)) }