1 use crate::cmp::{max, min};
2 use crate::io::*;
3
4 #[test]
copy_copies()5 fn copy_copies() {
6 let mut r = repeat(0).take(4);
7 let mut w = sink();
8 assert_eq!(copy(&mut r, &mut w).unwrap(), 4);
9
10 let mut r = repeat(0).take(1 << 17);
11 assert_eq!(copy(&mut r as &mut dyn Read, &mut w as &mut dyn Write).unwrap(), 1 << 17);
12 }
13
14 struct ShortReader {
15 cap: usize,
16 read_size: usize,
17 observed_buffer: usize,
18 }
19
20 impl Read for ShortReader {
read(&mut self, buf: &mut [u8]) -> Result<usize>21 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
22 let bytes = min(self.cap, self.read_size);
23 self.cap -= bytes;
24 self.observed_buffer = max(self.observed_buffer, buf.len());
25 Ok(bytes)
26 }
27 }
28
29 struct WriteObserver {
30 observed_buffer: usize,
31 }
32
33 impl Write for WriteObserver {
write(&mut self, buf: &[u8]) -> Result<usize>34 fn write(&mut self, buf: &[u8]) -> Result<usize> {
35 self.observed_buffer = max(self.observed_buffer, buf.len());
36 Ok(buf.len())
37 }
38
flush(&mut self) -> Result<()>39 fn flush(&mut self) -> Result<()> {
40 Ok(())
41 }
42 }
43
44 #[test]
copy_specializes_bufwriter()45 fn copy_specializes_bufwriter() {
46 let cap = 117 * 1024;
47 let buf_sz = 16 * 1024;
48 let mut r = ShortReader { cap, observed_buffer: 0, read_size: 1337 };
49 let mut w = BufWriter::with_capacity(buf_sz, WriteObserver { observed_buffer: 0 });
50 assert_eq!(
51 copy(&mut r, &mut w).unwrap(),
52 cap as u64,
53 "expected the whole capacity to be copied"
54 );
55 assert_eq!(r.observed_buffer, buf_sz, "expected a large buffer to be provided to the reader");
56 assert!(w.get_mut().observed_buffer > DEFAULT_BUF_SIZE, "expected coalesced writes");
57 }
58
59 #[test]
copy_specializes_bufreader()60 fn copy_specializes_bufreader() {
61 let mut source = vec![0; 768 * 1024];
62 source[1] = 42;
63 let mut buffered = BufReader::with_capacity(256 * 1024, Cursor::new(&mut source));
64
65 let mut sink = Vec::new();
66 assert_eq!(crate::io::copy(&mut buffered, &mut sink).unwrap(), source.len() as u64);
67 assert_eq!(source.as_slice(), sink.as_slice());
68
69 let buf_sz = 71 * 1024;
70 assert!(buf_sz > DEFAULT_BUF_SIZE, "test precondition");
71
72 let mut buffered = BufReader::with_capacity(buf_sz, Cursor::new(&mut source));
73 let mut sink = WriteObserver { observed_buffer: 0 };
74 assert_eq!(crate::io::copy(&mut buffered, &mut sink).unwrap(), source.len() as u64);
75 assert_eq!(
76 sink.observed_buffer, buf_sz,
77 "expected a large buffer to be provided to the writer"
78 );
79 }
80
81 #[cfg(unix)]
82 mod io_benches {
83 use crate::fs::File;
84 use crate::fs::OpenOptions;
85 use crate::io::prelude::*;
86 use crate::io::BufReader;
87
88 use test::Bencher;
89
90 #[bench]
bench_copy_buf_reader(b: &mut Bencher)91 fn bench_copy_buf_reader(b: &mut Bencher) {
92 let mut file_in = File::open("/dev/zero").expect("opening /dev/zero failed");
93 // use dyn to avoid specializations unrelated to readbuf
94 let dyn_in = &mut file_in as &mut dyn Read;
95 let mut reader = BufReader::with_capacity(256 * 1024, dyn_in.take(0));
96 let mut writer =
97 OpenOptions::new().write(true).open("/dev/null").expect("opening /dev/null failed");
98
99 const BYTES: u64 = 1024 * 1024;
100
101 b.bytes = BYTES;
102
103 b.iter(|| {
104 reader.get_mut().set_limit(BYTES);
105 crate::io::copy(&mut reader, &mut writer).unwrap()
106 });
107 }
108 }
109