Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
500 changes: 500 additions & 0 deletions library/alloc/src/io/buf_read.rs

Large diffs are not rendered by default.

18 changes: 16 additions & 2 deletions library/alloc/src/io/cursor.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::alloc::Allocator;
use crate::boxed::Box;
use crate::io::{
self, BorrowedCursor, Cursor, ErrorKind, IoSlice, IoSliceMut, Read, WriteThroughCursor,
slice_write, slice_write_all, slice_write_all_vectored, slice_write_vectored,
self, BorrowedCursor, BufRead, Cursor, ErrorKind, IoSlice, IoSliceMut, Read,
WriteThroughCursor, slice_write, slice_write_all, slice_write_all_vectored,
slice_write_vectored,
};
use crate::string::String;
use crate::vec::Vec;
Expand Down Expand Up @@ -103,6 +104,19 @@ where
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> BufRead for Cursor<T>
where
T: AsRef<[u8]>,
{
fn fill_buf(&mut self) -> io::Result<&[u8]> {
Ok(Cursor::split(self).1)
}
fn consume(&mut self, amt: usize) {
self.set_position(self.position() + amt as u64);
}
}

/// Reserves the required space, and pads the vec with 0s if necessary.
fn reserve_and_pad<A: Allocator>(
pos_mut: &mut u64,
Expand Down
101 changes: 100 additions & 1 deletion library/alloc/src/io/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use crate::boxed::Box;
#[cfg(not(no_global_oom_handling))]
use crate::collections::VecDeque;
use crate::fmt;
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, Seek, SeekFrom, SizeHint, Write};
use crate::io::{
self, BorrowedCursor, BufRead, IoSlice, IoSliceMut, Read, Seek, SeekFrom, SizeHint, Write,
};
use crate::string::String;
#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
use crate::sync::Arc;
Expand Down Expand Up @@ -56,6 +58,38 @@ impl<R: Read + ?Sized> Read for &mut R {
(**self).read_buf_exact(cursor)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B: BufRead + ?Sized> BufRead for &mut B {
#[inline]
fn fill_buf(&mut self) -> io::Result<&[u8]> {
(**self).fill_buf()
}

#[inline]
fn consume(&mut self, amt: usize) {
(**self).consume(amt)
}

#[inline]
fn has_data_left(&mut self) -> io::Result<bool> {
(**self).has_data_left()
}

#[inline]
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
(**self).read_until(byte, buf)
}

#[inline]
fn skip_until(&mut self, byte: u8) -> io::Result<usize> {
(**self).skip_until(byte)
}

#[inline]
fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
(**self).read_line(buf)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<R: Read + ?Sized> Read for Box<R> {
Expand Down Expand Up @@ -177,6 +211,38 @@ impl<S: Seek + ?Sized> Seek for Box<S> {
(**self).seek_relative(offset)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<B: BufRead + ?Sized> BufRead for Box<B> {
#[inline]
fn fill_buf(&mut self) -> io::Result<&[u8]> {
(**self).fill_buf()
}

#[inline]
fn consume(&mut self, amt: usize) {
(**self).consume(amt)
}

#[inline]
fn has_data_left(&mut self) -> io::Result<bool> {
(**self).has_data_left()
}

#[inline]
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
(**self).read_until(byte, buf)
}

#[inline]
fn skip_until(&mut self, byte: u8) -> io::Result<usize> {
(**self).skip_until(byte)
}

#[inline]
fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
(**self).read_line(buf)
}
}

// =============================================================================
// In-memory buffer implementations
Expand Down Expand Up @@ -311,6 +377,19 @@ impl Read for &[u8] {
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl BufRead for &[u8] {
#[inline]
fn fill_buf(&mut self) -> io::Result<&[u8]> {
Ok(*self)
}

#[inline]
fn consume(&mut self, amt: usize) {
*self = &self[amt..];
}
}

/// Write is implemented for `Vec<u8>` by appending to the vector.
/// The vector will grow as needed.
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -459,6 +538,26 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
unsafe { io::append_to_string(buf, |buf| self.read_to_end(buf)) }
}
}

/// BufRead is implemented for `VecDeque<u8>` by reading bytes from the front of the `VecDeque`.
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "vecdeque_buf_read", since = "1.75.0")]
impl<A: Allocator> BufRead for VecDeque<u8, A> {
/// Returns the contents of the "front" slice as returned by
/// [`as_slices`][`VecDeque::as_slices`]. If the contained byte slices of the `VecDeque` are
/// discontiguous, multiple calls to `fill_buf` will be needed to read the entire content.
#[inline]
fn fill_buf(&mut self) -> io::Result<&[u8]> {
let (front, _) = self.as_slices();
Ok(front)
}

#[inline]
fn consume(&mut self, amt: usize) {
self.drain(..amt);
}
}

/// Write is implemented for `VecDeque<u8>` by appending to the `VecDeque`, growing it as needed.
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "vecdeque_read_write", since = "1.63.0")]
Expand Down
14 changes: 8 additions & 6 deletions library/alloc/src/io/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Traits, helpers, and type definitions for core I/O functionality.

mod buf_read;
mod cursor;
mod error;
mod impls;
Expand Down Expand Up @@ -27,17 +28,18 @@ pub use core::io::{
stream_len_default, take,
};

#[unstable(feature = "alloc_io", issue = "154046")]
pub use self::{
buf_read::BufRead,
read::{Read, read_to_string},
util::{Bytes, Lines, Split},
};
#[doc(hidden)]
#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
pub use self::{
read::{
DEFAULT_BUF_SIZE, append_to_string, default_read_buf, default_read_buf_exact,
default_read_exact, default_read_to_end, default_read_to_string, default_read_vectored,
},
util::{SpecReadByte, bytes, uninlined_slow_read_byte},
};
#[unstable(feature = "alloc_io", issue = "154046")]
pub use self::{
read::{Read, read_to_string},
util::Bytes,
util::{SpecReadByte, bytes, lines, split, uninlined_slow_read_byte},
};
4 changes: 3 additions & 1 deletion library/alloc/src/io/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ use crate::vec::Vec;
/// trait.
///
/// Please note that each call to [`read()`] may involve a system call, and
/// therefore, using something that implements `BufRead`, such as
/// `BufReader`, will be more efficient.
/// therefore, using something that implements [`BufRead`], such as
///
/// [`BufRead`]: crate::io::BufRead
///
/// Repeated calls to the reader use the same cursor, so for example
/// calling `read_to_end` twice on a `File` will only return the file's
Expand Down
Loading
Loading