11use super :: { BorrowedBuf , BufReader , BufWriter , ErrorKind , Read , Result , Write , DEFAULT_BUF_SIZE } ;
2+ use crate :: alloc:: Allocator ;
3+ use crate :: cmp;
4+ use crate :: collections:: VecDeque ;
5+ use crate :: io:: IoSlice ;
26use crate :: mem:: MaybeUninit ;
37
48#[ cfg( test) ]
8690
8791/// Specialization of the read-write loop that reuses the internal
8892/// buffer of a BufReader. If there's no buffer then the writer side
89- /// should be used intead .
93+ /// should be used instead .
9094trait BufferedReaderSpec {
9195 fn buffer_size ( & self ) -> usize ;
9296
@@ -104,7 +108,39 @@ where
104108 }
105109
106110 default fn copy_to ( & mut self , _to : & mut ( impl Write + ?Sized ) ) -> Result < u64 > {
107- unimplemented ! ( "only called from specializations" ) ;
111+ unreachable ! ( "only called from specializations" )
112+ }
113+ }
114+
115+ impl BufferedReaderSpec for & [ u8 ] {
116+ fn buffer_size ( & self ) -> usize {
117+ // prefer this specialization since the source "buffer" is all we'll ever need,
118+ // even if it's small
119+ usize:: MAX
120+ }
121+
122+ fn copy_to ( & mut self , to : & mut ( impl Write + ?Sized ) ) -> Result < u64 > {
123+ let len = self . len ( ) ;
124+ to. write_all ( self ) ?;
125+ * self = & self [ len..] ;
126+ Ok ( len as u64 )
127+ }
128+ }
129+
130+ impl < A : Allocator > BufferedReaderSpec for VecDeque < u8 , A > {
131+ fn buffer_size ( & self ) -> usize {
132+ // prefer this specialization since the source "buffer" is all we'll ever need,
133+ // even if it's small
134+ usize:: MAX
135+ }
136+
137+ fn copy_to ( & mut self , to : & mut ( impl Write + ?Sized ) ) -> Result < u64 > {
138+ let len = self . len ( ) ;
139+ let ( front, back) = self . as_slices ( ) ;
140+ let bufs = & mut [ IoSlice :: new ( front) , IoSlice :: new ( back) ] ;
141+ to. write_all_vectored ( bufs) ?;
142+ self . clear ( ) ;
143+ Ok ( len as u64 )
108144 }
109145}
110146
@@ -218,6 +254,47 @@ impl<I: Write + ?Sized> BufferedWriterSpec for BufWriter<I> {
218254 }
219255}
220256
257+ impl < A : Allocator > BufferedWriterSpec for Vec < u8 , A > {
258+ fn buffer_size ( & self ) -> usize {
259+ cmp:: max ( DEFAULT_BUF_SIZE , self . capacity ( ) - self . len ( ) )
260+ }
261+
262+ fn copy_from < R : Read + ?Sized > ( & mut self , reader : & mut R ) -> Result < u64 > {
263+ let mut bytes = 0 ;
264+
265+ // avoid allocating before we have determined that there's anything to read
266+ if self . capacity ( ) == 0 {
267+ bytes = stack_buffer_copy ( & mut reader. take ( DEFAULT_BUF_SIZE as u64 ) , self ) ?;
268+ if bytes == 0 {
269+ return Ok ( 0 ) ;
270+ }
271+ }
272+
273+ loop {
274+ self . reserve ( DEFAULT_BUF_SIZE ) ;
275+ let mut buf: BorrowedBuf < ' _ > = self . spare_capacity_mut ( ) . into ( ) ;
276+ match reader. read_buf ( buf. unfilled ( ) ) {
277+ Ok ( ( ) ) => { }
278+ Err ( e) if e. kind ( ) == ErrorKind :: Interrupted => continue ,
279+ Err ( e) => return Err ( e) ,
280+ } ;
281+
282+ let read = buf. filled ( ) . len ( ) ;
283+ if read == 0 {
284+ break ;
285+ }
286+
287+ // SAFETY: BorrowedBuf guarantees all of its filled bytes are init
288+ // and the number of read bytes can't exceed the spare capacity since
289+ // that's what the buffer is borrowing from.
290+ unsafe { self . set_len ( self . len ( ) + read) } ;
291+ bytes += read as u64 ;
292+ }
293+
294+ Ok ( bytes)
295+ }
296+ }
297+
221298fn stack_buffer_copy < R : Read + ?Sized , W : Write + ?Sized > (
222299 reader : & mut R ,
223300 writer : & mut W ,
0 commit comments