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
use std::{cmp, io};
use std::io::SeekFrom;
use std::io::{Seek,Read,Write};
pub struct T<S>(pub S);
impl<S: Read + Seek> Read for T<S> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let pos = try!(self.0.seek(SeekFrom::Current(0)));
let t_dist = -(cmp::min(buf.len(), pos as usize) as i64);
let n_pos = try!(self.0.seek(SeekFrom::Current(t_dist)));
let dist = (pos - n_pos) as usize;
let ct = try!(self.0.read(&mut buf[..dist]));
try!(self.0.seek(SeekFrom::Start(n_pos)));
buf[..ct].reverse();
Ok(ct)
}
}
impl<S: Write + io::Seek> Write for T<S> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let pos = try!(self.0.seek(SeekFrom::Current(0)));
let seek_goal = cmp::min(buf.len(), pos as usize) as i64;
let new_pos = try!(self.0.seek(SeekFrom::Current(-seek_goal)));
let seek_dist = (pos - new_pos) as usize;
let mut r_buf = buf[..seek_dist].to_vec();
r_buf.reverse();
try!(self.0.write_all(&r_buf));
try!(self.0.seek(SeekFrom::Start(new_pos)));
Ok(seek_dist)
}
fn flush(&mut self) -> io::Result<()> {
self.0.flush()
}
}
impl<S: io::Seek> io::Seek for T<S> {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
let real_pos = match pos {
SeekFrom::Current(x) => SeekFrom::Current(-x),
SeekFrom::Start(x) => {
assert!(x <= std::i64::MAX as u64);
SeekFrom::End(-(x as i64))
},
SeekFrom::End(x) => {
assert!(x >= 0);
SeekFrom::Start(x as u64)
},
};
let u_res = try!(self.0.seek(real_pos));
let cur = try!(self.0.seek(SeekFrom::Current(0)));
let end = try!(self.0.seek(SeekFrom::End(0)));
try!(self.0.seek(SeekFrom::Start(cur)));
Ok(end - u_res)
}
}
#[test]
fn seek() {
use std::io::Cursor;
let mut c = T(Cursor::new(vec![4u8, 6, 2]));
assert_eq!(c.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(c.seek(SeekFrom::Start(1)).unwrap(), 1);
assert_eq!(c.seek(SeekFrom::End(0)).unwrap(), 3);
assert_eq!(c.seek(SeekFrom::Current(-1)).unwrap(), 2);
}
#[test]
fn read() {
use std::io::Cursor;
let t = vec![4u8, 6, 2];
let r : &mut[_] = &mut t.clone();
r.reverse();
let mut c = T(Cursor::new(t));
let b : &mut[_] = &mut [0; 3];
assert_eq!(c.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(c.read(b).unwrap(), 3);
assert_eq!(b, r);
assert_eq!(c.seek(SeekFrom::Current(0)).unwrap(), 3);
assert_eq!(c.read(b).unwrap(), 0);
assert_eq!(b, r);
}
#[test]
fn write() {
use std::io::Cursor;
let t = vec![4u8, 6, 2];
let mut c = T(Cursor::new(t));
let b = [5, 2, 6];
let mut r = b;
r.reverse();
assert_eq!(c.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(c.write(&b).unwrap(), 3);
assert_eq!(&c.0.get_ref()[..], &r);
assert_eq!(c.write(&b).unwrap(), 0);
assert_eq!(c.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(c.write(&b[..2]).unwrap(), 2);
assert_eq!(c.write(&b[..2]).unwrap(), 1);
}