Coverage Report

Created: 2026-10-28 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-decompressor-6.2.0/src/reader.rs
Line
Count
Source
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::HeapAlloc;
7
pub use huffman::{HuffmanCode, HuffmanTreeGroup};
8
pub use state::BrotliState;
9
use state::BrotliDecoderParameter;
10
// use io_wrappers::write_all;
11
pub use io_wrappers::{CustomRead, CustomWrite};
12
#[cfg(feature="std")]
13
pub use io_wrappers::{IntoIoReader, IoReaderWrapper, IoWriterWrapper};
14
pub use super::decode::{BrotliDecompressStream, BrotliResult};
15
pub use alloc::{AllocatedStackMemory, Allocator, SliceWrapper, SliceWrapperMut, StackAllocator};
16
17
#[cfg(feature="std")]
18
pub struct DecompressorCustomAlloc<R: Read,
19
     BufferType : SliceWrapperMut<u8>,
20
     AllocU8 : Allocator<u8>,
21
     AllocU32 : Allocator<u32>,
22
     AllocHC : Allocator<HuffmanCode> >(DecompressorCustomIo<io::Error,
23
                                                             IntoIoReader<R>,
24
                                                             BufferType,
25
                                                             AllocU8, AllocU32, AllocHC>);
26
27
28
#[cfg(feature="std")]
29
impl<R: Read,
30
     BufferType : SliceWrapperMut<u8>,
31
     AllocU8,
32
     AllocU32,
33
     AllocHC> DecompressorCustomAlloc<R, BufferType, AllocU8, AllocU32, AllocHC>
34
 where AllocU8 : Allocator<u8>, AllocU32 : Allocator<u32>, AllocHC : Allocator<HuffmanCode>
35
    {
36
37
0
    pub fn new(r: R, buffer : BufferType,
38
0
               alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC) -> Self {
39
0
        DecompressorCustomAlloc::<R, BufferType, AllocU8, AllocU32, AllocHC>(
40
0
          DecompressorCustomIo::<Error,
41
0
                                 IntoIoReader<R>,
42
0
                                 BufferType,
43
0
                                 AllocU8, AllocU32, AllocHC>::new(IntoIoReader::<R>(r),
44
0
                                                                  buffer,
45
0
                                                                  alloc_u8, alloc_u32, alloc_hc,
46
0
                                                                  Error::new(ErrorKind::InvalidData,
47
0
                                                                             "Invalid Data")))
48
0
    }
49
50
12.1k
    pub fn new_with_custom_dictionary(r: R, buffer : BufferType,
51
12.1k
               alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC,
52
12.1k
               dict: AllocU8::AllocatedMemory) -> Self {
53
12.1k
        DecompressorCustomAlloc::<R, BufferType, AllocU8, AllocU32, AllocHC>(
54
12.1k
          DecompressorCustomIo::<Error,
55
12.1k
                                 IntoIoReader<R>,
56
12.1k
                                 BufferType,
57
12.1k
                                 AllocU8, AllocU32, AllocHC>::new_with_custom_dictionary(IntoIoReader::<R>(r),
58
12.1k
                                                                                   buffer,
59
12.1k
                                                                                   alloc_u8, alloc_u32, alloc_hc,
60
12.1k
                                                                                   dict,
61
12.1k
                                                                                   Error::new(ErrorKind::InvalidData,
62
12.1k
                                                                                              "Invalid Data")))
63
12.1k
    }
<brotli_decompressor::reader::DecompressorCustomAlloc<&[u8], alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc>>::new_with_custom_dictionary
Line
Count
Source
50
12.1k
    pub fn new_with_custom_dictionary(r: R, buffer : BufferType,
51
12.1k
               alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC,
52
12.1k
               dict: AllocU8::AllocatedMemory) -> Self {
53
12.1k
        DecompressorCustomAlloc::<R, BufferType, AllocU8, AllocU32, AllocHC>(
54
12.1k
          DecompressorCustomIo::<Error,
55
12.1k
                                 IntoIoReader<R>,
56
12.1k
                                 BufferType,
57
12.1k
                                 AllocU8, AllocU32, AllocHC>::new_with_custom_dictionary(IntoIoReader::<R>(r),
58
12.1k
                                                                                   buffer,
59
12.1k
                                                                                   alloc_u8, alloc_u32, alloc_hc,
60
12.1k
                                                                                   dict,
61
12.1k
                                                                                   Error::new(ErrorKind::InvalidData,
62
12.1k
                                                                                              "Invalid Data")))
63
12.1k
    }
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomAlloc<_, _, _, _, _>>::new_with_custom_dictionary
64
65
0
    pub fn attach_dictionary(&mut self, dict: AllocU8::AllocatedMemory) -> bool {
66
0
      self.0.attach_dictionary(dict)
67
0
    }
68
0
    pub fn attach_serialized_dictionary(&mut self, dict: AllocU8::AllocatedMemory) -> bool {
69
0
      self.0.attach_serialized_dictionary(dict)
70
0
    }
71
0
    pub fn set_parameter(&mut self, param: BrotliDecoderParameter, value: u32) -> bool {
72
0
      self.0.set_parameter(param, value)
73
0
    }
74
0
    pub fn set_initial_ring_buffer_size(&mut self, size: u32) -> bool {
75
0
      self.0.set_initial_ring_buffer_size(size)
76
0
    }
77
78
0
    pub fn get_ref(&self) -> &R {
79
0
      &self.0.get_ref().0
80
0
    }
81
0
    pub fn get_mut(&mut self) -> &mut R {
82
0
      &mut self.0.get_mut().0
83
0
    }
84
0
    pub fn into_inner(self) -> R {
85
0
      self.0.into_inner().0
86
0
    }
87
}
88
#[cfg(feature="std")]
89
impl<R: Read,
90
     BufferType : SliceWrapperMut<u8>,
