streaming_crypto/core_api/compression/codecs/
auto.rs1use crate::compression::{compute_checksum, types::{CompressionError, Compressor, Decompressor}, verify_checksum};
7
8pub struct AutoCompressor;
9pub struct AutoDecompressor;
10
11impl AutoCompressor {
12 pub fn new() -> Self { Self }
13}
14impl AutoDecompressor {
15 pub fn new() -> Self { Self }
16}
17
18impl Compressor for AutoCompressor {
19 fn compress_chunk(&mut self, input: &[u8], out: &mut Vec<u8>) -> Result<(), CompressionError> {
20 let compressed = input;
21
22 let orig_len = input.len() as u32;
24 out.extend_from_slice(&orig_len.to_le_bytes());
25 out.extend_from_slice(&compressed);
26
27 let checksum = compute_checksum(&input, None);
29 out.extend_from_slice(&checksum.to_le_bytes());
30
31 Ok(())
32 }
33 fn finish(&mut self, _out: &mut Vec<u8>) -> Result<(), CompressionError> {
34 Ok(())
35 }
36}
37
38impl Decompressor for AutoDecompressor {
39 fn decompress_chunk(&mut self, input: &[u8], out: &mut Vec<u8>) -> Result<(), CompressionError> {
40 if input.len() < 8 {
41 return Err(CompressionError::CodecProcessFailed {
42 codec: "auto".into(),
43 msg: "input too short for length+checksum prefix".into(),
44 });
45 }
46
47 let orig_len = u32::from_le_bytes(input[0..4].try_into().unwrap()) as usize;
49
50 let compressed = &input[4..input.len() - 4];
52 let checksum_bytes = &input[input.len() - 4..];
53 let expected_crc = u32::from_le_bytes(checksum_bytes.try_into().unwrap());
54
55 let decompressed = compressed;
56
57 if decompressed.len() != orig_len {
59 return Err(CompressionError::CodecProcessFailed {
60 codec: "auto".into(),
61 msg: format!("decoded size {} != prefix {}", decompressed.len(), orig_len),
62 });
63 }
64
65 let actual_crc = compute_checksum(&decompressed, None);
67 verify_checksum(expected_crc, actual_crc, "auto".into())?;
68
69 out.extend_from_slice(&decompressed);
70 Ok(())
71 }
72}