]> git.lizzy.rs Git - rust.git/blob - src/libstd/io/util.rs
8e0cd6608164a2cee1688e8767d138f6b7d70772
[rust.git] / src / libstd / io / util.rs
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 slice::bytes::MutableByteVector;
17
18 /// Wraps a `Reader`, limiting the number of bytes that can be read from it.
19 pub struct LimitReader<R> {
20     limit: uint,
21     inner: R
22 }
23
24 impl<R: Reader> LimitReader<R> {
25     /// Creates a new `LimitReader`
26     pub fn new(r: R, limit: uint) -> LimitReader<R> {
27         LimitReader { limit: limit, inner: r }
28     }
29
30     /// Consumes the `LimitReader`, returning the underlying `Reader`.
31     pub fn into_inner(self) -> R { self.inner }
32
33     /// Deprecated, use into_inner() instead
34     #[deprecated = "renamed to into_inner"]
35     pub fn unwrap(self) -> R { self.into_inner() }
36
37     /// Returns the number of bytes that can be read before the `LimitReader`
38     /// will return EOF.
39     ///
40     /// # Note
41     ///
42     /// The reader may reach EOF after reading fewer bytes than indicated by
43     /// this method if the underlying reader reaches EOF.
44     pub fn limit(&self) -> uint { self.limit }
45 }
46
47 impl<R: Reader> Reader for LimitReader<R> {
48     fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
49         if self.limit == 0 {
50             return Err(io::standard_error(io::EndOfFile));
51         }
52
53         let len = cmp::min(self.limit, buf.len());
54         let res = self.inner.read(buf[mut ..len]);
55         match res {
56             Ok(len) => self.limit -= len,
57             _ => {}
58         }
59         res
60     }
61 }
62
63 impl<R: Buffer> Buffer for LimitReader<R> {
64     fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
65         let amt = try!(self.inner.fill_buf());
66         let buf = amt[..cmp::min(amt.len(), self.limit)];
67         if buf.len() == 0 {
68             Err(io::standard_error(io::EndOfFile))
69         } else {
70             Ok(buf)
71         }
72     }
73
74     fn consume(&mut self, amt: uint) {
75         // Don't let callers reset the limit by passing an overlarge value
76         let amt = cmp::min(amt, self.limit);
77         self.limit -= amt;
78         self.inner.consume(amt);
79     }
80
81 }
82
83 /// A `Writer` which ignores bytes written to it, like /dev/null.
84 pub struct NullWriter;
85
86 impl Writer for NullWriter {
87     #[inline]
88     fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> { Ok(()) }
89 }
90
91 /// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
92 pub struct ZeroReader;
93
94 impl Reader for ZeroReader {
95     #[inline]
96     fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
97         buf.set_memory(0);
98         Ok(buf.len())
99     }
100 }
101
102 impl Buffer for ZeroReader {
103     fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
104         static DATA: [u8, ..64] = [0, ..64];
105         Ok(DATA.as_slice())
106     }
107
108     fn consume(&mut self, _amt: uint) {}
109 }
110
111 /// A `Reader` which is always at EOF, like /dev/null.
112 pub struct NullReader;
113
114 impl Reader for NullReader {
115     #[inline]
116     fn read(&mut self, _buf: &mut [u8]) -> io::IoResult<uint> {
117         Err(io::standard_error(io::EndOfFile))
118     }
119 }
120
121 impl Buffer for NullReader {
122     fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> {
123         Err(io::standard_error(io::EndOfFile))
124     }
125     fn consume(&mut self, _amt: uint) {}
126 }
127
128 /// A `Writer` which multiplexes writes to a set of `Writer`s.
129 ///
130 /// The `Writer`s are delegated to in order. If any `Writer` returns an error,
131 /// that error is returned immediately and remaining `Writer`s are not called.
132 pub struct MultiWriter {
133     writers: Vec<Box<Writer+'static>>
134 }
135
136 impl MultiWriter {
137     /// Creates a new `MultiWriter`
138     pub fn new(writers: Vec<Box<Writer+'static>>) -> MultiWriter {
139         MultiWriter { writers: writers }
140     }
141 }
142
143 impl Writer for MultiWriter {
144     #[inline]
145     fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
146         for writer in self.writers.iter_mut() {
147             try!(writer.write(buf));
148         }
149         Ok(())
150     }
151
152     #[inline]
153     fn flush(&mut self) -> io::IoResult<()> {
154         for writer in self.writers.iter_mut() {
155             try!(writer.flush());
156         }
157         Ok(())
158     }
159 }
160
161 /// A `Reader` which chains input from multiple `Reader`s, reading each to
162 /// completion before moving onto the next.
163 pub struct ChainedReader<I, R> {
164     readers: I,
165     cur_reader: Option<R>,
166 }
167
168 impl<R: Reader, I: Iterator<R>> ChainedReader<I, R> {
169     /// Creates a new `ChainedReader`
170     pub fn new(mut readers: I) -> ChainedReader<I, R> {
171         let r = readers.next();
172         ChainedReader { readers: readers, cur_reader: r }
173     }
174 }
175
176 impl<R: Reader, I: Iterator<R>> Reader for ChainedReader<I, R> {
177     fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
178         loop {
179             let err = match self.cur_reader {
180                 Some(ref mut r) => {
181                     match r.read(buf) {
182                         Ok(len) => return Ok(len),
183                         Err(ref e) if e.kind == io::EndOfFile => None,
184                         Err(e) => Some(e),
185                     }
186                 }
187                 None => break
188             };
189             self.cur_reader = self.readers.next();
190             match err {
191                 Some(e) => return Err(e),
192                 None => {}
193             }
194         }
195         Err(io::standard_error(io::EndOfFile))
196     }
197 }
198
199 /// A `Reader` which forwards input from another `Reader`, passing it along to
200 /// a `Writer` as well. Similar to the `tee(1)` command.
201 pub struct TeeReader<R, W> {
202     reader: R,
203     writer: W,
204 }
205
206 impl<R: Reader, W: Writer> TeeReader<R, W> {
207     /// Creates a new `TeeReader`
208     pub fn new(r: R, w: W) -> TeeReader<R, W> {
209         TeeReader { reader: r, writer: w }
210     }
211
212     /// Consumes the `TeeReader`, returning the underlying `Reader` and
213     /// `Writer`.
214     pub fn into_inner(self) -> (R, W) {
215         let TeeReader { reader, writer } = self;
216         (reader, writer)
217     }
218
219     /// Deprecated, use into_inner() instead
220     #[deprecated = "renamed to into_inner"]
221     pub fn unwrap(self) -> (R, W) { self.into_inner() }
222 }
223
224 impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
225     fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
226         self.reader.read(buf).and_then(|len| {
227             self.writer.write(buf[mut ..len]).map(|()| len)
228         })
229     }
230 }
231
232 /// Copies all data from a `Reader` to a `Writer`.
233 pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
234     let mut buf = [0, ..super::DEFAULT_BUF_SIZE];
235     loop {
236         let len = match r.read(&mut buf) {
237             Ok(len) => len,
238             Err(ref e) if e.kind == io::EndOfFile => return Ok(()),
239             Err(e) => return Err(e),
240         };
241         try!(w.write(buf[..len]));
242     }
243 }
244
245 /// An adaptor converting an `Iterator<u8>` to a `Reader`.
246 pub struct IterReader<T> {
247     iter: T,
248 }
249
250 impl<T: Iterator<u8>> IterReader<T> {
251     /// Creates a new `IterReader` which will read from the specified
252     /// `Iterator`.
253     pub fn new(iter: T) -> IterReader<T> {
254         IterReader { iter: iter }
255     }
256 }
257
258 impl<T: Iterator<u8>> Reader for IterReader<T> {
259     #[inline]
260     fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
261         let mut len = 0;
262         for (slot, elt) in buf.iter_mut().zip(self.iter.by_ref()) {
263             *slot = elt;
264             len += 1;
265         }
266         if len == 0 && buf.len() != 0 {
267             Err(io::standard_error(io::EndOfFile))
268         } else {
269             Ok(len)
270         }
271     }
272 }
273
274 #[cfg(test)]
275 mod test {
276     use io::{MemReader, BufReader, ByRefReader};
277     use io;
278     use boxed::Box;
279     use super::*;
280     use prelude::*;
281
282     #[test]
283     fn test_limit_reader_unlimited() {
284         let mut r = MemReader::new(vec!(0, 1, 2));
285         {
286             let mut r = LimitReader::new(r.by_ref(), 4);
287             assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
288         }
289     }
290
291     #[test]
292     fn test_limit_reader_limited() {
293         let mut r = MemReader::new(vec!(0, 1, 2));
294         {
295             let mut r = LimitReader::new(r.by_ref(), 2);
296             assert_eq!(vec!(0, 1), r.read_to_end().unwrap());
297         }
298         assert_eq!(vec!(2), r.read_to_end().unwrap());
299     }
300
301     #[test]
302     fn test_limit_reader_limit() {
303         let r = MemReader::new(vec!(0, 1, 2));
304         let mut r = LimitReader::new(r, 3);
305         assert_eq!(3, r.limit());
306         assert_eq!(0, r.read_byte().unwrap());
307         assert_eq!(2, r.limit());
308         assert_eq!(vec!(1, 2), r.read_to_end().unwrap());
309         assert_eq!(0, r.limit());
310     }
311
312     #[test]
313     fn test_limit_reader_overlong_consume() {
314         let mut r = MemReader::new(vec![0, 1, 2, 3, 4, 5]);
315         let mut r = LimitReader::new(r.by_ref(), 1);
316         r.consume(2);
317         assert_eq!(vec![], r.read_to_end().unwrap());
318     }
319
320     #[test]
321     fn test_null_writer() {
322         let mut s = NullWriter;
323         let buf = vec![0, 0, 0];
324         s.write(buf.as_slice()).unwrap();
325         s.flush().unwrap();
326     }
327
328     #[test]
329     fn test_zero_reader() {
330         let mut s = ZeroReader;
331         let mut buf = vec![1, 2, 3];
332         assert_eq!(s.read(buf.as_mut_slice()), Ok(3));
333         assert_eq!(vec![0, 0, 0], buf);
334     }
335
336     #[test]
337     fn test_null_reader() {
338         let mut r = NullReader;
339         let mut buf = vec![0];
340         assert!(r.read(buf.as_mut_slice()).is_err());
341     }
342
343     #[test]
344     fn test_multi_writer() {
345         static mut writes: uint = 0;
346         static mut flushes: uint = 0;
347
348         struct TestWriter;
349         impl Writer for TestWriter {
350             fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> {
351                 unsafe { writes += 1 }
352                 Ok(())
353             }
354
355             fn flush(&mut self) -> io::IoResult<()> {
356                 unsafe { flushes += 1 }
357                 Ok(())
358             }
359         }
360
361         let mut multi = MultiWriter::new(vec!(box TestWriter as Box<Writer>,
362                                               box TestWriter as Box<Writer>));
363         multi.write(&[1, 2, 3]).unwrap();
364         assert_eq!(2, unsafe { writes });
365         assert_eq!(0, unsafe { flushes });
366         multi.flush().unwrap();
367         assert_eq!(2, unsafe { writes });
368         assert_eq!(2, unsafe { flushes });
369     }
370
371     #[test]
372     fn test_chained_reader() {
373         let rs = vec!(MemReader::new(vec!(0, 1)), MemReader::new(vec!()),
374                       MemReader::new(vec!(2, 3)));
375         let mut r = ChainedReader::new(rs.into_iter());
376         assert_eq!(vec!(0, 1, 2, 3), r.read_to_end().unwrap());
377     }
378
379     #[test]
380     fn test_tee_reader() {
381         let mut r = TeeReader::new(MemReader::new(vec!(0, 1, 2)),
382                                    Vec::new());
383         assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
384         let (_, w) = r.unwrap();
385         assert_eq!(vec!(0, 1, 2), w);
386     }
387
388     #[test]
389     fn test_copy() {
390         let mut r = MemReader::new(vec!(0, 1, 2, 3, 4));
391         let mut w = Vec::new();
392         copy(&mut r, &mut w).unwrap();
393         assert_eq!(vec!(0, 1, 2, 3, 4), w);
394     }
395
396     #[test]
397     fn limit_reader_buffer() {
398         let data = "0123456789\n0123456789\n";
399         let mut r = BufReader::new(data.as_bytes());
400         {
401             let mut r = LimitReader::new(r.by_ref(), 3);
402             assert_eq!(r.read_line(), Ok("012".to_string()));
403             assert_eq!(r.limit(), 0);
404             assert_eq!(r.read_line().err().unwrap().kind, io::EndOfFile);
405         }
406         {
407             let mut r = LimitReader::new(r.by_ref(), 9);
408             assert_eq!(r.read_line(), Ok("3456789\n".to_string()));
409             assert_eq!(r.limit(), 1);
410             assert_eq!(r.read_line(), Ok("0".to_string()));
411         }
412         {
413             let mut r = LimitReader::new(r.by_ref(), 100);
414             assert_eq!(r.read_char(), Ok('1'));
415             assert_eq!(r.limit(), 99);
416             assert_eq!(r.read_line(), Ok("23456789\n".to_string()));
417         }
418     }
419
420     #[test]
421     fn test_iter_reader() {
422         let mut r = IterReader::new(range(0u8, 8));
423         let mut buf = [0, 0, 0];
424         let len = r.read(&mut buf).unwrap();
425         assert_eq!(len, 3);
426         assert!(buf == [0, 1, 2]);
427
428         let len = r.read(&mut buf).unwrap();
429         assert_eq!(len, 3);
430         assert!(buf == [3, 4, 5]);
431
432         let len = r.read(&mut buf).unwrap();
433         assert_eq!(len, 2);
434         assert!(buf == [6, 7, 5]);
435
436         assert_eq!(r.read(&mut buf).unwrap_err().kind, io::EndOfFile);
437     }
438
439     #[test]
440     fn iter_reader_zero_length() {
441         let mut r = IterReader::new(range(0u8, 8));
442         let mut buf = [];
443         assert_eq!(Ok(0), r.read(&mut buf));
444     }
445 }