Skip to content

Commit

Permalink
fix(tokio): attempt to decode from internal state even if nothing was…
Browse files Browse the repository at this point in the history
… read

Unlike zlib, miniz_oxide consumes data into internal state
even if there is not enough space in the output buffer.
Next time poll_fill_buf() is called we should try
to decode from internal state even if no new compressed data
was read.

This change is a port of fix
<#123>
(commit 22ed0ac)
from `futures` to `tokio`.
  • Loading branch information
link2xt committed Oct 9, 2024
1 parent 3337a1b commit ed83d67
Showing 1 changed file with 22 additions and 3 deletions.
25 changes: 22 additions & 3 deletions src/tokio/bufread/generic/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,37 @@ impl<R: AsyncBufRead, D: Decode> Decoder<R, D> {
) -> Poll<Result<()>> {
let mut this = self.project();

let mut first = true;

loop {
*this.state = match this.state {
State::Decoding => {
let input = ready!(this.reader.as_mut().poll_fill_buf(cx))?;
if input.is_empty() {
let input = if first {
&[][..]
} else {
ready!(this.reader.as_mut().poll_fill_buf(cx))?
};

if input.is_empty() && !first {
// Avoid attempting to reinitialise the decoder if the reader
// has returned EOF.
*this.multiple_members = false;

State::Flushing
} else {
let mut input = PartialBuffer::new(input);
let done = this.decoder.decode(&mut input, output)?;
let done = this.decoder.decode(&mut input, output).or_else(|err| {
// ignore the first error, occurs when input is empty
// but we need to run decode to flush
if first {
Ok(false)
} else {
Err(err)
}
})?;

first = false;

let len = input.written().len();
this.reader.as_mut().consume(len);
if done {
Expand Down

0 comments on commit ed83d67

Please sign in to comment.