1#![cfg_attr(docsrs, feature(doc_cfg))]
51#![warn(missing_docs)]
52
53#[cfg(target_arch = "wasm32")]
54extern crate wasm_bindgen;
55
56pub mod container;
57#[cfg(feature = "aes256")]
58mod crypto_backend;
59#[cfg(feature = "compress")]
60mod encoder;
61#[cfg(feature = "compress")]
63pub mod encoder_options;
64mod encryption;
65
66#[cfg(feature = "aes256")]
74#[must_use]
75pub fn crypto_backend() -> &'static str {
76 crypto_backend::BACKEND
77}
78
79#[cfg(feature = "aes256")]
85#[must_use]
86pub fn sha256(data: &[u8]) -> [u8; 32] {
87 let mut sha = crypto_backend::Sha256::new();
88 sha.update(data);
89 sha.finalize()
90}
91
92#[cfg(feature = "compress")]
95#[must_use]
96pub fn lzma_encoder() -> &'static str {
97 "lzma-turbo"
98}
99
100#[cfg(any(feature = "crc-host", feature = "crypto-host"))]
105pub mod hooks;
106
107mod error;
108#[cfg(not(target_arch = "wasm32"))]
109mod ordered;
110mod positional;
111mod reader;
112
113#[cfg(feature = "compress")]
114mod writer;
115
116pub(crate) mod archive;
117pub(crate) mod bitset;
118pub(crate) mod block;
119pub(crate) mod codec;
120pub(crate) mod decoder;
121pub(crate) mod pipeline;
122
123mod time;
124#[cfg(feature = "util")]
125mod util;
126
127use std::{
128 io::{Read, Write},
129 ops::{Deref, DerefMut},
130};
131
132pub use archive::*;
133pub use block::*;
134pub use codec::lzma_turbo::{
135 Lzma2Handle, Lzma2Ledger, Lzma2Progress, Lzma2RunCompletion, Lzma2RunCrc,
136 PositionalLzma2Folder, PositionalLzma2Run, PositionalLzma2Scanner,
137};
138pub use container::{
139 ArchiveLimits, BlockCompletion, CrcFolder, PackStreamRange, SubStream, SubStreamCompletion,
140 UnsizedCoder, coder_memory_estimate, crc32_combine,
141};
142pub use encryption::Password;
143#[cfg(feature = "aes256")]
144pub use encryption::{AesKey, AesProperties};
145pub use error::{BlockErrorKind, Error, Limit};
146pub use positional::{ReadAt, ReadAtCursor, SerialReadAt};
147pub use reader::{ArchiveReader, BlockDecoder, EntryRead, PositionalBlockDecoder};
148pub use time::NtTime;
149#[cfg(all(feature = "compress", feature = "util", not(target_arch = "wasm32")))]
150pub use util::compress::*;
151#[cfg(all(feature = "util", not(target_arch = "wasm32")))]
152pub use util::decompress::*;
153#[cfg(all(feature = "util", target_arch = "wasm32"))]
154pub use util::wasm::*;
155#[cfg(feature = "compress")]
156pub use writer::*;
157
158trait ByteReader {
159 fn read_u8(&mut self) -> std::io::Result<u8>;
160
161 #[cfg(feature = "brotli")]
162 fn read_u16(&mut self) -> std::io::Result<u16>;
163
164 fn read_u32(&mut self) -> std::io::Result<u32>;
165
166 fn read_u64(&mut self) -> std::io::Result<u64>;
167}
168
169trait ByteWriter {
170 #[cfg(feature = "compress")]
171 fn write_u8(&mut self, value: u8) -> std::io::Result<()>;
172
173 fn write_u16(&mut self, value: u16) -> std::io::Result<()>;
174
175 #[cfg(feature = "compress")]
176 fn write_u32(&mut self, value: u32) -> std::io::Result<()>;
177
178 #[cfg(feature = "compress")]
179 fn write_u64(&mut self, value: u64) -> std::io::Result<()>;
180}
181
182impl<T: Read> ByteReader for T {
183 #[inline(always)]
184 fn read_u8(&mut self) -> std::io::Result<u8> {
185 let mut buf = [0; 1];
186 self.read_exact(&mut buf)?;
187 Ok(buf[0])
188 }
189
190 #[cfg(feature = "brotli")]
191 #[inline(always)]
192 fn read_u16(&mut self) -> std::io::Result<u16> {
193 let mut buf = [0; 2];
194 self.read_exact(buf.as_mut())?;
195 Ok(u16::from_le_bytes(buf))
196 }
197
198 #[inline(always)]
199 fn read_u32(&mut self) -> std::io::Result<u32> {
200 let mut buf = [0; 4];
201 self.read_exact(buf.as_mut())?;
202 Ok(u32::from_le_bytes(buf))
203 }
204
205 #[inline(always)]
206 fn read_u64(&mut self) -> std::io::Result<u64> {
207 let mut buf = [0; 8];
208 self.read_exact(buf.as_mut())?;
209 Ok(u64::from_le_bytes(buf))
210 }
211}
212
213impl<T: Write> ByteWriter for T {
214 #[cfg(feature = "compress")]
215 #[inline(always)]
216 fn write_u8(&mut self, value: u8) -> std::io::Result<()> {
217 self.write_all(&[value])
218 }
219
220 #[inline(always)]
221 fn write_u16(&mut self, value: u16) -> std::io::Result<()> {
222 self.write_all(&value.to_le_bytes())
223 }
224
225 #[cfg(feature = "compress")]
226 #[inline(always)]
227 fn write_u32(&mut self, value: u32) -> std::io::Result<()> {
228 self.write_all(&value.to_le_bytes())
229 }
230
231 #[cfg(feature = "compress")]
232 #[inline(always)]
233 fn write_u64(&mut self, value: u64) -> std::io::Result<()> {
234 self.write_all(&value.to_le_bytes())
235 }
236}
237
238trait AutoFinish {
240 fn finish_ignore_error(self);
242}
243
244#[allow(private_bounds)]
246pub struct AutoFinisher<T: AutoFinish>(Option<T>);
247
248impl<T: AutoFinish> Drop for AutoFinisher<T> {
249 fn drop(&mut self) {
250 if let Some(writer) = self.0.take() {
251 writer.finish_ignore_error();
252 }
253 }
254}
255
256impl<T: AutoFinish> Deref for AutoFinisher<T> {
257 type Target = T;
258
259 fn deref(&self) -> &Self::Target {
260 self.0.as_ref().unwrap()
261 }
262}
263
264impl<T: AutoFinish> DerefMut for AutoFinisher<T> {
265 fn deref_mut(&mut self) -> &mut Self::Target {
266 self.0.as_mut().unwrap()
267 }
268}