compression/
compression_decode.rs1use crate::{ffi, Algorithm, CompressionError, Decoder, Result};
2
3fn decode_len(dst: &mut [u8], src: &[u8], algorithm: Algorithm) -> usize {
4 unsafe {
5 ffi::compression_decode::compression_rs_compression_decode_buffer(
6 dst.as_mut_ptr(),
7 dst.len(),
8 src.as_ptr(),
9 src.len(),
10 algorithm.as_raw(),
11 )
12 }
13}
14
15pub fn compression_decode_scratch_buffer_size(algorithm: Algorithm) -> usize {
17 unsafe {
18 ffi::compression_decode::compression_rs_compression_decode_scratch_buffer_size(
19 algorithm.as_raw(),
20 )
21 }
22}
23
24pub fn compression_decode_buffer(
26 dst: &mut [u8],
27 src: &[u8],
28 algorithm: Algorithm,
29) -> Result<usize> {
30 let written = decode_len(dst, src, algorithm);
31 if src.is_empty() || written > 0 {
32 Ok(written)
33 } else {
34 Err(CompressionError::BufferOperationFailed {
35 operation: "compression_decode_buffer",
36 algorithm,
37 input_len: src.len(),
38 output_capacity: dst.len(),
39 })
40 }
41}
42
43pub fn decompress(input: &[u8], algorithm: Algorithm) -> Result<Vec<u8>> {
45 if input.is_empty() {
46 return Ok(Vec::new());
47 }
48
49 if algorithm.supports_streams() {
50 let mut decoder = Decoder::new(algorithm)?;
51 let mut output = decoder.process(input)?;
52 output.extend(decoder.finish()?);
53 return Ok(output);
54 }
55
56 let mut capacity = 4 * 1024;
57 let max_capacity = 64 * 1024 * 1024;
58 loop {
59 let mut output = vec![0_u8; capacity];
60 let written = decode_len(&mut output, input, algorithm);
61 if written == 0 {
62 return Err(CompressionError::BufferOperationFailed {
63 operation: "compression_decode_buffer",
64 algorithm,
65 input_len: input.len(),
66 output_capacity: capacity,
67 });
68 }
69 if written < capacity {
70 output.truncate(written);
71 return Ok(output);
72 }
73 if capacity >= max_capacity {
74 return Err(CompressionError::BufferOperationFailed {
75 operation: "compression_decode_buffer",
76 algorithm,
77 input_len: input.len(),
78 output_capacity: capacity,
79 });
80 }
81 capacity = capacity.saturating_mul(2).min(max_capacity);
82 }
83}