sevenz_rust2/writer/
seq_reader.rs1use crc32fast::Hasher;
2#[cfg(feature = "util")]
3use std::path::PathBuf;
4use std::{fs::File, io::Read, ops::Deref};
5
6#[cfg(not(target_arch = "wasm32"))]
7use std::path::Path;
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
124#[cfg(feature = "util")]
125pub(crate) struct LazyFileReader {
126 path: PathBuf,
127 reader: Option<File>,
128 end: bool,
129}
130
131#[cfg(feature = "util")]
132impl LazyFileReader {
133 pub fn new(path: PathBuf) -> Self {
134 Self {
135 path,
136 reader: None,
137 end: false,
138 }
139 }
140}
141
142#[cfg(feature = "util")]
143impl Read for LazyFileReader {
144 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
145 if self.end {
146 return Ok(0);
147 }
148 if self.reader.is_none() {
149 self.reader = Some(File::open(&self.path)?);
150 }
151 let n = self.reader.as_mut().unwrap().read(buf)?;
152 if n == 0 {
153 self.end = true;
154 self.reader = None;
155 }
156 Ok(n)
157 }
158}