/// }
/// ```
///
-/// Read from [`&str`] because [`&[u8]`][slice] implements `Read`:
+/// Read from [`&str`] because [`&[u8]`][prim@slice] implements `Read`:
///
/// ```no_run
/// # use std::io;
/// [`&str`]: prim@str
/// [`std::io`]: self
/// [`File`]: crate::fs::File
-/// [slice]: ../../std/primitive.slice.html
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(spotlight)]
pub trait Read {
/// waiting for data, but if an object needs to block for a read and cannot,
/// it will typically signal this via an [`Err`] return value.
///
- /// If the return value of this method is [`Ok(n)`], then it must be
- /// guaranteed that `0 <= n <= buf.len()`. A nonzero `n` value indicates
+ /// If the return value of this method is [`Ok(n)`], then implementations must
+ /// guarantee that `0 <= n <= buf.len()`. A nonzero `n` value indicates
/// that the buffer `buf` has been filled in with `n` bytes of data from this
/// source. If `n` is `0`, then it can indicate one of two scenarios:
///
/// This may happen for example because fewer bytes are actually available right now
/// (e. g. being close to end-of-file) or because read() was interrupted by a signal.
///
+ /// As this trait is safe to implement, callers cannot rely on `n <= buf.len()` for safety.
+ /// Extra care needs to be taken when `unsafe` functions are used to access the read bytes.
+ /// Callers have to ensure that no unchecked out-of-bounds accesses are possible even if
+ /// `n > buf.len()`.
+ ///
/// No guarantees are provided about the contents of `buf` when this
/// function is called, implementations cannot rely on any property of the
/// contents of `buf` being true. It is recommended that *implementations*
}
}
+impl<T, U> SizeHint for Chain<T, U> {
+ fn lower_bound(&self) -> usize {
+ SizeHint::lower_bound(&self.first) + SizeHint::lower_bound(&self.second)
+ }
+
+ fn upper_bound(&self) -> Option<usize> {
+ match (SizeHint::upper_bound(&self.first), SizeHint::upper_bound(&self.second)) {
+ (Some(first), Some(second)) => Some(first + second),
+ _ => None,
+ }
+ }
+}
+
/// Reader adaptor which limits the bytes read from an underlying reader.
///
/// This struct is generally created by calling [`take`] on a reader.
};
}
}
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ SizeHint::size_hint(&self.inner)
+ }
+}
+
+trait SizeHint {
+ fn lower_bound(&self) -> usize;
+
+ fn upper_bound(&self) -> Option<usize>;
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.lower_bound(), self.upper_bound())
+ }
+}
+
+impl<T> SizeHint for T {
+ default fn lower_bound(&self) -> usize {
+ 0
+ }
+
+ default fn upper_bound(&self) -> Option<usize> {
+ None
+ }
}
/// An iterator over the contents of an instance of `BufRead` split on a