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