Implement read_char on the Buffer trait

This commit is contained in:
Alex Crichton 2013-11-13 11:36:21 -08:00
parent 7bc092f109
commit 01343d3d29
2 changed files with 43 additions and 0 deletions

View File

@ -299,4 +299,20 @@ fn test_with_mem_writer() {
let buf = with_mem_writer(|wr| wr.write([1,2,3,4,5,6,7]));
assert_eq!(buf, ~[1,2,3,4,5,6,7]);
}
#[test]
fn test_read_char() {
let mut r = BufReader::new(bytes!("Việt"));
assert_eq!(r.read_char(), Some('V'));
assert_eq!(r.read_char(), Some('i'));
assert_eq!(r.read_char(), Some('ệ'));
assert_eq!(r.read_char(), Some('t'));
assert_eq!(r.read_char(), None);
}
#[test]
fn test_read_bad_char() {
let mut r = BufReader::new(bytes!(0x80));
assert_eq!(r.read_char(), None);
}
}

View File

@ -1048,6 +1048,33 @@ fn read_until(&mut self, byte: u8) -> Option<~[u8]> {
self.consume(used);
return if res.len() == 0 {None} else {Some(res)};
}
/// Reads the next utf8-encoded character from the underlying stream.
///
/// This will return `None` if the following sequence of bytes in the
/// stream are not a valid utf8-sequence, or if an I/O error is encountered.
///
/// # Failure
///
/// This function will raise on the `io_error` condition if a read error is
/// encountered.
fn read_char(&mut self) -> Option<char> {
let width = {
let available = self.fill();
if available.len() == 0 { return None } // read error
str::utf8_char_width(available[0])
};
if width == 0 { return None } // not uf8
let mut buf = [0, ..4];
match self.read(buf.mut_slice_to(width)) {
Some(n) if n == width => {}
Some(*) | None => return None // read error
}
match str::from_utf8_slice_opt(buf.slice_to(width)) {
Some(s) => Some(s.char_at(0)),
None => None
}
}
}
pub enum SeekStyle {