91
     AllocU8 : Allocator<u8>,
92
     AllocU32 : Allocator<u32>,
93
     AllocHC : Allocator<HuffmanCode> > Read for DecompressorCustomAlloc<R,
94
                                                                         BufferType,
95
                                                                         AllocU8,
96
                                                                         AllocU32,
97
                                                                         AllocHC> {
98
1.82M
    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
99
1.82M
       self.0.read(buf)
100
1.82M
    }
<brotli_decompressor::reader::DecompressorCustomAlloc<&[u8], alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as std::io::Read>::read
Line
Count
Source
98
1.82M
    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
99
1.82M
       self.0.read(buf)
100
1.82M
    }
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomAlloc<_, _, _, _, _> as std::io::Read>::read
101
}
102
103
104
#[cfg(not(any(feature="unsafe", not(feature="std"))))]
105
pub struct Decompressor<R: Read>(DecompressorCustomAlloc<R,
106
                                                         <StandardAlloc
107
                                                          as Allocator<u8>>::AllocatedMemory,
108
                                                         StandardAlloc,
109
                                                         StandardAlloc,
110
                                                         StandardAlloc>);
111
112
113
#[cfg(not(any(feature="unsafe", not(feature="std"))))]
114
impl<R: Read> Decompressor<R> {
115
12.1k
  pub fn new(r: R, buffer_size: usize) -> Self {
116
12.1k
     let dict = <StandardAlloc as Allocator<u8>>::AllocatedMemory::default();
117
12.1k
     Self::new_with_custom_dict(r, buffer_size, dict)
118
12.1k
  }
<brotli_decompressor::reader::Decompressor<&[u8]>>::new
Line
Count
Source
115
12.1k
  pub fn new(r: R, buffer_size: usize) -> Self {
116
12.1k
     let dict = <StandardAlloc as Allocator<u8>>::AllocatedMemory::default();
117
12.1k
     Self::new_with_custom_dict(r, buffer_size, dict)
118
12.1k
  }
Unexecuted instantiation: <brotli_decompressor::reader::Decompressor<_>>::new
119
12.1k
  pub fn new_with_custom_dict(r: R, buffer_size: usize, dict: <StandardAlloc as Allocator<u8>>::AllocatedMemory) -> Self {
120
12.1k
    let mut alloc = StandardAlloc::default();
121
12.1k
    let buffer = <StandardAlloc as Allocator<u8>>::alloc_cell(&mut alloc, if buffer_size == 0 {4096} else {buffer_size});
122
12.1k
    Decompressor::<R>(DecompressorCustomAlloc::<R,
123
12.1k
                                                <StandardAlloc
124
12.1k
                                                 as Allocator<u8>>::AllocatedMemory,
125
12.1k
                                                StandardAlloc,
126
12.1k
                                                StandardAlloc,
127
12.1k
                                                StandardAlloc>::new_with_custom_dictionary(r,
128
12.1k
                                                                              buffer,
129
12.1k
                                                                              alloc,
130
12.1k
                                                                              StandardAlloc::default(),
131
12.1k
                                                                              StandardAlloc::default(),
132
12.1k
                                                                              dict))
133
12.1k
  }
<brotli_decompressor::reader::Decompressor<&[u8]>>::new_with_custom_dict
Line
Count
Source
119
12.1k
  pub fn new_with_custom_dict(r: R, buffer_size: usize, dict: <StandardAlloc as Allocator<u8>>::AllocatedMemory) -> Self {
120
12.1k
    let mut alloc = StandardAlloc::default();
121
12.1k
    let buffer = <StandardAlloc as Allocator<u8>>::alloc_cell(&mut alloc, if buffer_size == 0 {4096} else {buffer_size});
122
12.1k
    Decompressor::<R>(DecompressorCustomAlloc::<R,
123
12.1k
                                                <StandardAlloc
124
12.1k
                                                 as Allocator<u8>>::AllocatedMemory,
125
12.1k
                                                StandardAlloc,
126
12.1k
                                                StandardAlloc,
127
12.1k
                                                StandardAlloc>::new_with_custom_dictionary(r,
128
12.1k
                                                                              buffer,
129
12.1k
                                                                              alloc,
130
12.1k
                                                                              StandardAlloc::default(),
131
12.1k
                                                                              StandardAlloc::default(),
132
12.1k
                                                                              dict))
133
12.1k
  }
Unexecuted instantiation: <brotli_decompressor::reader::Decompressor<_>>::new_with_custom_dict
134
135
  // Attaches an additional raw LZ77 prefix dictionary; only allowed before
136
  // the first read. Returns false if the dictionary could not be attached.
137
0
  pub fn attach_dictionary(&mut self, dict: <StandardAlloc as Allocator<u8>>::AllocatedMemory) -> bool {
138
0
    self.0.attach_dictionary(dict)
139
0
  }
140
141
  // Attaches a serialized shared dictionary (magic 0x91 0x00, may contain an
142
  // LZ77 prefix dictionary and custom word/transform lists); only allowed
143
  // before the first read.
144
0
  pub fn attach_serialized_dictionary(&mut self, dict: <StandardAlloc as Allocator<u8>>::AllocatedMemory) -> bool {
145
0
    self.0.attach_serialized_dictionary(dict)
146
0
  }
147
148
  // Sets a decoder parameter (see BrotliState::set_parameter); only allowed
149
  // before the first read.
150
0
  pub fn set_parameter(&mut self, param: BrotliDecoderParameter, value: u32) -> bool {
151
0
    self.0.set_parameter(param, value)
152
0
  }
153
154
  // Sets the smallest ring buffer the decoder starts from (see
155
  // BrotliState::set_initial_ring_buffer_size); only allowed before the first
156
  // read.
157
0
  pub fn set_initial_ring_buffer_size(&mut self, size: u32) -> bool {
158
0
    self.0.set_initial_ring_buffer_size(size)
159
0
  }
160
161
0
  pub fn get_ref(&self) -> &R {
162
0
    &self.0.get_ref()
163
0
  }
164
0
  pub fn get_mut(&mut self) -> &mut R {
165
0
    &mut ((self.0).0).get_mut().0
166
0
  }
167
0
  pub fn into_inner(self) -> R {
168
0
    self.0.into_inner()
169
0
  }
170
}
171
172
173
#[cfg(all(feature="unsafe", feature="std"))]
174
pub struct Decompressor<R: Read>(DecompressorCustomAlloc<R,
175
                                                         <HeapAlloc<u8>
176
                                                          as Allocator<u8>>::AllocatedMemory,
177
                                                         HeapAlloc<u8>,
178
                                                         HeapAlloc<u32>,
179
                                                         HeapAlloc<HuffmanCode> >);
