miniz_oxide/inflate/
output_buffer.rs

1/// A wrapper for the output slice used when decompressing.
2///
3/// Using this rather than `Cursor` lets us implement the writing methods directly on
4/// the buffer and lets us use a usize rather than u64 for the position which helps with
5/// performance on 32-bit systems.
6pub struct OutputBuffer<'a> {
7    slice: &'a mut [u8],
8    position: usize,
9    max: usize,
10}
11
12impl<'a> OutputBuffer<'a> {
13    #[inline]
14    pub fn from_slice_pos_and_max(
15        slice: &'a mut [u8],
16        position: usize,
17        max_count: usize,
18    ) -> OutputBuffer<'a> {
19        let mut max = position.saturating_add(max_count);
20        if max > slice.len() {
21            max = slice.len();
22        }
23        OutputBuffer {
24            slice,
25            position,
26            max,
27        }
28    }
29
30    #[inline(always)]
31    pub const fn position(&self) -> usize {
32        self.position
33    }
34
35    #[inline(always)]
36    pub fn set_position(&mut self, position: usize) {
37        self.position = position;
38    }
39
40    /// Write a byte to the current position and increment
41    ///
42    /// Assumes that there is space.
43    #[inline]
44    pub fn write_byte(&mut self, byte: u8) {
45        self.slice[self.position] = byte;
46        self.position += 1;
47    }
48
49    /// Write a slice to the current position and increment
50    ///
51    /// Assumes that there is space.
52    #[inline]
53    pub fn write_slice(&mut self, data: &[u8]) {
54        let len = data.len();
55        self.slice[self.position..self.position + len].copy_from_slice(data);
56        self.position += data.len();
57    }
58
59    #[inline]
60    pub const fn bytes_left(&self) -> usize {
61        self.max - self.position
62    }
63
64    #[inline(always)]
65    pub const fn get_ref(&self) -> &[u8] {
66        self.slice
67    }
68
69    #[inline(always)]
70    pub fn get_mut(&mut self) -> &mut [u8] {
71        self.slice
72    }
73}
74
75/// A wrapper for the output slice used when decompressing.
76///
77/// Using this rather than `Cursor` lets us implement the writing methods directly on
78/// the buffer and lets us use a usize rather than u64 for the position which helps with
79/// performance on 32-bit systems.
80#[derive(Copy, Clone)]
81pub struct InputWrapper<'a> {
82    slice: &'a [u8],
83}
84
85impl<'a> InputWrapper<'a> {
86    #[inline(always)]
87    pub const fn as_slice(&self) -> &[u8] {
88        self.slice
89    }
90
91    #[inline(always)]
92    pub const fn from_slice(slice: &'a [u8]) -> InputWrapper<'a> {
93        InputWrapper { slice }
94    }
95
96    #[inline(always)]
97    pub fn advance(&mut self, steps: usize) {
98        self.slice = &self.slice[steps..];
99    }
100
101    #[inline]
102    pub fn read_byte(&mut self) -> Option<u8> {
103        self.slice.first().map(|n| {
104            self.advance(1);
105            *n
106        })
107    }
108
109    #[inline]
110    #[cfg(target_pointer_width = "64")]
111    pub fn read_u32_le(&mut self) -> u32 {
112        let ret = {
113            let four_bytes: [u8; 4] = self.slice[..4].try_into().unwrap_or_default();
114            u32::from_le_bytes(four_bytes)
115        };
116        self.advance(4);
117        ret
118    }
119
120    #[inline(always)]
121    pub const fn bytes_left(&self) -> usize {
122        self.slice.len()
123    }
124}