Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ruzstd"
version = "0.4.0"
version = "0.5.0"
authors = ["Moritz Borcherding <[email protected]>"]
edition = "2018"
license = "MIT"
Expand All @@ -11,17 +11,17 @@ exclude = ["decodecorpus_files/*", "dict_tests/*", "fuzz_decodecorpus/*"]
readme = "Readme.md"

[dependencies]
byteorder = { version = "1.4", default-features = false }
byteorder = { version = "1.5", default-features = false }
twox-hash = { version = "1.6", default-features = false }
thiserror = { package = "thiserror-core", version = "1.0.38", default-features = false }
derive_more = { version = "0.99", default-features = false, features = ["display", "from"] }

[dev-dependencies]
criterion = "0.3"
rand = {version = "0.8.5", features = ["small_rng"]}

[features]
default = ["std"]
std = ["thiserror/std"]
std = ["derive_more/error"]

[[bench]]
name = "reversedbitreader_bench"
Expand Down
14 changes: 9 additions & 5 deletions src/blocks/literals_section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@ pub enum LiteralsSectionType {
Treeless,
}

#[derive(Debug, thiserror::Error)]
#[derive(Debug, derive_more::Display, derive_more::From)]
#[cfg_attr(feature = "std", derive(derive_more::Error))]
#[non_exhaustive]
pub enum LiteralsSectionParseError {
#[error("Illegal literalssectiontype. Is: {got}, must be in: 0, 1, 2, 3")]
#[display(fmt = "Illegal literalssectiontype. Is: {got}, must be in: 0, 1, 2, 3")]
IllegalLiteralSectionType { got: u8 },
#[error(transparent)]
GetBitsError(#[from] GetBitsError),
#[error("Not enough byte to parse the literals section header. Have: {have}, Need: {need}")]
#[display(fmt = "{_0:?}")]
#[from]
GetBitsError(GetBitsError),
#[display(
fmt = "Not enough byte to parse the literals section header. Have: {have}, Need: {need}"
)]
NotEnoughBytes { have: usize, need: u8 },
}

Expand Down
7 changes: 5 additions & 2 deletions src/blocks/sequence_section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,13 @@ impl Default for SequencesHeader {
}
}

#[derive(Debug, thiserror::Error)]
#[derive(Debug, derive_more::Display)]
#[cfg_attr(feature = "std", derive(derive_more::Error))]
#[non_exhaustive]
pub enum SequencesHeaderParseError {
#[error("source must have at least {need_at_least} bytes to parse header; got {got} bytes")]
#[display(
fmt = "source must have at least {need_at_least} bytes to parse header; got {got} bytes"
)]
NotEnoughBytes { need_at_least: u8, got: usize },
}

Expand Down
9 changes: 6 additions & 3 deletions src/decoding/bit_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ pub struct BitReader<'s> {
source: &'s [u8],
}

#[derive(Debug, thiserror::Error)]
#[derive(Debug, derive_more::Display)]
#[cfg_attr(feature = "std", derive(derive_more::Error))]
#[non_exhaustive]
pub enum GetBitsError {
#[error("Cant serve this request. The reader is limited to {limit} bits, requested {num_requested_bits} bits")]
#[display(
fmt = "Cant serve this request. The reader is limited to {limit} bits, requested {num_requested_bits} bits"
)]
TooManyBits {
num_requested_bits: usize,
limit: u8,
},
#[error("Can't read {requested} bits, only have {remaining} bits left")]
#[display(fmt = "Can't read {requested} bits, only have {remaining} bits left")]
NotEnoughRemainingBits { requested: usize, remaining: usize },
}

Expand Down
93 changes: 55 additions & 38 deletions src/decoding/block_decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,72 +25,89 @@ enum DecoderState {
Failed, //TODO put "self.internal_state = DecoderState::Failed;" everywhere an unresolvable error occurs
}