180
181
182
#[cfg(all(feature="unsafe", feature="std"))]
183
impl<R: Read> Decompressor<R> {
184
  pub fn new(r: R, buffer_size: usize) -> Self {
185
     let dict = <HeapAlloc<u8> as Allocator<u8>>::AllocatedMemory::default();
186
     Self::new_with_custom_dictionary(r, buffer_size, dict)
187
  }
188
  pub fn new_with_custom_dictionary(r: R, buffer_size: usize, dict: <HeapAlloc<u8>
189
                                                 as Allocator<u8>>::AllocatedMemory) -> Self {
190
    let mut alloc_u8 = HeapAlloc::<u8>::new(0);
191
    let buffer = alloc_u8.alloc_cell(if buffer_size == 0 {4096} else {buffer_size});
192
    let alloc_u32 = HeapAlloc::<u32>::new(0);
193
    let alloc_hc = HeapAlloc::<HuffmanCode>::new(HuffmanCode{
194
        bits:0, value: 0,
195
    });
196
    Decompressor::<R>(DecompressorCustomAlloc::<R,
197
                                                <HeapAlloc<u8>
198
                                                 as Allocator<u8>>::AllocatedMemory,
199
                                                HeapAlloc<u8>,
200
                                                HeapAlloc<u32>,
201
                                                HeapAlloc<HuffmanCode> >
202
      ::new_with_custom_dictionary(r, buffer, alloc_u8, alloc_u32, alloc_hc, dict))
203
  }
204
205
  // Attaches an additional raw LZ77 prefix dictionary; only allowed before
206
  // the first read. Returns false if the dictionary could not be attached.
207
  pub fn attach_dictionary(&mut self, dict: <HeapAlloc<u8> as Allocator<u8>>::AllocatedMemory) -> bool {
208
    self.0.attach_dictionary(dict)
209
  }
210
211
  // Attaches a serialized shared dictionary (magic 0x91 0x00, may contain an
212
  // LZ77 prefix dictionary and custom word/transform lists); only allowed
213
  // before the first read.
214
  pub fn attach_serialized_dictionary(&mut self, dict: <HeapAlloc<u8> as Allocator<u8>>::AllocatedMemory) -> bool {
215
    self.0.attach_serialized_dictionary(dict)
216
  }
217
218
  // Sets a decoder parameter (see BrotliState::set_parameter); only allowed
219
  // before the first read.
220
  pub fn set_parameter(&mut self, param: BrotliDecoderParameter, value: u32) -> bool {
221
    self.0.set_parameter(param, value)
222
  }
223
224
  // Sets the smallest ring buffer the decoder starts from (see
225
  // BrotliState::set_initial_ring_buffer_size); only allowed before the first
226
  // read.
227
  pub fn set_initial_ring_buffer_size(&mut self, size: u32) -> bool {
228
    self.0.set_initial_ring_buffer_size(size)
229
  }
230
231
  pub fn get_ref(&self) -> &R {
232
    self.0.get_ref()
233
  }
234
  pub fn get_mut(&mut self) -> &mut R {
235
    &mut (self.0).0.get_mut().0
236
  }
237
  pub fn into_inner(self) -> R {
238
    self.0.into_inner()
239
  }
240
}
241
242
243
#[cfg(feature="std")]
244
impl<R: Read> Read for Decompressor<R> {
245
1.82M
  fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
246
1.82M
    self.0.read(buf)
247
1.82M
  }
