Skip to content

Commit

Permalink
auto merge of #18980 : erickt/rust/reader, r=erickt
Browse files Browse the repository at this point in the history
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]`.
  • Loading branch information
bors committed Dec 4, 2014
2 parents 4053e82 + 298b525 commit d9c7c00
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 21 deletions.
9 changes: 4 additions & 5 deletions src/libcore/result.rs
Expand Up @@ -444,15 +444,14 @@ impl<T, E> Result<T, E> {
/// ignoring I/O and parse errors:
///
/// ```
/// use std::io::{BufReader, IoResult};
/// use std::io::IoResult;
///
/// let buffer = "1\n2\n3\n4\n";
/// let mut reader = BufReader::new(buffer.as_bytes());
/// let mut buffer = &mut b"1\n2\n3\n4\n";
///
/// let mut sum = 0;
///
/// while !reader.eof() {
/// let line: IoResult<String> = reader.read_line();
/// while !buffer.is_empty() {
/// let line: IoResult<String> = buffer.read_line();
/// // Convert the string line to a number using `map` and `from_str`
/// let val: IoResult<int> = line.map(|line| {
/// from_str::<int>(line.as_slice().trim_right()).unwrap_or(0)
Expand Down
8 changes: 3 additions & 5 deletions src/libgraphviz/lib.rs
Expand Up @@ -547,7 +547,7 @@ mod tests {
use self::NodeLabels::*;
use super::{Id, LabelText, LabelStr, EscStr, Labeller};
use super::{Nodes, Edges, GraphWalk, render};
use std::io::{BufReader, IoResult};
use std::io::IoResult;
use std::str;

/// each node is an index in a vector in the graph.
Expand Down Expand Up @@ -698,8 +698,7 @@ mod tests {
fn test_input(g: LabelledGraph) -> IoResult<String> {
let mut writer = Vec::new();
render(&g, &mut writer).unwrap();
let mut r = BufReader::new(writer[]);
r.read_to_string()
(&mut writer.as_slice()).read_to_string()
}

// All of the tests use raw-strings as the format for the expected outputs,
Expand Down Expand Up @@ -811,8 +810,7 @@ r#"digraph hasse_diagram {
edge(1, 3, ";"), edge(2, 3, ";" )));

render(&g, &mut writer).unwrap();
let mut r = BufReader::new(writer[]);
let r = r.read_to_string();
let r = (&mut writer.as_slice()).read_to_string();

assert_eq!(r.unwrap().as_slice(),
r#"digraph syntax_tree {
Expand Down
6 changes: 3 additions & 3 deletions src/libstd/io/buffered.rs
Expand Up @@ -406,7 +406,7 @@ mod test {
use prelude::*;
use super::*;
use super::super::{IoResult, EndOfFile};
use super::super::mem::{MemReader, BufReader};
use super::super::mem::MemReader;
use self::test::Bencher;
use str::StrPrelude;

Expand Down Expand Up @@ -626,14 +626,14 @@ mod test {
#[test]
fn read_char_buffered() {
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('ß'));
}

#[test]
fn test_chars() {
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();
assert_eq!(it.next(), Some(Ok('ß')));
assert_eq!(it.next(), Some(Ok('a')));
Expand Down
73 changes: 73 additions & 0 deletions src/libstd/io/mem.rs
Expand Up @@ -206,6 +206,41 @@ impl Buffer for MemReader {
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
///
/// If a write will not fit in the buffer, it returns an error and does not
Expand Down Expand Up @@ -362,6 +397,16 @@ mod test {
use self::test::Bencher;
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]
fn test_mem_writer() {
let mut writer = MemWriter::new();
Expand All @@ -385,6 +430,8 @@ mod test {
assert_eq!(writer.tell(), Ok(8));
writer.write(&[]).unwrap();
assert_eq!(writer.tell(), Ok(8));

assert!(writer.write(&[1]).is_err());
}
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
assert_eq!(buf.as_slice(), b);
Expand Down Expand Up @@ -457,6 +504,32 @@ mod test {
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]
fn test_buf_reader() {
let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
Expand Down
5 changes: 2 additions & 3 deletions src/libstd/io/util.rs
Expand Up @@ -273,7 +273,7 @@ impl<T: Iterator<u8>> Reader for IterReader<T> {

#[cfg(test)]
mod test {
use io::{MemReader, BufReader, ByRefReader};
use io::{MemReader, ByRefReader};
use io;
use boxed::Box;
use super::*;
Expand Down Expand Up @@ -395,8 +395,7 @@ mod test {

#[test]
fn limit_reader_buffer() {
let data = "0123456789\n0123456789\n";
let mut r = BufReader::new(data.as_bytes());
let r = &mut b"0123456789\n0123456789\n";
{
let mut r = LimitReader::new(r.by_ref(), 3);
assert_eq!(r.read_line(), Ok("012".to_string()));
Expand Down
9 changes: 4 additions & 5 deletions src/libtime/lib.rs
Expand Up @@ -32,7 +32,6 @@ use self::Fmt::*;

use std::fmt::Show;
use std::fmt;
use std::io::BufReader;
use std::num::SignedInt;
use std::string::String;
use std::time::Duration;
Expand Down Expand Up @@ -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 {
tm_sec: 0_i32,
tm_min: 0_i32,
Expand All @@ -1211,13 +1210,13 @@ pub fn strptime(s: &str, format: &str) -> Result<Tm, ParseError> {
let next = range.next;

let mut buf = [0];
let c = match rdr.read(&mut buf) {
let c = match (&mut rdr).read(&mut buf) {
Ok(..) => buf[0] as char,
Err(..) => break
};
match c {
'%' => {
let ch = match rdr.read(&mut buf) {
let ch = match (&mut rdr).read(&mut buf) {
Ok(..) => buf[0] as char,
Err(..) => break
};
Expand All @@ -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 {
tm_sec: tm.tm_sec,
tm_min: tm.tm_min,
Expand Down

0 comments on commit d9c7c00

Please sign in to comment.