Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename IoSlice(Mut)::advance to advance_slice and add IoSlice(Mut)::advance #85802

Merged
merged 4 commits into from
Jun 17, 2021
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
75 changes: 63 additions & 12 deletions library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ mod tests;

use crate::cmp;
use crate::fmt;
use crate::mem::replace;
use crate::ops::{Deref, DerefMut};
use crate::ptr;
use crate::slice;
Expand Down Expand Up @@ -1044,6 +1045,32 @@ impl<'a> IoSliceMut<'a> {

/// Advance the internal cursor of the slice.
///
/// Also see [`IoSliceMut::advance_slices`] to advance the cursors of
/// multiple buffers.
///
/// # Examples
///
/// ```
/// #![feature(io_slice_advance)]
///
/// use std::io::IoSliceMut;
/// use std::ops::Deref;
///
/// let mut data = [1; 8];
/// let mut buf = IoSliceMut::new(&mut data);
///
/// // Mark 3 bytes as read.
/// buf.advance(3);
/// assert_eq!(buf.deref(), [1; 5].as_ref());
/// ```
#[unstable(feature = "io_slice_advance", issue = "62726")]
#[inline]
pub fn advance(&mut self, n: usize) {
self.0.advance(n)
}

/// Advance the internal cursor of the slices.
///
/// # Notes
///
/// Elements in the slice may be modified if the cursor is not advanced to
Expand All @@ -1070,13 +1097,13 @@ impl<'a> IoSliceMut<'a> {
/// ][..];
///
/// // Mark 10 bytes as read.
/// bufs = IoSliceMut::advance(bufs, 10);
/// IoSliceMut::advance_slices(&mut bufs, 10);
/// assert_eq!(bufs[0].deref(), [2; 14].as_ref());
/// assert_eq!(bufs[1].deref(), [3; 8].as_ref());
/// ```
#[unstable(feature = "io_slice_advance", issue = "62726")]
#[inline]
pub fn advance<'b>(bufs: &'b mut [IoSliceMut<'a>], n: usize) -> &'b mut [IoSliceMut<'a>] {
pub fn advance_slices(bufs: &mut &mut [IoSliceMut<'a>], n: usize) {
// Number of buffers to remove.
let mut remove = 0;
// Total length of all the to be removed buffers.
Expand All @@ -1090,11 +1117,10 @@ impl<'a> IoSliceMut<'a> {
}
}

let bufs = &mut bufs[remove..];
*bufs = &mut replace(bufs, &mut [])[remove..];
if !bufs.is_empty() {
bufs[0].0.advance(n - accumulated_len)
bufs[0].advance(n - accumulated_len)
}
bufs
}
}

Expand Down Expand Up @@ -1153,6 +1179,32 @@ impl<'a> IoSlice<'a> {

/// Advance the internal cursor of the slice.
///
/// Also see [`IoSlice::advance_slices`] to advance the cursors of multiple
/// buffers.
///
/// # Examples
///
/// ```
/// #![feature(io_slice_advance)]
///
/// use std::io::IoSlice;
/// use std::ops::Deref;
///
/// let mut data = [1; 8];
/// let mut buf = IoSlice::new(&mut data);
///
/// // Mark 3 bytes as read.
/// buf.advance(3);
/// assert_eq!(buf.deref(), [1; 5].as_ref());
/// ```
#[unstable(feature = "io_slice_advance", issue = "62726")]
#[inline]
pub fn advance(&mut self, n: usize) {
self.0.advance(n)
}

/// Advance the internal cursor of the slices.
///
/// # Notes
///
/// Elements in the slice may be modified if the cursor is not advanced to
Expand All @@ -1179,12 +1231,12 @@ impl<'a> IoSlice<'a> {
/// ][..];
///
/// // Mark 10 bytes as written.
/// bufs = IoSlice::advance(bufs, 10);
/// IoSlice::advance_slices(&mut bufs, 10);
/// assert_eq!(bufs[0].deref(), [2; 14].as_ref());
/// assert_eq!(bufs[1].deref(), [3; 8].as_ref());
#[unstable(feature = "io_slice_advance", issue = "62726")]
#[inline]
pub fn advance<'b>(bufs: &'b mut [IoSlice<'a>], n: usize) -> &'b mut [IoSlice<'a>] {
pub fn advance_slices(bufs: &mut &mut [IoSlice<'a>], n: usize) {
// Number of buffers to remove.
let mut remove = 0;
// Total length of all the to be removed buffers.
Expand All @@ -1198,11 +1250,10 @@ impl<'a> IoSlice<'a> {
}
}

let bufs = &mut bufs[remove..];
*bufs = &mut replace(bufs, &mut [])[remove..];
if !bufs.is_empty() {
bufs[0].0.advance(n - accumulated_len)
bufs[0].advance(n - accumulated_len)
}
bufs
}
}

Expand Down Expand Up @@ -1511,7 +1562,7 @@ pub trait Write {
fn write_all_vectored(&mut self, mut bufs: &mut [IoSlice<'_>]) -> Result<()> {
// Guarantee that bufs is empty if it contains no data,
// to avoid calling write_vectored if there is no data to be written.
bufs = IoSlice::advance(bufs, 0);
IoSlice::advance_slices(&mut bufs, 0);
while !bufs.is_empty() {
match self.write_vectored(bufs) {
Ok(0) => {
Expand All @@ -1520,7 +1571,7 @@ pub trait Write {
&"failed to write whole buffer",
));
}
Ok(n) => bufs = IoSlice::advance(bufs, n),
Ok(n) => IoSlice::advance_slices(&mut bufs, n),
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
Expand Down
36 changes: 18 additions & 18 deletions library/std/src/io/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ fn test_read_to_end_capacity() -> io::Result<()> {
}

#[test]
fn io_slice_mut_advance() {
fn io_slice_mut_advance_slices() {
let mut buf1 = [1; 8];
let mut buf2 = [2; 16];
let mut buf3 = [3; 8];
Expand All @@ -364,75 +364,75 @@ fn io_slice_mut_advance() {
][..];

// Only in a single buffer..
bufs = IoSliceMut::advance(bufs, 1);
IoSliceMut::advance_slices(&mut bufs, 1);
assert_eq!(bufs[0].deref(), [1; 7].as_ref());
assert_eq!(bufs[1].deref(), [2; 16].as_ref());
assert_eq!(bufs[2].deref(), [3; 8].as_ref());

// Removing a buffer, leaving others as is.
bufs = IoSliceMut::advance(bufs, 7);
IoSliceMut::advance_slices(&mut bufs, 7);
assert_eq!(bufs[0].deref(), [2; 16].as_ref());
assert_eq!(bufs[1].deref(), [3; 8].as_ref());

// Removing a buffer and removing from the next buffer.
bufs = IoSliceMut::advance(bufs, 18);
IoSliceMut::advance_slices(&mut bufs, 18);
assert_eq!(bufs[0].deref(), [3; 6].as_ref());
}

#[test]
fn io_slice_mut_advance_empty_slice() {
let empty_bufs = &mut [][..];
fn io_slice_mut_advance_slices_empty_slice() {
let mut empty_bufs = &mut [][..];
// Shouldn't panic.
IoSliceMut::advance(empty_bufs, 1);
IoSliceMut::advance_slices(&mut empty_bufs, 1);
}

#[test]
fn io_slice_mut_advance_beyond_total_length() {
fn io_slice_mut_advance_slices_beyond_total_length() {
let mut buf1 = [1; 8];
let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..];

// Going beyond the total length should be ok.
bufs = IoSliceMut::advance(bufs, 9);
IoSliceMut::advance_slices(&mut bufs, 9);
assert!(bufs.is_empty());
}

#[test]
fn io_slice_advance() {
fn io_slice_advance_slices() {
let buf1 = [1; 8];
let buf2 = [2; 16];
let buf3 = [3; 8];
let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..];

// Only in a single buffer..
bufs = IoSlice::advance(bufs, 1);
IoSlice::advance_slices(&mut bufs, 1);
assert_eq!(bufs[0].deref(), [1; 7].as_ref());
assert_eq!(bufs[1].deref(), [2; 16].as_ref());
assert_eq!(bufs[2].deref(), [3; 8].as_ref());

// Removing a buffer, leaving others as is.
bufs = IoSlice::advance(bufs, 7);
IoSlice::advance_slices(&mut bufs, 7);
assert_eq!(bufs[0].deref(), [2; 16].as_ref());
assert_eq!(bufs[1].deref(), [3; 8].as_ref());

// Removing a buffer and removing from the next buffer.
bufs = IoSlice::advance(bufs, 18);
IoSlice::advance_slices(&mut bufs, 18);
assert_eq!(bufs[0].deref(), [3; 6].as_ref());
}

#[test]
fn io_slice_advance_empty_slice() {
let empty_bufs = &mut [][..];
fn io_slice_advance_slices_empty_slice() {
let mut empty_bufs = &mut [][..];
// Shouldn't panic.
IoSlice::advance(empty_bufs, 1);
IoSlice::advance_slices(&mut empty_bufs, 1);
}

#[test]
fn io_slice_advance_beyond_total_length() {
fn io_slice_advance_slices_beyond_total_length() {
let buf1 = [1; 8];
let mut bufs = &mut [IoSlice::new(&buf1)][..];

// Going beyond the total length should be ok.
bufs = IoSlice::advance(bufs, 9);
IoSlice::advance_slices(&mut bufs, 9);
assert!(bufs.is_empty());
}

Expand Down