1use std::io;
2
3pub struct NoneReader<R> {
4 inner: R,
5 start: u64,
6 end: u64,
7 position: u64,
8}
9
10impl<R> NoneReader<R> {
11 pub fn with_length(inner: R, start: u64, length: u64) -> Self {
12 Self {
13 inner,
14 start,
15 end: start + length,
16 position: 0,
17 }
18 }
19}
20
21impl<R: io::Read> io::Read for NoneReader<R> {
22 #[inline]
23 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
24 if self.start + self.position >= self.end {
25 return Ok(0);
26 }
27
28 if self.start + self.position + buf.len() as u64 >= self.end {
29 let available_bytes = self.end - self.start - self.position;
30 let result = self.inner.read(&mut buf[0..(available_bytes as usize)])?;
31 self.position += result as u64;
32 return Ok(result);
33 }
34
35 let consumed = self.inner.read(buf)?;
36 self.position += consumed as u64;
37 Ok(consumed)
38 }
39}
40
41impl<R: io::Seek> io::Seek for NoneReader<R> {
42 #[inline]
43 fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
44 match pos {
45 io::SeekFrom::Start(pos) => {
46 let new_offset = self.inner.seek(io::SeekFrom::Start(pos + self.start))?;
47 self.position = new_offset - self.start;
48 Ok(self.position)
49 }
50 io::SeekFrom::End(pos) => {
51 let new_offset = self
52 .inner
53 .seek(io::SeekFrom::Start((self.end as i64 + pos) as u64))?;
54 self.position = new_offset - self.start;
55 Ok(self.position)
56 }
57 io::SeekFrom::Current(pos) => {
58 if pos == 0 {
59 return Ok(self.position);
60 }
61
62 let new_offset = self.inner.seek(io::SeekFrom::Current(pos))?;
63 self.position = new_offset - self.start;
64 Ok(self.position)
65 }
66 }
67 }
68
69 #[inline]
70 fn stream_position(&mut self) -> io::Result<u64> {
71 Ok(self.position)
72 }
73
74 #[inline]
75 fn stream_len(&mut self) -> io::Result<u64> {
76 Ok(self.end - self.start)
77 }
78}