Skip to main content

compression/
compression_decode.rs

1use 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
15/// Wraps `compression_decode_buffer`.
16pub 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
24/// Wraps `compression_decode_buffer`.
25pub 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
43/// Wraps `compression_decode_buffer`.
44pub 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}