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