Skip to content

Instantly share code, notes, and snippets.

@japaric
Created November 24, 2014 16:03
Show Gist options
  • Save japaric/97a41a7bd0c7d5f6694c to your computer and use it in GitHub Desktop.
Save japaric/97a41a7bd0c7d5f6694c to your computer and use it in GitHub Desktop.
BufWriter
#![feature(slicing_syntax)]
extern crate criterion;
use criterion::Criterion;
use std::cmp::min;
use std::io::{IoError, IoResult};
use std::raw::Repr;
use std::{io, mem, ptr, raw, slice};
const SRC_LEN: uint = 4;
const BATCHES: uint = 128;
fn main() {
Criterion::default().
bench("never/std_vec_writer", |b| {
let mut dst = Vec::with_capacity(BATCHES * SRC_LEN);
let src = &[1, .. SRC_LEN];
b.iter(|| {
dst.clear();
do_std_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/std_buf_writer", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = io::BufWriter::new(dst);
do_std_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/copy_nonoverlapping", |b| {
let dst = &mut [0_u8, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
unsafe {
do_copy_nonoverlapping_memory_inline_never(dst.as_mut_ptr(), src.as_ptr(), src.len(), BATCHES);
}
})
}).
bench("never/slice_writer", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = dst.as_mut_slice();
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/unsafe_writer", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = UnsafeWriter::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_0", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter0::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_1", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter1::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_2", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter2::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_3", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter3::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_4", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter4::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_5", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter5::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_6", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter6::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_7", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter7::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_8", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter8::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_9", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter9::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_10", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter10::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_11", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter11::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_12", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter12::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/buf_writer_13", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter13::new(dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
bench("never/vec_writer_1", |b| {
let mut dst = Vec::with_capacity(BATCHES * SRC_LEN);
let src = &[1, .. SRC_LEN];
b.iter(|| {
dst.clear();
let mut dst = VecWriter1::new(&mut dst);
do_my_writes_inline_never(&mut dst, src, BATCHES);
})
}).
summarize("never").
bench("always/std_vec_writer", |b| {
let mut dst = Vec::with_capacity(BATCHES * SRC_LEN);
let src = &[1, .. SRC_LEN];
b.iter(|| {
dst.clear();
do_std_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/std_buf_writer", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = io::BufWriter::new(dst);
do_std_writes_inline_always(&mut dst, src, BATCHES);
})
}).
//bench("always/copy_nonoverlapping", |b| {
//let dst = &mut [0_u8, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//unsafe {
//do_copy_nonoverlapping_memory_inline_always(dst.as_mut_ptr(), src.as_ptr(), src.len(), BATCHES);
//}
//})
//}).
bench("always/slice_writer", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = dst.as_mut_slice();
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
//bench("always/unsafe_writer", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = UnsafeWriter::new(dst);
//do_my_writes_inline_always(&mut dst, src, BATCHES);
//})
//}).
bench("always/buf_writer_0", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter0::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_1", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter1::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_2", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter2::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_3", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter3::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_4", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter4::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_5", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter5::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_6", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter6::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
//bench("always/buf_writer_7", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter7::new(dst);
//do_my_writes_inline_always(&mut dst, src, BATCHES);
//})
//}).
bench("always/buf_writer_8", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter8::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_9", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter9::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_10", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter10::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_11", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter11::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_12", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter12::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/buf_writer_13", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter13::new(dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
bench("always/vec_writer_1", |b| {
let mut dst = Vec::with_capacity(BATCHES * SRC_LEN);
let src = &[1, .. SRC_LEN];
b.iter(|| {
dst.clear();
let mut dst = VecWriter1::new(&mut dst);
do_my_writes_inline_always(&mut dst, src, BATCHES);
})
}).
summarize("always").
bench("inline/std_vec_writer", |b| {
let mut dst = Vec::with_capacity(BATCHES * SRC_LEN);
let src = &[1, .. SRC_LEN];
b.iter(|| {
dst.clear();
do_std_writes(&mut dst, src, BATCHES);
})
}).
bench("inline/std_buf_writer", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = io::BufWriter::new(dst);
do_std_writes(&mut dst, src, BATCHES);
})
}).
//bench("inline/copy_nonoverlapping", |b| {
//let dst = &mut [0_u8, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//unsafe {
//do_copy_nonoverlapping_memory(dst.as_mut_ptr(), src.as_ptr(), src.len(), BATCHES);
//}
//})
//}).
bench("inline/slice_writer", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = dst.as_mut_slice();
do_my_writes(&mut dst, src, BATCHES);
})
}).
//bench("inline/unsafe_writer", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = UnsafeWriter::new(dst);
//do_my_writes(&mut dst, src, BATCHES);
//})
//}).
bench("inline/buf_writer_0", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter0::new(dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
bench("inline/buf_writer_1", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter1::new(dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
bench("inline/buf_writer_2", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter2::new(dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
bench("inline/buf_writer_3", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter3::new(dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
bench("inline/buf_writer_4", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter4::new(dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
bench("inline/buf_writer_5", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter5::new(dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
bench("inline/buf_writer_6", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter6::new(dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
//bench("inline/buf_writer_7", |b| {
//let dst = &mut [0, .. BATCHES * SRC_LEN];
//let src = &[1, .. SRC_LEN];
//b.iter(|| {
//let mut dst = BufWriter7::new(dst);
//do_my_writes(&mut dst, src, BATCHES);
//})
//}).
bench("inline/buf_writer_8", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter8::new(dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
bench("inline/buf_writer_9", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter9::new(dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
bench("inline/buf_writer_10", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter10::new(dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
bench("inline/buf_writer_11", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter11::new(dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
bench("inline/buf_writer_12", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter12::new(dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
bench("inline/buf_writer_13", |b| {
let dst = &mut [0, .. BATCHES * SRC_LEN];
let src = &[1, .. SRC_LEN];
b.iter(|| {
let mut dst = BufWriter13::new(dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
bench("inline/vec_writer_1", |b| {
let mut dst = Vec::with_capacity(BATCHES * SRC_LEN);
let src = &[1, .. SRC_LEN];
b.iter(|| {
dst.clear();
let mut dst = VecWriter1::new(&mut dst);
do_my_writes(&mut dst, src, BATCHES);
})
}).
summarize("inline");
}
#[inline(never)]
fn do_std_writes_inline_never<W: Writer>(dst: &mut W, src: &[u8], batches: uint) {
for _ in range(0, batches) {
dst.write(src).unwrap();
}
}
#[inline(never)]
unsafe fn do_copy_nonoverlapping_memory_inline_never(mut dst: *mut u8, src: *const u8, len: uint, batches: uint) {
for _ in range(0, batches) {
ptr::copy_nonoverlapping_memory(dst, src, len);
dst = dst.offset(len as int);
}
}
trait MyWriter {
fn my_write(&mut self, src: &[u8]) -> IoResult<()>;
}
#[inline(never)]
fn do_my_writes_inline_never<W>(dst: &mut W, src: &[u8], batches: uint) where W: MyWriter {
for _ in range(0, batches) {
dst.my_write(src).unwrap();
}
}
#[inline(always)]
fn do_std_writes_inline_always<W: Writer>(dst: &mut W, src: &[u8], batches: uint) {
for _ in range(0, batches) {
dst.write(src).unwrap();
}
}
#[inline(always)]
fn do_my_writes_inline_always<W>(dst: &mut W, src: &[u8], batches: uint) where W: MyWriter {
for _ in range(0, batches) {
dst.my_write(src).unwrap();
}
}
#[inline]
fn do_my_writes<W>(dst: &mut W, src: &[u8], batches: uint) where W: MyWriter {
for _ in range(0, batches) {
dst.my_write(src).unwrap();
}
}
#[inline]
fn do_std_writes<W: Writer>(dst: &mut W, src: &[u8], batches: uint) {
for _ in range(0, batches) {
dst.write(src).unwrap();
}
}
#[inline]
unsafe fn do_copy_nonoverlapping_memory(mut dst: *mut u8, src: *const u8, len: uint, batches: uint) {
for _ in range(0, batches) {
ptr::copy_nonoverlapping_memory(dst, src, len);
dst = dst.offset(len as int);
}
}
#[inline(always)]
unsafe fn do_copy_nonoverlapping_memory_inline_always(mut dst: *mut u8, src: *const u8, len: uint, batches: uint) {
for _ in range(0, batches) {
ptr::copy_nonoverlapping_memory(dst, src, len);
dst = dst.offset(len as int);
}
}
impl<'a> MyWriter for &'a mut [u8] {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
if self.is_empty() { return Err(io::standard_error(io::EndOfFile)); }
let dst_len = self.len();
let src_len = src.len();
let write_len = min(dst_len, src_len);
slice::bytes::copy_memory(*self, src.slice_to(write_len));
unsafe {
*self = mem::transmute(raw::Slice {
data: self.as_ptr().offset(write_len as int),
len: dst_len - write_len,
});
}
if src_len > dst_len {
Err(io::standard_error(io::ShortWrite(write_len)))
} else {
Ok(())
}
}
}
struct UnsafeWriter<'a> {
dst: *mut u8,
}
impl<'a> UnsafeWriter<'a> {
#[inline]
fn new(dst: &'a mut [u8]) -> UnsafeWriter<'a> {
UnsafeWriter {
dst: dst.as_mut_ptr(),
}
}
}
impl<'a> MyWriter for UnsafeWriter<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let len = src.len();
unsafe {
ptr::copy_nonoverlapping_memory(self.dst, src.as_ptr(), len);
self.dst = self.dst.offset(len as int);
}
Ok(())
}
}
struct BufWriter0<'a> {
dst: &'a mut [u8],
}
impl<'a> BufWriter0<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter0<'a> {
BufWriter0 {
dst: dst
}
}
}
impl<'a> MyWriter for BufWriter0<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
if self.dst.is_empty() { return Err(io::standard_error(io::EndOfFile)); }
let dst_len = self.dst.len();
let src_len = src.len();
let write_len = min(dst_len, src_len);
slice::bytes::copy_memory(self.dst, src.slice_to(write_len));
unsafe {
self.dst = mem::transmute(raw::Slice {
data: self.dst.as_ptr().offset(write_len as int),
len: dst_len - write_len,
});
}
if src_len > dst_len {
Err(io::standard_error(io::ShortWrite(write_len)))
} else {
Ok(())
}
}
}
struct BufWriter1<'a> {
dst: &'a mut [u8],
}
impl<'a> BufWriter1<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter1<'a> {
BufWriter1 {
dst: dst,
}
}
}
impl<'a> MyWriter for BufWriter1<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.dst.len();
let src_len = src.len();
let write_len = min(dst_len, src_len);
slice::bytes::copy_memory(self.dst, src[..write_len]);
unsafe {
let self_: &mut raw::Slice<u8> = mem::transmute(self);
self_.data = self_.data.offset(write_len as int);
self_.len = dst_len - write_len;
}
Ok(())
}
}
struct BufWriter2<'a> {
dst: &'a mut [u8],
}
impl<'a> BufWriter2<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter2<'a> {
BufWriter2 {
dst: dst,
}
}
}
impl<'a> MyWriter for BufWriter2<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.dst.len();
let write_len = src.len();
slice::bytes::copy_memory(self.dst, src[..write_len]);
unsafe {
let self_: &mut raw::Slice<u8> = mem::transmute(self);
self_.data = self_.data.offset(write_len as int);
self_.len = dst_len - write_len;
}
Ok(())
}
}
struct BufWriter3<'a> {
dst: &'a mut [u8],
pos: uint,
}
impl<'a> BufWriter3<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter3<'a> {
BufWriter3 {
dst: dst,
pos: 0,
}
}
}
impl<'a> MyWriter for BufWriter3<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
// return an error if the entire write does not fit in the buffer
let cap = if self.pos >= self.dst.len() { 0 } else { self.dst.len() - self.pos };
if src.len() > cap {
return Err(IoError {
kind: io::OtherIoError,
desc: "Trying to write past end of buffer",
detail: None
})
}
slice::bytes::copy_memory(self.dst[mut self.pos..], src);
self.pos += src.len();
Ok(())
}
}
struct BufWriter4<'a> {
dst: *mut u8,
end: *mut u8,
}
impl<'a> BufWriter4<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter4<'a> {
let dst_ptr = dst.as_mut_ptr();
unsafe {
BufWriter4 {
dst: dst_ptr,
end: dst_ptr.offset(dst.len() as int),
}
}
}
#[inline]
fn capacity(&self) -> uint {
self.end as uint - self.dst as uint
}
}
impl<'a> MyWriter for BufWriter4<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let src_len = src.len();
if src_len > self.capacity() {
return Err(IoError {
kind: io::OtherIoError,
desc: "Trying to write past end of buffer",
detail: None
})
}
unsafe {
ptr::copy_nonoverlapping_memory(self.dst, src.as_ptr(), src_len);
self.dst = self.dst.offset(src_len as int);
}
Ok(())
}
}
struct BufWriter5<'a> {
dst: &'a mut [u8],
}
impl<'a> BufWriter5<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter5<'a> {
BufWriter5 {
dst: dst,
}
}
}
impl<'a> MyWriter for BufWriter5<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.dst.len();
let src_len = src.len();
let x = (dst_len < src_len) as uint;
let write_len = dst_len * x + src_len * (1 - x);
slice::bytes::copy_memory(self.dst, src[..write_len]);
unsafe {
let self_: &mut raw::Slice<u8> = mem::transmute(self);
self_.data = self_.data.offset(write_len as int);
self_.len = dst_len - write_len;
}
Ok(())
}
}
struct BufWriter6<'a> {
dst: &'a mut [u8],
}
impl<'a> BufWriter6<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter6<'a> {
BufWriter6 {
dst: dst,
}
}
}
impl<'a> MyWriter for BufWriter6<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.dst.len();
let src_len = src.len();
let write_len = min(dst_len, src_len);
unsafe {
ptr::copy_nonoverlapping_memory(
self.dst.as_mut_ptr(),
src.as_ptr(),
write_len);
let self_: &mut raw::Slice<u8> = mem::transmute(self);
self_.data = self_.data.offset(write_len as int);
self_.len = dst_len - write_len;
}
Ok(())
}
}
struct BufWriter7<'a> {
dst: &'a mut [u8],
pos: uint,
}
impl<'a> BufWriter7<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter7<'a> {
BufWriter7 {
dst: dst,
pos: 0,
}
}
}
impl<'a> MyWriter for BufWriter7<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
// return an error if the entire write does not fit in the buffer
let dst_len = self.dst.len();
let src_len = src.len();
let cap = if self.pos >= dst_len { 0 } else { dst_len - self.pos };
if src_len > cap {
return Err(IoError {
kind: io::OtherIoError,
desc: "Trying to write past end of buffer",
detail: None
})
}
unsafe {
ptr::copy_nonoverlapping_memory(
self.dst.as_mut_ptr().offset(self.pos as int),
src.as_ptr(),
src_len);
}
self.pos += src_len;
Ok(())
}
}
struct BufWriter8<'a> {
dst: *mut u8,
end: *mut u8,
}
impl<'a> BufWriter8<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter8<'a> {
let dst_ptr = dst.as_mut_ptr();
unsafe {
BufWriter8 {
dst: dst_ptr,
end: dst_ptr.offset(dst.len() as int),
}
}
}
}
impl<'a> MyWriter for BufWriter8<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let src_len = src.len();
let cap = self.end as uint - self.dst as uint;
if src_len > cap {
return Err(IoError {
kind: io::OtherIoError,
desc: "Trying to write past end of buffer",
detail: None
})
}
unsafe {
ptr::copy_nonoverlapping_memory(self.dst, src.as_ptr(), src_len);
self.dst = self.dst.offset(src_len as int);
}
Ok(())
}
}
struct BufWriter9<'a> {
dst: *mut u8,
end: *mut u8,
}
impl<'a> BufWriter9<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter9<'a> {
let dst_ptr = dst.as_mut_ptr();
unsafe {
BufWriter9 {
dst: dst_ptr,
end: dst_ptr.offset(dst.len() as int),
}
}
}
}
impl<'a> MyWriter for BufWriter9<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
unsafe {
let raw::Slice { data: src_ptr, len: src_len } = src.repr();
let cap = self.end as uint - self.dst as uint;
if src_len > cap {
return Err(IoError {
kind: io::OtherIoError,
desc: "Trying to write past end of buffer",
detail: None
})
}
ptr::copy_nonoverlapping_memory(self.dst, src_ptr, src_len);
self.dst = self.dst.offset(src_len as int);
}
Ok(())
}
}
struct BufWriter10<'a> {
dst: &'a mut [u8],
pos: uint,
}
impl<'a> BufWriter10<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter10<'a> {
BufWriter10 {
dst: dst,
pos: 0,
}
}
}
impl<'a> MyWriter for BufWriter10<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.dst.len();
let src_len = src.len();
if self.pos == dst_len { return Err(io::standard_error(io::EndOfFile)); }
let cap = dst_len - self.pos;
let write_len = min(cap, src_len);
slice::bytes::copy_memory(self.dst[mut self.pos..], src[..write_len]);
if src_len > dst_len {
return Err(io::standard_error(io::ShortWrite(write_len)));
}
self.pos += write_len;
Ok(())
}
}
struct BufWriter11<'a> {
dst: &'a mut [u8],
pos: uint,
}
impl<'a> BufWriter11<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter11<'a> {
BufWriter11 {
dst: dst,
pos: 0,
}
}
}
impl<'a> MyWriter for BufWriter11<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst = self.dst[mut self.pos..];
let dst_len = dst.len();
if dst_len == 0 {
return Err(io::standard_error(io::EndOfFile));
}
let src_len = src.len();
if dst_len >= src_len {
unsafe {
ptr::copy_nonoverlapping_memory(
dst.as_mut_ptr(),
src.as_ptr(),
src_len);
}
self.pos += src_len;
Ok(())
} else {
unsafe {
ptr::copy_nonoverlapping_memory(
dst.as_mut_ptr(),
src.as_ptr(),
dst_len);
}
self.pos += dst_len;
Err(io::standard_error(io::ShortWrite(dst_len)))
}
}
}
struct BufWriter12<'a> {
dst: &'a mut [u8],
}
impl<'a> BufWriter12<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter12<'a> {
BufWriter12 {
dst: dst,
}
}
}
impl<'a> MyWriter for BufWriter12<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.dst.len();
if dst_len == 0 {
return Err(io::standard_error(io::EndOfFile));
}
let src_len = src.len();
if dst_len >= src_len {
unsafe {
ptr::copy_nonoverlapping_memory(
self.dst.as_mut_ptr(),
src.as_ptr(),
src_len);
self.dst = mem::transmute(raw::Slice {
data: self.dst.as_ptr().offset(src_len as int),
len: dst_len - src_len,
});
}
Ok(())
} else {
unsafe {
ptr::copy_nonoverlapping_memory(
self.dst.as_mut_ptr(),
src.as_ptr(),
dst_len);
self.dst = mem::transmute(raw::Slice {
data: self.dst.as_ptr().offset(dst_len as int),
len: 0,
});
}
Err(io::standard_error(io::ShortWrite(dst_len)))
}
}
}
struct BufWriter13<'a> {
dst: *mut u8,
end: *mut u8,
}
impl<'a> BufWriter13<'a> {
#[inline]
fn new<'a>(dst: &'a mut [u8]) -> BufWriter13<'a> {
let dst_ptr = dst.as_mut_ptr();
unsafe {
BufWriter13 {
dst: dst_ptr,
end: dst_ptr.offset(dst.len() as int),
}
}
}
}
impl<'a> MyWriter for BufWriter13<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let dst_len = self.end as uint - self.dst as uint;
if dst_len == 0 {
return Err(io::standard_error(io::EndOfFile));
}
let src_len = src.len();
if dst_len >= src_len {
unsafe {
ptr::copy_nonoverlapping_memory(
self.dst,
src.as_ptr(),
src_len);
self.dst = self.dst.offset(src_len as int);
}
Ok(())
} else {
unsafe {
ptr::copy_nonoverlapping_memory(
self.dst,
src.as_ptr(),
dst_len);
self.dst = self.dst.offset(dst_len as int);
}
Err(io::standard_error(io::ShortWrite(dst_len)))
}
}
}
struct VecWriter1<'a> {
dst: &'a mut Vec<u8>,
}
impl<'a> VecWriter1<'a> {
#[inline]
fn new<'a>(dst: &'a mut Vec<u8>) -> VecWriter1<'a> {
VecWriter1 {
dst: dst,
}
}
}
impl<'a> MyWriter for VecWriter1<'a> {
#[inline]
fn my_write(&mut self, src: &[u8]) -> IoResult<()> {
let src_len = src.len();
self.dst.reserve(src_len);
let dst = self.dst.as_mut_slice();
unsafe {
// we reserved enough room in `dst` to store `src`.
ptr::copy_nonoverlapping_memory(
dst.as_mut_ptr(),
src.as_ptr(),
src_len);
}
Ok(())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment