pub struct BlockDecoder { /* private fields */ }Expand description
Block decoder with constructor-owned working memory.
This type mirrors BlockEncoder on the decode side and never touches
the encoder. The hash table and the entropy coder state persist
across calls but reset per block, exactly like the reference. One
call decodes one block payload through the inverse pipeline:
entropy decode, inverse Burrows-Wheeler transform, then inverse
Lempel-Ziv prediction and inverse run-length transform as the model
byte selects. Every check runs in reference order, first failure
wins. Like the reference, a short entropy stream reads filler bytes
past its end; the port retries with equivalent filler and fails
downstream exactly as the reference does.
§Examples
use bzip3_rs::{BlockDecoder, BlockEncoder, BlockSize};
let data = b"hello world ".repeat(100);
let size = BlockSize::MIN;
let payload = BlockEncoder::new(size)?.encode_block(&data)?;
let mut decoder = BlockDecoder::new(size)?;
let mut plain = Vec::new();
decoder.decode_block_into(&payload, u32::try_from(data.len())?, &mut plain)?;
assert_eq!(plain, data);Implementations§
Source§impl BlockDecoder
impl BlockDecoder
Sourcepub fn new(block_size: BlockSize) -> Result<Self>
pub fn new(block_size: BlockSize) -> Result<Self>
Build a decoder for block_size, allocating working memory once.
§Errors
Returns Error::OutOfMemory when any working buffer allocation fails.
§Examples
use bzip3_rs::{BlockDecoder, BlockSize};
let decoder = BlockDecoder::new(BlockSize::MIN)?;
assert_eq!(decoder.block_size(), BlockSize::MIN);Sourcepub const fn block_size(&self) -> BlockSize
pub const fn block_size(&self) -> BlockSize
Return the block size this decoder was built for.
Sourcepub fn decode_block(
&mut self,
payload: &[u8],
orig_size: u32,
) -> Result<Vec<u8>>
pub fn decode_block( &mut self, payload: &[u8], orig_size: u32, ) -> Result<Vec<u8>>
Decode one block payload into a new vector.
Same result as BlockDecoder::decode_block_into. Use that call
to reuse one output vector across blocks.
§Errors
Returns the same errors as BlockDecoder::decode_block_into.
§Examples
use bzip3_rs::{BlockDecoder, BlockEncoder, BlockSize};
let data = b"hello world ".repeat(100);
let payload = BlockEncoder::new(BlockSize::MIN)?.encode_block(&data)?;
let mut decoder = BlockDecoder::new(BlockSize::MIN)?;
let block = decoder.decode_block(&payload, u32::try_from(data.len())?)?;
assert_eq!(block, data);Sourcepub fn decode_block_into(
&mut self,
payload: &[u8],
orig_size: u32,
out: &mut Vec<u8>,
) -> Result<()>
pub fn decode_block_into( &mut self, payload: &[u8], orig_size: u32, out: &mut Vec<u8>, ) -> Result<()>
Decode one block payload and append its original bytes to out.
On an error, out keeps its length. The call checks the sizes
before it grows out, so a hostile orig_size cannot force a
large allocation.
§Errors
Returns the errors of BlockDecoder::decode_block_to, and
Error::OutOfMemory when out cannot grow.
§Examples
use bzip3_rs::{BlockDecoder, BlockEncoder, BlockSize};
let first = b"first block ".repeat(50);
let second = b"second block ".repeat(50);
let mut encoder = BlockEncoder::new(BlockSize::MIN)?;
let mut decoder = BlockDecoder::new(BlockSize::MIN)?;
let mut plain = Vec::new();
for block in [&first, &second] {
let payload = encoder.encode_block(block)?;
decoder.decode_block_into(&payload, u32::try_from(block.len())?, &mut plain)?;
}
assert_eq!(plain, [first, second].concat());Sourcepub fn recover_block_into(
&mut self,
payload: &[u8],
orig_size: u32,
out: &mut Vec<u8>,
) -> Result<BlockStatus>
pub fn recover_block_into( &mut self, payload: &[u8], orig_size: u32, out: &mut Vec<u8>, ) -> Result<BlockStatus>
Decode one block payload and always append orig_size bytes to out.
Use this call to recover the data of a damaged stream. A checksum
fault keeps the decoded bytes, because the checksum is the last
check. Any other block fault appends zero bytes, because the
decode stages leave partial data. The returned BlockStatus
tells which case happened. A size above the block size appends the
block size.
§Errors
Returns Error::OutOfMemory when out cannot grow.
Then out keeps its length. Block faults are not errors. They
come back in the BlockStatus value.
§Examples
use bzip3_rs::error::Error;
use bzip3_rs::{BlockDecoder, BlockEncoder, BlockStatus, BlockSize};
let data = b"hello world ".repeat(100);
let orig_size = u32::try_from(data.len())?;
let mut payload = BlockEncoder::new(BlockSize::MIN)?.encode_block(&data)?;
let mut decoder = BlockDecoder::new(BlockSize::MIN)?;
// A wrong checksum keeps the decoded bytes.
payload[0] ^= 1;
let mut plain = Vec::new();
let result = decoder.recover_block_into(&payload, orig_size, &mut plain)?;
assert!(matches!(result, BlockStatus::BadChecksum));
assert_eq!(plain, data);
// A short payload gives zero bytes.
let mut plain = Vec::new();
let result = decoder.recover_block_into(&payload[..4], orig_size, &mut plain)?;
assert!(matches!(result, BlockStatus::Zeroed(Error::TruncatedHeader)));
assert_eq!(plain, vec![0_u8; data.len()]);Sourcepub fn decode_block_to(
&mut self,
payload: &[u8],
orig_size: u32,
out: &mut [u8],
) -> Result<()>
pub fn decode_block_to( &mut self, payload: &[u8], orig_size: u32, out: &mut [u8], ) -> Result<()>
Decode one block payload into out.
payload holds the block bytes (compressed_size long) and
orig_size holds the claimed original size. out must be
exactly orig_size bytes long. The call runs the reference
check order: buffer fit, compressed-size range, original-size
range, stored-raw path, header-size fit, stage sizes,
intermediate-size fit, entropy decode, index range, inverse
transform, inverse stages, final-size match, checksum. The call
does not allocate after the first block, except on a starved
entropy stream.
§Errors
Returns Error::BufferTooSmall when a size exceeds the decode buffer,
Error::OutputSizeMismatch when out has the wrong length,
Error::TruncatedHeader on a short payload,
Error::InvalidHeader on bad sizes,
Error::BwtFailed when the inverse transform fails,
Error::ChecksumMismatch on checksum mismatch,
Error::CorruptStageData on corrupt RLE or LZP data,
Error::OutOfMemory when working memory allocation fails.
§Examples
use bzip3_rs::error::Error;
use bzip3_rs::{BlockDecoder, BlockEncoder, BlockSize};
let data = b"hello world ".repeat(100);
let orig_size = u32::try_from(data.len())?;
let payload = BlockEncoder::new(BlockSize::MIN)?.encode_block(&data)?;
let mut decoder = BlockDecoder::new(BlockSize::MIN)?;
let mut out = vec![0_u8; data.len()];
decoder.decode_block_to(&payload, orig_size, &mut out)?;
assert_eq!(out, data);
// A wrong output length fails.
let mut short = vec![0_u8; data.len() - 1];
let result = decoder.decode_block_to(&payload, orig_size, &mut short);
assert!(matches!(result, Err(Error::OutputSizeMismatch)));Trait Implementations§
Auto Trait Implementations§
impl Freeze for BlockDecoder
impl RefUnwindSafe for BlockDecoder
impl Send for BlockDecoder
impl Sync for BlockDecoder
impl Unpin for BlockDecoder
impl UnsafeUnpin for BlockDecoder
impl UnwindSafe for BlockDecoder
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more