<brotli_decompressor::reader::Decompressor<&[u8]> as std::io::Read>::read
Line
Count
Source
245
1.82M
  fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
246
1.82M
    self.0.read(buf)
247
1.82M
  }
Unexecuted instantiation: <brotli_decompressor::reader::Decompressor<_> as std::io::Read>::read
248
}
249
250
pub struct DecompressorCustomIo<ErrType,
251
                                R: CustomRead<ErrType>,
252
                                BufferType: SliceWrapperMut<u8>,
253
                                AllocU8: Allocator<u8>,
254
                                AllocU32: Allocator<u32>,
255
                                AllocHC: Allocator<HuffmanCode>>
256
{
257
  input_buffer: BufferType,
258
  total_out: usize,
259
  input_offset: usize,
260
  input_len: usize,
261
  input: R,
262
  error_if_invalid_data: Option<ErrType>,
263
  state: BrotliState<AllocU8, AllocU32, AllocHC>,
264
  done: bool,
265
}
266
267
impl<ErrType,
268
     R: CustomRead<ErrType>,
269
     BufferType : SliceWrapperMut<u8>,
270
     AllocU8,
271
     AllocU32,
272
     AllocHC> DecompressorCustomIo<ErrType, R, BufferType, AllocU8, AllocU32, AllocHC>
