impl<'a> Writer for BufWriter<'a> {
#[inline]
- fn write(&mut self, buf: &[u8]) -> IoResult<()> {
- // return an error if the entire write does not fit in the buffer
- let cap = if self.pos >= self.buf.len() { 0 } else { self.buf.len() - self.pos };
- if buf.len() > cap {
- return Err(IoError {
- kind: io::OtherIoError,
- desc: "Trying to write past end of buffer",
- detail: None
- })
+ fn write(&mut self, src: &[u8]) -> IoResult<()> {
+ let dst = self.buf[mut self.pos..];
+ let dst_len = dst.len();
+
+ if dst_len == 0 {
+ return Err(io::standard_error(io::EndOfFile));
}
- slice::bytes::copy_memory(self.buf[mut self.pos..], buf);
- self.pos += buf.len();
- Ok(())
+ let src_len = src.len();
+
+ if dst_len >= src_len {
+ slice::bytes::copy_memory(dst, src);
+
+ self.pos += src_len;
+
+ Ok(())
+ } else {
+ slice::bytes::copy_memory(dst, src[..dst_len]);
+
+ self.pos += dst_len;
+
+ Err(io::standard_error(io::ShortWrite(dst_len)))
+ }
}
}
#[inline]
fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
let new = try!(combine(style, self.pos, self.buf.len(), pos));
- self.pos = new as uint;
+ self.pos = min(new as uint, self.buf.len());
Ok(())
}
}
#[test]
fn test_buf_writer() {
- let mut buf = [0 as u8, ..8];
+ let mut buf = [0 as u8, ..9];
{
let mut writer = BufWriter::new(&mut buf);
assert_eq!(writer.tell(), Ok(0));
writer.write(&[]).unwrap();
assert_eq!(writer.tell(), Ok(8));
- assert!(writer.write(&[1]).is_err());
+ assert_eq!(writer.write(&[8, 9]).unwrap_err().kind, io::ShortWrite(1));
+ assert_eq!(writer.write(&[10]).unwrap_err().kind, io::EndOfFile);
}
- let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
+ let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
assert_eq!(buf.as_slice(), b);
}
match writer.write(&[0, 0]) {
Ok(..) => panic!(),
- Err(e) => assert_eq!(e.kind, io::OtherIoError),
+ Err(e) => assert_eq!(e.kind, io::ShortWrite(1)),
}
}