Skip to content

Commit 61026ae

Browse files
author
blake2-ppc
committed
rt::io: Add Bytes iterator for Reader
An iterator that simply calls `.read_bytes()` each iteration. I think choosing to own the Reader value and implementing Decorator to allow extracting it is the most generically useful. The Reader type variable can of course be some kind of reference type that implements Reader.
1 parent 1f4aba8 commit 61026ae

File tree

1 file changed

+83
-1
lines changed

1 file changed

+83
-1
lines changed

src/libstd/rt/io/extensions.rs

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515

1616
use uint;
1717
use int;
18+
use iterator::Iterator;
1819
use vec;
19-
use rt::io::{Reader, Writer};
20+
use rt::io::{Reader, Writer, Decorator};
2021
use rt::io::{read_error, standard_error, EndOfFile, DEFAULT_BUF_SIZE};
2122
use option::{Option, Some, None};
2223
use unstable::finally::Finally;
@@ -62,6 +63,16 @@ pub trait ReaderUtil {
6263
/// Raises the same conditions as the `read` method.
6364
fn read_to_end(&mut self) -> ~[u8];
6465

66+
/// Create an iterator that reads a single byte on
67+
/// each iteration, until EOF.
68+
///
69+
/// # Failure
70+
///
71+
/// Raises the same conditions as the `read` method, for
72+
/// each call to its `.next()` method.
73+
/// Ends the iteration if the condition is handled.
74+
fn bytes(self) -> Bytes<Self>;
75+
6576
}
6677

6778
pub trait ReaderByteConversions {
@@ -337,6 +348,35 @@ impl<T: Reader> ReaderUtil for T {
337348
}
338349
return buf;
339350
}
351+
352+
fn bytes(self) -> Bytes<T> {
353+
Bytes{reader: self}
354+
}
355+
}
356+
357+
/// An iterator that reads a single byte on each iteration,
358+
/// until EOF.
359+
///
360+
/// # Failure
361+
///
362+
/// Raises the same conditions as the `read` method, for
363+
/// each call to its `.next()` method.
364+
/// Ends the iteration if the condition is handled.
365+
pub struct Bytes<T> {
366+
priv reader: T,
367+
}
368+
369+
impl<R> Decorator<R> for Bytes<R> {
370+
fn inner(self) -> R { self.reader }
371+
fn inner_ref<'a>(&'a self) -> &'a R { &self.reader }
372+
fn inner_mut_ref<'a>(&'a mut self) -> &'a mut R { &mut self.reader }
373+
}
374+
375+
impl<'self, R: Reader> Iterator<u8> for Bytes<R> {
376+
#[inline]
377+
fn next(&mut self) -> Option<u8> {
378+
self.reader.read_byte()
379+
}
340380
}
341381

342382
impl<T: Reader> ReaderByteConversions for T {
@@ -646,6 +686,48 @@ mod test {
646686
}
647687
}
648688

689+
#[test]
690+
fn bytes_0_bytes() {
691+
let mut reader = MockReader::new();
692+
let count = Cell::new(0);
693+
reader.read = |buf| {
694+
do count.with_mut_ref |count| {
695+
if *count == 0 {
696+
*count = 1;
697+
Some(0)
698+
} else {
699+
buf[0] = 10;
700+
Some(1)
701+
}
702+
}
703+
};
704+
let byte = reader.bytes().next();
705+
assert!(byte == Some(10));
706+
}
707+
708+
#[test]
709+
fn bytes_eof() {
710+
let mut reader = MockReader::new();
711+
reader.read = |_| None;
712+
let byte = reader.bytes().next();
713+
assert!(byte == None);
714+
}
715+
716+
#[test]
717+
fn bytes_error() {
718+
let mut reader = MockReader::new();
719+
reader.read = |_| {
720+
read_error::cond.raise(placeholder_error());
721+
None
722+
};
723+
let mut it = reader.bytes();
724+
do read_error::cond.trap(|_| ()).inside {
725+
let byte = it.next();
726+
assert!(byte == None);
727+
}
728+
}
729+
730+
649731
#[test]
650732
fn read_bytes() {
651733
let mut reader = MemReader::new(~[10, 11, 12, 13]);

0 commit comments

Comments
 (0)