(index<- ) ./libstd/io/util.rs
git branch: * master 5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
modified: Fri May 9 13:02:28 2014
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
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
11 /*! Utility implementations of Reader and Writer */
12
13 use prelude::*;
14 use cmp;
15 use io;
16 use owned::Box;
17 use slice::bytes::MutableByteVector;
18
19 /// Wraps a `Reader`, limiting the number of bytes that can be read from it.
20 pub struct LimitReader<R> {
21 limit: uint,
22 inner: R
23 }
24
25 impl<R: Reader> LimitReader<R> {
26 /// Creates a new `LimitReader`
27 pub fn new(r: R, limit: uint) -> LimitReader<R> {
28 LimitReader { limit: limit, inner: r }
29 }
30
31 /// Consumes the `LimitReader`, returning the underlying `Reader`.
32 pub fn unwrap(self) -> R { self.inner }
33
34 /// Returns the number of bytes that can be read before the `LimitReader`
35 /// will return EOF.
36 ///
37 /// # Note
38 ///
39 /// The reader may reach EOF after reading fewer bytes than indicated by
40 /// this method if the underlying reader reaches EOF.
41 pub fn limit(&self) -> uint { self.limit }
42 }
43
44 impl<R: Reader> Reader for LimitReader<R> {
45 fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
46 if self.limit == 0 {
47 return Err(io::standard_error(io::EndOfFile));
48 }
49
50 let len = cmp::min(self.limit, buf.len());
51 self.inner.read(buf.mut_slice_to(len)).map(|len| {
52 self.limit -= len;
53 len
54 })
55 }
56 }
57
58 impl<R: Buffer> Buffer for LimitReader<R> {
59 fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
60 let amt = try!(self.inner.fill_buf());
61 let buf = amt.slice_to(cmp::min(amt.len(), self.limit));
62 if buf.len() == 0 {
63 Err(io::standard_error(io::EndOfFile))
64 } else {
65 Ok(buf)
66 }
67 }
68
69 fn consume(&mut self, amt: uint) {
70 self.limit -= amt;
71 self.inner.consume(amt);
72 }
73
74 }
75
76 /// A `Writer` which ignores bytes written to it, like /dev/null.
77 pub struct NullWriter;
78
79 impl Writer for NullWriter {
80 #[inline]
81 fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> { Ok(()) }
82 }
83
84 /// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
85 pub struct ZeroReader;
86
87 impl Reader for ZeroReader {
88 #[inline]
89 fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
90 buf.set_memory(0);
91 Ok(buf.len())
92 }
93 }
94
95 impl Buffer for ZeroReader {
96 fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
97 static DATA: [u8, ..64] = [0, ..64];
98 Ok(DATA.as_slice())
99 }
100 fn consume(&mut self, _amt: uint) {}
101 }
102
103 /// A `Reader` which is always at EOF, like /dev/null.
104 pub struct NullReader;
105
106 impl Reader for NullReader {
107 #[inline]
108 fn read(&mut self, _buf: &mut [u8]) -> io::IoResult<uint> {
109 Err(io::standard_error(io::EndOfFile))
110 }
111 }
112
113 impl Buffer for NullReader {
114 fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
115 Err(io::standard_error(io::EndOfFile))
116 }
117 fn consume(&mut self, _amt: uint) {}
118 }
119
120 /// A `Writer` which multiplexes writes to a set of `Writers`.
121 pub struct MultiWriter {
122 writers: Vec<Box<Writer>>
123 }
124
125 impl MultiWriter {
126 /// Creates a new `MultiWriter`
127 pub fn new(writers: Vec<Box<Writer>>) -> MultiWriter {
128 MultiWriter { writers: writers }
129 }
130 }
131
132 impl Writer for MultiWriter {
133 #[inline]
134 fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
135 let mut ret = Ok(());
136 for writer in self.writers.mut_iter() {
137 ret = ret.and(writer.write(buf));
138 }
139 return ret;
140 }
141
142 #[inline]
143 fn flush(&mut self) -> io::IoResult<()> {
144 let mut ret = Ok(());
145 for writer in self.writers.mut_iter() {
146 ret = ret.and(writer.flush());
147 }
148 return ret;
149 }
150 }
151
152 /// A `Reader` which chains input from multiple `Readers`, reading each to
153 /// completion before moving onto the next.
154 pub struct ChainedReader<I, R> {
155 readers: I,
156 cur_reader: Option<R>,
157 }
158
159 impl<R: Reader, I: Iterator<R>> ChainedReader<I, R> {
160 /// Creates a new `ChainedReader`
161 pub fn new(mut readers: I) -> ChainedReader<I, R> {
162 let r = readers.next();
163 ChainedReader { readers: readers, cur_reader: r }
164 }
165 }
166
167 impl<R: Reader, I: Iterator<R>> Reader for ChainedReader<I, R> {
168 fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
169 loop {
170 let err = match self.cur_reader {
171 Some(ref mut r) => {
172 match r.read(buf) {
173 Ok(len) => return Ok(len),
174 Err(ref e) if e.kind == io::EndOfFile => None,
175 Err(e) => Some(e),
176 }
177 }
178 None => break
179 };
180 self.cur_reader = self.readers.next();
181 match err {
182 Some(e) => return Err(e),
183 None => {}
184 }
185 }
186 Err(io::standard_error(io::EndOfFile))
187 }
188 }
189
190 /// A `Reader` which forwards input from another `Reader`, passing it along to
191 /// a `Writer` as well. Similar to the `tee(1)` command.
192 pub struct TeeReader<R, W> {
193 reader: R,
194 writer: W,
195 }
196
197 impl<R: Reader, W: Writer> TeeReader<R, W> {
198 /// Creates a new `TeeReader`
199 pub fn new(r: R, w: W) -> TeeReader<R, W> {
200 TeeReader { reader: r, writer: w }
201 }
202
203 /// Consumes the `TeeReader`, returning the underlying `Reader` and
204 /// `Writer`.
205 pub fn unwrap(self) -> (R, W) {
206 let TeeReader { reader, writer } = self;
207 (reader, writer)
208 }
209 }
210
211 impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
212 fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
213 self.reader.read(buf).and_then(|len| {
214 self.writer.write(buf.slice_to(len)).map(|()| len)
215 })
216 }
217 }
218
219 /// Copies all data from a `Reader` to a `Writer`.
220 pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
221 let mut buf = [0, ..super::DEFAULT_BUF_SIZE];
222 loop {
223 let len = match r.read(buf) {
224 Ok(len) => len,
225 Err(ref e) if e.kind == io::EndOfFile => return Ok(()),
226 Err(e) => return Err(e),
227 };
228 try!(w.write(buf.slice_to(len)));
229 }
230 }
231
232 #[cfg(test)]
233 mod test {
234 use io::{MemReader, MemWriter, BufReader};
235 use io;
236 use owned::Box;
237 use super::*;
238 use prelude::*;
239
240 #[test]
241 fn test_limit_reader_unlimited() {
242 let mut r = MemReader::new(vec!(0, 1, 2));
243 {
244 let mut r = LimitReader::new(r.by_ref(), 4);
245 assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
246 }
247 }
248
249 #[test]
250 fn test_limit_reader_limited() {
251 let mut r = MemReader::new(vec!(0, 1, 2));
252 {
253 let mut r = LimitReader::new(r.by_ref(), 2);
254 assert_eq!(vec!(0, 1), r.read_to_end().unwrap());
255 }
256 assert_eq!(vec!(2), r.read_to_end().unwrap());
257 }
258
259 #[test]
260 fn test_limit_reader_limit() {
261 let r = MemReader::new(vec!(0, 1, 2));
262 let mut r = LimitReader::new(r, 3);
263 assert_eq!(3, r.limit());
264 assert_eq!(0, r.read_byte().unwrap());
265 assert_eq!(2, r.limit());
266 assert_eq!(vec!(1, 2), r.read_to_end().unwrap());
267 assert_eq!(0, r.limit());
268 }
269
270 #[test]
271 fn test_null_writer() {
272 let mut s = NullWriter;
273 let buf = box [0, 0, 0];
274 s.write(buf).unwrap();
275 s.flush().unwrap();
276 }
277
278 #[test]
279 fn test_zero_reader() {
280 let mut s = ZeroReader;
281 let mut buf = box [1, 2, 3];
282 assert_eq!(s.read(buf), Ok(3));
283 assert_eq!(box [0, 0, 0], buf);
284 }
285
286 #[test]
287 fn test_null_reader() {
288 let mut r = NullReader;
289 let mut buf = box [0];
290 assert!(r.read(buf).is_err());
291 }
292
293 #[test]
294 fn test_multi_writer() {
295 static mut writes: uint = 0;
296 static mut flushes: uint = 0;
297
298 struct TestWriter;
299 impl Writer for TestWriter {
300 fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> {
301 unsafe { writes += 1 }
302 Ok(())
303 }
304
305 fn flush(&mut self) -> io::IoResult<()> {
306 unsafe { flushes += 1 }
307 Ok(())
308 }
309 }
310
311 let mut multi = MultiWriter::new(vec!(box TestWriter as Box<Writer>,
312 box TestWriter as Box<Writer>));
313 multi.write([1, 2, 3]).unwrap();
314 assert_eq!(2, unsafe { writes });
315 assert_eq!(0, unsafe { flushes });
316 multi.flush().unwrap();
317 assert_eq!(2, unsafe { writes });
318 assert_eq!(2, unsafe { flushes });
319 }
320
321 #[test]
322 fn test_chained_reader() {
323 let rs = vec!(MemReader::new(vec!(0, 1)), MemReader::new(vec!()),
324 MemReader::new(vec!(2, 3)));
325 let mut r = ChainedReader::new(rs.move_iter());
326 assert_eq!(vec!(0, 1, 2, 3), r.read_to_end().unwrap());
327 }
328
329 #[test]
330 fn test_tee_reader() {
331 let mut r = TeeReader::new(MemReader::new(vec!(0, 1, 2)),
332 MemWriter::new());
333 assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
334 let (_, w) = r.unwrap();
335 assert_eq!(vec!(0, 1, 2), w.unwrap());
336 }
337
338 #[test]
339 fn test_copy() {
340 let mut r = MemReader::new(vec!(0, 1, 2, 3, 4));
341 let mut w = MemWriter::new();
342 copy(&mut r, &mut w).unwrap();
343 assert_eq!(vec!(0, 1, 2, 3, 4), w.unwrap());
344 }
345
346 #[test]
347 fn limit_reader_buffer() {
348 let data = "0123456789\n0123456789\n";
349 let mut r = BufReader::new(data.as_bytes());
350 {
351 let mut r = LimitReader::new(r.by_ref(), 3);
352 assert_eq!(r.read_line(), Ok("012".to_str()));
353 assert_eq!(r.limit(), 0);
354 assert_eq!(r.read_line().err().unwrap().kind, io::EndOfFile);
355 }
356 {
357 let mut r = LimitReader::new(r.by_ref(), 9);
358 assert_eq!(r.read_line(), Ok("3456789\n".to_str()));
359 assert_eq!(r.limit(), 1);
360 assert_eq!(r.read_line(), Ok("0".to_str()));
361 }
362 {
363 let mut r = LimitReader::new(r.by_ref(), 100);
364 assert_eq!(r.read_char(), Ok('1'));
365 assert_eq!(r.limit(), 99);
366 assert_eq!(r.read_line(), Ok("23456789\n".to_str()));
367 }
368 }
369 }
libstd/io/util.rs:153:44-153:44 -struct- definition:
/// completion before moving onto the next.
pub struct ChainedReader<I, R> {
readers: I,
references:- 4162: let r = readers.next();
163: ChainedReader { readers: readers, cur_reader: r }
164: }
--
167: impl<R: Reader, I: Iterator<R>> Reader for ChainedReader<I, R> {
168: fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
libstd/io/util.rs:84:76-84:76 -struct- definition:
/// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
pub struct ZeroReader;
impl Reader for ZeroReader {
references:- 295: impl Buffer for ZeroReader {
96: fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
libstd/io/util.rs:19:77-19:77 -struct- definition:
/// Wraps a `Reader`, limiting the number of bytes that can be read from it.
pub struct LimitReader<R> {
limit: uint,
references:- 527: pub fn new(r: R, limit: uint) -> LimitReader<R> {
28: LimitReader { limit: limit, inner: r }
29: }
--
58: impl<R: Buffer> Buffer for LimitReader<R> {
59: fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
libstd/io/util.rs:103:55-103:55 -struct- definition:
/// A `Reader` which is always at EOF, like /dev/null.
pub struct NullReader;
impl Reader for NullReader {
references:- 2113: impl Buffer for NullReader {
114: fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
libstd/io/util.rs:191:57-191:57 -struct- definition:
/// a `Writer` as well. Similar to the `tee(1)` command.
pub struct TeeReader<R, W> {
reader: R,
references:- 5199: pub fn new(r: R, w: W) -> TeeReader<R, W> {
200: TeeReader { reader: r, writer: w }
201: }
--
205: pub fn unwrap(self) -> (R, W) {
206: let TeeReader { reader, writer } = self;
207: (reader, writer)
--
211: impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
212: fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
libstd/io/util.rs:120:63-120:63 -struct- definition:
/// A `Writer` which multiplexes writes to a set of `Writers`.
pub struct MultiWriter {
writers: Vec<Box<Writer>>
references:- 4132: impl Writer for MultiWriter {
133: #[inline]