From 2d85d44f47a7effeba78dbeef2c5f42bd47d11a3 Mon Sep 17 00:00:00 2001 From: nwin Date: Sat, 14 Mar 2015 13:39:39 +0100 Subject: [PATCH 1/2] Use generic trait implementations for Cursor when possible. --- src/libstd/io/cursor.rs | 79 +++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 51 deletions(-) diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index 2445f5a7a4040..f5fc5601de9ba 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -12,6 +12,7 @@ use prelude::v1::*; use io::prelude::*; use cmp; +use ops::Deref; use io::{self, SeekFrom, Error, ErrorKind}; use iter::repeat; use num::Int; @@ -27,7 +28,7 @@ use slice; /// * `Cursor>` /// * `Cursor<&[u8]>` /// -/// Implementations of the I/O traits for `Cursor` are not currently generic +/// The implementation of the `Write` trait for `Cursor` is currently not generic /// over `T` itself. Instead, specific implementations are provided for various /// in-memory buffer types like `Vec` and `&[u8]`. #[stable(feature = "rust1", since = "1.0.0")] @@ -67,68 +68,44 @@ impl Cursor { pub fn set_position(&mut self, pos: u64) { self.pos = pos; } } -macro_rules! seek { - () => { - fn seek(&mut self, style: SeekFrom) -> io::Result { - let pos = match style { - SeekFrom::Start(n) => { self.pos = n; return Ok(n) } - SeekFrom::End(n) => self.inner.len() as i64 + n, - SeekFrom::Current(n) => self.pos as i64 + n, - }; - - if pos < 0 { - Err(Error::new(ErrorKind::InvalidInput, - "invalid seek to a negative position", - None)) - } else { - self.pos = pos as u64; - Ok(self.pos) - } +#[stable(feature = "rust1", since = "1.0.0")] +impl io::Seek for Cursor where T: Deref { + fn seek(&mut self, style: SeekFrom) -> io::Result { + let pos = match style { + SeekFrom::Start(n) => { self.pos = n; return Ok(n) } + SeekFrom::End(n) => self.inner.len() as i64 + n, + SeekFrom::Current(n) => self.pos as i64 + n, + }; + + if pos < 0 { + Err(Error::new(ErrorKind::InvalidInput, + "invalid seek to a negative position", + None)) + } else { + self.pos = pos as u64; + Ok(self.pos) } } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a> io::Seek for Cursor<&'a [u8]> { seek!(); } -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a> io::Seek for Cursor<&'a mut [u8]> { seek!(); } -#[stable(feature = "rust1", since = "1.0.0")] -impl io::Seek for Cursor> { seek!(); } - -macro_rules! read { - () => { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - let n = try!(Read::read(&mut try!(self.fill_buf()), buf)); - self.pos += n as u64; - Ok(n) - } +impl Read for Cursor where T: Deref { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let n = try!(Read::read(&mut try!(self.fill_buf()), buf)); + self.pos += n as u64; + Ok(n) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a> Read for Cursor<&'a [u8]> { read!(); } -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a> Read for Cursor<&'a mut [u8]> { read!(); } -#[stable(feature = "rust1", since = "1.0.0")] -impl Read for Cursor> { read!(); } - -macro_rules! buffer { - () => { - fn fill_buf(&mut self) -> io::Result<&[u8]> { - let amt = cmp::min(self.pos, self.inner.len() as u64); - Ok(&self.inner[(amt as usize)..]) - } - fn consume(&mut self, amt: usize) { self.pos += amt as u64; } +impl BufRead for Cursor where T: Deref { + fn fill_buf(&mut self) -> io::Result<&[u8]> { + let amt = cmp::min(self.pos, self.inner.len() as u64); + Ok(&self.inner[(amt as usize)..]) } + fn consume(&mut self, amt: usize) { self.pos += amt as u64; } } -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a> BufRead for Cursor<&'a [u8]> { buffer!(); } -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a> BufRead for Cursor<&'a mut [u8]> { buffer!(); } -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a> BufRead for Cursor> { buffer!(); } - #[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for Cursor<&'a mut [u8]> { fn write(&mut self, data: &[u8]) -> io::Result { From ed65ab909199d3293acfd927fa28f95c2606d00b Mon Sep 17 00:00:00 2001 From: nwin Date: Sat, 14 Mar 2015 13:40:04 +0100 Subject: [PATCH 2/2] Add test and move test_slice_reader to the appropriate module. --- src/libstd/io/cursor.rs | 16 +++++++++------- src/libstd/io/impls.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index f5fc5601de9ba..3c9bb026dbbab 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -259,21 +259,23 @@ mod tests { } #[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(); + fn test_boxed_reader() { + let mut reader = Cursor::new( + vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice(), + ); let mut buf = []; assert_eq!(reader.read(&mut buf), Ok(0)); + assert_eq!(reader.position(), 0); let mut buf = [0]; assert_eq!(reader.read(&mut buf), Ok(1)); - assert_eq!(reader.len(), 7); + assert_eq!(reader.position(), 1); let b: &[_] = &[0]; - assert_eq!(buf.as_slice(), b); + assert_eq!(buf, b); let mut buf = [0; 4]; assert_eq!(reader.read(&mut buf), Ok(4)); - assert_eq!(reader.len(), 3); + assert_eq!(reader.position(), 5); let b: &[_] = &[1, 2, 3, 4]; - assert_eq!(buf.as_slice(), b); + assert_eq!(buf, b); assert_eq!(reader.read(&mut buf), Ok(3)); let b: &[_] = &[5, 6, 7]; assert_eq!(&buf[..3], b); diff --git a/src/libstd/io/impls.rs b/src/libstd/io/impls.rs index 16298240acfbe..238be93cdf4b8 100644 --- a/src/libstd/io/impls.rs +++ b/src/libstd/io/impls.rs @@ -155,3 +155,33 @@ impl Write for Vec { fn flush(&mut self) -> io::Result<()> { Ok(()) } } + + +#[cfg(test)] +mod tests { + use core::prelude::*; + + use io::prelude::*; + + #[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[..3], b); + assert_eq!(reader.read(&mut buf), Ok(0)); + } +} \ No newline at end of file