Coverage Report

Created: 2026-06-13 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-decompressor-5.0.1/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 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
36
0
    pub fn new(r: R, buffer : BufferType,
37
0
               alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC) -> Self {
38
0
        DecompressorCustomAlloc::<R, BufferType, AllocU8, AllocU32, AllocHC>(
39
0
          DecompressorCustomIo::<Error,
40
0
                                 IntoIoReader<R>,
41
0
                                 BufferType,
42
0
                                 AllocU8, AllocU32, AllocHC>::new(IntoIoReader::<R>(r),
43
0
                                                                  buffer,
44
0
                                                                  alloc_u8, alloc_u32, alloc_hc,
45
0
                                                                  Error::new(ErrorKind::InvalidData,
46
0
                                                                             "Invalid Data")))
47
0
    }
48
49
12.5k
    pub fn new_with_custom_dictionary(r: R, buffer : BufferType,
50
12.5k
               alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC,
51
12.5k
               dict: AllocU8::AllocatedMemory) -> Self {
52
12.5k
        DecompressorCustomAlloc::<R, BufferType, AllocU8, AllocU32, AllocHC>(
53
12.5k
          DecompressorCustomIo::<Error,
54
12.5k
                                 IntoIoReader<R>,
55
12.5k
                                 BufferType,
56
12.5k
                                 AllocU8, AllocU32, AllocHC>::new_with_custom_dictionary(IntoIoReader::<R>(r),
57
12.5k
                                                                                   buffer,
58
12.5k
                                                                                   alloc_u8, alloc_u32, alloc_hc,
59
12.5k
                                                                                   dict,
60
12.5k
                                                                                   Error::new(ErrorKind::InvalidData,
61
12.5k
                                                                                              "Invalid Data")))
62
12.5k
    }
<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
49
12.5k
    pub fn new_with_custom_dictionary(r: R, buffer : BufferType,
50
12.5k
               alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC,
51
12.5k
               dict: AllocU8::AllocatedMemory) -> Self {
52
12.5k
        DecompressorCustomAlloc::<R, BufferType, AllocU8, AllocU32, AllocHC>(
53
12.5k
          DecompressorCustomIo::<Error,
54
12.5k
                                 IntoIoReader<R>,
55
12.5k
                                 BufferType,
56
12.5k
                                 AllocU8, AllocU32, AllocHC>::new_with_custom_dictionary(IntoIoReader::<R>(r),
57
12.5k
                                                                                   buffer,
58
12.5k
                                                                                   alloc_u8, alloc_u32, alloc_hc,
59
12.5k
                                                                                   dict,
60
12.5k
                                                                                   Error::new(ErrorKind::InvalidData,
61
12.5k
                                                                                              "Invalid Data")))
62
12.5k
    }
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomAlloc<_, _, _, _, _>>::new_with_custom_dictionary
63
64
0
    pub fn get_ref(&self) -> &R {
65
0
      &self.0.get_ref().0
66
0
    }
67
0
    pub fn get_mut(&mut self) -> &mut R {
68
0
      &mut self.0.get_mut().0
69
0
    }
70
0
    pub fn into_inner(self) -> R {
71
0
      self.0.into_inner().0
72
0
    }
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> {
84
1.85M
    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
85
1.85M
       self.0.read(buf)
86
1.85M
    }
<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
84
1.85M
    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
85
1.85M
       self.0.read(buf)
