1
1
use 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 ;
2
6
use crate :: mem:: MaybeUninit ;
3
7
4
8
#[ cfg( test) ]
86
90
87
91
/// Specialization of the read-write loop that reuses the internal
88
92
/// buffer of a BufReader. If there's no buffer then the writer side
89
- /// should be used intead .
93
+ /// should be used instead .
90
94
trait BufferedReaderSpec {
91
95
fn buffer_size ( & self ) -> usize ;
92
96
@@ -104,7 +108,39 @@ where
104
108
}
105
109
106
110
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 )
108
144
}
109
145
}
110
146
@@ -218,6 +254,47 @@ impl<I: Write + ?Sized> BufferedWriterSpec for BufWriter<I> {
218
254
}
219
255
}
220
256
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
+
221
298
fn stack_buffer_copy < R : Read + ?Sized , W : Write + ?Sized > (
222
299
reader : & mut R ,
223
300
writer : & mut W ,
0 commit comments