Skip to content

Add Reader impl for &[u8] and Writer impl for &mut [u8] #18980

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 4, 2014
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src/libcore/result.rs
Original file line number Diff line number Diff line change
@@ -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)
8 changes: 3 additions & 5 deletions src/libgraphviz/lib.rs
Original file line number Diff line number Diff line change
@@ -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.
@@ -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,
@@ -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 {
6 changes: 3 additions & 3 deletions src/libstd/io/buffered.rs
Original file line number Diff line number Diff line change
@@ -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;

@@ -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')));
73 changes: 73 additions & 0 deletions src/libstd/io/mem.rs
Original file line number Diff line number Diff line change
@@ -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
@@ -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();
@@ -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);
@@ -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];
5 changes: 2 additions & 3 deletions src/libstd/io/util.rs
Original file line number Diff line number Diff line change
@@ -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::*;
@@ -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()));
9 changes: 4 additions & 5 deletions src/libtime/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
@@ -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,
@@ -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
};
@@ -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,