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