86
1.85M
    }
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomAlloc<_, _, _, _, _> as std::io::Read>::read
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> {
101
12.5k
  pub fn new(r: R, buffer_size: usize) -> Self {
102
12.5k
     let dict = <StandardAlloc as Allocator<u8>>::AllocatedMemory::default();
103
12.5k
     Self::new_with_custom_dict(r, buffer_size, dict)
104
12.5k
  }
<brotli_decompressor::reader::Decompressor<&[u8]>>::new
Line
Count
Source
101
12.5k
  pub fn new(r: R, buffer_size: usize) -> Self {
102
12.5k
     let dict = <StandardAlloc as Allocator<u8>>::AllocatedMemory::default();
103
12.5k
     Self::new_with_custom_dict(r, buffer_size, dict)
104
12.5k
  }
Unexecuted instantiation: <brotli_decompressor::reader::Decompressor<_>>::new
105
12.5k
  pub fn new_with_custom_dict(r: R, buffer_size: usize, dict: <StandardAlloc as Allocator<u8>>::AllocatedMemory) -> Self {
106
12.5k
    let mut alloc = StandardAlloc::default();
107
12.5k
    let buffer = <StandardAlloc as Allocator<u8>>::alloc_cell(&mut alloc, if buffer_size == 0 {4096} else {buffer_size});
108
12.5k
    Decompressor::<R>(DecompressorCustomAlloc::<R,
109
12.5k
                                                <StandardAlloc
110
12.5k
                                                 as Allocator<u8>>::AllocatedMemory,
111
12.5k
                                                StandardAlloc,
112
12.5k
                                                StandardAlloc,
113
12.5k
                                                StandardAlloc>::new_with_custom_dictionary(r,
114
12.5k
                                                                              buffer,
115
12.5k
                                                                              alloc,
116
12.5k
                                                                              StandardAlloc::default(),
117
12.5k
                                                                              StandardAlloc::default(),
118
12.5k
                                                                              dict))
119
12.5k
  }
<brotli_decompressor::reader::Decompressor<&[u8]>>::new_with_custom_dict
Line
Count
Source
105
12.5k
  pub fn new_with_custom_dict(r: R, buffer_size: usize, dict: <StandardAlloc as Allocator<u8>>::AllocatedMemory) -> Self {
106
12.5k
    let mut alloc = StandardAlloc::default();
107
12.5k
    let buffer = <StandardAlloc as Allocator<u8>>::alloc_cell(&mut alloc, if buffer_size == 0 {4096} else {buffer_size});
108
12.5k
    Decompressor::<R>(DecompressorCustomAlloc::<R,
109
12.5k
                                                <StandardAlloc
110
12.5k
                                                 as Allocator<u8>>::AllocatedMemory,
111
12.5k
                                                StandardAlloc,
112
12.5k
                                                StandardAlloc,
113
12.5k
                                                StandardAlloc>::new_with_custom_dictionary(r,
114
12.5k
                                                                              buffer,
115
12.5k
                                                                              alloc,
116
12.5k
                                                                              StandardAlloc::default(),
117
12.5k
                                                                              StandardAlloc::default(),
118
12.5k
                                                                              dict))
119
12.5k
  }
Unexecuted instantiation: <brotli_decompressor::reader::Decompressor<_>>::new_with_custom_dict
120
121
0
  pub fn get_ref(&self) -> &R {
122
0
    &self.0.get_ref()
123
0
  }
124
0
  pub fn get_mut(&mut self) -> &mut R {
125
0
    &mut ((self.0).0).get_mut().0
126
0
  }
127
0
  pub fn into_inner(self) -> R {
128
0
    self.0.into_inner()
129
0
  }
130
}
131
132
133
#[cfg(all(feature="unsafe", feature="std"))]
134
pub struct Decompressor<R: Read>(DecompressorCustomAlloc<R,
135
                                                         <HeapAlloc<u8>
136
                                                          as Allocator<u8>>::AllocatedMemory,
137
                                                         HeapAlloc<u8>,
138
                                                         HeapAlloc<u32>,
139
                                                         HeapAlloc<HuffmanCode> >);
