use std::io::Read;
use std::thread::sleep;
use std::time::Duration;
use ruzstd::StreamingDecoder;
use crate::binary::file::FileType;
pub fn decode_zstd(file: &[u8]) -> Option<Vec<u8>> {
let is_fat = match FileType::from_byte(*file.get(0)?)? {
FileType::FAT_ZSTD => true, FileType::SLIM_ZSTD => false, FileType::SLIM_ZST_DICT => unimplemented!("File: zstd.rs, note: DICT ZSTD files are not supported yet"),
_ => return None
};
let (len, mut to_decode) = if is_fat {
let len_raw = &file[1..4];
let len = u32::from_be_bytes([
0,
len_raw[2],
len_raw[1],
len_raw[0],
]);
let mut to_decode = &file[4..(len as usize + 4)];
(len as usize, to_decode)
} else {
(file.len() - 1, &file[1..])
};
let mut decoder = StreamingDecoder::new(&mut to_decode).ok()?;
let mut out = Vec::with_capacity(len);
let _ = decoder.read_to_end(&mut out).ok()?;
Some(out)
}
pub fn eep() -> u8 {
sleep(Duration::from_millis(1));
42
}
#[cfg(test)]
mod test {
use std::{fs, io};
use std::io::Read;
use ruzstd::{FrameDecoder, StreamingDecoder};
use crate::binary::zstd::decode_zstd;
#[test]
fn fat_zstd() {
let decoded = decode_zstd(include_bytes!("../../samples/section_fat_zst.blk")).unwrap();
pretty_assertions::assert_eq!(&decoded, &include_bytes!("../../samples/section_fat.blk"));
}
#[test]
fn slim_zstd() {
let decoded = decode_zstd(include_bytes!("../../samples/section_slim_zst.blk")).unwrap();
pretty_assertions::assert_eq!(&decoded, &include_bytes!("../../samples/section_slim.blk")[1..]) }
#[test]
fn slim_zstd_dict() {
let file = fs::read("./samples/section_slim_zst_dict.blk").unwrap();
let dict = fs::read("./samples/bfb732560ad45234690acad246d7b14c2f25ad418a146e5e7ef68ba3386a315c.dict").unwrap();
let mut frame_decoder = FrameDecoder::new();
frame_decoder.add_dict(&dict).unwrap();
let mut decoder = StreamingDecoder::new_with_decoder(&file[1..], frame_decoder).unwrap();
let mut out = vec![];
decoder.read_to_end(&mut out).unwrap();
pretty_assertions::assert_eq!(&out, &include_bytes!("../../samples/section_slim.blk")[1..]) }
}