Skip to content

Commit a76c82c

Browse files
committed
Override default Write methods for cursor-like types
1 parent c58d3bc commit a76c82c

File tree

2 files changed

+143
-14
lines changed

2 files changed

+143
-14
lines changed

library/std/src/io/cursor.rs

+87-13
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,27 @@ fn slice_write_vectored(
439439
Ok(nwritten)
440440
}
441441

442+
#[inline]
443+
fn slice_write_all(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<()> {
444+
let n = slice_write(pos_mut, slice, buf)?;
445+
if n < buf.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) }
446+
}
447+
448+
#[inline]
449+
fn slice_write_all_vectored(
450+
pos_mut: &mut u64,
451+
slice: &mut [u8],
452+
bufs: &[IoSlice<'_>],
453+
) -> io::Result<()> {
454+
for buf in bufs {
455+
let n = slice_write(pos_mut, slice, buf)?;
456+
if n < buf.len() {
457+
return Err(io::Error::WRITE_ALL_EOF);
458+
}
459+
}
460+
Ok(())
461+
}
462+
442463
/// Reserves the required space, and pads the vec with 0s if necessary.
443464
fn reserve_and_pad<A: Allocator>(
444465
pos_mut: &mut u64,
@@ -481,9 +502,12 @@ fn reserve_and_pad<A: Allocator>(
481502
Ok(pos)
482503
}
483504

484-
/// Writes the slice to the vec without allocating
485-
/// # Safety: vec must have buf.len() spare capacity
486-
unsafe fn vec_write_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -> usize
505+
/// Writes the slice to the vec without allocating.
506+
///
507+
/// # Safety
508+
///
509+
/// `vec` must have `buf.len()` spare capacity.
510+
unsafe fn vec_write_all_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -> usize
487511
where
488512
A: Allocator,
489513
{
@@ -492,7 +516,7 @@ where
492516
pos + buf.len()
493517
}
494518

495-
/// Resizing write implementation for [`Cursor`]
519+
/// Resizing `write_all` implementation for [`Cursor`].
496520
///
497521
/// Cursor is allowed to have a pre-allocated and initialised
498522
/// vector body, but with a position of 0. This means the [`Write`]
@@ -501,7 +525,7 @@ where
501525
/// This also allows for the vec body to be empty, but with a position of N.
502526
/// This means that [`Write`] will pad the vec with 0 initially,
503527
/// before writing anything from that point
504-
fn vec_write<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
528+
fn vec_write_all<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
505529
where
506530
A: Allocator,
507531
{
@@ -512,7 +536,7 @@ where
512536
// Safety: we have ensured that the capacity is available
513537
// and that all bytes get written up to pos
514538
unsafe {
515-
pos = vec_write_unchecked(pos, vec, buf);
539+
pos = vec_write_all_unchecked(pos, vec, buf);
516540
if pos > vec.len() {
517541
vec.set_len(pos);
518542
}
@@ -523,7 +547,7 @@ where
523547
Ok(buf_len)
524548
}
525549

526-
/// Resizing write_vectored implementation for [`Cursor`]
550+
/// Resizing `write_all_vectored` implementation for [`Cursor`].
527551
///
528552
/// Cursor is allowed to have a pre-allocated and initialised
529553
/// vector body, but with a position of 0. This means the [`Write`]
@@ -532,7 +556,7 @@ where
532556
/// This also allows for the vec body to be empty, but with a position of N.
533557
/// This means that [`Write`] will pad the vec with 0 initially,
534558
/// before writing anything from that point
535-
fn vec_write_vectored<A>(
559+
fn vec_write_all_vectored<A>(
536560
pos_mut: &mut u64,
537561
vec: &mut Vec<u8, A>,
538562
bufs: &[IoSlice<'_>],
@@ -550,7 +574,7 @@ where
550574
// and that all bytes get written up to the last pos
551575
unsafe {
552576
for buf in bufs {
553-
pos = vec_write_unchecked(pos, vec, buf);
577+
pos = vec_write_all_unchecked(pos, vec, buf);
554578
}
555579
if pos > vec.len() {
556580
vec.set_len(pos);
@@ -579,6 +603,16 @@ impl Write for Cursor<&mut [u8]> {
579603
true
580604
}
581605

606+
#[inline]
607+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
608+
slice_write_all(&mut self.pos, self.inner, buf)
609+
}
610+
611+
#[inline]
612+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
613+
slice_write_all_vectored(&mut self.pos, self.inner, bufs)
614+
}
615+
582616
#[inline]
583617
fn flush(&mut self) -> io::Result<()> {
584618
Ok(())
@@ -591,18 +625,28 @@ where
591625
A: Allocator,
592626
{
593627
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
594-
vec_write(&mut self.pos, self.inner, buf)
628+
vec_write_all(&mut self.pos, self.inner, buf)
595629
}
596630

597631
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
598-
vec_write_vectored(&mut self.pos, self.inner, bufs)
632+
vec_write_all_vectored(&mut self.pos, self.inner, bufs)
599633
}
600634

601635
#[inline]
602636
fn is_write_vectored(&self) -> bool {
603637
true
604638
}
605639

640+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
641+
vec_write_all(&mut self.pos, self.inner, buf)?;
642+
Ok(())
643+
}
644+
645+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
646+
vec_write_all_vectored(&mut self.pos, self.inner, bufs)?;
647+
Ok(())
648+
}
649+
606650
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
607651
self.inner.reserve(fmt.estimated_capacity());
608652
io::default_write_fmt(self, fmt)
@@ -620,18 +664,28 @@ where
620664
A: Allocator,
621665
{
622666
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
623-
vec_write(&mut self.pos, &mut self.inner, buf)
667+
vec_write_all(&mut self.pos, &mut self.inner, buf)
624668
}
625669

626670
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
627-
vec_write_vectored(&mut self.pos, &mut self.inner, bufs)
671+
vec_write_all_vectored(&mut self.pos, &mut self.inner, bufs)
628672
}
629673

630674
#[inline]
631675
fn is_write_vectored(&self) -> bool {
632676
true
633677
}
634678

679+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
680+
vec_write_all(&mut self.pos, &mut self.inner, buf)?;
681+
Ok(())
682+
}
683+
684+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
685+
vec_write_all_vectored(&mut self.pos, &mut self.inner, bufs)?;
686+
Ok(())
687+
}
688+
635689
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
636690
self.inner.reserve(fmt.estimated_capacity());
637691
io::default_write_fmt(self, fmt)
@@ -663,6 +717,16 @@ where
663717
true
664718
}
665719