140
141
142
#[cfg(all(feature="unsafe", feature="std"))]
143
impl<R: Read> Decompressor<R> {
144
  pub fn new(r: R, buffer_size: usize) -> Self {
145
     let dict = <HeapAlloc<u8> as Allocator<u8>>::AllocatedMemory::default();
146
     Self::new_with_custom_dictionary(r, buffer_size, dict)
147
  }
148
  pub fn new_with_custom_dictionary(r: R, buffer_size: usize, dict: <HeapAlloc<u8>
149
                                                 as Allocator<u8>>::AllocatedMemory) -> Self {
150
    let mut alloc_u8 = HeapAlloc::<u8>::new(0);
151
    let buffer = alloc_u8.alloc_cell(if buffer_size == 0 {4096} else {buffer_size});
152
    let alloc_u32 = HeapAlloc::<u32>::new(0);
153
    let alloc_hc = HeapAlloc::<HuffmanCode>::new(HuffmanCode{
154
        bits:0, value: 0,
155
    });
156
    Decompressor::<R>(DecompressorCustomAlloc::<R,
157
                                                <HeapAlloc<u8>
158
                                                 as Allocator<u8>>::AllocatedMemory,
159
                                                HeapAlloc<u8>,
160
                                                HeapAlloc<u32>,
161
                                                HeapAlloc<HuffmanCode> >
162
      ::new_with_custom_dictionary(r, buffer, alloc_u8, alloc_u32, alloc_hc, dict))
163
  }
164
165
  pub fn get_ref(&self) -> &R {
166
    self.0.get_ref()
167
  }
168
  pub fn get_mut(&mut self) -> &mut R {
169
    &mut (self.0).0.get_mut().0
170
  }
171
  pub fn into_inner(self) -> R {
172
    self.0.into_inner()
173
  }
174
}
175
176
177
#[cfg(feature="std")]
178
impl<R: Read> Read for Decompressor<R> {
179
1.85M
  fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
180
1.85M
    self.0.read(buf)
181
1.85M
  }
<brotli_decompressor::reader::Decompressor<&[u8]> as std::io::Read>::read
Line
Count
Source
179
1.85M
  fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
180
1.85M
    self.0.read(buf)
181
1.85M
  }
Unexecuted instantiation: <brotli_decompressor::reader::Decompressor<_> as std::io::Read>::read
182
}
183
184
pub struct DecompressorCustomIo<ErrType,
185
                                R: CustomRead<ErrType>,
186
                                BufferType: SliceWrapperMut<u8>,
187
                                AllocU8: Allocator<u8>,
188
                                AllocU32: Allocator<u32>,
189
                                AllocHC: Allocator<HuffmanCode>>
190
{
191
  input_buffer: BufferType,
192
  total_out: usize,
193
  input_offset: usize,
194
  input_len: usize,
195
  input: R,
196
  error_if_invalid_data: Option<ErrType>,
197
  state: BrotliState<AllocU8, AllocU32, AllocHC>,
198
  done: bool,
199
}
200
201
impl<ErrType,
202
     R: CustomRead<ErrType>,
203
     BufferType : SliceWrapperMut<u8>,
204
     AllocU8,
205
     AllocU32,
206
     AllocHC> DecompressorCustomIo<ErrType, R, BufferType, AllocU8, AllocU32, AllocHC>
207
 where AllocU8 : Allocator<u8>, AllocU32 : Allocator<u32>, AllocHC : Allocator<HuffmanCode>
