structured_zstd/decoding/streaming_decoder.rs
1//! The [StreamingDecoder] wraps a [FrameDecoder] and provides a Read impl that decodes data when necessary
2
3use core::borrow::BorrowMut;
4
5use crate::common::MAX_BLOCK_SIZE;
6use crate::decoding::errors::{FrameDecoderError, ReadFrameHeaderError};
7use crate::decoding::{BlockDecodingStrategy, DictionaryHandle, FrameDecoder};
8use crate::io::{Error, ErrorKind, Read};
9
10/// High level Zstandard frame decoder that can be used to decompress a given Zstandard frame.
11///
12/// This decoder implements `io::Read`, so you can interact with it by calling
13/// `io::Read::read_to_end` / `io::Read::read_exact` or passing this to another library / module as a source for the decoded content
14///
15/// If you need more control over how decompression takes place, you can use
16/// the lower level [FrameDecoder], which allows for greater control over how
17/// decompression takes place but the implementor must call
18/// [FrameDecoder::decode_blocks] repeatedly to decode the entire frame.
19///
20/// ## Multiple frames
21/// A stream is one or more frames (RFC 8878 3). Every read path, plain `read`
22/// and `io::copy` over it included, decodes them in turn, skips skippable
23/// frames wherever they stand, and applies the constructor's dictionary to
24/// each frame. The source ending at a frame boundary ends the stream; bytes
25/// that do not form a frame are an error. `read` hands back a finished frame's
26/// bytes before it reads the next frame's header, so a source that stays open
27/// is not waited on while output is pending.
28///
29/// To decode a single frame and leave the bytes after it unread, drive a
30/// [FrameDecoder] directly.
31///
32/// ## When the source is read
33/// Construction reads nothing; the first frame's header is read by the first
34/// `read` or `read_to_end`, and a source that is not a zstd stream fails
35/// there, as upstream's `ZSTD_DStream` reads nothing until it is fed. So
36/// [`into_inner`](Self::into_inner) hands back an untouched source when the
37/// decoder was never read, and the source is not lost when its first frame
38/// turns out to be damaged.
39///
40/// ```no_run
41/// // `File` is std-only; `read_to_end` itself is available under no_std too.
42/// #[cfg(feature = "std")]
43/// {
44/// use std::fs::File;
45/// use std::io::Read;
46/// use structured_zstd::decoding::StreamingDecoder;
47///
48/// // Read a Zstandard archive from the filesystem then decompress it into a vec.
49/// let mut f: File = todo!("Read a .zstd archive from somewhere");
50/// let mut decoder = StreamingDecoder::new(f);
51/// let mut result = Vec::new();
52/// Read::read_to_end(&mut decoder, &mut result).unwrap();
53/// }
54/// ```
55pub struct StreamingDecoder<READ: Read, DEC: BorrowMut<FrameDecoder>> {
56 pub decoder: DEC,
57 source: READ,
58 /// Whether the decoder was constructed with a dictionary it applies to
59 /// every frame, the first included (a plain init resolves dictionaries by
60 /// frame id only and would lose it for frames omitting the id); the
61 /// decoder already holds its handle, so this one keeps none of its own.
62 forced_dictionary: bool,
63 /// Where the stream stands between frames.
64 position: Position,
65 /// Source bytes read ahead and not yet decoded.
66 input: Input,
67}
68
69/// Where a [`StreamingDecoder`] stands in its stream.
70#[derive(Clone, Copy, PartialEq, Eq)]
71enum Position {
72 /// Nothing read yet: the next step is the first frame's header, and the
73 /// source ending here is an error, as an empty stream holds no frame.
74 BeforeFirstFrame,
75 /// A frame or skippable frame has ended: the next step is the next
76 /// frame's header, and the source ending here is the end of the stream.
77 BetweenFrames,
78 /// Inside a frame whose header has been read.
79 InFrame,
80 /// The source has ended at a frame boundary: every read from here on is
81 /// the end of the stream, without asking the source again.
82 End,
83}
84
85/// The most of a skippable frame's content read in one step.
86const SKIP_CHUNK: u32 = 8 * 1024;
87
88/// Source bytes of the decoder's next step, gathered the way upstream zstd's
89/// `ZSTD_decompressStream` loads `nextSrcSizeToDecompress` bytes: exactly the
90/// next frame header, block or checksum, and nothing past it. A step is decoded
91/// only once it is all in hand, so a non-blocking source that returns
92/// `WouldBlock` part-way through loses nothing, and the source never stands
93/// beyond what the decoder has taken. A Raw block's content is the exception:
94/// it is read straight into the decoder's buffer, see [`RawBlock`].
95struct Input {
96 /// Grown to the largest step seen; holds the pending bytes at
97 /// `start..end`.
98 buf: alloc::vec::Vec<u8>,
99 start: usize,
100 end: usize,
101 /// Content of a skippable frame still to step over.
102 skip_left: u32,
103 /// The Raw block whose content is being read.
104 raw: Option<RawBlock>,
105}
106
107/// A Raw block in progress. Its content is the output itself, so it is not
108/// gathered whole: each read lands in a [`RAW_CHUNK`] of the input buffer,
109/// still in cache, and goes on to the decode buffer at once.
110struct RawBlock {
111 size: u32,
112 left: u32,
113 last: bool,
114 /// The running digest of the block, when per-block checksums are asked
115 /// for: its content may be handed on before the block ends, so it cannot
116 /// be hashed from the decode buffer at the end as other blocks are.
117 #[cfg(all(feature = "lsm", feature = "hash"))]
118 digest: Option<twox_hash::XxHash64>,
119}
120
121/// The most of a Raw block read in one step. Every byte of the input buffer
122/// is initialised once, when it first grows, so a source that hands content
123/// over in small pieces costs a copy of each piece and nothing more.
124const RAW_CHUNK: usize = 32 * 1024;
125
126impl Input {
127 const fn new() -> Self {
128 Self {
129 buf: alloc::vec::Vec::new(),
130 start: 0,
131 end: 0,
132 skip_left: 0,
133 raw: None,
134 }
135 }
136
137 fn pending(&self) -> &[u8] {
138 &self.buf[self.start..self.end]
139 }
140
141 /// Read the rest of `source` behind the pending bytes. What it reads stays
142 /// pending whatever it returns, so a source that stops part-way through
143 /// is retried from where it stopped, with nothing lost.
144 fn read_rest<R: Read>(&mut self, source: &mut R) -> Result<(), Error> {
145 if self.start > 0 {
146 self.buf.copy_within(self.start..self.end, 0);
147 self.end -= self.start;
148 self.start = 0;
149 }
150 self.buf.truncate(self.end);
151 // Both `read_to_end`s keep what they appended when they fail.
152 let result = source.read_to_end(&mut self.buf);
153 self.end = self.buf.len();
154 result.map(drop)
155 }
156
157 /// Read the next part of a Raw block, at most `left` bytes and at most
158 /// [`RAW_CHUNK`], into the start of the buffer and return how many. Only
159 /// called while nothing is pending. `Ok(0)` is the source's end;
160 /// `Interrupted` is retried.
161 fn read_raw<R: Read>(&mut self, source: &mut R, left: u32) -> Result<usize, Error> {
162 debug_assert!(
163 self.pending().is_empty(),
164 "a Raw block is read with nothing pending"
165 );
166 // `RAW_CHUNK` fits a `u32`, so the minimum is taken in the wire's width.
167 let chunk = left.min(RAW_CHUNK as u32) as usize;
168 if self.buf.len() < chunk {
169 self.buf.resize(chunk, 0);
170 }
171 loop {
172 match source.read(&mut self.buf[..chunk]) {
173 Err(e) if e.kind() == ErrorKind::Interrupted => {}
174 other => return other,
175 }
176 }
177 }
178
179 /// Drop the input, buffer and all: after `read_rest` it holds a whole
180 /// stream, which a decoder kept alive must not pin.
181 fn release(&mut self) {
182 self.buf = alloc::vec::Vec::new();
183 self.start = 0;
184 self.end = 0;
185 }
186
187 fn consume(&mut self, n: usize) {
188 debug_assert!(n <= self.end - self.start);
189 self.start += n;
190 if self.start == self.end {
191 self.start = 0;
192 self.end = 0;
193 }
194 }
195
196 /// Read more of `source` behind the pending bytes, up to `want` pending in
197 /// all and no further. `Ok(0)` is its end; its errors come back as it
198 /// reported them, `Interrupted` retried.
199 fn fill<R: Read>(&mut self, source: &mut R, want: usize) -> Result<usize, Error> {
200 // Pending bytes are an unfinished step, which reads stop at, so they
201 // are rarely moved; when they are, they are less than one step.
202 if self.start > 0 {
203 self.buf.copy_within(self.start..self.end, 0);
204 self.end -= self.start;
205 self.start = 0;
206 }
207 debug_assert!(self.end < want, "a fill must ask for more than is pending");
208 if self.buf.len() < want {
209 // Doubling keeps a stream of growing blocks to a few allocations.
210 let len = want.max(2 * self.buf.len());
211 self.buf.resize(len, 0);
212 }
213 loop {
214 match source.read(&mut self.buf[self.end..want]) {
215 Ok(n) => {
216 self.end += n;
217 return Ok(n);
218 }
219 Err(e) if e.kind() == ErrorKind::Interrupted => {}
220 Err(e) => return Err(e),
221 }
222 }
223 }
224}
225
226/// How much of a frame header `bytes` says there is to read: 4 for the magic,
227/// 8 for a skippable frame's header, and for a frame its descriptor's fields.
228/// A magic that is neither stops at 4, where the parser rejects it. A
229/// magicless frame (`ZSTD_f_zstd1_magicless`) starts at its descriptor and
230/// has no skippable form.
231fn header_len(bytes: &[u8], magicless: bool) -> usize {
232 let descriptor_at = if magicless {
233 0
234 } else {
235 let Some(magic) = bytes.first_chunk::<4>() else {
236 return 4;
237 };
238 let magic = u32::from_le_bytes(*magic);
239 if magic & 0xFFFF_FFF0 == 0x184D_2A50 {
240 return 8;
241 }
242 if magic != crate::common::MAGIC_NUM {
243 return 4;
244 }
245 4
246 };
247 let Some(&descriptor) = bytes.get(descriptor_at) else {
248 return descriptor_at + 1;
249 };
250 descriptor_at + crate::decoding::frame::FrameDescriptor(descriptor).header_len()
251}
252
253impl<READ: Read, DEC: BorrowMut<FrameDecoder>> StreamingDecoder<READ, DEC> {
254 /// [`new`](StreamingDecoder::new) driving a caller-supplied
255 /// [`FrameDecoder`], so its buffers and settings (magicless format,
256 /// registered dictionaries, checksum mode) carry over from stream to
257 /// stream. Nothing is read from `source` until the first read.
258 ///
259 /// # Examples
260 /// ```
261 /// use std::io::Read;
262 /// use structured_zstd::decoding::{FrameDecoder, StreamingDecoder};
263 /// use structured_zstd::encoding::{CompressionLevel, compress_to_vec};
264 ///
265 /// let frame = compress_to_vec(&b"reused decoder"[..], CompressionLevel::Fastest);
266 /// let mut decoder = FrameDecoder::new();
267 /// for _ in 0..2 {
268 /// let mut stream = StreamingDecoder::new_with_decoder(&frame[..], &mut decoder);
269 /// let mut decoded = Vec::new();
270 /// stream.read_to_end(&mut decoded).unwrap();
271 /// assert_eq!(decoded, b"reused decoder");
272 /// }
273 /// ```
274 pub fn new_with_decoder(source: READ, decoder: DEC) -> StreamingDecoder<READ, DEC> {
275 StreamingDecoder {
276 decoder,
277 source,
278 forced_dictionary: false,
279 position: Position::BeforeFirstFrame,
280 input: Input::new(),
281 }
282 }
283
284 /// [`new_with_decoder`](Self::new_with_decoder) with `dict` applied to
285 /// every frame even when its header omits the dictionary ID, as
286 /// [`new_with_dictionary_handle`](StreamingDecoder::new_with_dictionary_handle)
287 /// applies it (same warning). A decoder reused frame after frame keeps its
288 /// buffers and, for the same dictionary, the handle it already holds, so
289 /// after the first frame it allocates nothing and touches no reference
290 /// count.
291 ///
292 /// # Errors
293 ///
294 /// Only for a dictionary whose content no frame can use. Nothing is read
295 /// from `source` until the first read, which reports a frame that does
296 /// not match the dictionary.
297 ///
298 /// # Examples
299 /// ```
300 /// use std::io::Read;
301 /// use structured_zstd::decoding::{Dictionary, DictionaryHandle, FrameDecoder, StreamingDecoder};
302 /// use structured_zstd::encoding::{FrameCompressor, CompressionLevel};
303 ///
304 /// let content = b"a dictionary of words the frames reuse".to_vec();
305 /// let dictionary = DictionaryHandle::from_dictionary(
306 /// Dictionary::from_raw_content(1, content.clone()).unwrap(),
307 /// );
308 /// let mut compressor: FrameCompressor = FrameCompressor::new(CompressionLevel::Default);
309 /// compressor.set_dictionary(Dictionary::from_raw_content(1, content).unwrap()).unwrap();
310 /// let frame = compressor.compress_independent_frame(b"the frames reuse words");
311 ///
312 /// let mut decoder = FrameDecoder::new();
313 /// for _ in 0..2 {
314 /// let mut stream =
315 /// StreamingDecoder::new_with_decoder_and_dictionary_handle(&frame[..], &mut decoder, &dictionary)
316 /// .unwrap();
317 /// let mut decoded = Vec::new();
318 /// stream.read_to_end(&mut decoded).unwrap();
319 /// assert_eq!(decoded, b"the frames reuse words");
320 /// }
321 /// ```
322 pub fn new_with_decoder_and_dictionary_handle(
323 source: READ,
324 mut decoder: DEC,
325 dict: &DictionaryHandle,
326 ) -> Result<StreamingDecoder<READ, DEC>, FrameDecoderError> {
327 decoder.borrow_mut().arm_dict(dict)?;
328 Ok(StreamingDecoder {
329 decoder,
330 source,
331 forced_dictionary: true,
332 position: Position::BeforeFirstFrame,
333 input: Input::new(),
334 })
335 }
336}
337
338impl<READ: Read> StreamingDecoder<READ, FrameDecoder> {
339 /// Create a streaming decoder over `source`.
340 ///
341 /// Nothing is read from `source` here: the first frame's header is read by
342 /// the first `read` or `read_to_end`, which is where a source that is not
343 /// a zstd stream, or is empty, reports its error. Until then
344 /// [`into_inner`](Self::into_inner) hands `source` back untouched, and
345 /// after such an error it hands back whatever the source holds past the
346 /// bytes the decoder took.
347 ///
348 /// # Examples
349 /// ```
350 /// use std::io::Read;
351 /// use structured_zstd::decoding::StreamingDecoder;
352 ///
353 /// let mut decoder = StreamingDecoder::new(&b"not a zstd frame"[..]);
354 /// let mut out = Vec::new();
355 /// assert!(decoder.read_to_end(&mut out).is_err());
356 /// ```
357 pub fn new(source: READ) -> StreamingDecoder<READ, FrameDecoder> {
358 StreamingDecoder::new_with_decoder(source, FrameDecoder::new())
359 }
360
361 /// Create a streaming decoder using a pre-parsed dictionary handle.
362 ///
363 /// Nothing is read from `source` here, as with [`new`](Self::new).
364 ///
365 /// # Errors
366 ///
367 /// Only for a dictionary whose content no frame can use.
368 ///
369 /// # Warning
370 ///
371 /// This constructor initializes the underlying [`FrameDecoder`] with
372 /// `dict`, even if a frame header omits the optional dictionary ID.
373 /// Callers must only use it when they already know the stream was encoded
374 /// with this dictionary; otherwise decoded output can be silently
375 /// corrupted.
376 pub fn new_with_dictionary_handle(
377 source: READ,
378 dict: &DictionaryHandle,
379 ) -> Result<StreamingDecoder<READ, FrameDecoder>, FrameDecoderError> {
380 Self::new_with_decoder_and_dictionary_handle(source, FrameDecoder::new(), dict)
381 }
382
383 /// Create a streaming decoder using a serialized dictionary blob.
384 ///
385 /// # Warning
386 ///
387 /// This API forwards to [`StreamingDecoder::new_with_dictionary_handle`]
388 /// and therefore applies the decoded dictionary to frames whose headers may
389 /// omit the optional dictionary ID. Only use it when the stream is known to
390 /// be encoded with that dictionary.
391 pub fn new_with_dictionary_bytes(
392 source: READ,
393 raw_dictionary: &[u8],
394 ) -> Result<StreamingDecoder<READ, FrameDecoder>, FrameDecoderError> {
395 let dict = DictionaryHandle::decode_dict(raw_dictionary)?;
396 Self::new_with_dictionary_handle(source, &dict)
397 }
398}
399
400impl<READ: Read, DEC: BorrowMut<FrameDecoder>> StreamingDecoder<READ, DEC> {
401 /// Gets a reference to the underlying reader.
402 pub fn get_ref(&self) -> &READ {
403 &self.source
404 }
405
406 /// Gets a mutable reference to the underlying reader.
407 ///
408 /// It is inadvisable to directly read from the underlying reader.
409 pub fn get_mut(&mut self) -> &mut READ {
410 &mut self.source
411 }
412
413 /// Gets a mutable reference to the frame decoder driving this stream.
414 ///
415 /// Exposed for settings that are read as decoding proceeds rather than at
416 /// construction — [`FrameDecoder::set_content_checksum`] above all, which a
417 /// caller that wants mismatches to fail (rather than merely be computed)
418 /// has to reach after the constructor has chosen the decoder, including
419 /// on the dictionary paths.
420 pub fn decoder_mut(&mut self) -> &mut FrameDecoder {
421 self.decoder.borrow_mut()
422 }
423
424 /// Destructures this object into the inner reader.
425 ///
426 /// This reads nothing. A decoder that was never read hands the reader back
427 /// untouched. The decoder reads only what its next step needs, so once a
428 /// frame's content has been delivered the reader stands right after that
429 /// frame. Bytes of a step a `WouldBlock` left unfinished stay with the
430 /// decoder.
431 ///
432 /// # Examples
433 /// ```
434 /// use structured_zstd::decoding::StreamingDecoder;
435 ///
436 /// let data = b"\x28\xb5\x2f\xfd and whatever follows";
437 /// let decoder = StreamingDecoder::new(&data[..]);
438 /// assert_eq!(decoder.into_inner(), &data[..]);
439 /// ```
440 pub fn into_inner(self) -> READ
441 where
442 READ: Sized,
443 {
444 self.source
445 }
446
447 /// Destructures this object into both the inner reader and [FrameDecoder].
448 pub fn into_parts(self) -> (READ, DEC)
449 where
450 READ: Sized,
451 {
452 (self.source, self.decoder)
453 }
454
455 /// Destructures this object into the inner [FrameDecoder].
456 pub fn into_frame_decoder(self) -> DEC {
457 self.decoder
458 }
459
460 /// The error for a source that ended inside a frame. Cut inside the
461 /// trailing checksum, that is what it reports; cut inside a block, the
462 /// leftover input goes to the block decoder, which reports how it was cut
463 /// short as it does for any truncated frame. Whole input never reaches
464 /// here (it would have decoded), so that decode fails; were it to pass,
465 /// the cut is still reported, as an early end of input.
466 fn cut_short(&mut self) -> Error {
467 let decoder = self.decoder.borrow_mut();
468 if decoder.awaits_checksum() {
469 return frame_error(FrameDecoderError::FailedToReadChecksum(Error::from(
470 ErrorKind::UnexpectedEof,
471 )));
472 }
473 let mut rest = self.input.pending();
474 decoder
475 .decode_blocks(&mut rest, BlockDecodingStrategy::All)
476 .map_or_else(frame_error, |_| Error::from(ErrorKind::UnexpectedEof))
477 }
478
479 /// Start the next frame of the stream, the first included, skipping
480 /// skippable frames, with the constructor's dictionary if it had one.
481 /// `false` when the source ends cleanly at a frame boundary, which the
482 /// start of the stream is not; anything else that is not a frame is an
483 /// error.
484 ///
485 /// The source's own errors go back as it reported them, so a non-blocking
486 /// source's `WouldBlock` stays one; what the boundary had read stays in
487 /// [`Input`], and the header is parsed only once it is whole, so a retry
488 /// resumes where the source stopped.
489 fn start_frame(&mut self) -> Result<bool, Error> {
490 let how = if self.forced_dictionary {
491 FrameStart::HeldDictionary
492 } else {
493 FrameStart::Plain
494 };
495 let magicless = self.decoder.borrow_mut().is_magicless();
496 loop {
497 while self.input.skip_left > 0 {
498 // Counted in the wire's `u32`; a step is at most `SKIP_CHUNK`,
499 // which every `usize` holds.
500 let step = self.input.skip_left.min(SKIP_CHUNK);
501 if self.input.pending().is_empty()
502 && self.input.fill(&mut self.source, step as usize)? == 0
503 {
504 return Err(frame_error(FrameDecoderError::FailedToSkipFrame));
505 }
506 // Reads stop at `step`, so what is pending is skippable content;
507 // the minimum is taken in `u32`, the wire's width.
508 let pending = u32::try_from(self.input.pending().len()).unwrap_or(u32::MAX);
509 let take = self.input.skip_left.min(pending);
510 self.input.consume(take as usize);
511 self.input.skip_left -= take;
512 }
513 loop {
514 let have = self.input.pending().len();
515 let want = header_len(self.input.pending(), magicless);
516 if have >= want {
517 break;
518 }
519 if self.input.fill(&mut self.source, want)? == 0 {
520 if have == 0 {
521 if self.position == Position::BeforeFirstFrame {
522 return Err(no_frame_error());
523 }
524 return Ok(false);
525 }
526 // The source ended inside a header: let the parser report
527 // it as it reports any header cut short.
528 break;
529 }
530 }
531 let mut header = self.input.pending();
532 let before = header.len();
533 let started = how.start(self.decoder.borrow_mut(), &mut header);
534 let used = before - header.len();
535 self.input.consume(used);
536 match started {
537 Ok(()) => {
538 self.position = Position::InFrame;
539 return Ok(true);
540 }
541 Err(e) => match skippable_frame_length(&e) {
542 Some(length) => {
543 // A stream of skippable frames alone is a stream that
544 // holds no content, not an empty one.
545 self.position = Position::BetweenFrames;
546 self.input.skip_left = length;
547 }
548 None => return Err(frame_error(e)),
549 },
550 }
551 }
552 }
553}
554
555/// The length of the skippable frame (RFC 8878 3.1.2) whose header `e`
556/// reports, if it is one.
557fn skippable_frame_length(e: &FrameDecoderError) -> Option<u32> {
558 match e {
559 FrameDecoderError::ReadFrameHeaderError(ReadFrameHeaderError::SkipFrame {
560 length, ..
561 }) => Some(*length),
562 _ => None,
563 }
564}
565
566/// How a frame's decoder is initialised.
567enum FrameStart {
568 /// Dictionaries resolved by the frame's dictionary id.
569 Plain,
570 /// The dictionary the decoder holds, applied whatever the frame header
571 /// names.
572 HeldDictionary,
573}
574
575impl FrameStart {
576 fn start(
577 &self,
578 decoder: &mut FrameDecoder,
579 source: impl Read,
580 ) -> Result<(), FrameDecoderError> {
581 match self {
582 Self::Plain => decoder.init(source),
583 Self::HeldDictionary => decoder.reset_with_active_dict(source),
584 }
585 }
586}
587
588/// Close a Raw block whose content is all in the decode buffer, recording its
589/// digest when per-block checksums are on.
590fn finish_raw_block(decoder: &mut FrameDecoder, raw: RawBlock) {
591 #[cfg(all(feature = "lsm", feature = "hash"))]
592 if let Some(digest) = raw.digest {
593 decoder.record_block_checksum(core::hash::Hasher::finish(&digest) as u32);
594 }
595 decoder.finish_raw_block(raw.size, raw.last);
596}
597
598/// A frame decode error as the `Read` error it surfaces through.
599fn frame_error(e: FrameDecoderError) -> Error {
600 #[cfg(feature = "std")]
601 return Error::other(e);
602 #[cfg(not(feature = "std"))]
603 return Error::new(ErrorKind::Other, alloc::boxed::Box::new(e));
604}
605
606/// The error for a source that ends before its first frame begins: there is no
607/// magic number to read, as there is for any frame header cut short there.
608fn no_frame_error() -> Error {
609 frame_error(FrameDecoderError::ReadFrameHeaderError(
610 ReadFrameHeaderError::MagicNumberReadError(Error::from(ErrorKind::UnexpectedEof)),
611 ))
612}
613
614/// The checks a frame can only pass once it is fully decoded and drained: the
615/// declared content size, then the content checksum in `Verify` mode.
616fn verify_finished_frame(decoder: &FrameDecoder) -> Result<(), Error> {
617 decoder.verify_content_size().map_err(frame_error)?;
618 #[cfg(feature = "hash")]
619 decoder.verify_content_checksum().map_err(frame_error)?;
620 Ok(())
621}
622
623impl<READ: Read, DEC: BorrowMut<FrameDecoder>> Read for StreamingDecoder<READ, DEC> {
624 /// Decode the stream into `buf`, frame after frame (RFC 8878 3: a stream
625 /// is one or more frames), as upstream zstd's `ZSTD_decompressStream`
626 /// does. Skippable frames are skipped; the source ending at a frame
627 /// boundary is the end of the stream, anything else is an error.
628 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
629 if buf.is_empty() || self.position == Position::End {
630 return Ok(0);
631 }
632 let mut written = 0;
633 loop {
634 if self.position != Position::InFrame {
635 // A call reaches a frame boundary with nothing delivered: a
636 // finished frame hands its last bytes back before it is left
637 // (the check below), so the next frame's header is read only
638 // by a call with nothing to deliver, an error never follows
639 // delivered bytes (the `Read` contract), and a source that has
640 // not sent the next frame yet is not waited on.
641 debug_assert_eq!(written, 0, "a frame boundary is reached empty-handed");
642 if !self.start_frame()? {
643 self.position = Position::End;
644 return Ok(0);
645 }
646 continue;
647 }
648 let decoder = self.decoder.borrow_mut();
649 if decoder.is_finished() && decoder.can_collect() == 0 {
650 // Bytes in hand go back first: the frame's checks and the
651 // next frame's header wait for a call with nothing to deliver.
652 if written > 0 {
653 return Ok(written);
654 }
655 // Fully decoded and drained: the frame's length and running
656 // digest are final, so a frame shorter or longer than it
657 // declared, or with a bad checksum in `Verify` mode, fails here.
658 verify_finished_frame(decoder)?;
659 self.position = Position::BetweenFrames;
660 continue;
661 }
662 // A full `buf` never strands a checksum: a frame's last window of
663 // output is collectable only once the frame is finished, its
664 // checksum read, so the source already stands past the frame.
665 if written == buf.len() {
666 return Ok(written);
667 }
668 // A Raw block in progress reads on into the decode buffer once
669 // the output already there has been handed over.
670 if self.input.raw.is_some() && decoder.can_collect() == 0 {
671 // Return what this call has rather than wait on the source.
672 if written > 0 {
673 return Ok(written);
674 }
675 // The block stays recorded until the read has delivered: a
676 // `WouldBlock` returns here with the block still open.
677 let left = self.input.raw.as_ref().map_or(0, |raw| raw.left);
678 let n = self.input.read_raw(&mut self.source, left)?;
679 let mut raw = self.input.raw.take().expect("checked just above");
680 if n == 0 {
681 return Err(frame_error(decoder.raw_block_cut_short(raw.size, raw.last)));
682 }
683 let content = &self.input.buf[..n];
684 decoder.raw_block_push(content);
685 #[cfg(all(feature = "lsm", feature = "hash"))]
686 if let Some(digest) = raw.digest.as_mut() {
687 core::hash::Hasher::write(digest, content);
688 }
689 // `n <= left`, so it fits the `u32` it is taken from.
690 raw.left -= n as u32;
691 if raw.left == 0 {
692 finish_raw_block(decoder, raw);
693 } else {
694 self.input.raw = Some(raw);
695 }
696 continue;
697 }
698 // Otherwise the decoder is entered only with its next step whole,
699 // or with output to hand over: entering it with part of a block
700 // only parses the block header to find the block incomplete.
701 let want = decoder.input_needed(self.input.pending());
702 if self.input.raw.is_none()
703 && want > self.input.pending().len()
704 && decoder.can_collect() == 0
705 {
706 // Return what this call has rather than wait on the source.
707 if written > 0 {
708 return Ok(written);
709 }
710 // A Raw block's header alone is in hand: its content goes
711 // straight to the decode buffer from here on.
712 if let Some(&header) = self.input.pending().first_chunk::<3>()
713 && self.input.pending().len() == 3
714 && let Some((size, last)) = decoder
715 .start_raw_block(&header, true)
716 .map_err(frame_error)?
717 {
718 self.input.consume(3);
719 let raw = RawBlock {
720 size,
721 left: size,
722 last,
723 #[cfg(all(feature = "lsm", feature = "hash"))]
724 digest: decoder
725 .per_block_checksums_enabled()
726 .then(|| twox_hash::XxHash64::with_seed(0)),
727 };
728 if size == 0 {
729 finish_raw_block(decoder, raw);
730 } else {
731 self.input.raw = Some(raw);
732 }
733 continue;
734 }
735 if self.input.fill(&mut self.source, want)? == 0 {
736 return Err(self.cut_short());
737 }
738 continue;
739 }
740 // Decode the step, handing output to `buf` block by block: the
741 // decode window stays one window plus one block, as upstream's
742 // flush loop keeps it. The buffer takes the whole window at the
743 // first block whatever the frame declares, as upstream sizes a
744 // stream's buffer from the window.
745 let (consumed, produced) = decoder
746 .decode_available(self.input.pending(), &mut buf[written..], true)
747 .map_err(frame_error)?;
748 self.input.consume(consumed);
749 written += produced;
750 if consumed > 0 || produced > 0 {
751 continue;
752 }
753 if written > 0 {
754 return Ok(written);
755 }
756 // A step whose input is all here yet decodes nothing (a block over
757 // the frame's maximum, say) is a damaged frame: report it.
758 return Err(self.cut_short());
759 }
760 }
761
762 /// Decode-in-place fast path for whole-frame consumption. Instead of the
763 /// generic `read` loop (decode block -> `RingBuffer` -> copy into the
764 /// caller buffer), buffer the (compressed, hence small) source and decode
765 /// STRAIGHT into `output`'s spare capacity via the single-copy direct path,
766 /// pre-sized from the frame's declared content size. Only taken when the
767 /// decoder is at a frame boundary (nothing partially decoded / undrained);
768 /// otherwise it falls back to the generic grow-and-`read` loop so a caller
769 /// that mixed `read` with `read_to_end` still gets correct output.
770 ///
771 /// Per the `Read::read_to_end` contract this consumes the source to EOF: if
772 /// the stream holds several concatenated frames they are ALL decoded (and
773 /// skippable frames skipped), as with `read`.
774 #[cfg(feature = "std")]
775 fn read_to_end(&mut self, output: &mut alloc::vec::Vec<u8>) -> Result<usize, Error> {
776 let start_total = output.len();
777 self.decode_rest_to_vec(output)?;
778 Ok(output.len() - start_total)
779 }
780
781 /// no_std counterpart of the decode-in-place `read_to_end` above (the
782 /// no_std `Read::read_to_end` returns `()` instead of the byte count).
783 #[cfg(not(feature = "std"))]
784 fn read_to_end(&mut self, output: &mut alloc::vec::Vec<u8>) -> Result<(), Error> {
785 self.decode_rest_to_vec(output)
786 }
787}
788
789impl<READ: Read, DEC: BorrowMut<FrameDecoder>> StreamingDecoder<READ, DEC> {
790 /// Body of both `read_to_end`s: decode the rest of the stream, appending
791 /// to `output`.
792 fn decode_rest_to_vec(&mut self, output: &mut alloc::vec::Vec<u8>) -> Result<(), Error> {
793 // A forced dictionary is the one the decoder already holds; every
794 // frame is initialised with it in place, touching no reference count.
795 let keep_dictionary = self.forced_dictionary;
796 // The first header is read the bounded way, a step at a time, so a
797 // source that is not a zstd stream is refused after a header's worth
798 // of bytes instead of after the whole of it is gathered below.
799 if self.position == Position::BeforeFirstFrame && !self.start_frame()? {
800 self.position = Position::End;
801 }
802 match self.position {
803 Position::End => return Ok(()),
804 // A frame whose header is read, with nothing decoded yet; a first
805 // Raw block part-read into the decode buffer is not that.
806 Position::InFrame
807 if self.input.raw.is_none() && {
808 let d = self.decoder.borrow_mut();
809 d.is_at_frame_start() && d.can_collect() == 0
810 } =>
811 {
812 self.input.read_rest(&mut self.source)?;
813 let decoded = self.decoder.borrow_mut().decode_current_frame_to_vec(
814 self.input.pending(),
815 output,
816 keep_dictionary,
817 );
818 self.input.release();
819 decoded.map_err(frame_error)?;
820 self.position = Position::End;
821 return Ok(());
822 }
823 Position::BeforeFirstFrame | Position::InFrame | Position::BetweenFrames => {}
824 }
825 // Mid-frame fallback: drain through the generic path, which carries on
826 // into the following frames, so the source is consumed to true EOF.
827 loop {
828 let start = output.len();
829 output.resize(start + MAX_BLOCK_SIZE as usize, 0);
830 // On error, drop the just-grown (zeroed) tail before propagating so
831 // the caller never observes bytes that were never decoded.
832 let n = match self.read(&mut output[start..]) {
833 Ok(n) => n,
834 Err(e) => {
835 output.truncate(start);
836 return Err(e);
837 }
838 };
839 output.truncate(start + n);
840 if n == 0 {
841 return Ok(());
842 }
843 }
844 }
845}
846
847#[cfg(test)]
848mod tests;