]>
Commit | Line | Data |
---|---|---|
85aaf69f | 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT |
1a4d82fc JJ |
2 | // file at the top-level directory of this distribution and at |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
85aaf69f | 11 | #![allow(missing_copy_implementations)] |
1a4d82fc JJ |
12 | |
13 | use prelude::v1::*; | |
1a4d82fc | 14 | |
c34b1796 | 15 | use io::{self, Read, Write, ErrorKind, BufRead}; |
1a4d82fc | 16 | |
85aaf69f | 17 | /// Copies the entire contents of a reader into a writer. |
1a4d82fc | 18 | /// |
62682a34 SL |
19 | /// This function will continuously read data from `reader` and then |
20 | /// write it into `writer` in a streaming fashion until `reader` | |
21 | /// returns EOF. | |
85aaf69f | 22 | /// |
62682a34 SL |
23 | /// On success, the total number of bytes that were copied from |
24 | /// `reader` to `writer` is returned. | |
85aaf69f SL |
25 | /// |
26 | /// # Errors | |
27 | /// | |
28 | /// This function will return an error immediately if any call to `read` or | |
29 | /// `write` returns an error. All instances of `ErrorKind::Interrupted` are | |
30 | /// handled by this function and the underlying operation is retried. | |
c1a9b12d SL |
31 | /// |
32 | /// # Examples | |
33 | /// | |
34 | /// ``` | |
35 | /// use std::io; | |
36 | /// | |
37 | /// # fn foo() -> io::Result<()> { | |
38 | /// let mut reader: &[u8] = b"hello"; | |
39 | /// let mut writer: Vec<u8> = vec![]; | |
40 | /// | |
41 | /// try!(io::copy(&mut reader, &mut writer)); | |
42 | /// | |
43 | /// assert_eq!(reader, &writer[..]); | |
44 | /// # Ok(()) | |
45 | /// # } | |
46 | /// ``` | |
c34b1796 | 47 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 48 | pub fn copy<R: Read, W: Write>(reader: &mut R, writer: &mut W) -> io::Result<u64> { |
1a4d82fc | 49 | let mut buf = [0; super::DEFAULT_BUF_SIZE]; |
85aaf69f | 50 | let mut written = 0; |
1a4d82fc | 51 | loop { |
62682a34 | 52 | let len = match reader.read(&mut buf) { |
85aaf69f | 53 | Ok(0) => return Ok(written), |
1a4d82fc | 54 | Ok(len) => len, |
85aaf69f | 55 | Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, |
1a4d82fc JJ |
56 | Err(e) => return Err(e), |
57 | }; | |
62682a34 | 58 | try!(writer.write_all(&buf[..len])); |
85aaf69f | 59 | written += len as u64; |
1a4d82fc JJ |
60 | } |
61 | } | |
62 | ||
85aaf69f | 63 | /// A reader which is always at EOF. |
c1a9b12d SL |
64 | /// |
65 | /// This struct is generally created by calling [`empty()`][empty]. Please see | |
66 | /// the documentation of `empty()` for more details. | |
67 | /// | |
68 | /// [empty]: fn.empty.html | |
c34b1796 | 69 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f | 70 | pub struct Empty { _priv: () } |
1a4d82fc | 71 | |
c1a9b12d | 72 | /// Constructs a new handle to an empty reader. |
85aaf69f SL |
73 | /// |
74 | /// All reads from the returned reader will return `Ok(0)`. | |
c1a9b12d SL |
75 | /// |
76 | /// # Examples | |
77 | /// | |
78 | /// A slightly sad example of not reading anything into a buffer: | |
79 | /// | |
80 | /// ``` | |
81 | /// use std::io; | |
82 | /// use std::io::Read; | |
83 | /// | |
84 | /// # fn foo() -> io::Result<String> { | |
85 | /// let mut buffer = String::new(); | |
86 | /// try!(io::empty().read_to_string(&mut buffer)); | |
87 | /// # Ok(buffer) | |
88 | /// # } | |
89 | /// ``` | |
c34b1796 | 90 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f | 91 | pub fn empty() -> Empty { Empty { _priv: () } } |
1a4d82fc | 92 | |
c34b1796 | 93 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
94 | impl Read for Empty { |
95 | fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) } | |
1a4d82fc | 96 | } |
c34b1796 AL |
97 | #[stable(feature = "rust1", since = "1.0.0")] |
98 | impl BufRead for Empty { | |
99 | fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) } | |
100 | fn consume(&mut self, _n: usize) {} | |
101 | } | |
1a4d82fc | 102 | |
c1a9b12d SL |
103 | /// A reader which yields one byte over and over and over and over and over and... |
104 | /// | |
105 | /// This struct is generally created by calling [`repeat()`][repeat]. Please | |
106 | /// see the documentation of `repeat()` for more details. | |
107 | /// | |
108 | /// [repeat]: fn.repeat.html | |
c34b1796 | 109 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f | 110 | pub struct Repeat { byte: u8 } |
1a4d82fc | 111 | |
85aaf69f SL |
112 | /// Creates an instance of a reader that infinitely repeats one byte. |
113 | /// | |
114 | /// All reads from this reader will succeed by filling the specified buffer with | |
115 | /// the given byte. | |
c34b1796 | 116 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
117 | pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } } |
118 | ||
c34b1796 | 119 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
120 | impl Read for Repeat { |
121 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | |
62682a34 | 122 | for slot in &mut *buf { |
85aaf69f | 123 | *slot = self.byte; |
1a4d82fc | 124 | } |
85aaf69f | 125 | Ok(buf.len()) |
1a4d82fc | 126 | } |
85aaf69f | 127 | } |
1a4d82fc | 128 | |
85aaf69f | 129 | /// A writer which will move data into the void. |
c1a9b12d SL |
130 | /// |
131 | /// This struct is generally created by calling [`sink()`][sink]. Please | |
132 | /// see the documentation of `sink()` for more details. | |
133 | /// | |
134 | /// [sink]: fn.sink.html | |
c34b1796 | 135 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f | 136 | pub struct Sink { _priv: () } |
1a4d82fc | 137 | |
85aaf69f SL |
138 | /// Creates an instance of a writer which will successfully consume all data. |
139 | /// | |
140 | /// All calls to `write` on the returned instance will return `Ok(buf.len())` | |
141 | /// and the contents of the buffer will not be inspected. | |
c34b1796 | 142 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f | 143 | pub fn sink() -> Sink { Sink { _priv: () } } |
1a4d82fc | 144 | |
c34b1796 | 145 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
146 | impl Write for Sink { |
147 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) } | |
148 | fn flush(&mut self) -> io::Result<()> { Ok(()) } | |
149 | } | |
1a4d82fc | 150 | |
85aaf69f | 151 | #[cfg(test)] |
d9579d0f | 152 | mod tests { |
85aaf69f | 153 | use prelude::v1::*; |
1a4d82fc | 154 | |
85aaf69f SL |
155 | use io::prelude::*; |
156 | use io::{sink, empty, repeat}; | |
1a4d82fc JJ |
157 | |
158 | #[test] | |
85aaf69f SL |
159 | fn sink_sinks() { |
160 | let mut s = sink(); | |
c34b1796 AL |
161 | assert_eq!(s.write(&[]).unwrap(), 0); |
162 | assert_eq!(s.write(&[0]).unwrap(), 1); | |
163 | assert_eq!(s.write(&[0; 1024]).unwrap(), 1024); | |
164 | assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024); | |
1a4d82fc JJ |
165 | } |
166 | ||
167 | #[test] | |
85aaf69f SL |
168 | fn empty_reads() { |
169 | let mut e = empty(); | |
c34b1796 AL |
170 | assert_eq!(e.read(&mut []).unwrap(), 0); |
171 | assert_eq!(e.read(&mut [0]).unwrap(), 0); | |
172 | assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0); | |
173 | assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0); | |
1a4d82fc JJ |
174 | } |
175 | ||
176 | #[test] | |
85aaf69f SL |
177 | fn repeat_repeats() { |
178 | let mut r = repeat(4); | |
179 | let mut b = [0; 1024]; | |
c34b1796 | 180 | assert_eq!(r.read(&mut b).unwrap(), 1024); |
85aaf69f | 181 | assert!(b.iter().all(|b| *b == 4)); |
1a4d82fc JJ |
182 | } |
183 | ||
184 | #[test] | |
85aaf69f SL |
185 | fn take_some_bytes() { |
186 | assert_eq!(repeat(4).take(100).bytes().count(), 100); | |
c34b1796 | 187 | assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4); |
85aaf69f | 188 | assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20); |
1a4d82fc JJ |
189 | } |
190 | ||
191 | #[test] | |
85aaf69f SL |
192 | fn tee() { |
193 | let mut buf = [0; 10]; | |
1a4d82fc | 194 | { |
85aaf69f | 195 | let mut ptr: &mut [u8] = &mut buf; |
c34b1796 | 196 | assert_eq!(repeat(4).tee(&mut ptr).take(5).read(&mut [0; 10]).unwrap(), 5); |
1a4d82fc | 197 | } |
85aaf69f | 198 | assert_eq!(buf, [4, 4, 4, 4, 4, 0, 0, 0, 0, 0]); |
1a4d82fc JJ |
199 | } |
200 | ||
201 | #[test] | |
85aaf69f SL |
202 | fn broadcast() { |
203 | let mut buf1 = [0; 10]; | |
204 | let mut buf2 = [0; 10]; | |
205 | { | |
206 | let mut ptr1: &mut [u8] = &mut buf1; | |
207 | let mut ptr2: &mut [u8] = &mut buf2; | |
1a4d82fc | 208 | |
85aaf69f | 209 | assert_eq!((&mut ptr1).broadcast(&mut ptr2) |
c34b1796 | 210 | .write(&[1, 2, 3]).unwrap(), 3); |
85aaf69f SL |
211 | } |
212 | assert_eq!(buf1, buf2); | |
213 | assert_eq!(buf1, [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]); | |
1a4d82fc JJ |
214 | } |
215 | } |