273
 where AllocU8 : Allocator<u8>, AllocU32 : Allocator<u32>, AllocHC : Allocator<HuffmanCode>
274
{
275
276
0
    pub fn new(r: R, buffer : BufferType,
277
0
               alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC,
278
0
               invalid_data_error_type : ErrType) -> Self {
279
0
     let dict = AllocU8::AllocatedMemory::default();
280
0
     Self::new_with_custom_dictionary(r, buffer, alloc_u8, alloc_u32, alloc_hc, dict, invalid_data_error_type)
281
0
    }
282
12.1k
    pub fn new_with_custom_dictionary(r: R, buffer : BufferType,
283
12.1k
               alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC,
284
12.1k
               dict: AllocU8::AllocatedMemory,
285
12.1k
               invalid_data_error_type : ErrType) -> Self {
286
12.1k
        DecompressorCustomIo::<ErrType, R, BufferType, AllocU8, AllocU32, AllocHC>{
287
12.1k
            input_buffer : buffer,
288
12.1k
            total_out : 0,
289
12.1k
            input_offset : 0,
290
12.1k
            input_len : 0,
291
12.1k
            input: r,
292
12.1k
            state : BrotliState::new_with_custom_dictionary(alloc_u8,
293
12.1k
                                     alloc_u32,
294
12.1k
                                     alloc_hc,
295
12.1k
                                     dict),
296
12.1k
            error_if_invalid_data : Some(invalid_data_error_type),
297
12.1k
            done: false,
298
12.1k
        }
299
12.1k
    }
<brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<&[u8]>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc>>::new_with_custom_dictionary
Line
Count
Source
282
12.1k
    pub fn new_with_custom_dictionary(r: R, buffer : BufferType,
283
12.1k
               alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC,
284
12.1k
               dict: AllocU8::AllocatedMemory,
285
12.1k
               invalid_data_error_type : ErrType) -> Self {
286
12.1k
        DecompressorCustomIo::<ErrType, R, BufferType, AllocU8, AllocU32, AllocHC>{
287
12.1k
            input_buffer : buffer,
288
12.1k
            total_out : 0,
289
12.1k
            input_offset : 0,
290
12.1k
            input_len : 0,
291
12.1k
            input: r,
292
12.1k
            state : BrotliState::new_with_custom_dictionary(alloc_u8,
293
12.1k
                                     alloc_u32,
294
12.1k
                                     alloc_hc,
295
12.1k
                                     dict),
296
12.1k
            error_if_invalid_data : Some(invalid_data_error_type),
297
12.1k
            done: false,
298
12.1k
        }
299
12.1k
    }
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _>>::new_with_custom_dictionary
300
301
    // Attaches an additional raw LZ77 prefix dictionary; only allowed before
302
    // the first read. Returns false if the dictionary could not be attached.
303
0
    pub fn attach_dictionary(&mut self, dict: AllocU8::AllocatedMemory) -> bool {
304
0
      self.state.attach_dictionary(dict)
305
0
    }
306
307
    // Attaches a serialized shared dictionary (magic 0x91 0x00, may contain
308
    // an LZ77 prefix dictionary and custom word/transform lists); only
309
    // allowed before the first read.
310
0
    pub fn attach_serialized_dictionary(&mut self, dict: AllocU8::AllocatedMemory) -> bool {
311
0
      self.state.attach_serialized_dictionary(dict)
312
0
    }
313
314
    // Sets a decoder parameter (see BrotliState::set_parameter); only
315
    // allowed before the first read.
316
0
    pub fn set_parameter(&mut self, param: BrotliDecoderParameter, value: u32) -> bool {
317
0
      self.state.set_parameter(param, value)
318
0
    }
319
320
    // Sets the smallest ring buffer the decoder starts from (see
321
    // BrotliState::set_initial_ring_buffer_size); only allowed before the
322
    // first read.
323
0
    pub fn set_initial_ring_buffer_size(&mut self, size: u32) -> bool {
324
0
      self.state.set_initial_ring_buffer_size(size)
325
0
    }
326
327
0
    pub fn get_ref(&self) -> &R {
328
0
      &self.input
329
0
    }
330
0
    pub fn get_mut(&mut self) -> &mut R {
331
0
      &mut self.input
332
0
    }
333
0
    pub fn into_inner(self) -> R {
334
0
      match self {
335
        DecompressorCustomIo {
336
0
          input_buffer: _ib,
337
0
          total_out: _to,
338
0
          state: _state,
339
0
          input_offset: _io,
340
0
          input_len: _il,
341
0
          error_if_invalid_data:_eiid,
342
0
          input,
343
0
          done: _done,
344
        } =>{
345
0
          input
346
        }
347
    }
348
0
    }
349
350
4.17M
    pub fn copy_to_front(&mut self) {
351
4.17M
        let avail_in = self.input_len - self.input_offset;
352
4.17M
        if self.input_offset == self.input_buffer.slice_mut().len() {
353
2.36M
            self.input_offset = 0;
354
2.36M
            self.input_len = 0;
355
2.36M
        } else if self.input_offset + 256 > self.input_buffer.slice_mut().len() && avail_in < self.input_offset {
356
0
            let (first, second) = self.input_buffer.slice_mut().split_at_mut(self.input_offset);
357
0
            self.input_len -= self.input_offset;
358
0
            first[0..avail_in].clone_from_slice(&second[0..avail_in]);
359
0
            self.input_offset = 0;
360
1.80M
        }
361
4.17M
    }
<brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<&[u8]>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc>>::copy_to_front
Line
Count
Source
350
4.17M
    pub fn copy_to_front(&mut self) {
351
4.17M
        let avail_in = self.input_len - self.input_offset;
352
4.17M
        if self.input_offset == self.input_buffer.slice_mut().len() {
353
2.36M
            self.input_offset = 0;
354
2.36M
            self.input_len = 0;
355
2.36M
        } else if self.input_offset + 256 > self.input_buffer.slice_mut().len() && avail_in < self.input_offset {
356
0
            let (first, second) = self.input_buffer.slice_mut().split_at_mut(self.input_offset);
357
0
            self.input_len -= self.input_offset;
358
0
            first[0..avail_in].clone_from_slice(&second[0..avail_in]);
359
0
            self.input_offset = 0;
360
1.80M
        }
361
4.17M
    }
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _>>::copy_to_front
362
}
363
364
impl<ErrType,
365
     R: CustomRead<ErrType>,