#[derive(Debug, thiserror::Error)]
#[derive(Debug, derive_more::Display, derive_more::From)]
#[cfg_attr(feature = "std", derive(derive_more::Error))]
#[non_exhaustive]
pub enum BlockHeaderReadError {
#[error("Error while reading the block header")]
ReadError(#[from] io::Error),
#[error("Reserved block occured. This is considered corruption by the documentation")]
#[display(fmt = "Error while reading the block header")]
#[from]
ReadError(io::Error),
#[display(fmt = "Reserved block occured. This is considered corruption by the documentation")]
FoundReservedBlock,
#[error("Error getting block type: {0}")]
BlockTypeError(#[from] BlockTypeError),
#[error("Error getting block content size: {0}")]
BlockSizeError(#[from] BlockSizeError),
#[display(fmt = "Error getting block type: {_0}")]
#[from]
BlockTypeError(BlockTypeError),
#[display(fmt = "Error getting block content size: {_0}")]
#[from]
BlockSizeError(BlockSizeError),
}

#[derive(Debug, thiserror::Error)]
#[derive(Debug, derive_more::Display)]
#[cfg_attr(feature = "std", derive(derive_more::Error))]
#[non_exhaustive]
pub enum BlockTypeError {
#[error(
"Invalid Blocktype number. Is: {num} Should be one of: 0, 1, 2, 3 (3 is reserved though"
#[display(
fmt = "Invalid Blocktype number. Is: {num} Should be one of: 0, 1, 2, 3 (3 is reserved though"
)]
InvalidBlocktypeNumber { num: u8 },
}

#[derive(Debug, thiserror::Error)]
#[derive(Debug, derive_more::Display)]
#[cfg_attr(feature = "std", derive(derive_more::Error))]
#[non_exhaustive]
pub enum BlockSizeError {
#[error("Blocksize was bigger than the absolute maximum {ABSOLUTE_MAXIMUM_BLOCK_SIZE} (128kb). Is: {size}")]
#[display(
fmt = "Blocksize was bigger than the absolute maximum {ABSOLUTE_MAXIMUM_BLOCK_SIZE} (128kb). Is: {size}"
)]
BlockSizeTooLarge { size: u32 },
}

