sevenz_rust2/writer/
seq_reader.rs

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