Skip to content

Commit 282790f

Browse files
committed
Specialize read_exact and read_buf_exact for VecDeque
1 parent 507193a commit 282790f

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

std/src/io/impls.rs

+46
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,29 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
453453
Ok(n)
454454
}
455455

456+
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
457+
let (front, back) = self.as_slices();
458+
459+
// Use only the front buffer if it is big enough to fill `buf`, else use
460+
// the back buffer too.
461+
match buf.split_at_mut_checked(front.len()) {
462+
None => buf.copy_from_slice(&front[..buf.len()]),
463+
Some((buf_front, buf_back)) => match back.split_at_checked(buf_back.len()) {
464+
Some((back, _)) => {
465+
buf_front.copy_from_slice(front);
466+
buf_back.copy_from_slice(back);
467+
}
468+
None => {
469+
self.clear();
470+
return Err(io::Error::READ_EXACT_EOF);
471+
}
472+
},
473+
}
474+
475+
self.drain(..buf.len());
476+
Ok(())
477+
}
478+
456479
#[inline]
457480
fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
458481
let (ref mut front, _) = self.as_slices();
@@ -462,6 +485,29 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
462485
Ok(())
463486
}
464487

488+
fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
489+
let len = cursor.capacity();
490+
let (front, back) = self.as_slices();
491+
492+
match front.split_at_checked(cursor.capacity()) {
493+
Some((front, _)) => cursor.append(front),
494+
None => {
495+
cursor.append(front);
496+
match back.split_at_checked(cursor.capacity()) {
497+
Some((back, _)) => cursor.append(back),
498+
None => {
499+
cursor.append(back);
500+
self.clear();
501+
return Err(io::Error::READ_EXACT_EOF);
502+
}
503+
}
504+
}
505+
}
506+
507+
self.drain(..len);
508+
Ok(())
509+
}
510+
465511
#[inline]
466512
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
467513
// The total len is known upfront so we can reserve it in a single call.

0 commit comments

Comments
 (0)