Skip to content

Commit 01343d3

Browse files
committed
Implement read_char on the Buffer trait
1 parent 7bc092f commit 01343d3

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

src/libstd/io/mem.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,4 +299,20 @@ mod test {
299299
let buf = with_mem_writer(|wr| wr.write([1,2,3,4,5,6,7]));
300300
assert_eq!(buf, ~[1,2,3,4,5,6,7]);
301301
}
302+
303+
#[test]
304+
fn test_read_char() {
305+
let mut r = BufReader::new(bytes!("Việt"));
306+
assert_eq!(r.read_char(), Some('V'));
307+
assert_eq!(r.read_char(), Some('i'));
308+
assert_eq!(r.read_char(), Some('ệ'));
309+
assert_eq!(r.read_char(), Some('t'));
310+
assert_eq!(r.read_char(), None);
311+
}
312+
313+
#[test]
314+
fn test_read_bad_char() {
315+
let mut r = BufReader::new(bytes!(0x80));
316+
assert_eq!(r.read_char(), None);
317+
}
302318
}

src/libstd/io/mod.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,33 @@ pub trait Buffer: Reader {
10481048
self.consume(used);
10491049
return if res.len() == 0 {None} else {Some(res)};
10501050
}
1051+
1052+
/// Reads the next utf8-encoded character from the underlying stream.
1053+
///
1054+
/// This will return `None` if the following sequence of bytes in the
1055+
/// stream are not a valid utf8-sequence, or if an I/O error is encountered.
1056+
///
1057+
/// # Failure
1058+
///
1059+
/// This function will raise on the `io_error` condition if a read error is
1060+
/// encountered.
1061+
fn read_char(&mut self) -> Option<char> {
1062+
let width = {
1063+
let available = self.fill();
1064+
if available.len() == 0 { return None } // read error
1065+
str::utf8_char_width(available[0])
1066+
};
1067+
if width == 0 { return None } // not uf8
1068+
let mut buf = [0, ..4];
1069+
match self.read(buf.mut_slice_to(width)) {
1070+
Some(n) if n == width => {}
1071+
Some(*) | None => return None // read error
1072+
}
1073+
match str::from_utf8_slice_opt(buf.slice_to(width)) {
1074+
Some(s) => Some(s.char_at(0)),
1075+
None => None
1076+
}
1077+
}
10511078
}
10521079

10531080
pub enum SeekStyle {

0 commit comments

Comments
 (0)