sevenz_rust2/writer/
seq_reader.rs

1use crc32fast::Hasher;
2use std::{
3    fs::File,
4    io::Read,
5    ops::Deref,
6    path::{Path, PathBuf},
7};
8
9#[derive(Default)]
10pub struct SeqReader<R> {
11    readers: Vec<R>,
12    current: usize,
13}
14
15impl<R> From<Vec<R>> for SeqReader<R> {
16    fn from(value: Vec<R>) -> Self {
17        Self::new(value)
18    }
19}
20
21impl<R> Deref for SeqReader<R> {
22    type Target = [R];
23
24    fn deref(&self) -> &Self::Target {
25        &self.readers
26    }
27}
28
29impl<R> AsRef<[R]> for SeqReader<R> {
30    fn as_ref(&self) -> &[R] {
31        &self.readers
32    }
33}
34
35#[cfg(not(target_arch = "wasm32"))]
36impl SeqReader<File> {
37    pub fn from_path_iter<'a>(paths: impl Iterator<Item = &'a Path>) -> std::io::Result<Self> {
38        let mut readers = Vec::new();
39        for path in paths {
40            readers.push(File::open(path)?);
41        }
42        Ok(Self::new(readers))
43    }
44}
45
46impl<R> SeqReader<R> {
47    pub fn new(readers: Vec<R>) -> Self {
48        Self {
49            readers,
50            current: 0,
51        }
52    }
53
54    pub fn reader_len(&self) -> usize {
55        self.readers.len()
56    }
57}
58
59impl<R: Read> Read for SeqReader<R> {
60    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
61        let mut i = 0;
62        while self.current < self.readers.len() {
63            let r = &mut self.readers[self.current];
64            i = r.read(buf)?;
65            if i == 0 {
66                self.current += 1;
67            } else {
68                break;
69            }
70        }
71
72        Ok(i)
73    }
74}
75
76pub struct SourceReader<R> {
77    reader: R,
78    size: usize,
79    crc: Hasher,
80    crc_value: u32,
81}
82
83impl<R> From<R> for SourceReader<R> {
84    fn from(value: R) -> Self {
85        Self::new(value)
86    }
87}
88
89impl<R: Read> Read for SourceReader<R> {
90    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
91        let n = self.reader.read(buf)?;
92        if self.crc_value == 0 {
93            if n > 0 {
94                self.size += n;
95                self.crc.update(&buf[..n]);
96            } else {
97                let crc = std::mem::replace(&mut self.crc, Hasher::new());
98                self.crc_value = crc.finalize();
99            }
100        }
101        Ok(n)
102    }
103}
104
105impl<R> SourceReader<R> {
106    pub fn new(reader: R) -> Self {
107        Self {
108            reader,
109            size: 0,
110            crc: Hasher::new(),
111            crc_value: 0,
112        }
113    }
114
115    pub fn read_count(&self) -> usize {
116        self.size
117    }
118
119    pub fn crc_value(&self) -> u32 {
120        self.crc_value
121    }
122}
123
124pub(crate) struct LazyFileReader {
125    path: PathBuf,
126    reader: Option<File>,
127    end: bool,
128}
129
130impl LazyFileReader {
131    pub fn new(path: PathBuf) -> Self {
132        Self {
133            path,
134            reader: None,
135            end: false,
136        }
137    }
138}
139
140impl Read for LazyFileReader {
141    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
142        if self.end {
143            return Ok(0);
144        }
145        if self.reader.is_none() {
146            self.reader = Some(File::open(&self.path)?);
147        }
148        let n = self.reader.as_mut().unwrap().read(buf)?;
149        if n == 0 {
150            self.end = true;
151            self.reader = None;
152        }
153        Ok(n)
154    }
155}