(
data: &mut Chunker<'_>,
d: &mut D,
bufsize: usize,
max_length: Option<usize>,
calc_flush: impl Fn(bool) -> D::Flush,
)
| 124 | } |
| 125 | |
| 126 | pub fn _decompress_chunks<D: Decompressor>( |
| 127 | data: &mut Chunker<'_>, |
| 128 | d: &mut D, |
| 129 | bufsize: usize, |
| 130 | max_length: Option<usize>, |
| 131 | calc_flush: impl Fn(bool) -> D::Flush, |
| 132 | ) -> Result<(Vec<u8>, bool), D::Error> { |
| 133 | if data.is_empty() { |
| 134 | return Ok((Vec::new(), true)); |
| 135 | } |
| 136 | let max_length = max_length.unwrap_or(usize::MAX); |
| 137 | let mut buf = Vec::new(); |
| 138 | |
| 139 | 'outer: loop { |
| 140 | let chunk = data.chunk(); |
| 141 | let flush = calc_flush(chunk.len() == data.len()); |
| 142 | loop { |
| 143 | let additional = core::cmp::min(bufsize, max_length - buf.capacity()); |
| 144 | if additional == 0 { |
| 145 | return Ok((buf, false)); |
| 146 | } |
| 147 | buf.reserve_exact(additional); |
| 148 | |
| 149 | let prev_in = d.total_in(); |
| 150 | let res = d.decompress_vec(chunk, &mut buf, flush); |
| 151 | let consumed = d.total_in() - prev_in; |
| 152 | |
| 153 | data.advance(consumed as usize); |
| 154 | |
| 155 | match res { |
| 156 | Ok(status) => { |
| 157 | let stream_end = status.is_stream_end(); |
| 158 | if stream_end || data.is_empty() { |
| 159 | // we've reached the end of the stream, we're done |
| 160 | buf.shrink_to_fit(); |
| 161 | return Ok((buf, stream_end)); |
| 162 | } else if !chunk.is_empty() && consumed == 0 { |
| 163 | // we're gonna need a bigger buffer |
| 164 | continue; |
| 165 | } else { |
| 166 | // next chunk |
| 167 | continue 'outer; |
| 168 | } |
| 169 | } |
| 170 | Err(e) => { |
| 171 | d.maybe_set_dict(e)?; |
| 172 | // now try the next chunk |
| 173 | continue 'outer; |
| 174 | } |
| 175 | }; |
| 176 | } |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | pub trait Compressor { |
| 181 | type Status: CompressStatusKind; |
no test coverage detected