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
use crate::{AsyncSeekForward, SeekForward};
use async_trait::async_trait;
use futures::io::{AsyncRead, AsyncReadExt};
use std::io::Read;
use std::io::Result as IOResult;
use std::pin::Pin;
use std::task::{Context, Poll};
pub struct Discarder<R: Read> {
reader: R,
}
impl<R: Read> Discarder<R> {
pub fn new(reader: R) -> Self {
Self { reader }
}
pub fn into_inner(self) -> R {
self.reader
}
}
impl<R: Read> Read for Discarder<R> {
fn read(&mut self, buf: &mut [u8]) -> IOResult<usize> {
self.reader.read(buf)
}
}
impl<R: Read> SeekForward for Discarder<R> {
fn seek_forward(&mut self, forward: u64) -> IOResult<()> {
let mut buf = [0; 4096];
let mut left = forward as usize;
while left > 0 {
let toread = left.min(buf.len());
let r = self.reader.read(&mut buf[0..toread])?;
left -= r;
}
Ok(())
}
}
pub struct AsyncDiscarder<R: AsyncRead> {
reader: R,
}
impl<R: AsyncRead> AsyncDiscarder<R> {
pub fn new(reader: R) -> Self {
Self { reader }
}
pub fn into_inner(self) -> R {
self.reader
}
}
impl<R: AsyncRead + Unpin> AsyncRead for AsyncDiscarder<R> {
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<IOResult<usize>> {
Pin::new(&mut self.reader).poll_read(cx, buf)
}
}
#[async_trait(?Send)]
impl<R: AsyncRead + Unpin> AsyncSeekForward for AsyncDiscarder<R> {
async fn async_seek_forward(&mut self, forward: u64) -> IOResult<()> {
let mut buf = [0; 4096];
let mut left = forward as usize;
while left > 0 {
let toread = left.min(buf.len());
let r = self.read(&mut buf[0..toread]).await?;
left -= r;
}
Ok(())
}
}
#[cfg(test)]
mod test {
use super::*;
use std::slice;
#[test]
fn discard() {
let mut data = Vec::with_capacity(256);
for byte in 0u8..=255 {
data.push(byte);
}
let mut discarder = Discarder::new(data.as_slice());
let _ = &[0u64, 5, 16, 31, 63, 200, 255]
.iter()
.fold(0, |pos, offset| {
let mut byte: u8 = 1;
discarder.seek_forward((offset - pos) as u64).unwrap();
assert_eq!(1, discarder.read(slice::from_mut(&mut byte)).unwrap());
assert_eq!(*offset, byte as u64);
*offset + 1
});
}
}