Skip to main content

Decompressor

Struct Decompressor 

Source
pub struct Decompressor { /* private fields */ }
Expand description

A reusable Zstandard decoder.

Keep it alive to reuse its buffers between payloads; its RetentionPolicy decides what stays allocated after each operation. One-shot methods take complete input; Self::start and Self::into_session decode incrementally, and with std its reader and writer methods (in the decompressor::io module) adapt it to std::io.

§Examples

use mzstd::Decompressor;
// "hello" as one raw block in a single-segment frame.
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x20, 0x05, 0x29, 0x00, 0x00, b'h', b'e', b'l', b'l', b'o'];
let mut decoder = Decompressor::default();
assert_eq!(decoder.decompress(&frame)?, b"hello");
assert_eq!(decoder.decompress(&[frame, frame].concat())?, b"hellohello");

Implementations§

Source§

impl Decompressor

Source

pub fn new(config: DecoderConfig) -> Self

A decoder with config that keeps its buffers between operations; nothing is allocated until it decodes.

Source

pub const fn builder(config: DecoderConfig) -> DecompressorBuilder

Starts building a decoder with non-default options.

Source

pub const fn backend(&self) -> Backend

The SIMD backend the decoder runs on.

§Examples
use mzstd::{Backend, Decompressor};
assert_eq!(Decompressor::default().backend(), Backend::default());
Source

pub const fn config(&self) -> &DecoderConfig

The decoder’s policy.

Source

pub const fn retention(&self) -> RetentionPolicy

The retention policy applied after each operation.

Source

pub fn reconfigure(&mut self, config: DecoderConfig)

Replaces the policy for later operations, keeping allocations.

§Examples
use mzstd::{Decompressor, FrameMode};
let mut decoder = Decompressor::default();
decoder.reconfigure(FrameMode::Single.into());
assert_eq!(decoder.config().frame_mode(), FrameMode::Single);
Source

pub fn retained_bytes(&self) -> usize

Heap bytes the decoder keeps between operations.

§Examples
use mzstd::Decompressor;
let mut decoder = Decompressor::default();
assert_eq!(decoder.retained_bytes(), 0);
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x00, 0x00, 0x09, 0x00, 0x00, b'o'];
decoder.start().process(&frame, &mut [0; 4], Default::default())?;
assert!(decoder.retained_bytes() > 0);
Source

pub fn trim(&mut self, policy: RetentionPolicy)

Releases buffers that policy does not allow to keep.

§Examples
use mzstd::{Decompressor, RetentionPolicy};
let mut decoder = Decompressor::default();
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x00, 0x00, 0x09, 0x00, 0x00, b'o'];
decoder.start().process(&frame, &mut [0; 4], Default::default())?;
decoder.trim(RetentionPolicy::Bounded { max_bytes: 1 << 30 });
assert!(decoder.retained_bytes() > 0);
decoder.trim(RetentionPolicy::ReleaseAll);
assert_eq!(decoder.retained_bytes(), 0);
Source

pub fn start(&mut self) -> DecoderSession<'_>

Starts an incremental operation borrowing this decoder.

See DecoderSession::process for a complete loop.

Source

pub fn start_with_dictionary<'d>( &'d mut self, dictionary: impl Into<DictionaryRef<'d>>, ) -> DecoderSession<'d>

Starts an incremental operation borrowing this decoder and dictionary, which every frame of the operation starts from.

The dictionary must be the one the frames were compressed with; see DecodeDictionary for how IDs are checked. It stays borrowed until the session is dropped. See DecoderSession::process for a complete loop and DictionaryRef for an example.

Source

pub fn into_session(self) -> DecoderSessionOwned

Starts an incremental operation that owns this decoder.

See DecoderSessionOwned for an example.

Source

pub fn into_session_with_dictionary<D: AsRef<DecodeDictionary> + 'static>( self, dictionary: D, ) -> DecoderSessionOwned<D>

Starts an incremental operation that owns this decoder and dictionary, which every frame of the operation starts from.

Pass an Arc<DecodeDictionary> to share one dictionary between sessions without copying it; the session then carries no lifetime.

§Examples
use std::sync::Arc;
use mzstd::dictionary::DecodeDictionary;
use mzstd::{DecodeOperation, DecoderStatus, Decompressor};

let dictionary = Arc::new(DecodeDictionary::try_from(&b"history"[..])?);
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x20, 0x02, 0x11, 0x00, 0x00, b'o', b'k'];
let mut session = Decompressor::default().into_session_with_dictionary(Arc::clone(&dictionary));
let mut output = [0u8; 8];
let progress = session.process(&frame, &mut output, DecodeOperation::Finish)?;
assert_eq!(progress.status, DecoderStatus::Finished);
assert_eq!(&output[..progress.produced], b"ok");
Source

pub fn decompress(&mut self, src: &[u8]) -> Result<Vec<u8>, DecodeError>

Decodes complete input into a new vector.