208
{
209
210
0
    pub fn new(r: R, buffer : BufferType,
211
0
               alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC,
212
0
               invalid_data_error_type : ErrType) -> Self {
213
0
     let dict = AllocU8::AllocatedMemory::default();
214
0
     Self::new_with_custom_dictionary(r, buffer, alloc_u8, alloc_u32, alloc_hc, dict, invalid_data_error_type)
215
0
    }
216
12.5k
    pub fn new_with_custom_dictionary(r: R, buffer : BufferType,
217
12.5k
               alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC,
218
12.5k
               dict: AllocU8::AllocatedMemory,
219
12.5k
               invalid_data_error_type : ErrType) -> Self {
220
12.5k
        DecompressorCustomIo::<ErrType, R, BufferType, AllocU8, AllocU32, AllocHC>{
221
12.5k
            input_buffer : buffer,
222
12.5k
            total_out : 0,
223
12.5k
            input_offset : 0,
224
12.5k
            input_len : 0,
225
12.5k
            input: r,
226
12.5k
            state : BrotliState::new_with_custom_dictionary(alloc_u8,
227
12.5k
                                     alloc_u32,
228
12.5k
                                     alloc_hc,
229
12.5k
                                     dict),
230
12.5k
            error_if_invalid_data : Some(invalid_data_error_type),
231
12.5k
            done: false,
232
12.5k
        }
233
12.5k
    }
<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
216
12.5k
    pub fn new_with_custom_dictionary(r: R, buffer : BufferType,
217
12.5k
               alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC,
218
12.5k
               dict: AllocU8::AllocatedMemory,
219
12.5k
               invalid_data_error_type : ErrType) -> Self {
220
12.5k
        DecompressorCustomIo::<ErrType, R, BufferType, AllocU8, AllocU32, AllocHC>{
221
12.5k
            input_buffer : buffer,
222
12.5k
            total_out : 0,
223
12.5k
            input_offset : 0,
224
12.5k
            input_len : 0,
225
12.5k
            input: r,
226
12.5k
            state : BrotliState::new_with_custom_dictionary(alloc_u8,
227
12.5k
                                     alloc_u32,
228
12.5k
                                     alloc_hc,
229
12.5k
                                     dict),
230
12.5k
            error_if_invalid_data : Some(invalid_data_error_type),
231
12.5k
            done: false,
232
12.5k
        }
233
12.5k
    }
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _>>::new_with_custom_dictionary
234
235
0
    pub fn get_ref(&self) -> &R {
236
0
      &self.input
237
0
    }
238
0
    pub fn get_mut(&mut self) -> &mut R {
239
0
      &mut self.input
240
0
    }
241
0
    pub fn into_inner(self) -> R {
242
0
      match self {
243
        DecompressorCustomIo {
244
0
          input_buffer: _ib,
245
0
          total_out: _to,
246
0
          state: _state,
247
0
          input_offset: _io,
248
0
          input_len: _il,
249
0
          error_if_invalid_data:_eiid,
250
0
          input,
251
0
          done: _done,
252
        } =>{
253
0
          input
254
        }
255
    }
256
0
    }
257
258
4.23M
    pub fn copy_to_front(&mut self) {
259
4.23M
        let avail_in = self.input_len - self.input_offset;
260
4.23M
        if self.input_offset == self.input_buffer.slice_mut().len() {
261
2.40M
            self.input_offset = 0;
262
2.40M
            self.input_len = 0;
263
2.40M
        } else if self.input_offset + 256 > self.input_buffer.slice_mut().len() && avail_in < self.input_offset {
264
0
            let (first, second) = self.input_buffer.slice_mut().split_at_mut(self.input_offset);
265
0
            self.input_len -= self.input_offset;
266
0
            first[0..avail_in].clone_from_slice(&second[0..avail_in]);
267
0
            self.input_offset = 0;
268
1.83M
        }
269
4.23M
    }
<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
258
4.23M
    pub fn copy_to_front(&mut self) {
259
4.23M
        let avail_in = self.input_len - self.input_offset;
260
4.23M
        if self.input_offset == self.input_buffer.slice_mut().len() {
261
2.40M
            self.input_offset = 0;
262
2.40M
            self.input_len = 0;
263
2.40M
        } else if self.input_offset + 256 > self.input_buffer.slice_mut().len() && avail_in < self.input_offset {
264
0
            let (first, second) = self.input_buffer.slice_mut().split_at_mut(self.input_offset);
265
0
            self.input_len -= self.input_offset;
266
0
            first[0..avail_in].clone_from_slice(&second[0..avail_in]);
267
0
            self.input_offset = 0;
268
1.83M
        }
269
4.23M
    }
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _>>::copy_to_front
270
}
271
272
impl<ErrType,
273
     R: CustomRead<ErrType>,
274
     BufferType : SliceWrapperMut<u8>,
275
     AllocU8 : Allocator<u8>,
276
     AllocU32 : Allocator<u32>,
277
     AllocHC : Allocator<HuffmanCode> > CustomRead<ErrType> for DecompressorCustomIo<ErrType,
278
                                                                                     R,
279
                                                                                     BufferType,
280
                                                                                     AllocU8,
281
                                                                                     AllocU32,
