Skip to content

Commit ecace6e

Browse files
committed
---
yaml --- r: 79384 b: refs/heads/snap-stage3 c: 6c13b0f h: refs/heads/master v: v3
1 parent fc16903 commit ecace6e

File tree

2 files changed

+90
-2
lines changed

2 files changed

+90
-2
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 124eb2119c78651cfaaa7a046a101fa2e20f83ca
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 60fba4d7d677ec098e6a43014132fe99f7547363
4+
refs/heads/snap-stage3: 6c13b0f4f6b6c51c0d83bad3c48d7249a1d15308
55
refs/heads/try: ac820906c0e53eab79a98ee64f7231f57c3887b4
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/libstd/rt/io/extensions.rs

Lines changed: 89 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) -> ByteIterator<Self>;
75+
6576
}
6677

6778
pub trait ReaderByteConversions {
@@ -337,6 +348,41 @@ impl<T: Reader> ReaderUtil for T {
337348
}
338349
return buf;
339350
}
351+
352+
fn bytes(self) -> ByteIterator<T> {
353+
ByteIterator{reader: self}
354+
}
355+
}
356+
357+
/// An iterator that reads a single byte on each iteration,
358+
/// until `.read_byte()` returns `None`.
359+
///
360+
/// # Notes about the Iteration Protocol
361+
///
362+
/// The `ByteIterator` may yield `None` and thus terminate
363+
/// an iteration, but continue to yield elements if iteration
364+
/// is attempted again.
365+
///
366+
/// # Failure
367+
///
368+
/// Raises the same conditions as the `read` method, for
369+
/// each call to its `.next()` method.
370+
/// Yields `None` if the condition is handled.
371+
pub struct ByteIterator<T> {
372+
priv reader: T,
373+
}
374+
375+
impl<R> Decorator<R> for ByteIterator<R> {
376+
fn inner(self) -> R { self.reader }
377+
fn inner_ref<'a>(&'a self) -> &'a R { &self.reader }
378+
fn inner_mut_ref<'a>(&'a mut self) -> &'a mut R { &mut self.reader }
379+
}
380+
381+
impl<'self, R: Reader> Iterator<u8> for ByteIterator<R> {
382+
#[inline]
383+
fn next(&mut self) -> Option<u8> {
384+
self.reader.read_byte()
385+
}
340386
}
341387

342388
impl<T: Reader> ReaderByteConversions for T {
@@ -646,6 +692,48 @@ mod test {
646692
}
647693
}
648694

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

0 commit comments

Comments
 (0)