In FrameMode::Concatenated the input must consist of whole frames, at least one; in FrameMode::Single of exactly one frame, which may be a skippable one (decoding to nothing), and nothing else.

§Errors

Returns format, checksum, content-size, limit and allocation errors, DecodeError::UnexpectedEndOfInput for empty or truncated input, and DecodeError::TrailingData for bytes after a single frame.

§Examples

See Decompressor.

Source

pub fn decompress_into( &mut self, src: &[u8], dst: &mut Vec<u8>, ) -> Result<Range<usize>, DecodeError>

Decodes complete input onto the end of dst, returning the range of the appended bytes.

The vector itself serves as the frames’ history, so output is never copied. On error dst is truncated back to its original length, though it may keep capacity it grew.

§Errors

As Self::decompress.

§Examples
use mzstd::Decompressor;
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x20, 0x02, 0x11, 0x00, 0x00, b'o', b'k'];
let mut decoder = Decompressor::default();
let mut output = b"status: ".to_vec();
let range = decoder.decompress_into(&frame, &mut output)?;
assert_eq!(&output[range], b"ok");
assert!(decoder.decompress_into(&frame[..10], &mut output).is_err());
assert_eq!(output, b"status: ok");
Source

pub fn decompress_to_slice( &mut self, src: &[u8], dst: &mut [u8], ) -> Result<usize, DecodeError>

Decodes complete input into dst, returning the number of bytes written; the rest of dst is left unchanged.

§Errors

As Self::decompress, plus DecodeError::OutputTooSmall when the output does not fit; dst is then completely filled with the output’s prefix. After other errors dst may hold a partial result.

§Examples
use mzstd::{DecodeError, Decompressor};
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x20, 0x02, 0x11, 0x00, 0x00, b'o', b'k'];
let mut decoder = Decompressor::default();
let mut output = [0xaa; 4];
let written = decoder.decompress_to_slice(&frame, &mut output)?;
assert_eq!(&output[..written], b"ok");
assert_eq!(&output[written..], &[0xaa, 0xaa]);
assert!(matches!(
    decoder.decompress_to_slice(&frame, &mut [0; 1]),
    Err(DecodeError::OutputTooSmall { written: 1 })
));
Source

pub fn decompress_to_uninit( &mut self, src: &[u8], dst: &mut [MaybeUninit<u8>], ) -> Result<usize, DecodeError>

Self::decompress_to_slice into uninitialized memory, such as Vec::spare_capacity_mut, without zeroing it first.

It returns the same counts and errors as Self::decompress_to_slice. On success exactly dst[..written] is initialized and no byte after it has been written. After DecodeError::OutputTooSmall all of dst holds the output’s prefix; after other errors treat dst as uninitialized.

§Errors

As Self::decompress_to_slice.

§Examples
use mzstd::Decompressor;
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x20, 0x02, 0x11, 0x00, 0x00, b'o', b'k'];
let mut decoder = Decompressor::default();
let mut output: Vec<u8> = Vec::with_capacity(16);
let written = decoder.decompress_to_uninit(&frame, output.spare_capacity_mut())?;
// SAFETY: `decompress_to_uninit` initialized the first `written` bytes.
unsafe { output.set_len(written) };
assert_eq!(output, b"ok");
Source

pub fn decompress_with_dictionary<'dict>( &mut self, dictionary: impl Into<DictionaryRef<'dict>>, src: &[u8], ) -> Result<Vec<u8>, DecodeError>

Decodes complete input that was compressed with dictionary into a new vector; every frame starts from the dictionary.

The dictionary is borrowed for this call only and not copied.

§Errors

As Self::decompress, plus DecodeError::DictionaryMismatch for a frame that names another dictionary ID.

§Examples

See DecodeDictionary.

Source

pub fn decompress_with_dictionary_into<'dict>( &mut self, dictionary: impl Into<DictionaryRef<'dict>>, src: &[u8], dst: &mut Vec<u8>, ) -> Result<Range<usize>, DecodeError>

Decodes complete input that was compressed with dictionary onto the end of dst, returning the range of the appended bytes, as Self::decompress_into does.

§Errors

As Self::decompress_with_dictionary; dst is truncated back to its original length.

§Examples
use mzstd::dictionary::DecodeDictionary;
use mzstd::Decompressor;
let dictionary = DecodeDictionary::try_from(&b"history"[..])?;
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x20, 0x02, 0x11, 0x00, 0x00, b'o', b'k'];
let mut output = b"status: ".to_vec();
let range = Decompressor::default().decompress_with_dictionary_into(&dictionary, &frame, &mut output)?;
assert_eq!(&output[range], b"ok");
Source

pub fn decompress_with_dictionary_to_slice<'dict>( &mut self, dictionary: impl Into<DictionaryRef<'dict>>, src: &[u8], dst: &mut [u8], ) -> Result<usize, DecodeError>

Decodes complete input that was compressed with dictionary into dst, returning the number of bytes written, as Self::decompress_to_slice does.

§Errors