366
     BufferType : SliceWrapperMut<u8>,
367
     AllocU8 : Allocator<u8>,
368
     AllocU32 : Allocator<u32>,
369
     AllocHC : Allocator<HuffmanCode> > CustomRead<ErrType> for DecompressorCustomIo<ErrType,
370
                                                                                     R,
371
                                                                                     BufferType,
372
                                                                                     AllocU8,
373
                                                                                     AllocU32,
374
                                                                                     AllocHC> {
375
  /// This variant of read will return Ok(number of bytes read) until the file
376
  /// Is completed at which point it will return Ok(0).
377
  /// However if there are additional unconsumed bytes in the buffer, it will
378
  /// return Err(InvalidData) at that point. Otherwise it will keep returning
379
  /// Ok(0).
380
  ///
381
  /// # Arguments
382
  ///
383
  /// * `buf` - The buffer to read into
384
  ///
385
  /// # Errors
386
  ///
387
  /// Returns Ok(0) if the file has been fully decompressed.
388
  /// If the file has been fully decompressed but there are additional
389
  /// non-brotli bytes in the buffer, then return an InvalidData error.
390
  /// Also upstream errors from the reader are returned.
391
1.82M
  fn read(&mut self, buf: &mut [u8]) -> Result<usize, ErrType > {
392
1.82M
    let mut output_offset : usize = 0;
393
1.82M
    let mut avail_out = buf.len() - output_offset;
394
1.82M
    let mut avail_in = self.input_len - self.input_offset;
395
4.20M
    while avail_out == buf.len() {
396
4.20M
      match BrotliDecompressStream(&mut avail_in,
397
4.20M
                                   &mut self.input_offset,
398
4.20M
                                   &self.input_buffer.slice_mut()[..],
399
4.20M
                                   &mut avail_out,
400
4.20M
                                   &mut output_offset,
401
4.20M
                                   buf,
402
4.20M
                                   &mut self.total_out,
403
4.20M
                                   &mut self.state) {
404
        BrotliResult::NeedsMoreInput => {
405
4.17M
          self.copy_to_front();
406
4.17M
          if output_offset != 0 {
407
            // The decompressor successfully decoded some bytes, but still requires more
408
            // we do not wish to risk self.input.read returning an error, so instead we
409
            // opt to return what we have and do not invoke the read trait method
410
1.79M
            return Ok(output_offset);
411
2.38M
          }
412
2.38M
          match self.input.read(&mut self.input_buffer.slice_mut()[self.input_len..]) {
413
0
            Err(e) => {
414
0
              return Err(e);
415
            },
416
2.38M
            Ok(size) => if size == 0 {
417
0
              return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0));
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<&[u8]>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as brotli_decompressor::io_wrappers::CustomRead<std::io::error::Error>>::read::{closure#0}
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _> as brotli_decompressor::io_wrappers::CustomRead<_>>::read::{closure#0}
418
2.38M
            }else {
419
2.38M
              self.input_len += size;
420
2.38M
              avail_in = self.input_len - self.input_offset;
421
2.38M
            },
422
          }
423
        },
424
        BrotliResult::NeedsMoreOutput => {
425
5.22k
          break;
426
        },
427
        BrotliResult::ResultSuccess => {
428
24.1k
            if output_offset == 0 {
429
12.1k
                if !self.done {
430
12.1k
                    self.done = true;
431
12.1k
                } else if self.input_len != self.input_offset {
432
                    // Did not consume entire input; report error.
433
0
                    return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(output_offset));
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<&[u8]>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as brotli_decompressor::io_wrappers::CustomRead<std::io::error::Error>>::read::{closure#1}
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _> as brotli_decompressor::io_wrappers::CustomRead<_>>::read::{closure#1}
434
0
                }
435
11.9k
            }
436
24.1k
            return Ok(output_offset);
437
        }
438
0
        BrotliResult::ResultFailure => return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0)),
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<&[u8]>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as brotli_decompressor::io_wrappers::CustomRead<std::io::error::Error>>::read::{closure#2}
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _> as brotli_decompressor::io_wrappers::CustomRead<_>>::read::{closure#2}
439
      }
440
    }
441
5.22k
    Ok(output_offset)
442
1.82M
  }
<brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<&[u8]>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as brotli_decompressor::io_wrappers::CustomRead<std::io::error::Error>>::read
Line
Count
Source
391
1.82M
  fn read(&mut self, buf: &mut [u8]) -> Result<usize, ErrType > {
392
1.82M
    let mut output_offset : usize = 0;
393
1.82M
    let mut avail_out = buf.len() - output_offset;
394
1.82M
    let mut avail_in = self.input_len - self.input_offset;
395
4.20M
    while avail_out == buf.len() {
396
4.20M
      match BrotliDecompressStream(&mut avail_in,
397
4.20M
                                   &mut self.input_offset,
398
4.20M
                                   &self.input_buffer.slice_mut()[..],
399
4.20M
                                   &mut avail_out,
400
4.20M
                                   &mut output_offset,
401
4.20M
                                   buf,
402
4.20M
                                   &mut self.total_out,
403
4.20M
                                   &mut self.state) {
404
        BrotliResult::NeedsMoreInput => {
405
4.17M
          self.copy_to_front();
406
4.17M
          if output_offset != 0 {
407
            // The decompressor successfully decoded some bytes, but still requires more
408
            // we do not wish to risk self.input.read returning an error, so instead we
409
            // opt to return what we have and do not invoke the read trait method
410
1.79M
            return Ok(output_offset);
411
2.38M
          }
412
2.38M
          match self.input.read(&mut self.input_buffer.slice_mut()[self.input_len..]) {
413
0
            Err(e) => {
414
0
              return Err(e);
415
            },
416
2.38M
            Ok(size) => if size == 0 {
417
0
              return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0));
418
2.38M
            }else {
419
2.38M
              self.input_len += size;
420
2.38M
              avail_in = self.input_len - self.input_offset;
421
2.38M
            },
422
          }
423
        },
424
        BrotliResult::NeedsMoreOutput => {
425
5.22k
          break;
426
        },
427
        BrotliResult::ResultSuccess => {
428
24.1k
            if output_offset == 0 {
429
12.1k
                if !self.done {
430
12.1k
                    self.done = true;
431
12.1k
                } else if self.input_len != self.input_offset {
432
                    // Did not consume entire input; report error.
433
0
                    return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(output_offset));
434
0
                }
435
11.9k
            }
436
24.1k
            return Ok(output_offset);
437
        }
438
0
        BrotliResult::ResultFailure => return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0)),
