1use crate::bit_io::GetBitsError;
4use crate::blocks::block::BlockType;
5use crate::blocks::literals_section::LiteralsSectionType;
6use crate::io::Error;
7use alloc::vec::Vec;
8use core::fmt;
9#[cfg(feature = "std")]
10use std::error::Error as StdError;
11
12#[derive(Debug)]
13#[non_exhaustive]
14pub enum FrameDescriptorError {
15 InvalidFrameContentSizeFlag {
16 got: u8,
17 },
18 ReservedBitSet,
21}
22
23impl fmt::Display for FrameDescriptorError {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 match self {
26 Self::InvalidFrameContentSizeFlag { got } => write!(
27 f,
28 "Invalid Frame_Content_Size_Flag; Is: {got}, Should be one of: 0, 1, 2, 3"
29 ),
30 Self::ReservedBitSet => write!(
31 f,
32 "Reserved_bit of the Frame_Header_Descriptor is set; it must be zero"
33 ),
34 }
35 }
36}
37
38#[cfg(feature = "std")]
39impl StdError for FrameDescriptorError {}
40
41#[derive(Debug)]
42#[non_exhaustive]
43pub enum FrameHeaderError {
44 WindowTooBig { got: u64 },
45 WindowTooSmall { got: u64 },
46 FrameDescriptorError(FrameDescriptorError),
47 DictIdTooSmall { got: usize, expected: usize },
48 MismatchedFrameSize { got: usize, expected: u8 },
49 FrameSizeIsZero,
50 InvalidFrameSize { got: u8 },
51}
52
53impl fmt::Display for FrameHeaderError {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 match self {
56 Self::WindowTooBig { got } => write!(
57 f,
58 "window_size bigger than allowed maximum. Is: {}, Should be lower than: {}",
59 got,
60 crate::common::MAX_WINDOW_SIZE
61 ),
62 Self::WindowTooSmall { got } => write!(
63 f,
64 "window_size smaller than allowed minimum. Is: {}, Should be greater than: {}",
65 got,
66 crate::common::MIN_WINDOW_SIZE
67 ),
68 Self::FrameDescriptorError(e) => write!(f, "{e:?}"),
69 Self::DictIdTooSmall { got, expected } => write!(
70 f,
71 "Not enough bytes in dict_id. Is: {got}, Should be: {expected}"
72 ),
73 Self::MismatchedFrameSize { got, expected } => write!(
74 f,
75 "frame_content_size does not have the right length. Is: {got}, Should be: {expected}"
76 ),
77 Self::FrameSizeIsZero => write!(f, "frame_content_size was zero"),
78 Self::InvalidFrameSize { got } => write!(
79 f,
80 "Invalid frame_content_size. Is: {got}, Should be one of 1, 2, 4, 8 bytes"
81 ),
82 }
83 }
84}
85
86#[cfg(feature = "std")]
87impl StdError for FrameHeaderError {
88 fn source(&self) -> Option<&(dyn StdError + 'static)> {
89 match self {
90 FrameHeaderError::FrameDescriptorError(source) => Some(source),
91 _ => None,
92 }
93 }
94}
95
96impl From<FrameDescriptorError> for FrameHeaderError {
97 fn from(error: FrameDescriptorError) -> Self {
98 Self::FrameDescriptorError(error)
99 }
100}
101
102#[derive(Debug)]
103#[non_exhaustive]
104pub enum ReadFrameHeaderError {
105 MagicNumberReadError(Error),
106 BadMagicNumber(u32),
107 FrameDescriptorReadError(Error),
108 InvalidFrameDescriptor(FrameDescriptorError),
109 WindowDescriptorReadError(Error),
110 DictionaryIdReadError(Error),
111 FrameContentSizeReadError(Error),
112 SkipFrame { magic_number: u32, length: u32 },
113}
114
115impl fmt::Display for ReadFrameHeaderError {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 match self {
118 Self::MagicNumberReadError(e) => write!(f, "Error while reading magic number: {e}"),
119 Self::BadMagicNumber(e) => write!(f, "Read wrong magic number: 0x{e:X}"),
120 Self::FrameDescriptorReadError(e) => {
121 write!(f, "Error while reading frame descriptor: {e}")
122 }
123 Self::InvalidFrameDescriptor(e) => write!(f, "{e:?}"),
124 Self::WindowDescriptorReadError(e) => {
125 write!(f, "Error while reading window descriptor: {e}")
126 }
127 Self::DictionaryIdReadError(e) => write!(f, "Error while reading dictionary id: {e}"),
128 Self::FrameContentSizeReadError(e) => {
129 write!(f, "Error while reading frame content size: {e}")
130 }
131 Self::SkipFrame {
132 magic_number,
133 length,
134 } => write!(
135 f,
136 "SkippableFrame encountered with MagicNumber 0x{magic_number:X} and length {length} bytes"
137 ),
138 }
139 }
140}
141
142#[cfg(feature = "std")]
143impl StdError for ReadFrameHeaderError {
144 fn source(&self) -> Option<&(dyn StdError + 'static)> {
145 match self {
146 ReadFrameHeaderError::MagicNumberReadError(source) => Some(source),
147 ReadFrameHeaderError::FrameDescriptorReadError(source) => Some(source),
148 ReadFrameHeaderError::InvalidFrameDescriptor(source) => Some(source),
149 ReadFrameHeaderError::WindowDescriptorReadError(source) => Some(source),
150 ReadFrameHeaderError::DictionaryIdReadError(source) => Some(source),
151 ReadFrameHeaderError::FrameContentSizeReadError(source) => Some(source),
152 _ => None,
153 }
154 }
155}
156
157impl From<FrameDescriptorError> for ReadFrameHeaderError {
158 fn from(error: FrameDescriptorError) -> Self {
159 Self::InvalidFrameDescriptor(error)
160 }
161}
162
163#[derive(Debug)]
164#[non_exhaustive]
165pub enum BlockHeaderReadError {
166 ReadError(Error),
167 FoundReservedBlock,
168 BlockTypeError(BlockTypeError),
169 BlockSizeError(BlockSizeError),
170}
171
172#[cfg(feature = "std")]
173impl std::error::Error for BlockHeaderReadError {
174 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
175 match self {
176 BlockHeaderReadError::ReadError(source) => Some(source),
177 BlockHeaderReadError::BlockTypeError(source) => Some(source),
178 BlockHeaderReadError::BlockSizeError(source) => Some(source),
179 BlockHeaderReadError::FoundReservedBlock => None,
180 }
181 }
182}
183
184impl ::core::fmt::Display for BlockHeaderReadError {
185 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> ::core::fmt::Result {
186 match self {
187 BlockHeaderReadError::ReadError(_) => write!(f, "Error while reading the block header"),
188 BlockHeaderReadError::FoundReservedBlock => write!(
189 f,
190 "Reserved block occured. This is considered corruption by the documentation"
191 ),
192 BlockHeaderReadError::BlockTypeError(e) => write!(f, "Error getting block type: {e}"),
193 BlockHeaderReadError::BlockSizeError(e) => {
194 write!(f, "Error getting block content size: {e}")
195 }
196 }
197 }
198}
199
200impl From<Error> for BlockHeaderReadError {
201 fn from(val: Error) -> Self {
202 Self::ReadError(val)
203 }
204}
205
206impl From<BlockTypeError> for BlockHeaderReadError {
207 fn from(val: BlockTypeError) -> Self {
208 Self::BlockTypeError(val)
209 }
210}
211
212impl From<BlockSizeError> for BlockHeaderReadError {
213 fn from(val: BlockSizeError) -> Self {
214 Self::BlockSizeError(val)
215 }
216}
217
218#[derive(Debug)]
219#[non_exhaustive]
220pub enum BlockTypeError {
221 InvalidBlocktypeNumber { num: u8 },
222}
223
224#[cfg(feature = "std")]
225impl std::error::Error for BlockTypeError {}
226
227impl core::fmt::Display for BlockTypeError {
228 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
229 match self {
230 BlockTypeError::InvalidBlocktypeNumber { num } => {
231 write!(
232 f,
233 "Invalid Blocktype number. Is: {num}. Should be one of: 0, 1, 2, 3 (3 is reserved).",
234 )
235 }
236 }
237 }
238}
239
240#[derive(Debug)]
241#[non_exhaustive]
242pub enum BlockSizeError {
243 BlockSizeTooLarge { size: u32 },
244}
245
246#[cfg(feature = "std")]
247impl std::error::Error for BlockSizeError {}
248
249impl core::fmt::Display for BlockSizeError {
250 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
251 match self {
252 BlockSizeError::BlockSizeTooLarge { size } => {
253 write!(
254 f,
255 "Blocksize was bigger than the absolute maximum {} (128kb). Is: {}",
256 crate::common::MAX_BLOCK_SIZE,
257 size,
258 )
259 }
260 }
261 }
262}
263
264#[derive(Debug)]
265#[non_exhaustive]
266pub enum DecompressBlockError {
267 BlockContentReadError(Error),
268 MalformedSectionHeader {
269 expected_len: usize,
270 remaining_bytes: usize,
271 },
272 DecompressLiteralsError(DecompressLiteralsError),
273 LiteralsSectionParseError(LiteralsSectionParseError),
274 SequencesHeaderParseError(SequencesHeaderParseError),
275 DecodeSequenceError(DecodeSequenceError),
276 ExecuteSequencesError(ExecuteSequencesError),
277 ExpandsPastBlockMaximum {
282 size: usize,
283 maximum: usize,
284 },
285 ContentPastBlockMaximum {
289 size: usize,
290 maximum: usize,
291 },
292 LiteralsOutputOverflow {
299 tail: usize,
300 requested: usize,
301 capacity: usize,
302 },
303}
304
305#[cfg(feature = "std")]
306impl std::error::Error for DecompressBlockError {
307 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
308 match self {
309 DecompressBlockError::BlockContentReadError(source) => Some(source),
310 DecompressBlockError::DecompressLiteralsError(source) => Some(source),
311 DecompressBlockError::LiteralsSectionParseError(source) => Some(source),
312 DecompressBlockError::SequencesHeaderParseError(source) => Some(source),
313 DecompressBlockError::DecodeSequenceError(source) => Some(source),
314 DecompressBlockError::ExecuteSequencesError(source) => Some(source),
315 _ => None,
316 }
317 }
318}
319
320impl core::fmt::Display for DecompressBlockError {
321 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
322 match self {
323 DecompressBlockError::BlockContentReadError(e) => {
324 write!(f, "Error while reading the block content: {e}")
325 }
326 DecompressBlockError::MalformedSectionHeader {
327 expected_len,
328 remaining_bytes,
329 } => {
330 write!(
331 f,
332 "Malformed section header. Says literals would be this long: {expected_len} but there are only {remaining_bytes} bytes left",
333 )
334 }
335 DecompressBlockError::DecompressLiteralsError(e) => write!(f, "{e:?}"),
336 DecompressBlockError::LiteralsSectionParseError(e) => write!(f, "{e:?}"),
337 DecompressBlockError::SequencesHeaderParseError(e) => write!(f, "{e:?}"),
338 DecompressBlockError::DecodeSequenceError(e) => write!(f, "{e:?}"),
339 DecompressBlockError::ExecuteSequencesError(e) => write!(f, "{e:?}"),
340 DecompressBlockError::ExpandsPastBlockMaximum { size, maximum } => write!(
341 f,
342 "Block expands to {size} bytes, past this frame's maximum of {maximum}"
343 ),
344 DecompressBlockError::ContentPastBlockMaximum { size, maximum } => write!(
345 f,
346 "Compressed block of {size} bytes, past this frame's maximum of {maximum}"
347 ),
348 DecompressBlockError::LiteralsOutputOverflow {
349 tail,
350 requested,
351 capacity,
352 } => write!(
353 f,
354 "Literals would write past the output buffer: tail={tail}, requested={requested}, capacity={capacity}"
355 ),
356 }
357 }
358}
359
360impl From<Error> for DecompressBlockError {
361 fn from(val: Error) -> Self {
362 Self::BlockContentReadError(val)
363 }
364}
365
366impl From<DecompressLiteralsError> for DecompressBlockError {
367 fn from(val: DecompressLiteralsError) -> Self {
368 Self::DecompressLiteralsError(val)
369 }
370}
371
372impl From<LiteralsSectionParseError> for DecompressBlockError {
373 fn from(val: LiteralsSectionParseError) -> Self {
374 Self::LiteralsSectionParseError(val)
375 }
376}
377
378impl From<SequencesHeaderParseError> for DecompressBlockError {
379 fn from(val: SequencesHeaderParseError) -> Self {
380 Self::SequencesHeaderParseError(val)
381 }
382}
383
384impl From<DecodeSequenceError> for DecompressBlockError {
385 fn from(val: DecodeSequenceError) -> Self {
386 Self::DecodeSequenceError(val)
387 }
388}
389
390impl From<ExecuteSequencesError> for DecompressBlockError {
391 fn from(val: ExecuteSequencesError) -> Self {
392 Self::ExecuteSequencesError(val)
393 }
394}
395
396#[derive(Debug)]
397#[non_exhaustive]
398pub enum DecodeBlockContentError {
399 DecoderStateIsFailed,
400 ExpectedHeaderOfPreviousBlock,
401 ReadError {
402 step: BlockType,
403 source: Error,
404 },
405 DecompressBlockError(DecompressBlockError),
406 BackendOverflow {
417 step: BlockType,
418 },
419}
420
421#[cfg(feature = "std")]
422impl std::error::Error for DecodeBlockContentError {
423 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
424 match self {
425 DecodeBlockContentError::ReadError { step: _, source } => Some(source),
426 DecodeBlockContentError::DecompressBlockError(source) => Some(source),
427 _ => None,
428 }
429 }
430}
431
432impl core::fmt::Display for DecodeBlockContentError {
433 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
434 match self {
435 DecodeBlockContentError::DecoderStateIsFailed => {
436 write!(
437 f,
438 "Can't decode next block if failed along the way. Results will be nonsense",
439 )
440 }
441 DecodeBlockContentError::ExpectedHeaderOfPreviousBlock => {
442 write!(
443 f,
444 "Can't decode next block body, while expecting to decode the header of the previous block. Results will be nonsense",
445 )
446 }
447 DecodeBlockContentError::ReadError { step, source } => {
448 write!(f, "Error while reading bytes for {step}: {source}",)
449 }
450 DecodeBlockContentError::DecompressBlockError(e) => write!(f, "{e:?}"),
451 DecodeBlockContentError::BackendOverflow { step } => write!(
452 f,
453 "{step} block's decompressed payload exceeds the caller-provided output buffer",
454 ),
455 }
456 }
457}
458
459impl From<DecompressBlockError> for DecodeBlockContentError {
460 fn from(val: DecompressBlockError) -> Self {
461 Self::DecompressBlockError(val)
462 }
463}
464
465#[derive(Debug)]
466#[non_exhaustive]
467pub enum DecodeBufferError {
468 NotEnoughBytesInDictionary {
469 got: usize,
470 need: usize,
471 },
472 OffsetTooBig {
473 offset: usize,
474 buf_len: usize,
475 },
476 ZeroOffset,
477 BackendOverflow,
489 OutputBufferOverflow {
499 tail: usize,
500 requested: usize,
501 capacity: usize,
502 },
503}
504
505#[cfg(feature = "std")]
506impl std::error::Error for DecodeBufferError {}
507
508impl core::fmt::Display for DecodeBufferError {
509 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
510 match self {
511 DecodeBufferError::NotEnoughBytesInDictionary { got, need } => {
512 write!(
513 f,
514 "Need {need} bytes from the dictionary but it is only {got} bytes long",
515 )
516 }
517 DecodeBufferError::OffsetTooBig { offset, buf_len } => {
518 write!(f, "offset: {offset} bigger than buffer: {buf_len}",)
519 }
520 DecodeBufferError::ZeroOffset => {
521 write!(f, "Illegal offset: 0 found")
522 }
523 DecodeBufferError::BackendOverflow => {
524 write!(
525 f,
526 "Match repeat would overflow the output buffer's fixed capacity"
527 )
528 }
529 DecodeBufferError::OutputBufferOverflow {
530 tail,
531 requested,
532 capacity,
533 } => {
534 write!(
535 f,
536 "Match repeat would write past fixed-capacity buffer: tail={tail}, requested={requested}, capacity={capacity}"
537 )
538 }
539 }
540 }
541}
542
543#[derive(Debug)]
544#[non_exhaustive]
545pub enum DictionaryDecodeError {
546 BadMagicNum { got: [u8; 4] },
547 DictionaryTooSmall { got: usize, need: usize },
548 ZeroDictionaryId,
549 ZeroRepeatOffsetInDictionary { index: u8 },
550 FSETableError(FSETableError),
551 HuffmanTableError(HuffmanTableError),
552}
553
554#[cfg(feature = "std")]
555impl std::error::Error for DictionaryDecodeError {
556 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
557 match self {
558 DictionaryDecodeError::FSETableError(source) => Some(source),
559 DictionaryDecodeError::HuffmanTableError(source) => Some(source),
560 _ => None,
561 }
562 }
563}
564
565impl core::fmt::Display for DictionaryDecodeError {
566 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
567 match self {
568 DictionaryDecodeError::BadMagicNum { got } => {
569 write!(
570 f,
571 "Bad magic_num at start of the dictionary; Got: {:#04X?}, Expected: {:#04x?}",
572 got,
573 crate::decoding::dictionary::MAGIC_NUM,
574 )
575 }
576 DictionaryDecodeError::DictionaryTooSmall { got, need } => {
577 write!(
578 f,
579 "Dictionary is too small: got {got} bytes, need at least {need} bytes",
580 )
581 }
582 DictionaryDecodeError::ZeroDictionaryId => {
583 write!(f, "Dictionary id must be non-zero")
584 }
585 DictionaryDecodeError::ZeroRepeatOffsetInDictionary { index } => {
586 write!(f, "Dictionary repeat offset rep{index} must be non-zero")
587 }
588 DictionaryDecodeError::FSETableError(e) => write!(f, "{e:?}"),
589 DictionaryDecodeError::HuffmanTableError(e) => write!(f, "{e:?}"),
590 }
591 }
592}
593
594impl From<FSETableError> for DictionaryDecodeError {
595 fn from(val: FSETableError) -> Self {
596 Self::FSETableError(val)
597 }
598}
599
600impl From<HuffmanTableError> for DictionaryDecodeError {
601 fn from(val: HuffmanTableError) -> Self {
602 Self::HuffmanTableError(val)
603 }
604}
605
606#[derive(Debug, Clone, Copy, PartialEq, Eq)]
620#[non_exhaustive]
621pub enum ErrorCode {
622 PrefixUnknown,
624 FrameParameterUnsupported,
626 FrameParameterWindowTooLarge,
628 ParameterOutOfBound,
630 DictionaryCorrupted,
632 DictionaryWrong,
635 DstSizeTooSmall,
637 InitMissing,
639 ChecksumWrong,
641 CorruptionDetected,
643}
644
645impl ErrorCode {
646 pub fn message(self) -> &'static str {
648 match self {
649 ErrorCode::PrefixUnknown => "Unknown frame descriptor",
650 ErrorCode::FrameParameterUnsupported => "Unsupported frame parameter",
651 ErrorCode::FrameParameterWindowTooLarge => {
652 "Frame requires too much memory for decoding"
653 }
654 ErrorCode::ParameterOutOfBound => "Parameter is out of bound",
655 ErrorCode::DictionaryCorrupted => "Dictionary is corrupted",
656 ErrorCode::DictionaryWrong => "Dictionary mismatch",
657 ErrorCode::DstSizeTooSmall => "Destination buffer is too small",
658 ErrorCode::InitMissing => "Context should be init first",
659 ErrorCode::ChecksumWrong => "Restored data doesn't match checksum",
660 ErrorCode::CorruptionDetected => "Data corruption detected",
661 }
662 }
663}
664
665impl FrameDescriptorError {
666 pub fn code(&self) -> ErrorCode {
668 match self {
669 FrameDescriptorError::ReservedBitSet => ErrorCode::FrameParameterUnsupported,
672 _ => ErrorCode::CorruptionDetected,
673 }
674 }
675}
676
677#[derive(Debug)]
678#[non_exhaustive]
679pub enum FrameDecoderError {
680 ReadFrameHeaderError(ReadFrameHeaderError),
681 FrameHeaderError(FrameHeaderError),
682 #[non_exhaustive]
686 WindowSizeTooBig {
687 requested: u64,
689 limit: u64,
691 },
692 WindowCeilingOutOfRange {
696 requested: u64,
698 },
699 DictionaryDecodeError(DictionaryDecodeError),
700 FailedToReadBlockHeader(BlockHeaderReadError),
701 FailedToReadBlockBody(DecodeBlockContentError),
702 FailedToReadChecksum(Error),
703 NotYetInitialized,
704 FailedToInitialize(FrameHeaderError),
705 FailedToDrainDecodebuffer(Error),
706 FailedToSkipFrame,
707 TargetTooSmall,
708 FrameContentSizeMismatch {
716 declared: u64,
717 produced: u64,
718 },
719 ChecksumMismatch {
726 expected: u32,
727 calculated: u32,
728 },
729 DictNotProvided {
730 dict_id: u32,
731 },
732 DictIdMismatch {
733 expected: u32,
734 provided: u32,
735 },
736 DictAlreadyRegistered {
737 dict_id: u32,
738 },
739 #[cfg(feature = "lsm")]
752 UnexpectedDictId {
753 expected: Option<u32>,
754 found: Option<u32>,
755 },
756 #[cfg(feature = "lsm")]
763 UnexpectedWindowDescriptor {
764 expected: u8,
765 found: Option<u8>,
766 },
767 #[cfg(feature = "lsm")]
775 FailedToReadBlockHeaderAt {
776 source: BlockHeaderReadError,
777 block_index: u32,
778 frame_offset: u32,
779 },
780 #[cfg(feature = "lsm")]
788 FailedToReadBlockBodyAt {
789 source: DecodeBlockContentError,
790 block_index: u32,
791 frame_offset: u32,
792 block: crate::encoding::frame_emit_info::FrameBlock,
793 },
794 #[cfg(feature = "lsm")]
801 InvalidBlockRange {
802 start_block: u32,
803 end_block: u32,
804 },
805 #[cfg(feature = "lsm")]
815 ResumeWindowTooShort {
816 got: usize,
817 need: usize,
818 },
819 #[cfg(feature = "lsm")]
831 ResumeFrameMismatch,
832 #[cfg(feature = "lsm")]
846 ResumeUnidentifiedDictionary,
847}
848
849impl FrameDecoderError {
850 pub fn code(&self) -> ErrorCode {
853 match self {
854 FrameDecoderError::ReadFrameHeaderError(
855 ReadFrameHeaderError::InvalidFrameDescriptor(descriptor),
856 ) => descriptor.code(),
857 FrameDecoderError::ReadFrameHeaderError(_) => ErrorCode::PrefixUnknown,
858 FrameDecoderError::FrameHeaderError(FrameHeaderError::WindowTooBig { .. })
861 | FrameDecoderError::FailedToInitialize(FrameHeaderError::WindowTooBig { .. }) => {
862 ErrorCode::FrameParameterWindowTooLarge
863 }
864 FrameDecoderError::FrameHeaderError(_) | FrameDecoderError::FailedToInitialize(_) => {
865 ErrorCode::FrameParameterUnsupported
866 }
867 FrameDecoderError::WindowSizeTooBig { .. } => ErrorCode::FrameParameterWindowTooLarge,
868 FrameDecoderError::WindowCeilingOutOfRange { .. } => ErrorCode::ParameterOutOfBound,
869 FrameDecoderError::DictionaryDecodeError(_) => ErrorCode::DictionaryCorrupted,
870 FrameDecoderError::DictNotProvided { .. }
871 | FrameDecoderError::DictIdMismatch { .. }
872 | FrameDecoderError::DictAlreadyRegistered { .. } => ErrorCode::DictionaryWrong,
873 FrameDecoderError::TargetTooSmall => ErrorCode::DstSizeTooSmall,
874 FrameDecoderError::NotYetInitialized => ErrorCode::InitMissing,
875 FrameDecoderError::ChecksumMismatch { .. } => ErrorCode::ChecksumWrong,
876 _ => ErrorCode::CorruptionDetected,
877 }
878 }
879}
880
881#[cfg(feature = "std")]
882impl StdError for FrameDecoderError {
883 fn source(&self) -> Option<&(dyn StdError + 'static)> {
884 match self {
885 FrameDecoderError::ReadFrameHeaderError(source) => Some(source),
886 FrameDecoderError::FrameHeaderError(source) => Some(source),
887 FrameDecoderError::DictionaryDecodeError(source) => Some(source),
888 FrameDecoderError::FailedToReadBlockHeader(source) => Some(source),
889 FrameDecoderError::FailedToReadBlockBody(source) => Some(source),
890 #[cfg(feature = "lsm")]
891 FrameDecoderError::FailedToReadBlockHeaderAt { source, .. } => Some(source),
892 #[cfg(feature = "lsm")]
893 FrameDecoderError::FailedToReadBlockBodyAt { source, .. } => Some(source),
894 FrameDecoderError::FailedToReadChecksum(source) => Some(source),
895 FrameDecoderError::FailedToInitialize(source) => Some(source),
896 FrameDecoderError::FailedToDrainDecodebuffer(source) => Some(source),
897 _ => None,
898 }
899 }
900}
901
902impl core::fmt::Display for FrameDecoderError {
903 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> ::core::fmt::Result {
904 match self {
905 FrameDecoderError::ReadFrameHeaderError(e) => {
906 write!(f, "{e:?}")
907 }
908 FrameDecoderError::FrameHeaderError(e) => {
909 write!(f, "{e:?}")
910 }
911 FrameDecoderError::WindowSizeTooBig { requested, limit } => {
912 write!(
913 f,
914 "Specified window_size is too big; Requested: {requested}, Allowed: {limit}",
915 )
916 }
917 FrameDecoderError::WindowCeilingOutOfRange { requested } => {
918 write!(
919 f,
920 "window ceiling {requested} is outside {}..={}",
921 crate::common::MIN_WINDOW_SIZE,
922 crate::common::MAX_DECODER_WINDOW_SIZE,
923 )
924 }
925 FrameDecoderError::DictionaryDecodeError(e) => {
926 write!(f, "{e:?}")
927 }
928 FrameDecoderError::FailedToReadBlockHeader(e) => {
929 write!(f, "Failed to parse/decode block body: {e}")
930 }
931 FrameDecoderError::FailedToReadBlockBody(e) => {
932 write!(f, "Failed to parse block header: {e}")
933 }
934 #[cfg(feature = "lsm")]
935 FrameDecoderError::FailedToReadBlockHeaderAt {
936 source,
937 block_index,
938 frame_offset,
939 } => {
940 write!(
941 f,
942 "Failed to read block header at block {block_index} (frame offset {frame_offset}): {source}"
943 )
944 }
945 #[cfg(feature = "lsm")]
946 FrameDecoderError::FailedToReadBlockBodyAt {
947 source,
948 block_index,
949 frame_offset,
950 ..
951 } => {
952 write!(
953 f,
954 "Failed to decode block body at block {block_index} (frame offset {frame_offset}): {source}"
955 )
956 }
957 FrameDecoderError::FailedToReadChecksum(e) => {
958 write!(f, "Failed to read checksum: {e}")
959 }
960 FrameDecoderError::NotYetInitialized => {
961 write!(f, "Decoder must initialized or reset before using it",)
962 }
963 FrameDecoderError::FailedToInitialize(e) => {
964 write!(f, "Decoder encountered error while initializing: {e}")
965 }
966 FrameDecoderError::FailedToDrainDecodebuffer(e) => {
967 write!(
968 f,
969 "Decoder encountered error while draining the decodebuffer: {e}",
970 )
971 }
972 FrameDecoderError::FailedToSkipFrame => {
973 write!(
974 f,
975 "Failed to skip bytes for the length given in the frame header"
976 )
977 }
978 FrameDecoderError::TargetTooSmall => {
979 write!(
980 f,
981 "Target must have at least as many bytes as the content size reported by the frame"
982 )
983 }
984 FrameDecoderError::FrameContentSizeMismatch { declared, produced } => {
985 write!(
986 f,
987 "Frame content size mismatch (corrupt frame): declared {declared} bytes, blocks summed to {produced} bytes"
988 )
989 }
990 FrameDecoderError::ChecksumMismatch {
991 expected,
992 calculated,
993 } => {
994 write!(
995 f,
996 "Content checksum mismatch (corrupt frame): frame stored 0x{expected:08X}, decoder calculated 0x{calculated:08X}"
997 )
998 }
999 FrameDecoderError::DictNotProvided { dict_id } => {
1000 write!(
1001 f,
1002 "Frame header specified dictionary id 0x{dict_id:X} that wasn't provided via add_dict()/add_dict_from_bytes() (or add_dict_handle() on atomic targets) or reset_with_dict_handle()/decode_all_with_dict_handle()/decode_all_with_dict_bytes()"
1003 )
1004 }
1005 FrameDecoderError::DictIdMismatch { expected, provided } => {
1006 write!(
1007 f,
1008 "Frame header dictionary id 0x{expected:X} does not match provided dictionary id 0x{provided:X}"
1009 )
1010 }
1011 FrameDecoderError::DictAlreadyRegistered { dict_id } => {
1012 write!(
1013 f,
1014 "Dictionary id 0x{dict_id:X} already registered in decoder"
1015 )
1016 }
1017 #[cfg(feature = "lsm")]
1018 FrameDecoderError::UnexpectedDictId { expected, found } => {
1019 write!(f, "Frame header dict_id mismatch: expected ")?;
1020 match expected {
1021 Some(id) => write!(f, "0x{id:X}")?,
1022 None => write!(f, "<none>")?,
1023 }
1024 write!(f, ", found ")?;
1025 match found {
1026 Some(id) => write!(f, "0x{id:X}"),
1027 None => write!(f, "<none>"),
1028 }
1029 }
1030 #[cfg(feature = "lsm")]
1031 FrameDecoderError::UnexpectedWindowDescriptor { expected, found } => {
1032 write!(
1033 f,
1034 "Frame header window_descriptor mismatch: expected 0x{expected:02X}, found "
1035 )?;
1036 match found {
1037 Some(byte) => write!(f, "0x{byte:02X}"),
1038 None => write!(f, "<none> (single-segment frame omits window_descriptor)"),
1039 }
1040 }
1041 #[cfg(feature = "lsm")]
1042 FrameDecoderError::InvalidBlockRange {
1043 start_block,
1044 end_block,
1045 } => {
1046 write!(
1047 f,
1048 "Invalid block range for partial decode: start_block {start_block} > end_block {end_block}"
1049 )
1050 }
1051 #[cfg(feature = "lsm")]
1052 FrameDecoderError::ResumeWindowTooShort { got, need } => {
1053 write!(
1054 f,
1055 "resume window_prime too short: got {got} bytes, need at least {need}"
1056 )
1057 }
1058 #[cfg(feature = "lsm")]
1059 FrameDecoderError::ResumeFrameMismatch => {
1060 write!(
1061 f,
1062 "resume state was captured from a frame with a different decode shape than the current frame"
1063 )
1064 }
1065 #[cfg(feature = "lsm")]
1066 FrameDecoderError::ResumeUnidentifiedDictionary => {
1067 write!(
1068 f,
1069 "a dictionary with no ID cannot be told from another one, so it cannot carry a resume state across frames"
1070 )
1071 }
1072 }
1073 }
1074}
1075
1076impl From<DictionaryDecodeError> for FrameDecoderError {
1077 fn from(val: DictionaryDecodeError) -> Self {
1078 Self::DictionaryDecodeError(val)
1079 }
1080}
1081
1082impl From<BlockHeaderReadError> for FrameDecoderError {
1083 fn from(val: BlockHeaderReadError) -> Self {
1084 Self::FailedToReadBlockHeader(val)
1085 }
1086}
1087
1088impl From<FrameHeaderError> for FrameDecoderError {
1089 fn from(val: FrameHeaderError) -> Self {
1090 Self::FrameHeaderError(val)
1091 }
1092}
1093
1094impl From<ReadFrameHeaderError> for FrameDecoderError {
1095 fn from(val: ReadFrameHeaderError) -> Self {
1096 Self::ReadFrameHeaderError(val)
1097 }
1098}
1099
1100#[derive(Debug)]
1101#[non_exhaustive]
1102pub enum DecompressLiteralsError {
1103 MissingCompressedSize,
1104 MissingNumStreams,
1105 GetBitsError(GetBitsError),
1106 HuffmanTableError(HuffmanTableError),
1107 HuffmanDecoderError(HuffmanDecoderError),
1108 UninitializedHuffmanTable,
1109 MissingBytesForJumpHeader { got: usize },
1110 MissingBytesForLiterals { got: usize, needed: usize },
1111 ExtraPadding { skipped_bits: i32 },
1112 BitstreamReadMismatch { read_til: isize, expected: isize },
1113 DecodedLiteralCountMismatch { decoded: usize, expected: usize },
1114}
1115
1116#[cfg(feature = "std")]
1117impl std::error::Error for DecompressLiteralsError {
1118 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1119 match self {
1120 DecompressLiteralsError::GetBitsError(source) => Some(source),
1121 DecompressLiteralsError::HuffmanTableError(source) => Some(source),
1122 DecompressLiteralsError::HuffmanDecoderError(source) => Some(source),
1123 _ => None,
1124 }
1125 }
1126}
1127impl core::fmt::Display for DecompressLiteralsError {
1128 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1129 match self {
1130 DecompressLiteralsError::MissingCompressedSize => {
1131 write!(
1132 f,
1133 "compressed size was none even though it must be set to something for compressed literals",
1134 )
1135 }
1136 DecompressLiteralsError::MissingNumStreams => {
1137 write!(
1138 f,
1139 "num_streams was none even though it must be set to something (1 or 4) for compressed literals",
1140 )
1141 }
1142 DecompressLiteralsError::GetBitsError(e) => write!(f, "{e:?}"),
1143 DecompressLiteralsError::HuffmanTableError(e) => write!(f, "{e:?}"),
1144 DecompressLiteralsError::HuffmanDecoderError(e) => write!(f, "{e:?}"),
1145 DecompressLiteralsError::UninitializedHuffmanTable => {
1146 write!(
1147 f,
1148 "Tried to reuse huffman table but it was never initialized",
1149 )
1150 }
1151 DecompressLiteralsError::MissingBytesForJumpHeader { got } => {
1152 write!(f, "Need 6 bytes to decode jump header, got {got} bytes",)
1153 }
1154 DecompressLiteralsError::MissingBytesForLiterals { got, needed } => {
1155 write!(
1156 f,
1157 "Need at least {needed} bytes to decode literals. Have: {got} bytes",
1158 )
1159 }
1160 DecompressLiteralsError::ExtraPadding { skipped_bits } => {
1161 write!(
1162 f,
1163 "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
1164 )
1165 }
1166 DecompressLiteralsError::BitstreamReadMismatch { read_til, expected } => {
1167 write!(
1168 f,
1169 "Bitstream was read till: {read_til}, should have been: {expected}",
1170 )
1171 }
1172 DecompressLiteralsError::DecodedLiteralCountMismatch { decoded, expected } => {
1173 write!(
1174 f,
1175 "Did not decode enough literals: {decoded}, Should have been: {expected}",
1176 )
1177 }
1178 }
1179 }
1180}
1181
1182impl From<HuffmanDecoderError> for DecompressLiteralsError {
1183 fn from(val: HuffmanDecoderError) -> Self {
1184 Self::HuffmanDecoderError(val)
1185 }
1186}
1187
1188impl From<GetBitsError> for DecompressLiteralsError {
1189 fn from(val: GetBitsError) -> Self {
1190 Self::GetBitsError(val)
1191 }
1192}
1193
1194impl From<HuffmanTableError> for DecompressLiteralsError {
1195 fn from(val: HuffmanTableError) -> Self {
1196 Self::HuffmanTableError(val)
1197 }
1198}
1199
1200#[derive(Debug)]
1201#[non_exhaustive]
1202pub enum ExecuteSequencesError {
1203 DecodebufferError(DecodeBufferError),
1204 NotEnoughBytesForSequence {
1205 wanted: usize,
1206 have: usize,
1207 },
1208 ZeroOffset,
1209 OutputBufferOverflow {
1219 tail: usize,
1220 requested: usize,
1221 capacity: usize,
1222 },
1223}
1224
1225impl core::fmt::Display for ExecuteSequencesError {
1226 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1227 match self {
1228 ExecuteSequencesError::DecodebufferError(e) => {
1229 write!(f, "{e:?}")
1230 }
1231 ExecuteSequencesError::NotEnoughBytesForSequence { wanted, have } => {
1232 write!(
1233 f,
1234 "Sequence wants to copy up to byte {wanted}. Bytes in literalsbuffer: {have}"
1235 )
1236 }
1237 ExecuteSequencesError::ZeroOffset => {
1238 write!(f, "Illegal offset: 0 found")
1239 }
1240 ExecuteSequencesError::OutputBufferOverflow {
1241 tail,
1242 requested,
1243 capacity,
1244 } => {
1245 write!(
1246 f,
1247 "Inline sequence would write past the output buffer: tail={tail}, requested={requested}, capacity={capacity}"
1248 )
1249 }
1250 }
1251 }
1252}
1253
1254#[cfg(feature = "std")]
1255impl std::error::Error for ExecuteSequencesError {
1256 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1257 match self {
1258 ExecuteSequencesError::DecodebufferError(source) => Some(source),
1259 _ => None,
1260 }
1261 }
1262}
1263
1264impl From<DecodeBufferError> for ExecuteSequencesError {
1265 fn from(val: DecodeBufferError) -> Self {
1266 Self::DecodebufferError(val)
1267 }
1268}
1269
1270impl From<crate::decoding::buffer_backend::BackendOverflow> for ExecuteSequencesError {
1271 fn from(val: crate::decoding::buffer_backend::BackendOverflow) -> Self {
1272 Self::OutputBufferOverflow {
1273 tail: val.tail,
1274 requested: val.requested,
1275 capacity: val.capacity,
1276 }
1277 }
1278}
1279
1280impl ExecuteSequencesError {
1281 pub(crate) fn output_overflow_requested(&self) -> Option<usize> {
1295 match self {
1296 ExecuteSequencesError::OutputBufferOverflow { requested, .. } => Some(*requested),
1297 ExecuteSequencesError::DecodebufferError(DecodeBufferError::OutputBufferOverflow {
1298 requested,
1299 ..
1300 }) => Some(*requested),
1301 _ => None,
1302 }
1303 }
1304}
1305
1306#[derive(Debug)]
1307#[non_exhaustive]
1308pub enum DecodeSequenceError {
1309 GetBitsError(GetBitsError),
1310 FSEDecoderError(FSEDecoderError),
1311 FSETableError(FSETableError),
1312 ExtraPadding {
1313 skipped_bits: i32,
1314 },
1315 UnsupportedOffset {
1316 offset_code: u8,
1317 },
1318 ZeroOffset,
1319 NotEnoughBytesForNumSequences,
1320 ExtraBits {
1321 bits_remaining: isize,
1322 },
1323 MissingCompressionMode,
1324 MissingByteForRleLlTable,
1325 MissingByteForRleOfTable,
1326 MissingByteForRleMlTable,
1327 InvalidRleCode {
1331 axis: &'static str,
1332 code: u8,
1333 },
1334}
1335
1336#[cfg(feature = "std")]
1337impl std::error::Error for DecodeSequenceError {
1338 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1339 match self {
1340 DecodeSequenceError::GetBitsError(source) => Some(source),
1341 DecodeSequenceError::FSEDecoderError(source) => Some(source),
1342 DecodeSequenceError::FSETableError(source) => Some(source),
1343 _ => None,
1344 }
1345 }
1346}
1347
1348impl core::fmt::Display for DecodeSequenceError {
1349 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1350 match self {
1351 DecodeSequenceError::GetBitsError(e) => write!(f, "{e:?}"),
1352 DecodeSequenceError::FSEDecoderError(e) => write!(f, "{e:?}"),
1353 DecodeSequenceError::FSETableError(e) => write!(f, "{e:?}"),
1354 DecodeSequenceError::ExtraPadding { skipped_bits } => {
1355 write!(
1356 f,
1357 "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
1358 )
1359 }
1360 DecodeSequenceError::UnsupportedOffset { offset_code } => {
1361 write!(
1362 f,
1363 "Do not support offsets bigger than 1<<32; got: {offset_code}",
1364 )
1365 }
1366 DecodeSequenceError::ZeroOffset => write!(
1367 f,
1368 "Read an offset == 0. That is an illegal value for offsets"
1369 ),
1370 DecodeSequenceError::NotEnoughBytesForNumSequences => write!(
1371 f,
1372 "Bytestream did not contain enough bytes to decode num_sequences"
1373 ),
1374 DecodeSequenceError::ExtraBits { bits_remaining } => write!(f, "{bits_remaining}"),
1375 DecodeSequenceError::MissingCompressionMode => write!(
1376 f,
1377 "compression modes are none but they must be set to something"
1378 ),
1379 DecodeSequenceError::MissingByteForRleLlTable => {
1380 write!(f, "Need a byte to read for RLE ll table")
1381 }
1382 DecodeSequenceError::MissingByteForRleOfTable => {
1383 write!(f, "Need a byte to read for RLE of table")
1384 }
1385 DecodeSequenceError::MissingByteForRleMlTable => {
1386 write!(f, "Need a byte to read for RLE ml table")
1387 }
1388 DecodeSequenceError::InvalidRleCode { axis, code } => {
1389 write!(f, "RLE {axis} table code {code} is out of range")
1390 }
1391 }
1392 }
1393}
1394
1395impl From<GetBitsError> for DecodeSequenceError {
1396 fn from(val: GetBitsError) -> Self {
1397 Self::GetBitsError(val)
1398 }
1399}
1400
1401impl From<FSETableError> for DecodeSequenceError {
1402 fn from(val: FSETableError) -> Self {
1403 Self::FSETableError(val)
1404 }
1405}
1406
1407impl From<FSEDecoderError> for DecodeSequenceError {
1408 fn from(val: FSEDecoderError) -> Self {
1409 Self::FSEDecoderError(val)
1410 }
1411}
1412
1413#[derive(Debug)]
1414#[non_exhaustive]
1415pub enum LiteralsSectionParseError {
1416 IllegalLiteralSectionType { got: u8 },
1417 GetBitsError(GetBitsError),
1418 NotEnoughBytes { have: usize, need: u8 },
1419}
1420
1421#[cfg(feature = "std")]
1422impl std::error::Error for LiteralsSectionParseError {
1423 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1424 match self {
1425 LiteralsSectionParseError::GetBitsError(source) => Some(source),
1426 _ => None,
1427 }
1428 }
1429}
1430impl core::fmt::Display for LiteralsSectionParseError {
1431 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1432 match self {
1433 LiteralsSectionParseError::IllegalLiteralSectionType { got } => {
1434 write!(
1435 f,
1436 "Illegal literalssectiontype. Is: {got}, must be in: 0, 1, 2, 3"
1437 )
1438 }
1439 LiteralsSectionParseError::GetBitsError(e) => write!(f, "{e:?}"),
1440 LiteralsSectionParseError::NotEnoughBytes { have, need } => {
1441 write!(
1442 f,
1443 "Not enough byte to parse the literals section header. Have: {have}, Need: {need}",
1444 )
1445 }
1446 }
1447 }
1448}
1449
1450impl From<GetBitsError> for LiteralsSectionParseError {
1451 fn from(val: GetBitsError) -> Self {
1452 Self::GetBitsError(val)
1453 }
1454}
1455
1456impl core::fmt::Display for LiteralsSectionType {
1457 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
1458 match self {
1459 LiteralsSectionType::Compressed => write!(f, "Compressed"),
1460 LiteralsSectionType::Raw => write!(f, "Raw"),
1461 LiteralsSectionType::RLE => write!(f, "RLE"),
1462 LiteralsSectionType::Treeless => write!(f, "Treeless"),
1463 }
1464 }
1465}
1466
1467#[derive(Debug)]
1468#[non_exhaustive]
1469pub enum SequencesHeaderParseError {
1470 NotEnoughBytes { need_at_least: u8, got: usize },
1471}
1472
1473#[cfg(feature = "std")]
1474impl std::error::Error for SequencesHeaderParseError {}
1475
1476impl core::fmt::Display for SequencesHeaderParseError {
1477 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1478 match self {
1479 SequencesHeaderParseError::NotEnoughBytes { need_at_least, got } => {
1480 write!(
1481 f,
1482 "source must have at least {need_at_least} bytes to parse header; got {got} bytes",
1483 )
1484 }
1485 }
1486 }
1487}
1488
1489#[derive(Debug)]
1490#[non_exhaustive]
1491pub enum FSETableError {
1492 AccLogIsZero,
1493 AccLogTooBig {
1494 got: u8,
1495 max: u8,
1496 },
1497 GetBitsError(GetBitsError),
1498 ProbabilityCounterMismatch {
1499 got: u32,
1500 expected_sum: u32,
1501 symbol_probabilities: Vec<i32>,
1502 },
1503 TooManySymbols {
1504 got: usize,
1505 },
1506 InvalidProbability {
1511 value: i32,
1512 table_size: u32,
1513 accuracy_log: u8,
1514 },
1515 TableInvariantViolation {
1523 prob: i32,
1524 symbol: u8,
1525 num_bits: u8,
1526 accuracy_log: u8,
1527 },
1528}
1529
1530#[cfg(feature = "std")]
1531impl std::error::Error for FSETableError {
1532 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1533 match self {
1534 FSETableError::GetBitsError(source) => Some(source),
1535 _ => None,
1536 }
1537 }
1538}
1539
1540impl core::fmt::Display for FSETableError {
1541 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1542 match self {
1543 FSETableError::AccLogIsZero => write!(f, "Acclog must be at least 1"),
1544 FSETableError::AccLogTooBig { got, max } => {
1545 write!(
1546 f,
1547 "Found FSE acc_log: {got} bigger than allowed maximum in this case: {max}"
1548 )
1549 }
1550 FSETableError::GetBitsError(e) => write!(f, "{e:?}"),
1551 FSETableError::ProbabilityCounterMismatch {
1552 got,
1553 expected_sum,
1554 symbol_probabilities,
1555 } => {
1556 write!(
1557 f,
1558 "FSE probability sum mismatch: got {got}, expected {expected_sum}. Indicates corrupted data or an invalid distribution\n {symbol_probabilities:?}",
1559 )
1560 }
1561 FSETableError::TooManySymbols { got } => {
1562 write!(
1563 f,
1564 "There are too many symbols in this distribution: {got}. Max: 256",
1565 )
1566 }
1567 FSETableError::InvalidProbability {
1568 value,
1569 table_size,
1570 accuracy_log,
1571 } => {
1572 write!(
1573 f,
1574 "FSE probability value {value} is outside the RFC 8878 allowed set (must be -1, 0, or in 1..={table_size}; accuracy_log={accuracy_log})",
1575 )
1576 }
1577 FSETableError::TableInvariantViolation {
1578 prob,
1579 symbol,
1580 num_bits,
1581 accuracy_log,
1582 } => {
1583 write!(
1584 f,
1585 "FSE table invariant violation: symbol {symbol} (prob {prob}) produced num_bits {num_bits} > accuracy_log {accuracy_log}",
1586 )
1587 }
1588 }
1589 }
1590}
1591
1592impl From<GetBitsError> for FSETableError {
1593 fn from(val: GetBitsError) -> Self {
1594 Self::GetBitsError(val)
1595 }
1596}
1597
1598#[derive(Debug)]
1599#[non_exhaustive]
1600pub enum FSEDecoderError {
1601 GetBitsError(GetBitsError),
1602 TableIsUninitialized,
1603 InvalidTableShape {
1609 decode_len: usize,
1610 accuracy_log: u8,
1611 },
1612}
1613
1614#[cfg(feature = "std")]
1615impl std::error::Error for FSEDecoderError {
1616 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1617 match self {
1618 FSEDecoderError::GetBitsError(source) => Some(source),
1619 _ => None,
1620 }
1621 }
1622}
1623
1624impl core::fmt::Display for FSEDecoderError {
1625 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1626 match self {
1627 FSEDecoderError::GetBitsError(e) => write!(f, "{e:?}"),
1628 FSEDecoderError::TableIsUninitialized => {
1629 write!(f, "Tried to use an uninitialized table!")
1630 }
1631 FSEDecoderError::InvalidTableShape {
1632 decode_len,
1633 accuracy_log,
1634 } => match 1usize.checked_shl((*accuracy_log).into()) {
1635 Some(expected) => write!(
1636 f,
1637 "FSETable shape invariant violated: decode.len() = {decode_len}, expected 1 << accuracy_log = {expected} (accuracy_log = {accuracy_log})",
1638 ),
1639 None => write!(
1640 f,
1641 "FSETable shape invariant violated: decode.len() = {decode_len}, accuracy_log = {accuracy_log} overflows 1 << accuracy_log for usize",
1642 ),
1643 },
1644 }
1645 }
1646}
1647
1648impl From<GetBitsError> for FSEDecoderError {
1649 fn from(val: GetBitsError) -> Self {
1650 Self::GetBitsError(val)
1651 }
1652}
1653
1654#[derive(Debug)]
1655#[non_exhaustive]
1656pub enum HuffmanTableError {
1657 GetBitsError(GetBitsError),
1658 FSEDecoderError(FSEDecoderError),
1659 FSETableError(FSETableError),
1660 SourceIsEmpty,
1661 NotEnoughBytesForWeights {
1662 got_bytes: usize,
1663 expected_bytes: u8,
1664 },
1665 ExtraPadding {
1666 skipped_bits: i32,
1667 },
1668 TooManyWeights {
1669 got: usize,
1670 },
1671 MissingWeights,
1672 LeftoverIsNotAPowerOf2 {
1673 got: u32,
1674 },
1675 NotEnoughBytesToDecompressWeights {
1676 have: usize,
1677 need: usize,
1678 },
1679 FSETableUsedTooManyBytes {
1680 used: usize,
1681 available_bytes: u8,
1682 },
1683 NotEnoughBytesInSource {
1684 got: usize,
1685 need: usize,
1686 },
1687 WeightBiggerThanMaxNumBits {
1688 got: u8,
1689 },
1690 MaxBitsTooHigh {
1691 got: u8,
1692 },
1693}
1694
1695#[cfg(feature = "std")]
1696impl StdError for HuffmanTableError {
1697 fn source(&self) -> Option<&(dyn StdError + 'static)> {
1698 match self {
1699 HuffmanTableError::GetBitsError(source) => Some(source),
1700 HuffmanTableError::FSEDecoderError(source) => Some(source),
1701 HuffmanTableError::FSETableError(source) => Some(source),
1702 _ => None,
1703 }
1704 }
1705}
1706
1707impl core::fmt::Display for HuffmanTableError {
1708 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1709 match self {
1710 HuffmanTableError::GetBitsError(e) => write!(f, "{e:?}"),
1711 HuffmanTableError::FSEDecoderError(e) => write!(f, "{e:?}"),
1712 HuffmanTableError::FSETableError(e) => write!(f, "{e:?}"),
1713 HuffmanTableError::SourceIsEmpty => write!(f, "Source needs to have at least one byte"),
1714 HuffmanTableError::NotEnoughBytesForWeights {
1715 got_bytes,
1716 expected_bytes,
1717 } => {
1718 write!(
1719 f,
1720 "Header says there should be {expected_bytes} bytes for the weights but there are only {got_bytes} bytes in the stream"
1721 )
1722 }
1723 HuffmanTableError::ExtraPadding { skipped_bits } => {
1724 write!(
1725 f,
1726 "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
1727 )
1728 }
1729 HuffmanTableError::TooManyWeights { got } => {
1730 write!(
1731 f,
1732 "More than 255 weights decoded (got {got} weights). Stream is probably corrupted",
1733 )
1734 }
1735 HuffmanTableError::MissingWeights => {
1736 write!(f, "Can\'t build huffman table without any weights")
1737 }
1738 HuffmanTableError::LeftoverIsNotAPowerOf2 { got } => {
1739 write!(f, "Leftover must be power of two but is: {got}")
1740 }
1741 HuffmanTableError::NotEnoughBytesToDecompressWeights { have, need } => {
1742 write!(
1743 f,
1744 "Not enough bytes in stream to decompress weights. Is: {have}, Should be: {need}",
1745 )
1746 }
1747 HuffmanTableError::FSETableUsedTooManyBytes {
1748 used,
1749 available_bytes,
1750 } => {
1751 write!(
1752 f,
1753 "FSE table used more bytes: {used} than were meant to be used for the whole stream of huffman weights ({available_bytes})",
1754 )
1755 }
1756 HuffmanTableError::NotEnoughBytesInSource { got, need } => {
1757 write!(f, "Source needs to have at least {need} bytes, got: {got}",)
1758 }
1759 HuffmanTableError::WeightBiggerThanMaxNumBits { got } => {
1760 write!(
1761 f,
1762 "Cant have weight: {} bigger than max_num_bits: {}",
1763 got,
1764 crate::huff0::MAX_MAX_NUM_BITS,
1765 )
1766 }
1767 HuffmanTableError::MaxBitsTooHigh { got } => {
1768 write!(
1769 f,
1770 "max_bits derived from weights is: {} should be lower than: {}",
1771 got,
1772 crate::huff0::MAX_MAX_NUM_BITS,
1773 )
1774 }
1775 }
1776 }
1777}
1778
1779impl From<GetBitsError> for HuffmanTableError {
1780 fn from(val: GetBitsError) -> Self {
1781 Self::GetBitsError(val)
1782 }
1783}
1784
1785impl From<FSEDecoderError> for HuffmanTableError {
1786 fn from(val: FSEDecoderError) -> Self {
1787 Self::FSEDecoderError(val)
1788 }
1789}
1790
1791impl From<FSETableError> for HuffmanTableError {
1792 fn from(val: FSETableError) -> Self {
1793 Self::FSETableError(val)
1794 }
1795}
1796
1797#[derive(Debug)]
1798#[non_exhaustive]
1799pub enum HuffmanDecoderError {
1800 GetBitsError(GetBitsError),
1801}
1802
1803impl core::fmt::Display for HuffmanDecoderError {
1804 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1805 match self {
1806 HuffmanDecoderError::GetBitsError(e) => write!(f, "{e:?}"),
1807 }
1808 }
1809}
1810
1811#[cfg(feature = "std")]
1812impl StdError for HuffmanDecoderError {
1813 fn source(&self) -> Option<&(dyn StdError + 'static)> {
1814 match self {
1815 HuffmanDecoderError::GetBitsError(source) => Some(source),
1816 }
1817 }
1818}
1819
1820impl From<GetBitsError> for HuffmanDecoderError {
1821 fn from(val: GetBitsError) -> Self {
1822 Self::GetBitsError(val)
1823 }
1824}
1825
1826#[cfg(test)]
1827mod tests;