720+
#[inline]
721+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
722+
slice_write_all(&mut self.pos, &mut self.inner, buf)
723+
}
724+
725+
#[inline]
726+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
727+
slice_write_all_vectored(&mut self.pos, &mut self.inner, bufs)
728+
}
729+
666730
#[inline]
667731
fn flush(&mut self) -> io::Result<()> {
668732
Ok(())
@@ -686,6 +750,16 @@ impl<const N: usize> Write for Cursor<[u8; N]> {
686750
true
687751
}
688752

753+
#[inline]
754+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
755+
slice_write_all(&mut self.pos, &mut self.inner, buf)
756+
}
757+
758+
#[inline]
759+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
760+
slice_write_all_vectored(&mut self.pos, &mut self.inner, bufs)
761+
}
762+
689763
#[inline]
690764
fn flush(&mut self) -> io::Result<()> {
691765
Ok(())

library/std/src/io/impls.rs

+56-1
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,17 @@ impl Write for &mut [u8] {
455455

456456
#[inline]
457457
fn write_all(&mut self, data: &[u8]) -> io::Result<()> {
458-
if self.write(data)? == data.len() { Ok(()) } else { Err(io::Error::WRITE_ALL_EOF) }
458+
if self.write(data)? < data.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) }
459+
}
460+
461+
#[inline]
462+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
463+
for buf in bufs {
464+
if self.write(buf)? < buf.len() {
465+
return Err(io::Error::WRITE_ALL_EOF);
466+
}
467+
}
468+
Ok(())
459469
}
460470

461471
#[inline]
@@ -495,6 +505,12 @@ impl<A: Allocator> Write for Vec<u8, A> {
495505
Ok(())
496506
}
497507

508+
#[inline]
509+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
510+
self.write_vectored(bufs)?;
511+
Ok(())
512+
}
513+
498514
#[inline]
499515
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
500516
self.reserve(fmt.estimated_capacity());
@@ -646,6 +662,12 @@ impl<A: Allocator> Write for VecDeque<u8, A> {
646662
Ok(())
647663
}
648664

665+
#[inline]
666+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
667+
self.write_vectored(bufs)?;
668+
Ok(())
669+
}
670+
649671
#[inline]
650672
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
651673
self.reserve(fmt.estimated_capacity());
@@ -667,6 +689,39 @@ impl<'a> io::Write for core::io::BorrowedCursor<'a> {
667689
Ok(amt)
668690
}
669691

692+
#[inline]
693+
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
694+
let mut nwritten = 0;
695+
for buf in bufs {
696+
let n = self.write(buf)?;
697+
nwritten += n;
698+
if n < buf.len() {
699+
break;
700+
}
701+
}
702+
Ok(nwritten)
703+
}
704+
705+
#[inline]
706+
fn is_write_vectored(&self) -> bool {
707+
true
708+
}
709+
710+
#[inline]
711+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
712+
if self.write(buf)? < buf.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) }
713+
}
714+
715+
#[inline]
716+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
717+
for buf in bufs {
718+
if self.write(buf)? < buf.len() {
719+
return Err(io::Error::WRITE_ALL_EOF);
720+
}
721+
}
722+
Ok(())
723+
}
724+
670725
#[inline]
671726
fn flush(&mut self) -> io::Result<()> {
672727
Ok(())

0 commit comments

Comments
 (0)