439
      }
440
    }
441
5.22k
    Ok(output_offset)
442
1.82M
  }
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _> as brotli_decompressor::io_wrappers::CustomRead<_>>::read
443
}
444
445
#[cfg(feature="std")]
446
#[test]
447
fn test_no_vanishing_bytes() {
448
    use std::string::ToString;
449
450
    // Output from this command:
451
    let compressed_with_extra = b"\x8f\x02\x80\x68\x65\x6c\x6c\x6f\x0a\x03\x67\x6f\x6f\x64\x62\x79\x65\x0a";
452
    // Make sure that read_to_string returns the data.
453
    let cursor = std::io::Cursor::new(compressed_with_extra);
454
    let mut reader = super::Decompressor::new(cursor, 8000);
455
    assert_eq!(std::io::read_to_string(&mut reader).unwrap(), "hello\n");
456
457
    // However you can call read extra times to make sure there's no data.
458
    let cursor = std::io::Cursor::new(compressed_with_extra);
459
    let mut reader = super::Decompressor::new(cursor, 8000);
460
    let mut data = std::vec::Vec::<u8>::default();
461
    loop {
462
        let mut buf = [0u8;5];
463
        let offset = reader.read(&mut buf).unwrap();
464
        if offset == 0 {
465
            break;
466
        }
467
        data.extend_from_slice(&buf[..offset]);
468
    }
469
    assert_eq!(
470
        &data,
471
        &['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8, '\n' as u8]);
472
473
    // But calling read, one last time, results in an error because there
474
    // were leftover bytes in the buffer.
475
    let mut buf = [0u8;5];
476
    assert_eq!(reader.read(&mut buf).unwrap_err().kind(),
477
               io::ErrorKind::InvalidData);
478
    data.clear();
479
480
481
}
482
483
#[cfg(feature="std")]
484
#[test]
485
fn test_repeated_read_returns_zero() {
486
    use std::string::ToString;
487
488
    // Output from this command:
489
    let compressed_without_extra = b"\x8f\x02\x80\x68\x65\x6c\x6c\x6f\x0a\x03";
490
    // Make sure that read_to_string returns the data.
491
    let cursor = std::io::Cursor::new(compressed_without_extra);
492
    let mut reader = super::Decompressor::new(cursor, 8000);
493
    assert_eq!(std::io::read_to_string(&mut reader).unwrap(), "hello\n");
494
495
    // However you can call read extra times to make sure there's no data.
496
    let cursor = std::io::Cursor::new(compressed_without_extra);
497
    let mut reader = super::Decompressor::new(cursor, 8000);
498
    let mut data = std::vec::Vec::<u8>::default();
499
    loop {
500
        let mut buf = [0u8;5];
501
        let offset = reader.read(&mut buf).unwrap();
502
        if offset == 0 {
503
            break;
504
        }
505
        data.extend_from_slice(&buf[..offset]);
506
    }
507
    assert_eq!(&data, &['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8, '\n' as u8]);
508
    let mut buf = [0u8;5];
509
    assert_eq!(reader.read(&mut buf).unwrap(), 0);
510
    data.clear();
511
512
513
}
514