1 #[cfg(feature="std")]
2 use std::io::{self, Error, ErrorKind, Read};
3 #[cfg(feature="std")]
4 pub use alloc_stdlib::StandardAlloc;
5 #[cfg(all(feature="unsafe",feature="std"))]
6 pub use alloc_stdlib::HeapAllocUninitialized;
7 pub use huffman::{HuffmanCode, HuffmanTreeGroup};
8 pub use state::BrotliState;
9 // use io_wrappers::write_all;
10 pub use io_wrappers::{CustomRead, CustomWrite};
11 #[cfg(feature="std")]
12 pub use io_wrappers::{IntoIoReader, IoReaderWrapper, IoWriterWrapper};
13 pub use super::decode::{BrotliDecompressStream, BrotliResult};
14 pub use alloc::{AllocatedStackMemory, Allocator, SliceWrapper, SliceWrapperMut, StackAllocator};
15 
16 #[cfg(feature="std")]
17 pub struct DecompressorCustomAlloc<R: Read,
18      BufferType : SliceWrapperMut<u8>,
19      AllocU8 : Allocator<u8>,
20      AllocU32 : Allocator<u32>,
21      AllocHC : Allocator<HuffmanCode> >(DecompressorCustomIo<io::Error,
22                                                              IntoIoReader<R>,
23                                                              BufferType,
24                                                              AllocU8, AllocU32, AllocHC>);
25 
26 
27 #[cfg(feature="std")]
28 impl<R: Read,
29      BufferType : SliceWrapperMut<u8>,
30      AllocU8,
31      AllocU32,
32      AllocHC> DecompressorCustomAlloc<R, BufferType, AllocU8, AllocU32, AllocHC>
33  where AllocU8 : Allocator<u8>, AllocU32 : Allocator<u32>, AllocHC : Allocator<HuffmanCode>
34     {
35 
new(r: R, buffer : BufferType, alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC) -> Self36     pub fn new(r: R, buffer : BufferType,
37                alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC) -> Self {
38         DecompressorCustomAlloc::<R, BufferType, AllocU8, AllocU32, AllocHC>(
39           DecompressorCustomIo::<Error,
40                                  IntoIoReader<R>,
41                                  BufferType,
42                                  AllocU8, AllocU32, AllocHC>::new(IntoIoReader::<R>(r),
43                                                                   buffer,
44                                                                   alloc_u8, alloc_u32, alloc_hc,
45                                                                   Error::new(ErrorKind::InvalidData,
46                                                                              "Invalid Data")))
47     }
48 
new_with_custom_dictionary(r: R, buffer : BufferType, alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC, dict: AllocU8::AllocatedMemory) -> Self49     pub fn new_with_custom_dictionary(r: R, buffer : BufferType,
50                alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC,
51                dict: AllocU8::AllocatedMemory) -> Self {
52         DecompressorCustomAlloc::<R, BufferType, AllocU8, AllocU32, AllocHC>(
53           DecompressorCustomIo::<Error,
54                                  IntoIoReader<R>,
55                                  BufferType,
56                                  AllocU8, AllocU32, AllocHC>::new_with_custom_dictionary(IntoIoReader::<R>(r),
57                                                                                    buffer,
58                                                                                    alloc_u8, alloc_u32, alloc_hc,
59                                                                                    dict,
60                                                                                    Error::new(ErrorKind::InvalidData,
61                                                                                               "Invalid Data")))
62     }
63 
get_ref(&self) -> &R64     pub fn get_ref(&self) -> &R {
65       &self.0.get_ref().0
66     }
get_mut(&mut self) -> &mut R67     pub fn get_mut(&mut self) -> &mut R {
68       &mut self.0.get_mut().0
69     }
into_inner(self) -> R70     pub fn into_inner(self) -> R {
71       self.0.into_inner().0
72     }
73 }
74 #[cfg(feature="std")]
75 impl<R: Read,
76      BufferType : SliceWrapperMut<u8>,
77      AllocU8 : Allocator<u8>,
78      AllocU32 : Allocator<u32>,
79      AllocHC : Allocator<HuffmanCode> > Read for DecompressorCustomAlloc<R,
80                                                                          BufferType,
81                                                                          AllocU8,
82                                                                          AllocU32,
83                                                                          AllocHC> {
read(&mut self, buf: &mut [u8]) -> Result<usize, Error>84   	fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
85        self.0.read(buf)
86     }
87 }
88 
89 
90 #[cfg(not(any(feature="unsafe", not(feature="std"))))]
91 pub struct Decompressor<R: Read>(DecompressorCustomAlloc<R,
92                                                          <StandardAlloc
93                                                           as Allocator<u8>>::AllocatedMemory,
94                                                          StandardAlloc,
95                                                          StandardAlloc,
96                                                          StandardAlloc>);
97 
98 
99 #[cfg(not(any(feature="unsafe", not(feature="std"))))]
100 impl<R: Read> Decompressor<R> {
new(r: R, buffer_size: usize) -> Self101   pub fn new(r: R, buffer_size: usize) -> Self {
102      let dict = <StandardAlloc as Allocator<u8>>::AllocatedMemory::default();
103      Self::new_with_custom_dict(r, buffer_size, dict)
104   }
new_with_custom_dict(r: R, buffer_size: usize, dict: <StandardAlloc as Allocator<u8>>::AllocatedMemory) -> Self105   pub fn new_with_custom_dict(r: R, buffer_size: usize, dict: <StandardAlloc as Allocator<u8>>::AllocatedMemory) -> Self {
106     let mut alloc = StandardAlloc::default();
107     let buffer = <StandardAlloc as Allocator<u8>>::alloc_cell(&mut alloc, if buffer_size == 0 {4096} else {buffer_size});
108     Decompressor::<R>(DecompressorCustomAlloc::<R,
109                                                 <StandardAlloc
110                                                  as Allocator<u8>>::AllocatedMemory,
111                                                 StandardAlloc,
112                                                 StandardAlloc,
113                                                 StandardAlloc>::new_with_custom_dictionary(r,
114                                                                               buffer,
115                                                                               alloc,
116                                                                               StandardAlloc::default(),
117                                                                               StandardAlloc::default(),
118                                                                               dict))
119   }
120 
get_ref(&self) -> &R121   pub fn get_ref(&self) -> &R {
122     &self.0.get_ref()
123   }
get_mut(&mut self) -> &mut R124   pub fn get_mut(&mut self) -> &mut R {
125     &mut ((self.0).0).get_mut().0
126   }
into_inner(self) -> R127   pub fn into_inner(self) -> R {
128     self.0.into_inner()
129   }
130 }
131 
132 
133 #[cfg(all(feature="unsafe", feature="std"))]
134 pub struct Decompressor<R: Read>(DecompressorCustomAlloc<R,
135                                                          <HeapAllocUninitialized<u8>
136                                                           as Allocator<u8>>::AllocatedMemory,
137                                                          HeapAllocUninitialized<u8>,
138                                                          HeapAllocUninitialized<u32>,
139                                                          HeapAllocUninitialized<HuffmanCode> >);
140 
141 
142 #[cfg(all(feature="unsafe", feature="std"))]
143 impl<R: Read> Decompressor<R> {
new(r: R, buffer_size: usize) -> Self144   pub fn new(r: R, buffer_size: usize) -> Self {
145      let dict = <HeapAllocUninitialized<u8> as Allocator<u8>>::AllocatedMemory::default();
146      Self::new_with_custom_dictionary(r, buffer_size, dict)
147   }
new_with_custom_dictionary(r: R, buffer_size: usize, dict: <HeapAllocUninitialized<u8> as Allocator<u8>>::AllocatedMemory) -> Self148   pub fn new_with_custom_dictionary(r: R, buffer_size: usize, dict: <HeapAllocUninitialized<u8>
149                                                  as Allocator<u8>>::AllocatedMemory) -> Self {
150     let mut alloc_u8 = unsafe { HeapAllocUninitialized::<u8>::new() };
151     let buffer = alloc_u8.alloc_cell(if buffer_size == 0 {4096} else {buffer_size});
152     let alloc_u32 = unsafe { HeapAllocUninitialized::<u32>::new() };
153     let alloc_hc = unsafe { HeapAllocUninitialized::<HuffmanCode>::new() };
154     Decompressor::<R>(DecompressorCustomAlloc::<R,
155                                                 <HeapAllocUninitialized<u8>
156                                                  as Allocator<u8>>::AllocatedMemory,
157                                                 HeapAllocUninitialized<u8>,
158                                                 HeapAllocUninitialized<u32>,
159                                                 HeapAllocUninitialized<HuffmanCode> >
160       ::new_with_custom_dictionary(r, buffer, alloc_u8, alloc_u32, alloc_hc, dict))
161   }
162 
get_ref(&self) -> &R163   pub fn get_ref(&self) -> &R {
164     self.0.get_ref()
165   }
get_mut(&mut self) -> &mut R166   pub fn get_mut(&mut self) -> &mut R {
167     &mut (self.0).0.get_mut().0
168   }
into_inner(self) -> R169   pub fn into_inner(self) -> R {
170     self.0.into_inner()
171   }
172 }
173 
174 
175 #[cfg(feature="std")]
176 impl<R: Read> Read for Decompressor<R> {
read(&mut self, buf: &mut [u8]) -> Result<usize, Error>177   fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
178     self.0.read(buf)
179   }
180 }
181 
182 pub struct DecompressorCustomIo<ErrType,
183                                 R: CustomRead<ErrType>,
184                                 BufferType: SliceWrapperMut<u8>,
185                                 AllocU8: Allocator<u8>,
186                                 AllocU32: Allocator<u32>,
187                                 AllocHC: Allocator<HuffmanCode>>
188 {
189   input_buffer: BufferType,
190   total_out: usize,
191   input_offset: usize,
192   input_len: usize,
193   input: R,
194   error_if_invalid_data: Option<ErrType>,
195   state: BrotliState<AllocU8, AllocU32, AllocHC>,
196 }
197 
198 impl<ErrType,
199      R: CustomRead<ErrType>,
200      BufferType : SliceWrapperMut<u8>,
201      AllocU8,
202      AllocU32,
203      AllocHC> DecompressorCustomIo<ErrType, R, BufferType, AllocU8, AllocU32, AllocHC>
204  where AllocU8 : Allocator<u8>, AllocU32 : Allocator<u32>, AllocHC : Allocator<HuffmanCode>
205 {
206 
new(r: R, buffer : BufferType, alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC, invalid_data_error_type : ErrType) -> Self207     pub fn new(r: R, buffer : BufferType,
208                alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC,
209                invalid_data_error_type : ErrType) -> Self {
210      let dict = AllocU8::AllocatedMemory::default();
211      Self::new_with_custom_dictionary(r, buffer, alloc_u8, alloc_u32, alloc_hc, dict, invalid_data_error_type)
212     }
new_with_custom_dictionary(r: R, buffer : BufferType, alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC, dict: AllocU8::AllocatedMemory, invalid_data_error_type : ErrType) -> Self213     pub fn new_with_custom_dictionary(r: R, buffer : BufferType,
214                alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC,
215                dict: AllocU8::AllocatedMemory,
216                invalid_data_error_type : ErrType) -> Self {
217         DecompressorCustomIo::<ErrType, R, BufferType, AllocU8, AllocU32, AllocHC>{
218             input_buffer : buffer,
219             total_out : 0,
220             input_offset : 0,
221             input_len : 0,
222             input: r,
223             state : BrotliState::new_with_custom_dictionary(alloc_u8,
224                                      alloc_u32,
225                                      alloc_hc,
226                                      dict),
227             error_if_invalid_data : Some(invalid_data_error_type),
228         }
229     }
230 
get_ref(&self) -> &R231     pub fn get_ref(&self) -> &R {
232       &self.input
233     }
get_mut(&mut self) -> &mut R234     pub fn get_mut(&mut self) -> &mut R {
235       &mut self.input
236     }
into_inner(self) -> R237     pub fn into_inner(self) -> R {
238       match self {
239         DecompressorCustomIo {
240           input_buffer: _ib,
241           total_out: _to,
242           state: _state,
243           input_offset: _io,
244           input_len: _il,
245           error_if_invalid_data:_eiid,
246           input,
247         } =>{
248           input
249         }
250     }
251     }
252 
copy_to_front(&mut self)253     pub fn copy_to_front(&mut self) {
254         let avail_in = self.input_len - self.input_offset;
255         if self.input_offset == self.input_buffer.slice_mut().len() {
256             self.input_offset = 0;
257             self.input_len = 0;
258         } else if self.input_offset + 256 > self.input_buffer.slice_mut().len() && avail_in < self.input_offset {
259             let (first, second) = self.input_buffer.slice_mut().split_at_mut(self.input_offset);
260             self.input_len -= self.input_offset;
261             first[0..avail_in].clone_from_slice(&second[0..avail_in]);
262             self.input_offset = 0;
263         }
264     }
265 }
266 
267 impl<ErrType,
268      R: CustomRead<ErrType>,
269      BufferType : SliceWrapperMut<u8>,
270      AllocU8 : Allocator<u8>,
271      AllocU32 : Allocator<u32>,
272      AllocHC : Allocator<HuffmanCode> > CustomRead<ErrType> for DecompressorCustomIo<ErrType,
273                                                                                      R,
274                                                                                      BufferType,
275                                                                                      AllocU8,
276                                                                                      AllocU32,
277                                                                                      AllocHC> {
read(&mut self, buf: &mut [u8]) -> Result<usize, ErrType >278   fn read(&mut self, buf: &mut [u8]) -> Result<usize, ErrType > {
279     let mut output_offset : usize = 0;
280     let mut avail_out = buf.len() - output_offset;
281     let mut avail_in = self.input_len - self.input_offset;
282     while avail_out == buf.len() {
283       match BrotliDecompressStream(&mut avail_in,
284                                    &mut self.input_offset,
285                                    &self.input_buffer.slice_mut()[..],
286                                    &mut avail_out,
287                                    &mut output_offset,
288                                    buf,
289                                    &mut self.total_out,
290                                    &mut self.state) {
291         BrotliResult::NeedsMoreInput => {
292           self.copy_to_front();
293           if output_offset != 0 {
294             // The decompressor successfully decoded some bytes, but still requires more
295             // we do not wish to risk self.input.read returning an error, so instead we
296             // opt to return what we have and do not invoke the read trait method
297             return Ok(output_offset);
298           }
299           match self.input.read(&mut self.input_buffer.slice_mut()[self.input_len..]) {
300             Err(e) => {
301               return Err(e);
302             },
303             Ok(size) => if size == 0 {
304               return Err(self.error_if_invalid_data.take().unwrap());
305             }else {
306               self.input_len += size;
307               avail_in = self.input_len - self.input_offset;
308             },
309           }
310         },
311         BrotliResult::NeedsMoreOutput => {
312           break;
313         },
314         BrotliResult::ResultSuccess => return Ok(output_offset),
315         BrotliResult::ResultFailure => return Err(self.error_if_invalid_data.take().unwrap()),
316       }
317     }
318     Ok(output_offset)
319   }
320 }
321 
322