282
                                                                                     AllocHC> {
283
  /// This variant of read will return Ok(number of bytes read) until the file
284
  /// Is completed at which point it will return Ok(0).
285
  /// However if there are additional unconsumed bytes in the buffer, it will
286
  /// return Err(InvalidData) at that point. Otherwise it will keep returning
287
  /// Ok(0).
288
  ///
289
  /// # Arguments
290
  ///
291
  /// * `buf` - The buffer to read into
292
  ///
293
  /// # Errors
294
  ///
295
  /// Returns Ok(0) if the file has been fully decompressed.
296
  /// If the file has been fully decompressed but there are additional
297
  /// non-brotli bytes in the buffer, then return an InvalidData error.
298
  /// Also upstream errors from the reader are returned.
299
1.85M
  fn read(&mut self, buf: &mut [u8]) -> Result<usize, ErrType > {
300
1.85M
    let mut output_offset : usize = 0;
301
1.85M
    let mut avail_out = buf.len() - output_offset;
302
1.85M
    let mut avail_in = self.input_len - self.input_offset;
303
4.26M
    while avail_out == buf.len() {
304
4.26M
      match BrotliDecompressStream(&mut avail_in,
305
4.26M
                                   &mut self.input_offset,
306
4.26M
                                   &self.input_buffer.slice_mut()[..],
307
4.26M
                                   &mut avail_out,
308
4.26M
                                   &mut output_offset,
309
4.26M
                                   buf,
310
4.26M
                                   &mut self.total_out,
311
4.26M
                                   &mut self.state) {
312
        BrotliResult::NeedsMoreInput => {
313
4.23M
          self.copy_to_front();
314
4.23M
          if output_offset != 0 {
315
            // The decompressor successfully decoded some bytes, but still requires more
316
            // we do not wish to risk self.input.read returning an error, so instead we
317
            // opt to return what we have and do not invoke the read trait method
318
1.82M
            return Ok(output_offset);
319
2.41M
          }
320
2.41M
          match self.input.read(&mut self.input_buffer.slice_mut()[self.input_len..]) {
321
0
            Err(e) => {
322
0
              return Err(e);
323
            },
324
2.41M
            Ok(size) => if size == 0 {
325
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}
326
2.41M
            }else {
327
2.41M
              self.input_len += size;
328
2.41M
              avail_in = self.input_len - self.input_offset;
329
2.41M
            },
330
          }
331
        },
332
        BrotliResult::NeedsMoreOutput => {
333
5.20k
          break;
334
        },
335
        BrotliResult::ResultSuccess => {
336
24.9k
            if output_offset == 0 {
337
12.5k
                if !self.done {
338
12.5k
                    self.done = true;
339
12.5k
                } else if self.input_len != self.input_offset {
340
                    // Did not consume entire input; report error.
341
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}
342
0
                }
343
12.3k
            }
344
24.9k
            return Ok(output_offset);
345
        }
346
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}
347
      }
348
    }
349
5.20k
    Ok(output_offset)
350
1.85M
  }
<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
299
1.85M
  fn read(&mut self, buf: &mut [u8]) -> Result<usize, ErrType > {
300
1.85M
    let mut output_offset : usize = 0;
301
1.85M
    let mut avail_out = buf.len() - output_offset;
302
1.85M
    let mut avail_in = self.input_len - self.input_offset;
303
4.26M
    while avail_out == buf.len() {
304
4.26M
      match BrotliDecompressStream(&mut avail_in,
305
4.26M
                                   &mut self.input_offset,
306
4.26M
                                   &self.input_buffer.slice_mut()[..],
307
4.26M
                                   &mut avail_out,
308
4.26M
                                   &mut output_offset,
309
4.26M
                                   buf,
310
4.26M
                                   &mut self.total_out,
311
4.26M
                                   &mut self.state) {
312
        BrotliResult::NeedsMoreInput => {
313
4.23M
          self.copy_to_front();
314
4.23M
          if output_offset != 0 {
315
            // The decompressor successfully decoded some bytes, but still requires more
316
            // we do not wish to risk self.input.read returning an error, so instead we
317
            // opt to return what we have and do not invoke the read trait method
318
1.82M
            return Ok(output_offset);
319
2.41M
          }
320
2.41M
          match self.input.read(&mut self.input_buffer.slice_mut()[self.input_len..]) {
321
0
            Err(e) => {
322
0
              return Err(e);
323
            },
324
2.41M
            Ok(size) => if size == 0 {
325
0
              return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0));
326
2.41M
            }else {
327
2.41M
              self.input_len += size;
328
2.41M
              avail_in = self.input_len - self.input_offset;
329
2.41M
            },
330
          }
331
        },
332
        BrotliResult::NeedsMoreOutput => {
333
5.20k
          break;
334
        },
335
        BrotliResult::ResultSuccess => {
336
24.9k
            if output_offset == 0 {
337
12.5k
                if !self.done {
338
12.5k
                    self.done = true;
339
12.5k
                } else if self.input_len != self.input_offset {
340
                    // Did not consume entire input; report error.
341
0
                    return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(output_offset));
342
0
                }
343
12.3k
            }
344
24.9k
            return Ok(output_offset);
345
        }
