async_sevenz/writer/
source_reader.rs1use futures_lite::io::AsyncRead;
2
3use crc32fast::Hasher;
4
5pub struct SourceReader<R> {
10 reader: R,
11 size: usize,
12 crc: Hasher,
13 crc_value: u32,
14}
15
16impl<R> From<R> for SourceReader<R> {
17 fn from(value: R) -> Self {
18 Self::new(value)
19 }
20}
21
22impl<R: AsyncRead + Unpin> AsyncRead for SourceReader<R> {
23 fn poll_read(
24 mut self: std::pin::Pin<&mut Self>,
25 cx: &mut std::task::Context<'_>,
26 buf: &mut [u8],
27 ) -> std::task::Poll<std::io::Result<usize>> {
28 let poll = std::pin::Pin::new(&mut self.reader).poll_read(cx, buf);
29 if let std::task::Poll::Ready(Ok(n)) = &poll {
30 if self.crc_value == 0 {
31 if *n > 0 {
32 self.size += *n;
33 self.crc.update(&buf[..*n]);
34 } else {
35 let crc = std::mem::replace(&mut self.crc, Hasher::new());
36 self.crc_value = crc.finalize();
37 }
38 }
39 }
40 poll
41 }
42}
43
44impl<R> SourceReader<R> {
45 pub fn new(reader: R) -> Self {
50 Self {
51 reader,
52 size: 0,
53 crc: Hasher::new(),
54 crc_value: 0,
55 }
56 }
57
58 pub fn read_count(&self) -> usize {
60 self.size
61 }
62
63 pub fn crc_value(&self) -> u32 {
67 self.crc_value
68 }
69}