use std::io::{ self, Read, Seek, Write, SeekFrom, ErrorKind };
pub fn buf_copy<I, O>(buf: &mut [u8], reader: &mut I, writer: &mut O)
-> Result<u64, io::Error> where I: Read, O: Write
{
let mut written = 0;
loop {
let len = match reader.read(buf) {
Ok(0) => return Ok(written),
Ok(len) => len,
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
};
try!(writer.write_all(&buf[..len]));
written += len as u64;
}
}
#[inline(always)]
pub fn seek_and_buf_copy<I, O>(loc: u64, len: u64, buf: &mut [u8], input: &mut I, output: &mut O)
-> Result<u64, io::Error> where I: Read + Seek, O: Write
{
try!(input.seek(SeekFrom::Start(loc)));
buf_copy(buf, &mut input.take(len), output)
}
#[cfg(test)]
mod test {
use std::io::{ Cursor };
use super::*;
#[test]
fn test_stream() {
let data = b"world helloand the quick fox jumps over that dog";
let mut input = Cursor::new(&data[..]);
let mut output = Vec::<u8>::new();
let mut buf = [0; 5];
seek_and_buf_copy(6, 5, &mut buf, &mut input, &mut output).unwrap();
seek_and_buf_copy(5, 1, &mut buf, &mut input, &mut output).unwrap();
seek_and_buf_copy(0, 5, &mut buf, &mut input, &mut output).unwrap();
seek_and_buf_copy(5, 1, &mut buf, &mut input, &mut output).unwrap();
seek_and_buf_copy(11, 37, &mut buf, &mut input, &mut output).unwrap();
assert_eq!(
"hello world and the quick fox jumps over that dog",
String::from_utf8_lossy(&output[..])
);
}
}
#[cfg(feature="nightly")]
mod bench {
extern crate test;
use std::io::{ Cursor };
use super::*;
#[bench]
fn bench_all_streaming(b: &mut test::Bencher) {
let data = b"world helloand the quick fox jumps over that dog";
b.iter(|| {
let mut input = test::black_box(Cursor::new(&data[..]));
let mut output = Vec::<u8>::new();
let mut buf = [0; 5];
seek_and_buf_copy(6, 5, &mut buf, &mut input, &mut output).unwrap();
seek_and_buf_copy(5, 1, &mut buf, &mut input, &mut output).unwrap();
seek_and_buf_copy(0, 5, &mut buf, &mut input, &mut output).unwrap();
seek_and_buf_copy(5, 1, &mut buf, &mut input, &mut output).unwrap();
seek_and_buf_copy(11, 37, &mut buf, &mut input, &mut output).unwrap();
output
});
}
}