@@ -2,7 +2,7 @@ use io::prelude::*;
22
33use core:: convert:: TryInto ;
44use cmp;
5- use io:: { self , Initializer , SeekFrom , Error , ErrorKind } ;
5+ use io:: { self , Initializer , SeekFrom , Error , ErrorKind , IoVec , IoVecMut } ;
66
77/// A `Cursor` wraps an in-memory buffer and provides it with a
88/// [`Seek`] implementation.
@@ -221,6 +221,18 @@ impl<T> Read for Cursor<T> where T: AsRef<[u8]> {
221221 Ok ( n)
222222 }
223223
224+ fn read_vectored ( & mut self , bufs : & mut [ IoVecMut < ' _ > ] ) -> io:: Result < usize > {
225+ let mut nread = 0 ;
226+ for buf in bufs {
227+ let n = self . read ( buf) ?;
228+ nread += n;
229+ if n < buf. len ( ) {
230+ break ;
231+ }
232+ }
233+ Ok ( nread)
234+ }
235+
224236 fn read_exact ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < ( ) > {
225237 let n = buf. len ( ) ;
226238 Read :: read_exact ( & mut self . fill_buf ( ) ?, buf) ?;
@@ -251,6 +263,23 @@ fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<us
251263 Ok ( amt)
252264}
253265
266+ fn slice_write_vectored (
267+ pos_mut : & mut u64 ,
268+ slice : & mut [ u8 ] ,
269+ bufs : & [ IoVec < ' _ > ] ,
270+ ) -> io:: Result < usize >
271+ {
272+ let mut nwritten = 0 ;
273+ for buf in bufs {
274+ let n = slice_write ( pos_mut, slice, buf) ?;
275+ nwritten += n;
276+ if n < buf. len ( ) {
277+ break ;
278+ }
279+ }
280+ Ok ( nwritten)
281+ }
282+
254283// Resizing write implementation
255284fn vec_write ( pos_mut : & mut u64 , vec : & mut Vec < u8 > , buf : & [ u8 ] ) -> io:: Result < usize > {
256285 let pos: usize = ( * pos_mut) . try_into ( ) . map_err ( |_| {
@@ -278,12 +307,31 @@ fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usi
278307 Ok ( buf. len ( ) )
279308}
280309
310+ fn vec_write_vectored (
311+ pos_mut : & mut u64 ,
312+ vec : & mut Vec < u8 > ,
313+ bufs : & [ IoVec < ' _ > ] ,
314+ ) -> io:: Result < usize >
315+ {
316+ let mut nwritten = 0 ;
317+ for buf in bufs {
318+ nwritten += vec_write ( pos_mut, vec, buf) ?;
319+ }
320+ Ok ( nwritten)
321+ }
322+
281323#[ stable( feature = "rust1" , since = "1.0.0" ) ]
282324impl Write for Cursor < & mut [ u8 ] > {
283325 #[ inline]
284326 fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
285327 slice_write ( & mut self . pos , self . inner , buf)
286328 }
329+
330+ #[ inline]
331+ fn write_vectored ( & mut self , bufs : & [ IoVec < ' _ > ] ) -> io:: Result < usize > {
332+ slice_write_vectored ( & mut self . pos , self . inner , bufs)
333+ }
334+
287335 fn flush ( & mut self ) -> io:: Result < ( ) > { Ok ( ( ) ) }
288336}
289337
@@ -292,6 +340,11 @@ impl Write for Cursor<&mut Vec<u8>> {
292340 fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
293341 vec_write ( & mut self . pos , self . inner , buf)
294342 }
343+
344+ fn write_vectored ( & mut self , bufs : & [ IoVec < ' _ > ] ) -> io:: Result < usize > {
345+ vec_write_vectored ( & mut self . pos , self . inner , bufs)
346+ }
347+
295348 fn flush ( & mut self ) -> io:: Result < ( ) > { Ok ( ( ) ) }
296349}
297350
@@ -300,6 +353,11 @@ impl Write for Cursor<Vec<u8>> {
300353 fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
301354 vec_write ( & mut self . pos , & mut self . inner , buf)
302355 }
356+
357+ fn write_vectored ( & mut self , bufs : & [ IoVec < ' _ > ] ) -> io:: Result < usize > {
358+ vec_write_vectored ( & mut self . pos , & mut self . inner , bufs)
359+ }
360+
303361 fn flush ( & mut self ) -> io:: Result < ( ) > { Ok ( ( ) ) }
304362}
305363
@@ -309,21 +367,30 @@ impl Write for Cursor<Box<[u8]>> {
309367 fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
310368 slice_write ( & mut self . pos , & mut self . inner , buf)
311369 }
370+
371+ #[ inline]
372+ fn write_vectored ( & mut self , bufs : & [ IoVec < ' _ > ] ) -> io:: Result < usize > {
373+ slice_write_vectored ( & mut self . pos , & mut self . inner , bufs)
374+ }
375+
312376 fn flush ( & mut self ) -> io:: Result < ( ) > { Ok ( ( ) ) }
313377}
314378
315379#[ cfg( test) ]
316380mod tests {
317381 use io:: prelude:: * ;
318- use io:: { Cursor , SeekFrom } ;
382+ use io:: { Cursor , SeekFrom , IoVec , IoVecMut } ;
319383
320384 #[ test]
321385 fn test_vec_writer ( ) {
322386 let mut writer = Vec :: new ( ) ;
323387 assert_eq ! ( writer. write( & [ 0 ] ) . unwrap( ) , 1 ) ;
324388 assert_eq ! ( writer. write( & [ 1 , 2 , 3 ] ) . unwrap( ) , 3 ) ;
325389 assert_eq ! ( writer. write( & [ 4 , 5 , 6 , 7 ] ) . unwrap( ) , 4 ) ;
326- let b: & [ _ ] = & [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ;
390+ assert_eq ! ( writer. write_vectored(
391+ & [ IoVec :: new( & [ ] ) , IoVec :: new( & [ 8 , 9 ] ) , IoVec :: new( & [ 10 ] ) ] ,
392+ ) . unwrap( ) , 3 ) ;
393+ let b: & [ _ ] = & [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] ;
327394 assert_eq ! ( writer, b) ;
328395 }
329396
@@ -333,7 +400,10 @@ mod tests {
333400 assert_eq ! ( writer. write( & [ 0 ] ) . unwrap( ) , 1 ) ;
334401 assert_eq ! ( writer. write( & [ 1 , 2 , 3 ] ) . unwrap( ) , 3 ) ;
335402 assert_eq ! ( writer. write( & [ 4 , 5 , 6 , 7 ] ) . unwrap( ) , 4 ) ;
336- let b: & [ _ ] = & [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ;
403+ assert_eq ! ( writer. write_vectored(
404+ & [ IoVec :: new( & [ ] ) , IoVec :: new( & [ 8 , 9 ] ) , IoVec :: new( & [ 10 ] ) ] ,
405+ ) . unwrap( ) , 3 ) ;
406+ let b: & [ _ ] = & [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] ;
337407 assert_eq ! ( & writer. get_ref( ) [ ..] , b) ;
338408 }
339409
@@ -344,7 +414,10 @@ mod tests {
344414 assert_eq ! ( writer. write( & [ 0 ] ) . unwrap( ) , 1 ) ;
345415 assert_eq ! ( writer. write( & [ 1 , 2 , 3 ] ) . unwrap( ) , 3 ) ;
346416 assert_eq ! ( writer. write( & [ 4 , 5 , 6 , 7 ] ) . unwrap( ) , 4 ) ;
347- let b: & [ _ ] = & [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ;
417+ assert_eq ! ( writer. write_vectored(
418+ & [ IoVec :: new( & [ ] ) , IoVec :: new( & [ 8 , 9 ] ) , IoVec :: new( & [ 10 ] ) ] ,
419+ ) . unwrap( ) , 3 ) ;
420+ let b: & [ _ ] = & [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] ;
348421 assert_eq ! ( & writer. get_ref( ) [ ..] , b) ;
349422 }
350423
@@ -366,6 +439,26 @@ mod tests {
366439 assert_eq ! ( & * * writer. get_ref( ) , b) ;
367440 }
368441
442+ #[ test]
443+ fn test_box_slice_writer_vectored ( ) {
444+ let mut writer = Cursor :: new ( vec ! [ 0u8 ; 9 ] . into_boxed_slice ( ) ) ;
445+ assert_eq ! ( writer. position( ) , 0 ) ;
446+ assert_eq ! ( writer. write_vectored( & [ IoVec :: new( & [ 0 ] ) ] ) . unwrap( ) , 1 ) ;
447+ assert_eq ! ( writer. position( ) , 1 ) ;
448+ assert_eq ! (
449+ writer. write_vectored( & [ IoVec :: new( & [ 1 , 2 , 3 ] ) , IoVec :: new( & [ 4 , 5 , 6 , 7 ] ) ] ) . unwrap( ) ,
450+ 7 ,
451+ ) ;
452+ assert_eq ! ( writer. position( ) , 8 ) ;
453+ assert_eq ! ( writer. write_vectored( & [ ] ) . unwrap( ) , 0 ) ;
454+ assert_eq ! ( writer. position( ) , 8 ) ;
455+
456+ assert_eq ! ( writer. write_vectored( & [ IoVec :: new( & [ 8 , 9 ] ) ] ) . unwrap( ) , 1 ) ;
457+ assert_eq ! ( writer. write_vectored( & [ IoVec :: new( & [ 10 ] ) ] ) . unwrap( ) , 0 ) ;
458+ let b: & [ _ ] = & [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ;
459+ assert_eq ! ( & * * writer. get_ref( ) , b) ;
460+ }
461+
369462 #[ test]
370463 fn test_buf_writer ( ) {
371464 let mut buf = [ 0 as u8 ; 9 ] ;
@@ -387,6 +480,31 @@ mod tests {
387480 assert_eq ! ( buf, b) ;
388481 }
389482
483+ #[ test]
484+ fn test_buf_writer_vectored ( ) {
485+ let mut buf = [ 0 as u8 ; 9 ] ;
486+ {
487+ let mut writer = Cursor :: new ( & mut buf[ ..] ) ;
488+ assert_eq ! ( writer. position( ) , 0 ) ;
489+ assert_eq ! ( writer. write_vectored( & [ IoVec :: new( & [ 0 ] ) ] ) . unwrap( ) , 1 ) ;
490+ assert_eq ! ( writer. position( ) , 1 ) ;
491+ assert_eq ! (
492+ writer. write_vectored(
493+ & [ IoVec :: new( & [ 1 , 2 , 3 ] ) , IoVec :: new( & [ 4 , 5 , 6 , 7 ] ) ] ,
494+ ) . unwrap( ) ,
495+ 7 ,
496+ ) ;
497+ assert_eq ! ( writer. position( ) , 8 ) ;
498+ assert_eq ! ( writer. write_vectored( & [ ] ) . unwrap( ) , 0 ) ;
499+ assert_eq ! ( writer. position( ) , 8 ) ;
500+
501+ assert_eq ! ( writer. write_vectored( & [ IoVec :: new( & [ 8 , 9 ] ) ] ) . unwrap( ) , 1 ) ;
502+ assert_eq ! ( writer. write_vectored( & [ IoVec :: new( & [ 10 ] ) ] ) . unwrap( ) , 0 ) ;
503+ }
504+ let b: & [ _ ] = & [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ;
505+ assert_eq ! ( buf, b) ;
506+ }
507+
390508 #[ test]
391509 fn test_buf_writer_seek ( ) {
392510 let mut buf = [ 0 as u8 ; 8 ] ;
@@ -447,6 +565,35 @@ mod tests {
447565 assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 0 ) ;
448566 }
449567
568+ #[ test]
569+ fn test_mem_reader_vectored ( ) {
570+ let mut reader = Cursor :: new ( vec ! [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ) ;
571+ let mut buf = [ ] ;
572+ assert_eq ! ( reader. read_vectored( & mut [ IoVecMut :: new( & mut buf) ] ) . unwrap( ) , 0 ) ;
573+ assert_eq ! ( reader. position( ) , 0 ) ;
574+ let mut buf = [ 0 ] ;
575+ assert_eq ! (
576+ reader. read_vectored( & mut [ IoVecMut :: new( & mut [ ] ) , IoVecMut :: new( & mut buf) ] ) . unwrap( ) ,
577+ 1 ,
578+ ) ;
579+ assert_eq ! ( reader. position( ) , 1 ) ;
580+ let b: & [ _ ] = & [ 0 ] ;
581+ assert_eq ! ( buf, b) ;
582+ let mut buf1 = [ 0 ; 4 ] ;
583+ let mut buf2 = [ 0 ; 4 ] ;
584+ assert_eq ! (
585+ reader. read_vectored(
586+ & mut [ IoVecMut :: new( & mut buf1) , IoVecMut :: new( & mut buf2) ] ,
587+ ) . unwrap( ) ,
588+ 7 ,
589+ ) ;
590+ let b1: & [ _ ] = & [ 1 , 2 , 3 , 4 ] ;
591+ let b2: & [ _ ] = & [ 5 , 6 , 7 ] ;
592+ assert_eq ! ( buf1, b1) ;
593+ assert_eq ! ( & buf2[ ..3 ] , b2) ;
594+ assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 0 ) ;
595+ }
596+
450597 #[ test]
451598 fn test_boxed_slice_reader ( ) {
452599 let mut reader = Cursor :: new ( vec ! [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] . into_boxed_slice ( ) ) ;
@@ -469,6 +616,35 @@ mod tests {
469616 assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 0 ) ;
470617 }
471618
619+ #[ test]
620+ fn test_boxed_slice_reader_vectored ( ) {
621+ let mut reader = Cursor :: new ( vec ! [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] . into_boxed_slice ( ) ) ;
622+ let mut buf = [ ] ;
623+ assert_eq ! ( reader. read_vectored( & mut [ IoVecMut :: new( & mut buf) ] ) . unwrap( ) , 0 ) ;
624+ assert_eq ! ( reader. position( ) , 0 ) ;
625+ let mut buf = [ 0 ] ;
626+ assert_eq ! (
627+ reader. read_vectored( & mut [ IoVecMut :: new( & mut [ ] ) , IoVecMut :: new( & mut buf) ] ) . unwrap( ) ,
628+ 1 ,
629+ ) ;
630+ assert_eq ! ( reader. position( ) , 1 ) ;
631+ let b: & [ _ ] = & [ 0 ] ;
632+ assert_eq ! ( buf, b) ;
633+ let mut buf1 = [ 0 ; 4 ] ;
634+ let mut buf2 = [ 0 ; 4 ] ;
635+ assert_eq ! (
636+ reader. read_vectored(
637+ & mut [ IoVecMut :: new( & mut buf1) , IoVecMut :: new( & mut buf2) ] ,
638+ ) . unwrap( ) ,
639+ 7 ,
640+ ) ;
641+ let b1: & [ _ ] = & [ 1 , 2 , 3 , 4 ] ;
642+ let b2: & [ _ ] = & [ 5 , 6 , 7 ] ;
643+ assert_eq ! ( buf1, b1) ;
644+ assert_eq ! ( & buf2[ ..3 ] , b2) ;
645+ assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 0 ) ;
646+ }
647+
472648 #[ test]
473649 fn read_to_end ( ) {
474650 let mut reader = Cursor :: new ( vec ! [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ) ;
@@ -499,6 +675,35 @@ mod tests {
499675 assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 0 ) ;
500676 }
501677
678+ #[ test]
679+ fn test_slice_reader_vectored ( ) {
680+ let in_buf = vec ! [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ;
681+ let reader = & mut & in_buf[ ..] ;
682+ let mut buf = [ ] ;
683+ assert_eq ! ( reader. read_vectored( & mut [ IoVecMut :: new( & mut buf) ] ) . unwrap( ) , 0 ) ;
684+ let mut buf = [ 0 ] ;
685+ assert_eq ! (
686+ reader. read_vectored( & mut [ IoVecMut :: new( & mut [ ] ) , IoVecMut :: new( & mut buf) ] ) . unwrap( ) ,
687+ 1 ,
688+ ) ;
689+ assert_eq ! ( reader. len( ) , 7 ) ;
690+ let b: & [ _ ] = & [ 0 ] ;
691+ assert_eq ! ( buf, b) ;
692+ let mut buf1 = [ 0 ; 4 ] ;
693+ let mut buf2 = [ 0 ; 4 ] ;
694+ assert_eq ! (
695+ reader. read_vectored(
696+ & mut [ IoVecMut :: new( & mut buf1) , IoVecMut :: new( & mut buf2) ] ,
697+ ) . unwrap( ) ,
698+ 7 ,
699+ ) ;
700+ let b1: & [ _ ] = & [ 1 , 2 , 3 , 4 ] ;
701+ let b2: & [ _ ] = & [ 5 , 6 , 7 ] ;
702+ assert_eq ! ( buf1, b1) ;
703+ assert_eq ! ( & buf2[ ..3 ] , b2) ;
704+ assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 0 ) ;
705+ }
706+
502707 #[ test]
503708 fn test_read_exact ( ) {
504709 let in_buf = vec ! [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ;
0 commit comments