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