1use alloc::vec;
3use alloc::vec::Vec;
4
5use crate::decompress;
6#[cfg(feature = "encoder")]
7use crate::{AutoFinish, AutoFinisher, Error, Result, Write};
8#[cfg(feature = "encoder")]
9use crate::{CompressionMode, compress_with_mode};
10use crate::{Read, Result as DecodeResult};
11
12const MAGIC_0: u8 = b'Z';
13const MAGIC_1: u8 = b'V';
14const TYPE_UNCOMPRESSED: u8 = 0;
15const TYPE_COMPRESSED: u8 = 1;
16
17pub struct LzfReader<R: Read> {
37 inner: R,
38 in_buf: Vec<u8>,
39 out_buf: Vec<u8>,
40 out_pos: usize,
41 finished: bool,
42}
43
44impl<R: Read> LzfReader<R> {
45 pub fn new(inner: R) -> Self {
47 Self { inner, in_buf: Vec::new(), out_buf: Vec::new(), out_pos: 0, finished: false }
48 }
49
50 pub fn into_inner(self) -> R {
52 self.inner
53 }
54
55 pub fn inner(&self) -> &R {
57 &self.inner
58 }
59
60 pub fn inner_mut(&mut self) -> &mut R {
62 &mut self.inner
63 }
64
65 fn load_next_block(&mut self) -> DecodeResult<bool> {
66 if self.finished {
67 return Ok(false);
68 }
69
70 let mut first = [0u8; 1];
71 let n = self.inner.read(&mut first)?;
72 if n == 0 || first[0] == 0 {
73 self.finished = true;
74 return Ok(false);
75 }
76
77 let mut rest = [0u8; 4];
78 self.inner.read_exact(&mut rest)?;
79
80 if first[0] != MAGIC_0 || rest[0] != MAGIC_1 {
81 return Err(crate::Error::InvalidHeader);
82 }
83
84 let block_type = rest[1];
85 match block_type {
86 TYPE_UNCOMPRESSED => {
87 let us = usize::from(u16::from_be_bytes([rest[2], rest[3]]));
88 self.out_buf.resize(us, 0);
89 self.inner.read_exact(&mut self.out_buf)?;
90 self.out_pos = 0;
91 Ok(true)
92 }
93 TYPE_COMPRESSED => {
94 let cs = usize::from(u16::from_be_bytes([rest[2], rest[3]]));
95 let mut us_buf = [0u8; 2];
96 self.inner.read_exact(&mut us_buf)?;
97 let us = usize::from(u16::from_be_bytes(us_buf));
98
99 self.in_buf.resize(cs, 0);
100 self.inner.read_exact(&mut self.in_buf)?;
101
102 self.out_buf.resize(us, 0);
103 let written = decompress(&self.in_buf, &mut self.out_buf)?;
104 if written != us {
105 return Err(crate::Error::InvalidData);
106 }
107 self.out_pos = 0;
108 Ok(true)
109 }
110 other => Err(crate::Error::UnknownBlockType(other)),
111 }
112 }
113}
114
115impl<R: Read> Read for LzfReader<R> {
116 fn read(&mut self, buf: &mut [u8]) -> DecodeResult<usize> {
117 if buf.is_empty() {
118 return Ok(0);
119 }
120
121 let mut written = 0usize;
122 while written < buf.len() {
123 if self.out_pos < self.out_buf.len() {
124 let avail = self.out_buf.len() - self.out_pos;
125 let take = (buf.len() - written).min(avail);
126 buf[written..written + take]
127 .copy_from_slice(&self.out_buf[self.out_pos..self.out_pos + take]);
128 self.out_pos += take;
129 written += take;
130 continue;
131 }
132
133 self.out_buf.clear();
134 self.out_pos = 0;
135 if !self.load_next_block()? {
136 break;
137 }
138 }
139
140 Ok(written)
141 }
142}
143
144#[cfg(feature = "encoder")]
149pub struct LzfWriter<W: Write> {
150 inner: W,
151 block_size: usize,
152 mode: CompressionMode,
153 in_buf: Vec<u8>,
154 comp_buf: Vec<u8>,
155 write_eof_marker: bool,
156}
157
158#[cfg(feature = "encoder")]
159impl<W: Write> LzfWriter<W> {
160 pub fn new(inner: W, block_size: usize) -> Result<Self> {
162 Self::new_with_mode(inner, block_size, CompressionMode::Normal)
163 }
164
165 pub fn new_with_mode(inner: W, block_size: usize, mode: CompressionMode) -> Result<Self> {
167 if block_size == 0 || block_size > usize::from(u16::MAX) {
168 return Err(Error::InvalidParameter);
169 }
170 Ok(Self {
171 inner,
172 block_size,
173 mode,
174 in_buf: Vec::with_capacity(block_size),
175 comp_buf: vec![0u8; block_size.saturating_sub(4)],
176 write_eof_marker: false,
177 })
178 }
179
180 pub fn new_with_eof_marker(inner: W, block_size: usize) -> Result<Self> {
184 Self::new_with_eof_marker_and_mode(inner, block_size, CompressionMode::Normal)
185 }
186
187 pub fn new_with_eof_marker_and_mode(
191 inner: W,
192 block_size: usize,
193 mode: CompressionMode,
194 ) -> Result<Self> {
195 let mut this = Self::new_with_mode(inner, block_size, mode)?;
196 this.write_eof_marker = true;
197 Ok(this)
198 }
199
200 pub fn into_inner(self) -> W {
202 self.inner
203 }
204
205 pub fn inner(&self) -> &W {
207 &self.inner
208 }
209
210 pub fn inner_mut(&mut self) -> &mut W {
212 &mut self.inner
213 }
214
215 pub fn finish(mut self) -> Result<W> {
220 self.flush_pending()?;
221 if self.write_eof_marker {
222 self.inner.write_all(&[0])?;
223 }
224 self.inner.flush()?;
225 Ok(self.inner)
226 }
227
228 pub fn auto_finish(self) -> AutoFinisher<Self> {
233 AutoFinisher(Some(self))
234 }
235
236 fn flush_pending(&mut self) -> Result<()> {
237 if !self.in_buf.is_empty() {
238 Self::write_block_into(&mut self.inner, self.mode, &mut self.comp_buf, &self.in_buf)?;
239 self.in_buf.clear();
240 }
241 Ok(())
242 }
243
244 fn write_block_into(
245 inner: &mut W,
246 mode: CompressionMode,
247 comp_buf: &mut Vec<u8>,
248 block: &[u8],
249 ) -> Result<()> {
250 let max_try = block.len().saturating_sub(4);
251 if max_try > 0 {
252 if comp_buf.len() < max_try {
253 comp_buf.resize(max_try, 0);
254 }
255 match compress_with_mode(block, &mut comp_buf[..max_try], mode) {
256 Ok(cs) => {
257 let cs_u16 =
258 u16::try_from(cs).map_err(|_| Error::InvalidParameter)?.to_be_bytes();
259 let us_u16 = u16::try_from(block.len())
260 .map_err(|_| Error::InvalidParameter)?
261 .to_be_bytes();
262 inner.write_all(&[MAGIC_0, MAGIC_1, TYPE_COMPRESSED])?;
263 inner.write_all(&cs_u16)?;
264 inner.write_all(&us_u16)?;
265 inner.write_all(&comp_buf[..cs])?;
266 return Ok(());
267 }
268 Err(Error::OutputTooSmall) => {}
269 Err(err) => return Err(err),
270 }
271 }
272
273 let us_u16 = u16::try_from(block.len()).map_err(|_| Error::InvalidParameter)?.to_be_bytes();
274 inner.write_all(&[MAGIC_0, MAGIC_1, TYPE_UNCOMPRESSED])?;
275 inner.write_all(&us_u16)?;
276 inner.write_all(block)?;
277 Ok(())
278 }
279}
280
281#[cfg(feature = "encoder")]
282impl<W: Write> AutoFinish for LzfWriter<W> {
283 fn finish_ignore_error(self) {
284 let _ = self.finish();
285 }
286}
287
288#[cfg(feature = "encoder")]
289impl<W: Write> Write for LzfWriter<W> {
290 fn write(&mut self, buf: &[u8]) -> Result<usize> {
291 let mut input = buf;
292
293 if !self.in_buf.is_empty() {
294 let need = self.block_size - self.in_buf.len();
295 let take = need.min(input.len());
296 self.in_buf.extend_from_slice(&input[..take]);
297 input = &input[take..];
298
299 if self.in_buf.len() == self.block_size {
300 Self::write_block_into(
301 &mut self.inner,
302 self.mode,
303 &mut self.comp_buf,
304 &self.in_buf,
305 )?;
306 self.in_buf.clear();
307 }
308 }
309
310 let mut consumed = 0usize;
311 while input.len() - consumed >= self.block_size {
312 let block = &input[consumed..consumed + self.block_size];
313 Self::write_block_into(&mut self.inner, self.mode, &mut self.comp_buf, block)?;
314 consumed += self.block_size;
315 }
316
317 if consumed < input.len() {
318 self.in_buf.extend_from_slice(&input[consumed..]);
319 }
320
321 Ok(buf.len())
322 }
323
324 fn flush(&mut self) -> Result<()> {
325 self.flush_pending()?;
326 self.inner.flush()
327 }
328}