mirror of https://github.com/rust-lang/rust.git
Rollup merge of #128406 - lolbinarycat:bufreader_peek, r=Mark-Simulacrum
implement BufReader::peek Part of https://github.com/rust-lang/rust/issues/128405
This commit is contained in:
commit
7e1360b1e1
|
@ -94,6 +94,40 @@ impl<R: Read> BufReader<R> {
|
||||||
pub fn with_capacity(capacity: usize, inner: R) -> BufReader<R> {
|
pub fn with_capacity(capacity: usize, inner: R) -> BufReader<R> {
|
||||||
BufReader { inner, buf: Buffer::with_capacity(capacity) }
|
BufReader { inner, buf: Buffer::with_capacity(capacity) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempt to look ahead `n` bytes.
|
||||||
|
///
|
||||||
|
/// `n` must be less than `capacity`.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// #![feature(bufreader_peek)]
|
||||||
|
/// use std::io::{Read, BufReader};
|
||||||
|
///
|
||||||
|
/// let mut bytes = &b"oh, hello"[..];
|
||||||
|
/// let mut rdr = BufReader::with_capacity(6, &mut bytes);
|
||||||
|
/// assert_eq!(rdr.peek(2).unwrap(), b"oh");
|
||||||
|
/// let mut buf = [0; 4];
|
||||||
|
/// rdr.read(&mut buf[..]).unwrap();
|
||||||
|
/// assert_eq!(&buf, b"oh, ");
|
||||||
|
/// assert_eq!(rdr.peek(2).unwrap(), b"he");
|
||||||
|
/// let mut s = String::new();
|
||||||
|
/// rdr.read_to_string(&mut s).unwrap();
|
||||||
|
/// assert_eq!(&s, "hello");
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "bufreader_peek", issue = "128405")]
|
||||||
|
pub fn peek(&mut self, n: usize) -> io::Result<&[u8]> {
|
||||||
|
assert!(n <= self.capacity());
|
||||||
|
while n > self.buf.buffer().len() {
|
||||||
|
if self.buf.pos() > 0 {
|
||||||
|
self.buf.backshift();
|
||||||
|
}
|
||||||
|
self.buf.read_more(&mut self.inner)?;
|
||||||
|
debug_assert_eq!(self.buf.pos(), 0);
|
||||||
|
}
|
||||||
|
Ok(&self.buf.buffer()[..n])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: ?Sized> BufReader<R> {
|
impl<R: ?Sized> BufReader<R> {
|
||||||
|
|
|
@ -97,6 +97,27 @@ impl Buffer {
|
||||||
self.pos = self.pos.saturating_sub(amt);
|
self.pos = self.pos.saturating_sub(amt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read more bytes into the buffer without discarding any of its contents
|
||||||
|
pub fn read_more(&mut self, mut reader: impl Read) -> io::Result<()> {
|
||||||
|
let mut buf = BorrowedBuf::from(&mut self.buf[self.pos..]);
|
||||||
|
let old_init = self.initialized - self.pos;
|
||||||
|
unsafe {
|
||||||
|
buf.set_init(old_init);
|
||||||
|
}
|
||||||
|
reader.read_buf(buf.unfilled())?;
|
||||||
|
self.filled += buf.len();
|
||||||
|
self.initialized += buf.init_len() - old_init;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove bytes that have already been read from the buffer.
|
||||||
|
pub fn backshift(&mut self) {
|
||||||
|
self.buf.copy_within(self.pos.., 0);
|
||||||
|
self.initialized -= self.pos;
|
||||||
|
self.filled -= self.pos;
|
||||||
|
self.pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn fill_buf(&mut self, mut reader: impl Read) -> io::Result<&[u8]> {
|
pub fn fill_buf(&mut self, mut reader: impl Read) -> io::Result<&[u8]> {
|
||||||
// If we've reached the end of our internal buffer then we need to fetch
|
// If we've reached the end of our internal buffer then we need to fetch
|
||||||
|
|
Loading…
Reference in New Issue