From 01343d3d2987dfea6a3982aba3735a95c9a0c51c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 13 Nov 2013 11:36:21 -0800 Subject: Implement read_char on the Buffer trait --- src/libstd/io/mem.rs | 16 ++++++++++++++++ src/libstd/io/mod.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index 541648a534f..2f4324f9db6 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -299,4 +299,20 @@ mod test { 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); + } } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 251e60bdbe0..6924b33aecd 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1048,6 +1048,33 @@ pub trait Buffer: Reader { 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 { + 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 { -- cgit 1.4.1-3-g733a5