Skip to content

Commit

Permalink
Specialize read_exact and read_buf_exact for VecDeque
Browse files Browse the repository at this point in the history
  • Loading branch information
a1phyr committed Oct 22, 2024
1 parent bca5fde commit a898641
Showing 1 changed file with 46 additions and 0 deletions.
46 changes: 46 additions & 0 deletions library/std/src/io/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,29 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
Ok(n)
}

fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
let (front, back) = self.as_slices();

// Use only the front buffer is big enough to fill `buf`, else use the
// back buffer too if it is big enough
match buf.split_at_mut_checked(front.len()) {
None => buf.copy_from_slice(&front[..buf.len()]),
Some((buf_front, buf_back)) => match back.split_at_checked(buf_back.len()) {
Some((back, _)) => {
buf_front.copy_from_slice(front);
buf_back.copy_from_slice(back);
}
None => {
self.clear();
return Err(io::Error::READ_EXACT_EOF);
}
},
}

self.drain(..buf.len());
Ok(())
}

#[inline]
fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
let (ref mut front, _) = self.as_slices();
Expand All @@ -462,6 +485,29 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
Ok(())
}

fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
let len = cursor.capacity();
let (front, back) = self.as_slices();

match front.split_at_checked(cursor.capacity()) {
Some((front, _)) => cursor.append(front),
None => {
cursor.append(front);
match back.split_at_checked(cursor.capacity()) {
Some((back, _)) => cursor.append(back),
None => {
cursor.append(back);
self.clear();
return Err(io::Error::READ_EXACT_EOF);
}
}
}
}

self.drain(..len);
Ok(())
}

#[inline]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
// The total len is known upfront so we can reserve it in a single call.
Expand Down

0 comments on commit a898641

Please sign in to comment.