auto merge of #18980 : erickt/rust/reader, r=erickt
This continues the work @thestinger started in #18885 (which hasn't landed yet, so wait for that to land before landing this one). Instead of adding more methods to `BufReader`, this just allows a `&[u8]` to be used directly as a `Reader`. It also adds an impl of `Writer` for `&mut [u8]`.
This commit is contained in:
commit
d9c7c00b9a
@ -444,15 +444,14 @@ impl<T, E> Result<T, E> {
|
|||||||
/// ignoring I/O and parse errors:
|
/// ignoring I/O and parse errors:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::io::{BufReader, IoResult};
|
/// use std::io::IoResult;
|
||||||
///
|
///
|
||||||
/// let buffer = "1\n2\n3\n4\n";
|
/// let mut buffer = &mut b"1\n2\n3\n4\n";
|
||||||
/// let mut reader = BufReader::new(buffer.as_bytes());
|
|
||||||
///
|
///
|
||||||
/// let mut sum = 0;
|
/// let mut sum = 0;
|
||||||
///
|
///
|
||||||
/// while !reader.eof() {
|
/// while !buffer.is_empty() {
|
||||||
/// let line: IoResult<String> = reader.read_line();
|
/// let line: IoResult<String> = buffer.read_line();
|
||||||
/// // Convert the string line to a number using `map` and `from_str`
|
/// // Convert the string line to a number using `map` and `from_str`
|
||||||
/// let val: IoResult<int> = line.map(|line| {
|
/// let val: IoResult<int> = line.map(|line| {
|
||||||
/// from_str::<int>(line.as_slice().trim_right()).unwrap_or(0)
|
/// from_str::<int>(line.as_slice().trim_right()).unwrap_or(0)
|
||||||
|
@ -547,7 +547,7 @@ mod tests {
|
|||||||
use self::NodeLabels::*;
|
use self::NodeLabels::*;
|
||||||
use super::{Id, LabelText, LabelStr, EscStr, Labeller};
|
use super::{Id, LabelText, LabelStr, EscStr, Labeller};
|
||||||
use super::{Nodes, Edges, GraphWalk, render};
|
use super::{Nodes, Edges, GraphWalk, render};
|
||||||
use std::io::{BufReader, IoResult};
|
use std::io::IoResult;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
/// each node is an index in a vector in the graph.
|
/// each node is an index in a vector in the graph.
|
||||||
@ -698,8 +698,7 @@ mod tests {
|
|||||||
fn test_input(g: LabelledGraph) -> IoResult<String> {
|
fn test_input(g: LabelledGraph) -> IoResult<String> {
|
||||||
let mut writer = Vec::new();
|
let mut writer = Vec::new();
|
||||||
render(&g, &mut writer).unwrap();
|
render(&g, &mut writer).unwrap();
|
||||||
let mut r = BufReader::new(writer[]);
|
(&mut writer.as_slice()).read_to_string()
|
||||||
r.read_to_string()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// All of the tests use raw-strings as the format for the expected outputs,
|
// All of the tests use raw-strings as the format for the expected outputs,
|
||||||
@ -811,8 +810,7 @@ r#"digraph hasse_diagram {
|
|||||||
edge(1, 3, ";"), edge(2, 3, ";" )));
|
edge(1, 3, ";"), edge(2, 3, ";" )));
|
||||||
|
|
||||||
render(&g, &mut writer).unwrap();
|
render(&g, &mut writer).unwrap();
|
||||||
let mut r = BufReader::new(writer[]);
|
let r = (&mut writer.as_slice()).read_to_string();
|
||||||
let r = r.read_to_string();
|
|
||||||
|
|
||||||
assert_eq!(r.unwrap().as_slice(),
|
assert_eq!(r.unwrap().as_slice(),
|
||||||
r#"digraph syntax_tree {
|
r#"digraph syntax_tree {
|
||||||
|
@ -406,7 +406,7 @@ mod test {
|
|||||||
use prelude::*;
|
use prelude::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::super::{IoResult, EndOfFile};
|
use super::super::{IoResult, EndOfFile};
|
||||||
use super::super::mem::{MemReader, BufReader};
|
use super::super::mem::MemReader;
|
||||||
use self::test::Bencher;
|
use self::test::Bencher;
|
||||||
use str::StrPrelude;
|
use str::StrPrelude;
|
||||||
|
|
||||||
@ -626,14 +626,14 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn read_char_buffered() {
|
fn read_char_buffered() {
|
||||||
let buf = [195u8, 159u8];
|
let buf = [195u8, 159u8];
|
||||||
let mut reader = BufferedReader::with_capacity(1, BufReader::new(&buf));
|
let mut reader = BufferedReader::with_capacity(1, buf[]);
|
||||||
assert_eq!(reader.read_char(), Ok('ß'));
|
assert_eq!(reader.read_char(), Ok('ß'));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_chars() {
|
fn test_chars() {
|
||||||
let buf = [195u8, 159u8, b'a'];
|
let buf = [195u8, 159u8, b'a'];
|
||||||
let mut reader = BufferedReader::with_capacity(1, BufReader::new(&buf));
|
let mut reader = BufferedReader::with_capacity(1, buf[]);
|
||||||
let mut it = reader.chars();
|
let mut it = reader.chars();
|
||||||
assert_eq!(it.next(), Some(Ok('ß')));
|
assert_eq!(it.next(), Some(Ok('ß')));
|
||||||
assert_eq!(it.next(), Some(Ok('a')));
|
assert_eq!(it.next(), Some(Ok('a')));
|
||||||
|
@ -206,6 +206,41 @@ impl Buffer for MemReader {
|
|||||||
fn consume(&mut self, amt: uint) { self.pos += amt; }
|
fn consume(&mut self, amt: uint) { self.pos += amt; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Reader for &'a [u8] {
|
||||||
|
#[inline]
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
|
||||||
|
if self.is_empty() { return Err(io::standard_error(io::EndOfFile)); }
|
||||||
|
|
||||||
|
let write_len = min(buf.len(), self.len());
|
||||||
|
{
|
||||||
|
let input = self[..write_len];
|
||||||
|
let output = buf[mut ..write_len];
|
||||||
|
slice::bytes::copy_memory(output, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
*self = self.slice_from(write_len);
|
||||||
|
|
||||||
|
Ok(write_len)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Buffer for &'a [u8] {
|
||||||
|
#[inline]
|
||||||
|
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
||||||
|
if self.is_empty() {
|
||||||
|
Err(io::standard_error(io::EndOfFile))
|
||||||
|
} else {
|
||||||
|
Ok(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn consume(&mut self, amt: uint) {
|
||||||
|
*self = self[amt..];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Writes to a fixed-size byte slice
|
/// Writes to a fixed-size byte slice
|
||||||
///
|
///
|
||||||
/// If a write will not fit in the buffer, it returns an error and does not
|
/// If a write will not fit in the buffer, it returns an error and does not
|
||||||
@ -362,6 +397,16 @@ mod test {
|
|||||||
use self::test::Bencher;
|
use self::test::Bencher;
|
||||||
use str::StrPrelude;
|
use str::StrPrelude;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_vec_writer() {
|
||||||
|
let mut writer = Vec::new();
|
||||||
|
writer.write(&[0]).unwrap();
|
||||||
|
writer.write(&[1, 2, 3]).unwrap();
|
||||||
|
writer.write(&[4, 5, 6, 7]).unwrap();
|
||||||
|
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
|
||||||
|
assert_eq!(writer.as_slice(), b);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mem_writer() {
|
fn test_mem_writer() {
|
||||||
let mut writer = MemWriter::new();
|
let mut writer = MemWriter::new();
|
||||||
@ -385,6 +430,8 @@ mod test {
|
|||||||
assert_eq!(writer.tell(), Ok(8));
|
assert_eq!(writer.tell(), Ok(8));
|
||||||
writer.write(&[]).unwrap();
|
writer.write(&[]).unwrap();
|
||||||
assert_eq!(writer.tell(), Ok(8));
|
assert_eq!(writer.tell(), Ok(8));
|
||||||
|
|
||||||
|
assert!(writer.write(&[1]).is_err());
|
||||||
}
|
}
|
||||||
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
|
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
|
||||||
assert_eq!(buf.as_slice(), b);
|
assert_eq!(buf.as_slice(), b);
|
||||||
@ -457,6 +504,32 @@ mod test {
|
|||||||
assert!(reader.read(&mut buf).is_err());
|
assert!(reader.read(&mut buf).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_slice_reader() {
|
||||||
|
let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
|
||||||
|
let mut reader = &mut in_buf.as_slice();
|
||||||
|
let mut buf = [];
|
||||||
|
assert_eq!(reader.read(&mut buf), Ok(0));
|
||||||
|
let mut buf = [0];
|
||||||
|
assert_eq!(reader.read(&mut buf), Ok(1));
|
||||||
|
assert_eq!(reader.len(), 7);
|
||||||
|
let b: &[_] = &[0];
|
||||||
|
assert_eq!(buf.as_slice(), b);
|
||||||
|
let mut buf = [0, ..4];
|
||||||
|
assert_eq!(reader.read(&mut buf), Ok(4));
|
||||||
|
assert_eq!(reader.len(), 3);
|
||||||
|
let b: &[_] = &[1, 2, 3, 4];
|
||||||
|
assert_eq!(buf.as_slice(), b);
|
||||||
|
assert_eq!(reader.read(&mut buf), Ok(3));
|
||||||
|
let b: &[_] = &[5, 6, 7];
|
||||||
|
assert_eq!(buf[0..3], b);
|
||||||
|
assert!(reader.read(&mut buf).is_err());
|
||||||
|
let mut reader = &mut in_buf.as_slice();
|
||||||
|
assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3));
|
||||||
|
assert_eq!(reader.read_until(3).unwrap(), vec!(4, 5, 6, 7));
|
||||||
|
assert!(reader.read(&mut buf).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_buf_reader() {
|
fn test_buf_reader() {
|
||||||
let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
|
let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
|
||||||
|
@ -273,7 +273,7 @@ impl<T: Iterator<u8>> Reader for IterReader<T> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use io::{MemReader, BufReader, ByRefReader};
|
use io::{MemReader, ByRefReader};
|
||||||
use io;
|
use io;
|
||||||
use boxed::Box;
|
use boxed::Box;
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -395,8 +395,7 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn limit_reader_buffer() {
|
fn limit_reader_buffer() {
|
||||||
let data = "0123456789\n0123456789\n";
|
let r = &mut b"0123456789\n0123456789\n";
|
||||||
let mut r = BufReader::new(data.as_bytes());
|
|
||||||
{
|
{
|
||||||
let mut r = LimitReader::new(r.by_ref(), 3);
|
let mut r = LimitReader::new(r.by_ref(), 3);
|
||||||
assert_eq!(r.read_line(), Ok("012".to_string()));
|
assert_eq!(r.read_line(), Ok("012".to_string()));
|
||||||
|
@ -32,7 +32,6 @@ use self::Fmt::*;
|
|||||||
|
|
||||||
use std::fmt::Show;
|
use std::fmt::Show;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::BufReader;
|
|
||||||
use std::num::SignedInt;
|
use std::num::SignedInt;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -1187,7 +1186,7 @@ pub fn strptime(s: &str, format: &str) -> Result<Tm, ParseError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut rdr = BufReader::new(format.as_bytes());
|
let mut rdr: &[u8] = format.as_bytes();
|
||||||
let mut tm = Tm {
|
let mut tm = Tm {
|
||||||
tm_sec: 0_i32,
|
tm_sec: 0_i32,
|
||||||
tm_min: 0_i32,
|
tm_min: 0_i32,
|
||||||
@ -1211,13 +1210,13 @@ pub fn strptime(s: &str, format: &str) -> Result<Tm, ParseError> {
|
|||||||
let next = range.next;
|
let next = range.next;
|
||||||
|
|
||||||
let mut buf = [0];
|
let mut buf = [0];
|
||||||
let c = match rdr.read(&mut buf) {
|
let c = match (&mut rdr).read(&mut buf) {
|
||||||
Ok(..) => buf[0] as char,
|
Ok(..) => buf[0] as char,
|
||||||
Err(..) => break
|
Err(..) => break
|
||||||
};
|
};
|
||||||
match c {
|
match c {
|
||||||
'%' => {
|
'%' => {
|
||||||
let ch = match rdr.read(&mut buf) {
|
let ch = match (&mut rdr).read(&mut buf) {
|
||||||
Ok(..) => buf[0] as char,
|
Ok(..) => buf[0] as char,
|
||||||
Err(..) => break
|
Err(..) => break
|
||||||
};
|
};
|
||||||
@ -1233,7 +1232,7 @@ pub fn strptime(s: &str, format: &str) -> Result<Tm, ParseError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if pos == len && rdr.tell().unwrap() == format.len() as u64 {
|
if pos == len && (&mut rdr).is_empty() {
|
||||||
Ok(Tm {
|
Ok(Tm {
|
||||||
tm_sec: tm.tm_sec,
|
tm_sec: tm.tm_sec,
|
||||||
tm_min: tm.tm_min,
|
tm_min: tm.tm_min,
|
||||||
|
Loading…
Reference in New Issue
Block a user