346
0
        BrotliResult::ResultFailure => return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0)),
347
      }
348
    }
349
5.20k
    Ok(output_offset)
350
1.85M
  }
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _> as brotli_decompressor::io_wrappers::CustomRead<_>>::read
351
}
352
353
#[cfg(feature="std")]
354
#[test]
355
fn test_no_vanishing_bytes() {
356
    use std::string::ToString;
357
358
    // Output from this command:
359
    let compressed_with_extra = b"\x8f\x02\x80\x68\x65\x6c\x6c\x6f\x0a\x03\x67\x6f\x6f\x64\x62\x79\x65\x0a";
360
    // Make sure that read_to_string returns the data.
361
    let cursor = std::io::Cursor::new(compressed_with_extra);
362
    let mut reader = super::Decompressor::new(cursor, 8000);
363
    assert_eq!(std::io::read_to_string(&mut reader).unwrap(), "hello\n");
364
365
    // However you can call read extra times to make sure there's no data.
366
    let cursor = std::io::Cursor::new(compressed_with_extra);
367
    let mut reader = super::Decompressor::new(cursor, 8000);
368
    let mut data = std::vec::Vec::<u8>::default();
369
    loop {
370
        let mut buf = [0u8;5];
371
        let offset = reader.read(&mut buf).unwrap();
372
        if offset == 0 {
373
            break;
374
        }
375
        data.extend_from_slice(&buf[..offset]);
376
    }
377
    assert_eq!(
378
        &data,
379
        &['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8, '\n' as u8]);
380
381
    // But calling read, one last time, results in an error because there
382
    // were leftover bytes in the buffer.
383
    let mut buf = [0u8;5];
384
    assert_eq!(reader.read(&mut buf).unwrap_err().kind(),
385
               io::ErrorKind::InvalidData);
386
    data.clear();
387
388
389
}
390
391
#[cfg(feature="std")]
392
#[test]
393
fn test_repeated_read_returns_zero() {
394
    use std::string::ToString;
395
396
    // Output from this command:
397
    let compressed_without_extra = b"\x8f\x02\x80\x68\x65\x6c\x6c\x6f\x0a\x03";
398
    // Make sure that read_to_string returns the data.
399
    let cursor = std::io::Cursor::new(compressed_without_extra);
400
    let mut reader = super::Decompressor::new(cursor, 8000);
401
    assert_eq!(std::io::read_to_string(&mut reader).unwrap(), "hello\n");
402
403
    // However you can call read extra times to make sure there's no data.
404
    let cursor = std::io::Cursor::new(compressed_without_extra);
405
    let mut reader = super::Decompressor::new(cursor, 8000);
406
    let mut data = std::vec::Vec::<u8>::default();
407
    loop {
408
        let mut buf = [0u8;5];
409
        let offset = reader.read(&mut buf).unwrap();
410
        if offset == 0 {
411
            break;
412
        }
413
        data.extend_from_slice(&buf[..offset]);
414
    }
415
    assert_eq!(&data, &['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8, '\n' as u8]);
416
    let mut buf = [0u8;5];
417
    assert_eq!(reader.read(&mut buf).unwrap(), 0);
418
    data.clear();
419
420
421
}
422