Skip to content

Commit 541ee71

Browse files
committed
Fix setting of decode_needs variable
Previously, `decode_needs` was set to the value returned by `nom` in the `nom::Err::Incomplete` error. This is incorrect, because `nom` returns the number of additional bytes needed rather than the total number of bytes. Current filled buffer size should be added to this number to obtain `decode_needs` value. In addition, unwrap `decode_needs` from `Option`. `None` was always unwrapped with `unwrap_or(0)`, so we can as well store 0 directly and save the memory.
1 parent 721e519 commit 541ee71

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

src/imap_stream.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ pub struct ImapStream<R: Read + Write> {
2626
/// The underlying stream
2727
pub(crate) inner: R,
2828
/// Number of bytes the next decode operation needs if known.
29-
decode_needs: Option<usize>,
29+
/// If the buffer contains less than this, it is a waste of time to try to parse it.
30+
/// If unknown, set it to 0, so decoding is always attempted.
31+
decode_needs: usize,
3032
/// The buffer.
3133
buffer: Buffer,
3234
/// Whether there is any more items to return from the stream. This is set to true once
@@ -40,7 +42,7 @@ impl<R: Read + Write + Unpin> ImapStream<R> {
4042
ImapStream {
4143
inner,
4244
buffer: Buffer::new(),
43-
decode_needs: None,
45+
decode_needs: 0,
4446
closed: false,
4547
}
4648
}
@@ -99,7 +101,7 @@ impl<R: Read + Write + Unpin> ImapStream<R> {
99101

100102
impl<R: Read + Write + Unpin> ImapStream<R> {
101103
fn maybe_decode(&mut self) -> io::Result<Option<ResponseData>> {
102-
if self.buffer.used() > self.decode_needs.unwrap_or(0) {
104+
if self.buffer.used() >= self.decode_needs {
103105
self.decode()
104106
} else {
105107
Ok(None)
@@ -116,22 +118,22 @@ impl<R: Read + Write + Unpin> ImapStream<R> {
116118
match imap_proto::parser::parse_response(buf) {
117119
Ok((remaining, response)) => {
118120
// TODO: figure out if we can use a minimum required size for a response.
119-
self.decode_needs = None;
121+
self.decode_needs = 0;
120122
self.buffer.reset_with_data(remaining);
121123
Ok(response)
122124
}
123125
Err(nom::Err::Incomplete(Needed::Size(min))) => {
124126
log::trace!("decode: incomplete data, need minimum {} bytes", min);
125-
self.decode_needs = Some(usize::from(min));
127+
self.decode_needs = self.buffer.used() + usize::from(min);
126128
Err(None)
127129
}
128130
Err(nom::Err::Incomplete(_)) => {
129131
log::trace!("decode: incomplete data, need unknown number of bytes");
130-
self.decode_needs = None;
132+
self.decode_needs = 0;
131133
Err(None)
132134
}
133135
Err(other) => {
134-
self.decode_needs = None;
136+
self.decode_needs = 0;
135137
Err(Some(io::Error::new(
136138
io::ErrorKind::Other,
137139
format!("{:?} during parsing of {:?}", other, buf),
@@ -197,9 +199,9 @@ impl Buffer {
197199
}
198200

199201
/// Ensure the buffer has free capacity, optionally ensuring minimum buffer size.
200-
fn ensure_capacity(&mut self, required: Option<usize>) -> io::Result<()> {
202+
fn ensure_capacity(&mut self, required: usize) -> io::Result<()> {
201203
let free_bytes: usize = self.block.size() - self.offset;
202-
let min_required_bytes: usize = required.unwrap_or(0);
204+
let min_required_bytes: usize = required;
203205
let extra_bytes_needed: usize = min_required_bytes.saturating_sub(self.block.size());
204206
if free_bytes == 0 || extra_bytes_needed > 0 {
205207
let increase = std::cmp::max(Buffer::BLOCK_SIZE, extra_bytes_needed);
@@ -384,7 +386,7 @@ mod tests {
384386
assert_eq!(buf.block.size(), Buffer::BLOCK_SIZE);
385387

386388
// Still has capacity, no size request.
387-
buf.ensure_capacity(None).unwrap();
389+
buf.ensure_capacity(0).unwrap();
388390
assert_eq!(buf.free_as_mut_slice().len(), 1);
389391
assert_eq!(buf.block.size(), Buffer::BLOCK_SIZE);
390392

@@ -394,15 +396,14 @@ mod tests {
394396
assert_eq!(buf.block.size(), Buffer::BLOCK_SIZE);
395397

396398
// No capacity, no size request.
397-
buf.ensure_capacity(None).unwrap();
399+
buf.ensure_capacity(0).unwrap();
398400
assert_eq!(buf.free_as_mut_slice().len(), Buffer::BLOCK_SIZE);
399401
assert_eq!(buf.block.size(), 2 * Buffer::BLOCK_SIZE);
400402

401403
// Some capacity, size request.
402404
buf.extend_used(5);
403405
assert_eq!(buf.offset, Buffer::BLOCK_SIZE + 5);
404-
buf.ensure_capacity(Some(3 * Buffer::BLOCK_SIZE - 6))
405-
.unwrap();
406+
buf.ensure_capacity(3 * Buffer::BLOCK_SIZE - 6).unwrap();
406407
assert_eq!(buf.free_as_mut_slice().len(), 2 * Buffer::BLOCK_SIZE - 5);
407408
assert_eq!(buf.block.size(), 3 * Buffer::BLOCK_SIZE);
408409
}

0 commit comments

Comments
 (0)