summaryrefslogtreecommitdiffstats
path: root/buffered-reader
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-10-20 14:26:32 +0200
committerJustus Winter <justus@sequoia-pgp.org>2020-10-20 16:09:58 +0200
commit999e0fce62eb13ee7a9b289a14c24c9552aface1 (patch)
treefb2b38c442ff5a307332666298702c34d9b8c3ae /buffered-reader
parent6a425698b77253afdba1b3b937af98273edfcfa2 (diff)
buffered-reader: Fix error propagation.
- If reading from the wrapped reader returns an error, but we still can satisfy the request in Generic::data_helper, we do so. But, it is important to keep the error and return it next time the function is called. Otherwise, error conditions are mis-reported as end of file.
Diffstat (limited to 'buffered-reader')
-rw-r--r--buffered-reader/src/generic.rs18
1 files changed, 12 insertions, 6 deletions
diff --git a/buffered-reader/src/generic.rs b/buffered-reader/src/generic.rs
index 408ab93b..12c28d3b 100644
--- a/buffered-reader/src/generic.rs
+++ b/buffered-reader/src/generic.rs
@@ -21,6 +21,8 @@ pub struct Generic<T: io::Read, C> {
preferred_chunk_size: usize,
// The wrapped reader.
reader: T,
+ // Stashed error, if any.
+ error: Option<Error>,
// The user settable cookie.
cookie: C,
@@ -71,6 +73,7 @@ impl<T: io::Read, C> Generic<T, C> {
if let Some(s) = preferred_chunk_size { s }
else { DEFAULT_BUF_SIZE },
reader,
+ error: None,
cookie,
}
}
@@ -102,6 +105,11 @@ impl<T: io::Read, C> Generic<T, C> {
// else { None });
+ // See if there is an error from the last invocation.
+ if let Some(e) = self.error.take() {
+ return Err(e);
+ }
+
if let Some(ref buffer) = self.buffer {
// We have a buffer. Make sure `cursor` is sane.
assert!(self.cursor <= buffer.len());
@@ -110,8 +118,6 @@ impl<T: io::Read, C> Generic<T, C> {
assert_eq!(self.cursor, 0);
}
- let mut error = None;
-
let amount_buffered
= self.buffer.as_ref().map(|b| b.len() - self.cursor).unwrap_or(0);
if amount > amount_buffered {
@@ -141,7 +147,7 @@ impl<T: io::Read, C> Generic<T, C> {
Err(err) => {
// Don't return yet, because we may have
// actually read something.
- error = Some(err);
+ self.error = Some(err);
break;
},
}
@@ -167,14 +173,14 @@ impl<T: io::Read, C> Generic<T, C> {
let amount_buffered
= self.buffer.as_ref().map(|b| b.len() - self.cursor).unwrap_or(0);
- if let Some(error) = error {
+ if self.error.is_some() {
// An error occurred. If we have enough data to fulfill
// the caller's request, then don't return the error.
if hard && amount > amount_buffered {
- return Err(error);
+ return Err(self.error.take().unwrap());
}
if !hard && amount_buffered == 0 {
- return Err(error);
+ return Err(self.error.take().unwrap());
}
}