As Self::decompress_with_dictionary, plus DecodeError::OutputTooSmall when the output does not fit.

§Examples
use mzstd::dictionary::DecodeDictionary;
use mzstd::Decompressor;
let dictionary = DecodeDictionary::try_from(&b"history"[..])?;
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x20, 0x02, 0x11, 0x00, 0x00, b'o', b'k'];
let mut output = [0u8; 4];
let written = Decompressor::default().decompress_with_dictionary_to_slice(&dictionary, &frame, &mut output)?;
assert_eq!(&output[..written], b"ok");
Source

pub fn decompress_with_dictionary_to_uninit<'dict>( &mut self, dictionary: impl Into<DictionaryRef<'dict>>, src: &[u8], dst: &mut [MaybeUninit<u8>], ) -> Result<usize, DecodeError>

Decodes complete input that was compressed with dictionary into uninitialized memory, as Self::decompress_to_uninit does.

§Errors

As Self::decompress_with_dictionary_to_slice.

§Examples
use mzstd::dictionary::DecodeDictionary;
use mzstd::Decompressor;
let dictionary = DecodeDictionary::try_from(&b"history"[..])?;
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x20, 0x02, 0x11, 0x00, 0x00, b'o', b'k'];
let mut output: Vec<u8> = Vec::with_capacity(4);
let written = Decompressor::default().decompress_with_dictionary_to_uninit(
    &dictionary,
    &frame,
    output.spare_capacity_mut(),
)?;
// SAFETY: the first `written` bytes were initialized.
unsafe { output.set_len(written) };
assert_eq!(output, b"ok");
Source§

impl Decompressor

Source

pub fn reader<R: Read>(&mut self, source: R) -> DecoderReader<'_, R> ⓘ

Wraps a compressed source; reading yields the decompressed content.

§Examples
use mzstd::Decompressor;
use std::io::Read;
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x20, 0x02, 0x11, 0x00, 0x00, b'o', b'k'];
let mut decoder = Decompressor::default();
let mut reader = decoder.reader(&frame[..]);
let mut content = Vec::new();
reader.read_to_end(&mut content)?;
assert_eq!(content, b"ok");
assert!(reader.is_finished());
Source

pub fn writer<W: Write>(&mut self, sink: W) -> DecoderWriter<'_, W> ⓘ

Wraps a content sink; writing compressed bytes writes their content.

Call DecoderWriter::finish to validate the end of the input and flush the sink; dropping the writer does neither.

§Examples
use mzstd::Decompressor;
use std::io::Write;
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x20, 0x02, 0x11, 0x00, 0x00, b'o', b'k'];
let mut decoder = Decompressor::default();
let mut writer = decoder.writer(Vec::new());
writer.write_all(&frame)?;
let content = writer.finish().map_err(mzstd::io::FinishError::into_error)?;
assert_eq!(content, b"ok");
Source

pub fn reader_with_dictionary<'d, R: Read>( &'d mut self, source: R, dictionary: impl Into<DictionaryRef<'d>>, ) -> DecoderReader<'d, R> ⓘ

Wraps a compressed source as Self::reader does, decoding every frame with dictionary, which stays borrowed with the reader.

§Examples
use mzstd::dictionary::DecodeDictionary;
use mzstd::Decompressor;
use std::io::Read;
let dictionary = DecodeDictionary::try_from(&b"history"[..])?;
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x20, 0x02, 0x11, 0x00, 0x00, b'o', b'k'];
let mut decoder = Decompressor::default();
let mut content = Vec::new();
decoder
    .reader_with_dictionary(&frame[..], &dictionary)
    .read_to_end(&mut content)?;
assert_eq!(content, b"ok");
Source

pub fn writer_with_dictionary<'d, W: Write>( &'d mut self, sink: W, dictionary: impl Into<DictionaryRef<'d>>, ) -> DecoderWriter<'d, W> ⓘ

Wraps a content sink as Self::writer does, decoding every frame with dictionary, which stays borrowed with the writer.

§Examples
use mzstd::dictionary::DecodeDictionary;
use mzstd::Decompressor;
use std::io::Write;
let dictionary = DecodeDictionary::try_from(&b"history"[..])?;
let frame = [0x28, 0xb5, 0x2f, 0xfd, 0x20, 0x02, 0x11, 0x00, 0x00, b'o', b'k'];
let mut decoder = Decompressor::default();
let mut writer = decoder.writer_with_dictionary(Vec::new(), &dictionary);
writer.write_all(&frame)?;
let content = writer.finish().map_err(mzstd::io::FinishError::into_error)?;
assert_eq!(content, b"ok");

Trait Implementations§

Source§

impl Debug for Decompressor

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Decompressor

Source§

fn default() -> Self

A decoder with DecoderConfig::DEFAULT.

Source§

impl From<DecoderConfig> for Decompressor

Source§

fn from(config: DecoderConfig) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

Source§

fn simd_from(_simd: S, value: T) -> T

Source§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

Source§

fn simd_into(self, simd: S) -> T

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.