Skip to content

Commit 1c0d2b8

Browse files
committed
Add IterReader
1 parent 9d439b4 commit 1c0d2b8

File tree

2 files changed

+215
-0
lines changed

2 files changed

+215
-0
lines changed

src/libstd/io/iterator.rs

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
#![crate_type = "lib"]
2+
3+
use prelude::v1::*;
4+
use io::prelude::*;
5+
6+
use cmp;
7+
use io::{self};
8+
use ptr;
9+
use slice;
10+
use sync;
11+
12+
/// An `IterReader` implements std::io::Read and std::io::BufRead for an iterator of byte sequences.
13+
pub struct IterReader<V, I> where V : AsRef<[u8]>, I : Iterator<Item=V> {
14+
iter: I, // The underlying source of the bytes we will read.
15+
buf: Option<V>, // Contains the last item that we got from the iterator.
16+
pos: usize, // The number of bytes that have already been read from buf.
17+
closed: bool,
18+
}
19+
20+
impl <V : AsRef<[u8]>, I : Iterator<Item=V>> IterReader<V, I> {
21+
pub fn new(iter: I) -> IterReader<V, I> {
22+
IterReader { iter: iter, buf: None, pos: 0, closed: false, }
23+
}
24+
25+
fn buffered(&self) -> &[u8] {
26+
match self.buf {
27+
Some(ref buf) => buf.as_ref()[self.pos..].as_ref(),
28+
None => &[],
29+
}
30+
}
31+
32+
fn needs_refill(&self) -> bool {
33+
!self.closed && self.buffered().len() == 0
34+
}
35+
36+
fn refill(&mut self) {
37+
self.pos = 0;
38+
self.buf = self.iter.next();
39+
self.closed = self.buf.is_none()
40+
}
41+
}
42+
43+
impl <V : AsRef<[u8]>, I : Iterator<Item=V>> io::BufRead for IterReader<V, I> {
44+
fn fill_buf(&mut self) -> io::Result<&[u8]> {
45+
while self.needs_refill() { // We loop in case the last item was empty.
46+
self.refill();
47+
}
48+
Ok(self.buffered())
49+
}
50+
51+
fn consume(&mut self, amt: usize) { self.pos += amt; }
52+
}
53+
54+
impl <V : AsRef<[u8]>, I : Iterator<Item=V>> io::Read for IterReader<V, I> {
55+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
56+
if self.needs_refill() {
57+
self.refill();
58+
}
59+
let amt = cmp::min(self.buffered().len(), buf.len());
60+
slice::bytes::copy_memory(&self.buffered()[..amt], &mut buf[..amt]);
61+
self.consume(amt);
62+
Ok(amt)
63+
}
64+
}
65+
66+
#[test]
67+
fn test_read_vec() {
68+
use io::Read;
69+
70+
let pieces = vec![
71+
vec![1, 2],
72+
vec![],
73+
vec![3, 4, 5],
74+
vec![6, 7, 8, 9],
75+
vec![10],
76+
];
77+
78+
let mut reader = IterReader::new(pieces.into_iter());
79+
80+
let mut buf = [0; 3];
81+
82+
assert_eq!(0, reader.read(&mut []).unwrap());
83+
84+
assert_eq!(2, reader.read(&mut buf).unwrap());
85+
assert_eq!([1,2,0], buf);
86+
87+
assert_eq!(0, reader.read(&mut buf).unwrap());
88+
assert_eq!([1,2,0], buf);
89+
90+
assert_eq!(3, reader.read(&mut buf).unwrap());
91+
assert_eq!([3,4,5], buf);
92+
93+
assert_eq!(3, reader.read(&mut buf).unwrap());
94+
assert_eq!([6,7,8], buf);
95+
96+
assert_eq!(1, reader.read(&mut buf).unwrap());
97+
assert_eq!([9,7,8], buf);
98+
99+
assert_eq!(1, reader.read(&mut buf).unwrap());
100+
assert_eq!([10,7,8], buf);
101+
102+
assert_eq!(0, reader.read(&mut buf).unwrap());
103+
assert_eq!(0, reader.read(&mut buf).unwrap());
104+
}
105+
106+
#[test]
107+
fn test_read_array() {
108+
use io::Read;
109+
110+
let pieces = vec![
111+
[1, 2],
112+
[3, 4],
113+
[5, 6],
114+
[7, 8],
115+
[9, 10],
116+
];
117+
118+
let mut reader = IterReader::new(pieces.into_iter());
119+
120+
let mut buf = [0; 3];
121+
122+
assert_eq!(0, reader.read(&mut []).unwrap());
123+
124+
assert_eq!(2, reader.read(&mut buf).unwrap());
125+
assert_eq!([1,2,0], buf);
126+
127+
assert_eq!(0, reader.read(&mut buf).unwrap());
128+
assert_eq!([1,2,0], buf);
129+
130+
assert_eq!(3, reader.read(&mut buf).unwrap());
131+
assert_eq!([3,4,5], buf);
132+
133+
assert_eq!(3, reader.read(&mut buf).unwrap());
134+
assert_eq!([6,7,8], buf);
135+
136+
assert_eq!(1, reader.read(&mut buf).unwrap());
137+
assert_eq!([9,7,8], buf);
138+
139+
assert_eq!(1, reader.read(&mut buf).unwrap());
140+
assert_eq!([10,7,8], buf);
141+
142+
assert_eq!(0, reader.read(&mut buf).unwrap());
143+
assert_eq!(0, reader.read(&mut buf).unwrap());
144+
}
145+
146+
#[test]
147+
fn test_read_from_chan() {
148+
use io::Read;
149+
150+
let mut reader = {
151+
let (tx, rx) = sync::mpsc::channel();
152+
tx.send(vec![1, 2]).unwrap();
153+
tx.send(vec![]).unwrap();
154+
tx.send(vec![3, 4, 5]).unwrap();
155+
tx.send(vec![6, 7, 8, 9]).unwrap();
156+
tx.send(vec![10]).unwrap();
157+
158+
IterReader::new(rx.into_iter())
159+
};
160+
161+
let mut buf = [0; 3];
162+
163+
assert_eq!(0, reader.read(&mut []).unwrap());
164+
165+
assert_eq!(2, reader.read(&mut buf).unwrap());
166+
assert_eq!([1,2,0], buf);
167+
168+
assert_eq!(0, reader.read(&mut buf).unwrap());
169+
assert_eq!([1,2,0], buf);
170+
171+
assert_eq!(3, reader.read(&mut buf).unwrap());
172+
assert_eq!([3,4,5], buf);
173+
174+
assert_eq!(3, reader.read(&mut buf).unwrap());
175+
assert_eq!([6,7,8], buf);
176+
177+
assert_eq!(1, reader.read(&mut buf).unwrap());
178+
assert_eq!([9,7,8], buf);
179+
180+
assert_eq!(1, reader.read(&mut buf).unwrap());
181+
assert_eq!([10,7,8], buf);
182+
183+
assert_eq!(0, reader.read(&mut buf).unwrap());
184+
assert_eq!(0, reader.read(&mut buf).unwrap());
185+
}
186+
187+
#[test]
188+
fn test_bufread() {
189+
let pieces = vec![
190+
b"he".to_vec(),
191+
b"llo wo".to_vec(),
192+
b"".to_vec(),
193+
b"rld\n\nhow ".to_vec(),
194+
b"are you?".to_vec(),
195+
b"".to_vec(),
196+
];
197+
198+
let lines = vec![
199+
"hello world\n",
200+
"\n",
201+
"how are you?",
202+
"",
203+
"",
204+
];
205+
206+
let mut reader = IterReader::new(pieces.into_iter());
207+
208+
for line in lines {
209+
let buf = &mut "".to_string();
210+
assert_eq!(line.len(), reader.read_line(buf).unwrap());
211+
assert_eq!(line.to_string(), *buf);
212+
}
213+
}

src/libstd/io/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub use self::buffered::{BufReader, BufWriter, BufStream, LineWriter};
3030
pub use self::buffered::IntoInnerError;
3131
pub use self::cursor::Cursor;
3232
pub use self::error::{Result, Error, ErrorKind};
33+
pub use self::iterator::{IterReader};
3334
pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat};
3435
pub use self::stdio::{stdin, stdout, stderr, _print, Stdin, Stdout, Stderr};
3536
pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
@@ -43,6 +44,7 @@ mod buffered;
4344
mod cursor;
4445
mod error;
4546
mod impls;
47+
mod iterator;
4648
mod util;
4749
mod stdio;
4850

0 commit comments

Comments
 (0)