#[derive(Debug, thiserror::Error)]
#[derive(Debug, derive_more::Display, derive_more::From)]
#[cfg_attr(feature = "std", derive(derive_more::Error))]
#[non_exhaustive]
pub enum DecompressBlockError {
#[error("Error while reading the block content: {0}")]
BlockContentReadError(#[from] io::Error),
#[error("Malformed section header. Says literals would be this long: {expected_len} but there are only {remaining_bytes} bytes left")]
#[display(fmt = "Error while reading the block content: {_0}")]
#[from]
BlockContentReadError(io::Error),
#[display(
fmt = "Malformed section header. Says literals would be this long: {expected_len} but there are only {remaining_bytes} bytes left"
)]
MalformedSectionHeader {
expected_len: usize,
remaining_bytes: usize,
},
#[error(transparent)]
DecompressLiteralsError(#[from] DecompressLiteralsError),
#[error(transparent)]
LiteralsSectionParseError(#[from] LiteralsSectionParseError),
#[error(transparent)]
SequencesHeaderParseError(#[from] SequencesHeaderParseError),
#[error(transparent)]
DecodeSequenceError(#[from] DecodeSequenceError),
#[error(transparent)]
ExecuteSequencesError(#[from] ExecuteSequencesError),
#[display(fmt = "{_0:?}")]
#[from]
DecompressLiteralsError(DecompressLiteralsError),
#[display(fmt = "{_0:?}")]
#[from]
LiteralsSectionParseError(LiteralsSectionParseError),
#[display(fmt = "{_0:?}")]
#[from]
SequencesHeaderParseError(SequencesHeaderParseError),
#[display(fmt = "{_0:?}")]
#[from]
DecodeSequenceError(DecodeSequenceError),
#[display(fmt = "{_0:?}")]
#[from]
ExecuteSequencesError(ExecuteSequencesError),
}

#[derive(Debug, thiserror::Error)]
#[derive(Debug, derive_more::Display, derive_more::From)]
#[cfg_attr(feature = "std", derive(derive_more::Error))]
#[non_exhaustive]
pub enum DecodeBlockContentError {
#[error("Can't decode next block if failed along the way. Results will be nonsense")]
#[display(fmt = "Can't decode next block if failed along the way. Results will be nonsense")]
DecoderStateIsFailed,
#[error("Cant decode next block body, while expecting to decode the header of the previous block. Results will be nonsense")]
#[display(
fmt = "Cant decode next block body, while expecting to decode the header of the previous block. Results will be nonsense"
)]
ExpectedHeaderOfPreviousBlock,
#[error("Error while reading bytes for {step}: {source}")]
ReadError {
step: BlockType,
#[source]
source: io::Error,
},
#[error(transparent)]
DecompressBlockError(#[from] DecompressBlockError),
#[display(fmt = "Error while reading bytes for {step}: {source}")]
ReadError { step: BlockType, source: io::Error },
#[display(fmt = "{_0:?}")]
#[from]
DecompressBlockError(DecompressBlockError),
}

pub fn new() -> BlockDecoder {
Expand Down
7 changes: 4 additions & 3 deletions src/decoding/decodebuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ pub struct Decodebuffer {
pub hash: XxHash64,
}

#[derive(Debug, thiserror::Error)]
#[derive(Debug, derive_more::Display)]
#[cfg_attr(feature = "std", derive(derive_more::Error))]
#[non_exhaustive]
pub enum DecodebufferError {
#[error("Need {need} bytes from the dictionary but it is only {got} bytes long")]
#[display(fmt = "Need {need} bytes from the dictionary but it is only {got} bytes long")]
NotEnoughBytesInDictionary { got: usize, need: usize },
#[error("offset: {offset} bigger than buffer: {buf_len}")]
#[display(fmt = "offset: {offset} bigger than buffer: {buf_len}")]
OffsetTooBig { offset: usize, buf_len: usize },
}

Expand Down
17 changes: 10 additions & 7 deletions src/decoding/dictionary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,20 @@ pub struct Dictionary {
pub offset_hist: [u32; 3],
}

#[derive(Debug, thiserror::Error)]
#[derive(Debug, derive_more::Display, derive_more::From)]
#[cfg_attr(feature = "std", derive(derive_more::Error))]
#[non_exhaustive]
pub enum DictionaryDecodeError {
#[error(
"Bad magic_num at start of the dictionary; Got: {got:#04X?}, Expected: {MAGIC_NUM:#04x?}"
#[display(
fmt = "Bad magic_num at start of the dictionary; Got: {got:#04X?}, Expected: {MAGIC_NUM:#04x?}"
)]
BadMagicNum { got: [u8; 4] },
#[error(transparent)]
FSETableError(#[from] FSETableError),
#[error(transparent)]
HuffmanTableError(#[from] HuffmanTableError),
#[display(fmt = "{_0:?}")]
#[from]
FSETableError(FSETableError),
#[display(fmt = "{_0:?}")]
#[from]
HuffmanTableError(HuffmanTableError),
}

pub const MAGIC_NUM: [u8; 4] = [0x37, 0xA4, 0x30, 0xEC];
Expand Down
40 changes: 24 additions & 16 deletions src/decoding/literals_section_decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,40 @@ use super::scratch::HuffmanScratch;
use crate::huff0::{HuffmanDecoder, HuffmanDecoderError, HuffmanTableError};
use alloc::vec::Vec;

#[derive(Debug, thiserror::Error)]
#[derive(Debug, derive_more::Display, derive_more::From)]
#[cfg_attr(feature = "std", derive(derive_more::Error))]
#[non_exhaustive]
pub enum DecompressLiteralsError {
#[error(
"compressed size was none even though it must be set to something for compressed literals"
#[display(
fmt = "compressed size was none even though it must be set to something for compressed literals"
)]
MissingCompressedSize,
#[error("num_streams was none even though it must be set to something (1 or 4) for compressed literals")]
#[display(
fmt = "num_streams was none even though it must be set to something (1 or 4) for compressed literals"
)]
MissingNumStreams,
#[error(transparent)]
GetBitsError(#[from] GetBitsError),
#[error(transparent)]
HuffmanTableError(#[from] HuffmanTableError),
#[error(transparent)]
HuffmanDecoderError(#[from] HuffmanDecoderError),
#[error("Tried to reuse huffman table but it was never initialized")]
#[display(fmt = "{_0:?}")]
#[from]
GetBitsError(GetBitsError),
#[display(fmt = "{_0:?}")]
#[from]
HuffmanTableError(HuffmanTableError),
#[display(fmt = "{_0:?}")]
#[from]
HuffmanDecoderError(HuffmanDecoderError),
#[display(fmt = "Tried to reuse huffman table but it was never initialized")]
UninitializedHuffmanTable,
#[error("Need 6 bytes to decode jump header, got {got} bytes")]
#[display(fmt = "Need 6 bytes to decode jump header, got {got} bytes")]
MissingBytesForJumpHeader { got: usize },
#[error("Need at least {needed} bytes to decode literals. Have: {got} bytes")]
#[display(fmt = "Need at least {needed} bytes to decode literals. Have: {got} bytes")]
MissingBytesForLiterals { got: usize, needed: usize },
#[error("Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption")]
#[display(
fmt = "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption"
)]
ExtraPadding { skipped_bits: i32 },
#[error("Bitstream was read till: {read_til}, should have been: {expected}")]
#[display(fmt = "Bitstream was read till: {read_til}, should have been: {expected}")]
BitstreamReadMismatch { read_til: isize, expected: isize },
#[error("Did not decode enough literals: {decoded}, Should have been: {expected}")]
#[display(fmt = "Did not decode enough literals: {decoded}, Should have been: {expected}")]
DecodedLiteralCountMismatch { decoded: usize, expected: usize },
}

Expand Down
2 changes: 0 additions & 2 deletions src/decoding/ringbuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,6 @@ impl RingBuffer {
/// 2. More then len reserved space so we do not write out-of-bounds
#[warn(unsafe_op_in_unsafe_fn)]
pub unsafe fn extend_from_within_unchecked(&mut self, start: usize, len: usize) {
debug_assert!(!self.buf.as_ptr().is_null());

if self.head < self.tail {
// continous data slice |____HDDDDDDDT_____|
let after_tail = usize::min(len, self.cap - self.tail);
Expand Down
12 changes: 7 additions & 5 deletions src/decoding/sequence_execution.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use super::{decodebuffer::DecodebufferError, scratch::DecoderScratch};

#[derive(Debug, thiserror::Error)]
#[derive(Debug, derive_more::Display, derive_more::From)]
#[cfg_attr(feature = "std", derive(derive_more::Error))]
#[non_exhaustive]
pub enum ExecuteSequencesError {
#[error(transparent)]
DecodebufferError(#[from] DecodebufferError),
#[error("Sequence wants to copy up to byte {wanted}. Bytes in literalsbuffer: {have}")]
#[display(fmt = "{_0:?}")]
#[from]
DecodebufferError(DecodebufferError),
#[display(fmt = "Sequence wants to copy up to byte {wanted}. Bytes in literalsbuffer: {have}")]
NotEnoughBytesForSequence { wanted: usize, have: usize },
#[error("Illegal offset: 0 found")]
#[display(fmt = "Illegal offset: 0 found")]
ZeroOffset,
}

Expand Down
Loading