1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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
});
}
}