sevenz_rust2/writer/
seq_reader.rs1use 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}