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#[cfg(feature = "legacy")]
43#[cfg_attr(docsrs, doc(cfg(feature = "legacy")))]
44#[derive(Debug, Clone, Copy, PartialEq, Eq)]
45#[non_exhaustive]
46pub enum LegacyFrameError {
47 Truncated,
49 UnsupportedParameter,
52 Corrupted {
54 reason: &'static str,
56 },
57 OutputTooSmall,
59 DictionaryCorrupted,
61 DictionaryMismatch {
63 expected: u32,
65 provided: u32,
67 },
68 ChecksumMismatch {
70 expected: u32,
72 calculated: u32,
74 },
75}
76
77#[cfg(feature = "legacy")]
78impl LegacyFrameError {
79 pub fn code(&self) -> ErrorCode {
81 match self {
82 LegacyFrameError::UnsupportedParameter => ErrorCode::FrameParameterUnsupported,
83 LegacyFrameError::OutputTooSmall => ErrorCode::DstSizeTooSmall,
84 LegacyFrameError::DictionaryCorrupted => ErrorCode::DictionaryCorrupted,
85 LegacyFrameError::DictionaryMismatch { .. } => ErrorCode::DictionaryWrong,
86 LegacyFrameError::ChecksumMismatch { .. } => ErrorCode::ChecksumWrong,
87 LegacyFrameError::Truncated => ErrorCode::SrcSizeWrong,
90 LegacyFrameError::Corrupted { .. } => ErrorCode::CorruptionDetected,
91 }
92 }
93}
94
95#[cfg(feature = "legacy")]
96impl fmt::Display for LegacyFrameError {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 match self {
99 Self::Truncated => write!(f, "the input ends inside a v0.5-v0.7 frame"),
100 Self::UnsupportedParameter => {
101 write!(
102 f,
103 "the v0.5-v0.7 frame header asks for an unsupported setting"
104 )
105 }
106 Self::Corrupted { reason } => write!(f, "corrupt v0.5-v0.7 frame: {reason}"),
107 Self::OutputTooSmall => write!(f, "the output buffer is too small for the frame"),
108 Self::DictionaryCorrupted => write!(f, "the dictionary could not be read"),
109 Self::DictionaryMismatch { expected, provided } => write!(
110 f,
111 "the frame needs dictionary 0x{expected:X}, the one supplied is 0x{provided:X}"
112 ),
113 Self::ChecksumMismatch {
114 expected,
115 calculated,
116 } => write!(
117 f,
118 "content checksum mismatch: frame stored 0x{expected:06X}, decoder calculated 0x{calculated:06X}"
119 ),
120 }
121 }
122}
123
124#[cfg(all(feature = "legacy", feature = "std"))]
125impl StdError for LegacyFrameError {}
126
127#[derive(Debug)]
128#[non_exhaustive]
129pub enum FrameHeaderError {
130 WindowTooBig { got: u64 },
131 WindowTooSmall { got: u64 },
132 FrameDescriptorError(FrameDescriptorError),
133 DictIdTooSmall { got: usize, expected: usize },
134 MismatchedFrameSize { got: usize, expected: u8 },
135 FrameSizeIsZero,
136 InvalidFrameSize { got: u8 },
137}
138
139impl fmt::Display for FrameHeaderError {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 match self {
142 Self::WindowTooBig { got } => write!(
143 f,
144 "window_size bigger than allowed maximum. Is: {}, Should be lower than: {}",
145 got,
146 crate::common::MAX_WINDOW_SIZE
147 ),
148 Self::WindowTooSmall { got } => write!(
149 f,
150 "window_size smaller than allowed minimum. Is: {}, Should be greater than: {}",
151 got,
152 crate::common::MIN_WINDOW_SIZE
153 ),
154 Self::FrameDescriptorError(e) => write!(f, "{e:?}"),
155 Self::DictIdTooSmall { got, expected } => write!(
156 f,
157 "Not enough bytes in dict_id. Is: {got}, Should be: {expected}"
158 ),
159 Self::MismatchedFrameSize { got, expected } => write!(
160 f,
161 "frame_content_size does not have the right length. Is: {got}, Should be: {expected}"
162 ),
163 Self::FrameSizeIsZero => write!(f, "frame_content_size was zero"),
164 Self::InvalidFrameSize { got } => write!(
165 f,
166 "Invalid frame_content_size. Is: {got}, Should be one of 1, 2, 4, 8 bytes"
167 ),
168 }
169 }
170}
171
172#[cfg(feature = "std")]
173impl StdError for FrameHeaderError {
174 fn source(&self) -> Option<&(dyn StdError + 'static)> {
175 match self {
176 FrameHeaderError::FrameDescriptorError(source) => Some(source),
177 _ => None,
178 }
179 }
180}
181
182impl From<FrameDescriptorError> for FrameHeaderError {
183 fn from(error: FrameDescriptorError) -> Self {
184 Self::FrameDescriptorError(error)
185 }
186}
187
188#[derive(Debug)]
189#[non_exhaustive]
190pub enum ReadFrameHeaderError {
191 MagicNumberReadError(Error),
192 BadMagicNumber(u32),
193 FrameDescriptorReadError(Error),
194 InvalidFrameDescriptor(FrameDescriptorError),
195 WindowDescriptorReadError(Error),
196 DictionaryIdReadError(Error),
197 FrameContentSizeReadError(Error),
198 SkipFrame { magic_number: u32, length: u32 },
199}
200
201impl fmt::Display for ReadFrameHeaderError {
202 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203 match self {
204 Self::MagicNumberReadError(e) => write!(f, "Error while reading magic number: {e}"),
205 Self::BadMagicNumber(e) => write!(f, "Read wrong magic number: 0x{e:X}"),
206 Self::FrameDescriptorReadError(e) => {
207 write!(f, "Error while reading frame descriptor: {e}")
208 }
209 Self::InvalidFrameDescriptor(e) => write!(f, "{e:?}"),
210 Self::WindowDescriptorReadError(e) => {
211 write!(f, "Error while reading window descriptor: {e}")
212 }
213 Self::DictionaryIdReadError(e) => write!(f, "Error while reading dictionary id: {e}"),
214 Self::FrameContentSizeReadError(e) => {
215 write!(f, "Error while reading frame content size: {e}")
216 }
217 Self::SkipFrame {
218 magic_number,
219 length,
220 } => write!(
221 f,
222 "SkippableFrame encountered with MagicNumber 0x{magic_number:X} and length {length} bytes"
223 ),
224 }
225 }
226}
227
228#[cfg(feature = "std")]
229impl StdError for ReadFrameHeaderError {
230 fn source(&self) -> Option<&(dyn StdError + 'static)> {
231 match self {
232 ReadFrameHeaderError::MagicNumberReadError(source) => Some(source),
233 ReadFrameHeaderError::FrameDescriptorReadError(source) => Some(source),
234 ReadFrameHeaderError::InvalidFrameDescriptor(source) => Some(source),
235 ReadFrameHeaderError::WindowDescriptorReadError(source) => Some(source),
236 ReadFrameHeaderError::DictionaryIdReadError(source) => Some(source),
237 ReadFrameHeaderError::FrameContentSizeReadError(source) => Some(source),
238 _ => None,
239 }
240 }
241}
242
243impl From<FrameDescriptorError> for ReadFrameHeaderError {
244 fn from(error: FrameDescriptorError) -> Self {
245 Self::InvalidFrameDescriptor(error)
246 }
247}
248
249#[derive(Debug)]
250#[non_exhaustive]
251pub enum BlockHeaderReadError {
252 ReadError(Error),
253 FoundReservedBlock,
254 BlockTypeError(BlockTypeError),
255 BlockSizeError(BlockSizeError),
256}
257
258#[cfg(feature = "std")]
259impl std::error::Error for BlockHeaderReadError {
260 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
261 match self {
262 BlockHeaderReadError::ReadError(source) => Some(source),
263 BlockHeaderReadError::BlockTypeError(source) => Some(source),
264 BlockHeaderReadError::BlockSizeError(source) => Some(source),
265 BlockHeaderReadError::FoundReservedBlock => None,
266 }
267 }
268}
269
270impl ::core::fmt::Display for BlockHeaderReadError {
271 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> ::core::fmt::Result {
272 match self {
273 BlockHeaderReadError::ReadError(_) => write!(f, "Error while reading the block header"),
274 BlockHeaderReadError::FoundReservedBlock => write!(
275 f,
276 "Reserved block occured. This is considered corruption by the documentation"
277 ),
278 BlockHeaderReadError::BlockTypeError(e) => write!(f, "Error getting block type: {e}"),
279 BlockHeaderReadError::BlockSizeError(e) => {
280 write!(f, "Error getting block content size: {e}")
281 }
282 }
283 }
284}
285
286impl From<Error> for BlockHeaderReadError {
287 fn from(val: Error) -> Self {
288 Self::ReadError(val)
289 }
290}
291
292impl From<BlockTypeError> for BlockHeaderReadError {
293 fn from(val: BlockTypeError) -> Self {
294 Self::BlockTypeError(val)
295 }
296}
297
298impl From<BlockSizeError> for BlockHeaderReadError {
299 fn from(val: BlockSizeError) -> Self {
300 Self::BlockSizeError(val)
301 }
302}
303
304#[derive(Debug)]
305#[non_exhaustive]
306pub enum BlockTypeError {
307 InvalidBlocktypeNumber { num: u8 },
308}
309
310#[cfg(feature = "std")]
311impl std::error::Error for BlockTypeError {}
312
313impl core::fmt::Display for BlockTypeError {
314 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
315 match self {
316 BlockTypeError::InvalidBlocktypeNumber { num } => {
317 write!(
318 f,
319 "Invalid Blocktype number. Is: {num}. Should be one of: 0, 1, 2, 3 (3 is reserved).",
320 )
321 }
322 }
323 }
324}
325
326#[derive(Debug)]
327#[non_exhaustive]
328pub enum BlockSizeError {
329 BlockSizeTooLarge { size: u32 },
330}
331
332#[cfg(feature = "std")]
333impl std::error::Error for BlockSizeError {}
334
335impl core::fmt::Display for BlockSizeError {
336 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
337 match self {
338 BlockSizeError::BlockSizeTooLarge { size } => {
339 write!(
340 f,
341 "Blocksize was bigger than the absolute maximum {} (128kb). Is: {}",
342 crate::common::MAX_BLOCK_SIZE,
343 size,
344 )
345 }
346 }
347 }
348}
349
350#[derive(Debug)]
351#[non_exhaustive]
352pub enum DecompressBlockError {
353 BlockContentReadError(Error),
354 MalformedSectionHeader {
355 expected_len: usize,
356 remaining_bytes: usize,
357 },
358 DecompressLiteralsError(DecompressLiteralsError),
359 LiteralsSectionParseError(LiteralsSectionParseError),
360 SequencesHeaderParseError(SequencesHeaderParseError),
361 DecodeSequenceError(DecodeSequenceError),
362 ExecuteSequencesError(ExecuteSequencesError),
363 ExpandsPastBlockMaximum {
368 size: usize,
369 maximum: usize,
370 },
371 ContentPastBlockMaximum {
375 size: usize,
376 maximum: usize,
377 },
378 LiteralsOutputOverflow {
385 tail: usize,
386 requested: usize,
387 capacity: usize,
388 },
389}
390
391#[cfg(feature = "std")]
392impl std::error::Error for DecompressBlockError {
393 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
394 match self {
395 DecompressBlockError::BlockContentReadError(source) => Some(source),
396 DecompressBlockError::DecompressLiteralsError(source) => Some(source),
397 DecompressBlockError::LiteralsSectionParseError(source) => Some(source),
398 DecompressBlockError::SequencesHeaderParseError(source) => Some(source),
399 DecompressBlockError::DecodeSequenceError(source) => Some(source),
400 DecompressBlockError::ExecuteSequencesError(source) => Some(source),
401 _ => None,
402 }
403 }
404}
405
406impl core::fmt::Display for DecompressBlockError {
407 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
408 match self {
409 DecompressBlockError::BlockContentReadError(e) => {
410 write!(f, "Error while reading the block content: {e}")
411 }
412 DecompressBlockError::MalformedSectionHeader {
413 expected_len,
414 remaining_bytes,
415 } => {
416 write!(
417 f,
418 "Malformed section header. Says literals would be this long: {expected_len} but there are only {remaining_bytes} bytes left",
419 )
420 }
421 DecompressBlockError::DecompressLiteralsError(e) => write!(f, "{e:?}"),
422 DecompressBlockError::LiteralsSectionParseError(e) => write!(f, "{e:?}"),
423 DecompressBlockError::SequencesHeaderParseError(e) => write!(f, "{e:?}"),
424 DecompressBlockError::DecodeSequenceError(e) => write!(f, "{e:?}"),
425 DecompressBlockError::ExecuteSequencesError(e) => write!(f, "{e:?}"),
426 DecompressBlockError::ExpandsPastBlockMaximum { size, maximum } => write!(
427 f,
428 "Block expands to {size} bytes, past this frame's maximum of {maximum}"
429 ),
430 DecompressBlockError::ContentPastBlockMaximum { size, maximum } => write!(
431 f,
432 "Compressed block of {size} bytes, past this frame's maximum of {maximum}"
433 ),
434 DecompressBlockError::LiteralsOutputOverflow {
435 tail,
436 requested,
437 capacity,
438 } => write!(
439 f,
440 "Literals would write past the output buffer: tail={tail}, requested={requested}, capacity={capacity}"
441 ),
442 }
443 }
444}
445
446impl From<Error> for DecompressBlockError {
447 fn from(val: Error) -> Self {
448 Self::BlockContentReadError(val)
449 }
450}
451
452impl From<DecompressLiteralsError> for DecompressBlockError {
453 fn from(val: DecompressLiteralsError) -> Self {
454 Self::DecompressLiteralsError(val)
455 }
456}
457
458impl From<LiteralsSectionParseError> for DecompressBlockError {
459 fn from(val: LiteralsSectionParseError) -> Self {
460 Self::LiteralsSectionParseError(val)
461 }
462}
463
464impl From<SequencesHeaderParseError> for DecompressBlockError {
465 fn from(val: SequencesHeaderParseError) -> Self {
466 Self::SequencesHeaderParseError(val)
467 }
468}
469
470impl From<DecodeSequenceError> for DecompressBlockError {
471 fn from(val: DecodeSequenceError) -> Self {
472 Self::DecodeSequenceError(val)
473 }
474}
475
476impl From<ExecuteSequencesError> for DecompressBlockError {
477 fn from(val: ExecuteSequencesError) -> Self {
478 Self::ExecuteSequencesError(val)
479 }
480}
481
482#[derive(Debug)]
483#[non_exhaustive]
484pub enum DecodeBlockContentError {
485 DecoderStateIsFailed,
486 ExpectedHeaderOfPreviousBlock,
487 ReadError {
488 step: BlockType,
489 source: Error,
490 },
491 DecompressBlockError(DecompressBlockError),
492 BackendOverflow {
503 step: BlockType,
504 },
505}
506
507#[cfg(feature = "std")]
508impl std::error::Error for DecodeBlockContentError {
509 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
510 match self {
511 DecodeBlockContentError::ReadError { step: _, source } => Some(source),
512 DecodeBlockContentError::DecompressBlockError(source) => Some(source),
513 _ => None,
514 }
515 }
516}
517
518impl core::fmt::Display for DecodeBlockContentError {
519 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
520 match self {
521 DecodeBlockContentError::DecoderStateIsFailed => {
522 write!(
523 f,
524 "Can't decode next block if failed along the way. Results will be nonsense",
525 )
526 }
527 DecodeBlockContentError::ExpectedHeaderOfPreviousBlock => {
528 write!(
529 f,
530 "Can't decode next block body, while expecting to decode the header of the previous block. Results will be nonsense",
531 )
532 }
533 DecodeBlockContentError::ReadError { step, source } => {
534 write!(f, "Error while reading bytes for {step}: {source}",)
535 }
536 DecodeBlockContentError::DecompressBlockError(e) => write!(f, "{e:?}"),
537 DecodeBlockContentError::BackendOverflow { step } => write!(
538 f,
539 "{step} block's decompressed payload exceeds the caller-provided output buffer",
540 ),
541 }
542 }
543}
544
545impl From<DecompressBlockError> for DecodeBlockContentError {
546 fn from(val: DecompressBlockError) -> Self {
547 Self::DecompressBlockError(val)
548 }
549}
550
551#[derive(Debug)]
552#[non_exhaustive]
553pub enum DecodeBufferError {
554 NotEnoughBytesInDictionary {
555 got: usize,
556 need: usize,
557 },
558 OffsetTooBig {
559 offset: usize,
560 buf_len: usize,
561 },
562 ZeroOffset,
563 BackendOverflow,
575 OutputBufferOverflow {
585 tail: usize,
586 requested: usize,
587 capacity: usize,
588 },
589}
590
591#[cfg(feature = "std")]
592impl std::error::Error for DecodeBufferError {}
593
594impl core::fmt::Display for DecodeBufferError {
595 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
596 match self {
597 DecodeBufferError::NotEnoughBytesInDictionary { got, need } => {
598 write!(
599 f,
600 "Need {need} bytes from the dictionary but it is only {got} bytes long",
601 )
602 }
603 DecodeBufferError::OffsetTooBig { offset, buf_len } => {
604 write!(f, "offset: {offset} bigger than buffer: {buf_len}",)
605 }
606 DecodeBufferError::ZeroOffset => {
607 write!(f, "Illegal offset: 0 found")
608 }
609 DecodeBufferError::BackendOverflow => {
610 write!(
611 f,
612 "Match repeat would overflow the output buffer's fixed capacity"
613 )
614 }
615 DecodeBufferError::OutputBufferOverflow {
616 tail,
617 requested,
618 capacity,
619 } => {
620 write!(
621 f,
622 "Match repeat would write past fixed-capacity buffer: tail={tail}, requested={requested}, capacity={capacity}"
623 )
624 }
625 }
626 }
627}
628
629#[derive(Debug)]
630#[non_exhaustive]
631pub enum DictionaryDecodeError {
632 BadMagicNum { got: [u8; 4] },
633 DictionaryTooSmall { got: usize, need: usize },
634 ZeroDictionaryId,
635 ZeroRepeatOffsetInDictionary { index: u8 },
636 FSETableError(FSETableError),
637 HuffmanTableError(HuffmanTableError),
638}
639
640#[cfg(feature = "std")]
641impl std::error::Error for DictionaryDecodeError {
642 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
643 match self {
644 DictionaryDecodeError::FSETableError(source) => Some(source),
645 DictionaryDecodeError::HuffmanTableError(source) => Some(source),
646 _ => None,
647 }
648 }
649}
650
651impl core::fmt::Display for DictionaryDecodeError {
652 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
653 match self {
654 DictionaryDecodeError::BadMagicNum { got } => {
655 write!(
656 f,
657 "Bad magic_num at start of the dictionary; Got: {:#04X?}, Expected: {:#04x?}",
658 got,
659 crate::decoding::dictionary::MAGIC_NUM,
660 )
661 }
662 DictionaryDecodeError::DictionaryTooSmall { got, need } => {
663 write!(
664 f,
665 "Dictionary is too small: got {got} bytes, need at least {need} bytes",
666 )
667 }
668 DictionaryDecodeError::ZeroDictionaryId => {
669 write!(f, "Dictionary id must be non-zero")
670 }
671 DictionaryDecodeError::ZeroRepeatOffsetInDictionary { index } => {
672 write!(f, "Dictionary repeat offset rep{index} must be non-zero")
673 }
674 DictionaryDecodeError::FSETableError(e) => write!(f, "{e:?}"),
675 DictionaryDecodeError::HuffmanTableError(e) => write!(f, "{e:?}"),
676 }
677 }
678}
679
680impl From<FSETableError> for DictionaryDecodeError {
681 fn from(val: FSETableError) -> Self {
682 Self::FSETableError(val)
683 }
684}
685
686impl From<HuffmanTableError> for DictionaryDecodeError {
687 fn from(val: HuffmanTableError) -> Self {
688 Self::HuffmanTableError(val)
689 }
690}
691
692#[derive(Debug, Clone, Copy, PartialEq, Eq)]
706#[non_exhaustive]
707pub enum ErrorCode {
708 PrefixUnknown,
710 FrameParameterUnsupported,
712 FrameParameterWindowTooLarge,
714 ParameterOutOfBound,
716 DictionaryCorrupted,
718 DictionaryWrong,
721 DstSizeTooSmall,
723 InitMissing,
725 ChecksumWrong,
727 SrcSizeWrong,
729 CorruptionDetected,
731}
732
733impl ErrorCode {
734 pub fn message(self) -> &'static str {
736 match self {
737 ErrorCode::PrefixUnknown => "Unknown frame descriptor",
738 ErrorCode::FrameParameterUnsupported => "Unsupported frame parameter",
739 ErrorCode::FrameParameterWindowTooLarge => {
740 "Frame requires too much memory for decoding"
741 }
742 ErrorCode::ParameterOutOfBound => "Parameter is out of bound",
743 ErrorCode::DictionaryCorrupted => "Dictionary is corrupted",
744 ErrorCode::DictionaryWrong => "Dictionary mismatch",
745 ErrorCode::DstSizeTooSmall => "Destination buffer is too small",
746 ErrorCode::InitMissing => "Context should be init first",
747 ErrorCode::ChecksumWrong => "Restored data doesn't match checksum",
748 ErrorCode::SrcSizeWrong => "Src size is incorrect",
749 ErrorCode::CorruptionDetected => "Data corruption detected",
750 }
751 }
752}
753
754impl FrameDescriptorError {
755 pub fn code(&self) -> ErrorCode {
757 match self {
758 FrameDescriptorError::ReservedBitSet => ErrorCode::FrameParameterUnsupported,
761 _ => ErrorCode::CorruptionDetected,
762 }
763 }
764}
765
766#[derive(Debug)]
767#[non_exhaustive]
768pub enum FrameDecoderError {
769 ReadFrameHeaderError(ReadFrameHeaderError),
770 FrameHeaderError(FrameHeaderError),
771 #[non_exhaustive]
775 WindowSizeTooBig {
776 requested: u64,
778 limit: u64,
780 },
781 WindowCeilingOutOfRange {
785 requested: u64,
787 },
788 DictionaryDecodeError(DictionaryDecodeError),
789 FailedToReadBlockHeader(BlockHeaderReadError),
790 FailedToReadBlockBody(DecodeBlockContentError),
791 FailedToReadChecksum(Error),
792 NotYetInitialized,
793 FailedToInitialize(FrameHeaderError),
794 FailedToDrainDecodebuffer(Error),
795 FailedToSkipFrame,
796 TargetTooSmall,
797 FrameContentSizeMismatch {
805 declared: u64,
806 produced: u64,
807 },
808 ChecksumMismatch {
815 expected: u32,
816 calculated: u32,
817 },
818 DictNotProvided {
819 dict_id: u32,
820 },
821 DictIdMismatch {
822 expected: u32,
823 provided: u32,
824 },
825 DictAlreadyRegistered {
826 dict_id: u32,
827 },
828 #[cfg(feature = "lsm")]
841 UnexpectedDictId {
842 expected: Option<u32>,
843 found: Option<u32>,
844 },
845 #[cfg(feature = "lsm")]
852 UnexpectedWindowDescriptor {
853 expected: u8,
854 found: Option<u8>,
855 },
856 #[cfg(feature = "lsm")]
864 FailedToReadBlockHeaderAt {
865 source: BlockHeaderReadError,
866 block_index: u32,
867 frame_offset: u32,
868 },
869 #[cfg(feature = "lsm")]
877 FailedToReadBlockBodyAt {
878 source: DecodeBlockContentError,
879 block_index: u32,
880 frame_offset: u32,
881 block: crate::encoding::frame_emit_info::FrameBlock,
882 },
883 #[cfg(feature = "lsm")]
890 InvalidBlockRange {
891 start_block: u32,
892 end_block: u32,
893 },
894 #[cfg(feature = "lsm")]
904 ResumeWindowTooShort {
905 got: usize,
906 need: usize,
907 },
908 #[cfg(feature = "lsm")]
920 ResumeFrameMismatch,
921 #[cfg(feature = "lsm")]
935 ResumeUnidentifiedDictionary,
936 #[cfg(feature = "legacy")]
938 #[cfg_attr(docsrs, doc(cfg(feature = "legacy")))]
939 LegacyFrame(LegacyFrameError),
940}
941
942#[cfg(feature = "legacy")]
943impl From<LegacyFrameError> for FrameDecoderError {
944 fn from(err: LegacyFrameError) -> Self {
945 FrameDecoderError::LegacyFrame(err)
946 }
947}
948
949impl FrameDecoderError {
950 pub fn code(&self) -> ErrorCode {
953 match self {
954 FrameDecoderError::ReadFrameHeaderError(
955 ReadFrameHeaderError::InvalidFrameDescriptor(descriptor),
956 ) => descriptor.code(),
957 FrameDecoderError::ReadFrameHeaderError(_) => ErrorCode::PrefixUnknown,
958 FrameDecoderError::FrameHeaderError(FrameHeaderError::WindowTooBig { .. })
961 | FrameDecoderError::FailedToInitialize(FrameHeaderError::WindowTooBig { .. }) => {
962 ErrorCode::FrameParameterWindowTooLarge
963 }
964 FrameDecoderError::FrameHeaderError(_) | FrameDecoderError::FailedToInitialize(_) => {
965 ErrorCode::FrameParameterUnsupported
966 }
967 FrameDecoderError::WindowSizeTooBig { .. } => ErrorCode::FrameParameterWindowTooLarge,
968 FrameDecoderError::WindowCeilingOutOfRange { .. } => ErrorCode::ParameterOutOfBound,
969 FrameDecoderError::DictionaryDecodeError(_) => ErrorCode::DictionaryCorrupted,
970 FrameDecoderError::DictNotProvided { .. }
971 | FrameDecoderError::DictIdMismatch { .. }
972 | FrameDecoderError::DictAlreadyRegistered { .. } => ErrorCode::DictionaryWrong,
973 FrameDecoderError::TargetTooSmall => ErrorCode::DstSizeTooSmall,
974 FrameDecoderError::NotYetInitialized => ErrorCode::InitMissing,
975 FrameDecoderError::ChecksumMismatch { .. } => ErrorCode::ChecksumWrong,
976 #[cfg(feature = "legacy")]
977 FrameDecoderError::LegacyFrame(err) => err.code(),
978 _ => ErrorCode::CorruptionDetected,
979 }
980 }
981}
982
983#[cfg(feature = "std")]
984impl StdError for FrameDecoderError {
985 fn source(&self) -> Option<&(dyn StdError + 'static)> {
986 match self {
987 FrameDecoderError::ReadFrameHeaderError(source) => Some(source),
988 FrameDecoderError::FrameHeaderError(source) => Some(source),
989 FrameDecoderError::DictionaryDecodeError(source) => Some(source),
990 FrameDecoderError::FailedToReadBlockHeader(source) => Some(source),
991 FrameDecoderError::FailedToReadBlockBody(source) => Some(source),
992 #[cfg(feature = "lsm")]
993 FrameDecoderError::FailedToReadBlockHeaderAt { source, .. } => Some(source),
994 #[cfg(feature = "lsm")]
995 FrameDecoderError::FailedToReadBlockBodyAt { source, .. } => Some(source),
996 FrameDecoderError::FailedToReadChecksum(source) => Some(source),
997 FrameDecoderError::FailedToInitialize(source) => Some(source),
998 FrameDecoderError::FailedToDrainDecodebuffer(source) => Some(source),
999 #[cfg(feature = "legacy")]
1000 FrameDecoderError::LegacyFrame(source) => Some(source),
1001 _ => None,
1002 }
1003 }
1004}
1005
1006impl core::fmt::Display for FrameDecoderError {
1007 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1008 match self {
1009 FrameDecoderError::ReadFrameHeaderError(e) => {
1010 write!(f, "{e:?}")
1011 }
1012 FrameDecoderError::FrameHeaderError(e) => {
1013 write!(f, "{e:?}")
1014 }
1015 FrameDecoderError::WindowSizeTooBig { requested, limit } => {
1016 write!(
1017 f,
1018 "Specified window_size is too big; Requested: {requested}, Allowed: {limit}",
1019 )
1020 }
1021 FrameDecoderError::WindowCeilingOutOfRange { requested } => {
1022 write!(
1023 f,
1024 "window ceiling {requested} is outside {}..={}",
1025 crate::common::MIN_WINDOW_SIZE,
1026 crate::common::MAX_DECODER_WINDOW_SIZE,
1027 )
1028 }
1029 FrameDecoderError::DictionaryDecodeError(e) => {
1030 write!(f, "{e:?}")
1031 }
1032 FrameDecoderError::FailedToReadBlockHeader(e) => {
1033 write!(f, "Failed to parse/decode block body: {e}")
1034 }
1035 FrameDecoderError::FailedToReadBlockBody(e) => {
1036 write!(f, "Failed to parse block header: {e}")
1037 }
1038 #[cfg(feature = "lsm")]
1039 FrameDecoderError::FailedToReadBlockHeaderAt {
1040 source,
1041 block_index,
1042 frame_offset,
1043 } => {
1044 write!(
1045 f,
1046 "Failed to read block header at block {block_index} (frame offset {frame_offset}): {source}"
1047 )
1048 }
1049 #[cfg(feature = "lsm")]
1050 FrameDecoderError::FailedToReadBlockBodyAt {
1051 source,
1052 block_index,
1053 frame_offset,
1054 ..
1055 } => {
1056 write!(
1057 f,
1058 "Failed to decode block body at block {block_index} (frame offset {frame_offset}): {source}"
1059 )
1060 }
1061 FrameDecoderError::FailedToReadChecksum(e) => {
1062 write!(f, "Failed to read checksum: {e}")
1063 }
1064 FrameDecoderError::NotYetInitialized => {
1065 write!(f, "Decoder must initialized or reset before using it",)
1066 }
1067 FrameDecoderError::FailedToInitialize(e) => {
1068 write!(f, "Decoder encountered error while initializing: {e}")
1069 }
1070 FrameDecoderError::FailedToDrainDecodebuffer(e) => {
1071 write!(
1072 f,
1073 "Decoder encountered error while draining the decodebuffer: {e}",
1074 )
1075 }
1076 FrameDecoderError::FailedToSkipFrame => {
1077 write!(
1078 f,
1079 "Failed to skip bytes for the length given in the frame header"
1080 )
1081 }
1082 FrameDecoderError::TargetTooSmall => {
1083 write!(
1084 f,
1085 "Target must have at least as many bytes as the content size reported by the frame"
1086 )
1087 }
1088 FrameDecoderError::FrameContentSizeMismatch { declared, produced } => {
1089 write!(
1090 f,
1091 "Frame content size mismatch (corrupt frame): declared {declared} bytes, blocks summed to {produced} bytes"
1092 )
1093 }
1094 FrameDecoderError::ChecksumMismatch {
1095 expected,
1096 calculated,
1097 } => {
1098 write!(
1099 f,
1100 "Content checksum mismatch (corrupt frame): frame stored 0x{expected:08X}, decoder calculated 0x{calculated:08X}"
1101 )
1102 }
1103 FrameDecoderError::DictNotProvided { dict_id } => {
1104 write!(
1105 f,
1106 "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()"
1107 )
1108 }
1109 FrameDecoderError::DictIdMismatch { expected, provided } => {
1110 write!(
1111 f,
1112 "Frame header dictionary id 0x{expected:X} does not match provided dictionary id 0x{provided:X}"
1113 )
1114 }
1115 FrameDecoderError::DictAlreadyRegistered { dict_id } => {
1116 write!(
1117 f,
1118 "Dictionary id 0x{dict_id:X} already registered in decoder"
1119 )
1120 }
1121 #[cfg(feature = "lsm")]
1122 FrameDecoderError::UnexpectedDictId { expected, found } => {
1123 write!(f, "Frame header dict_id mismatch: expected ")?;
1124 match expected {
1125 Some(id) => write!(f, "0x{id:X}")?,
1126 None => write!(f, "<none>")?,
1127 }
1128 write!(f, ", found ")?;
1129 match found {
1130 Some(id) => write!(f, "0x{id:X}"),
1131 None => write!(f, "<none>"),
1132 }
1133 }
1134 #[cfg(feature = "lsm")]
1135 FrameDecoderError::UnexpectedWindowDescriptor { expected, found } => {
1136 write!(
1137 f,
1138 "Frame header window_descriptor mismatch: expected 0x{expected:02X}, found "
1139 )?;
1140 match found {
1141 Some(byte) => write!(f, "0x{byte:02X}"),
1142 None => write!(f, "<none> (single-segment frame omits window_descriptor)"),
1143 }
1144 }
1145 #[cfg(feature = "lsm")]
1146 FrameDecoderError::InvalidBlockRange {
1147 start_block,
1148 end_block,
1149 } => {
1150 write!(
1151 f,
1152 "Invalid block range for partial decode: start_block {start_block} > end_block {end_block}"
1153 )
1154 }
1155 #[cfg(feature = "lsm")]
1156 FrameDecoderError::ResumeWindowTooShort { got, need } => {
1157 write!(
1158 f,
1159 "resume window_prime too short: got {got} bytes, need at least {need}"
1160 )
1161 }
1162 #[cfg(feature = "lsm")]
1163 FrameDecoderError::ResumeFrameMismatch => {
1164 write!(
1165 f,
1166 "resume state was captured from a frame with a different decode shape than the current frame"
1167 )
1168 }
1169 #[cfg(feature = "lsm")]
1170 FrameDecoderError::ResumeUnidentifiedDictionary => {
1171 write!(
1172 f,
1173 "a dictionary with no ID cannot be told from another one, so it cannot carry a resume state across frames"
1174 )
1175 }
1176 #[cfg(feature = "legacy")]
1177 FrameDecoderError::LegacyFrame(e) => write!(f, "{e}"),
1178 }
1179 }
1180}
1181
1182impl From<DictionaryDecodeError> for FrameDecoderError {
1183 fn from(val: DictionaryDecodeError) -> Self {
1184 Self::DictionaryDecodeError(val)
1185 }
1186}
1187
1188impl From<BlockHeaderReadError> for FrameDecoderError {
1189 fn from(val: BlockHeaderReadError) -> Self {
1190 Self::FailedToReadBlockHeader(val)
1191 }
1192}
1193
1194impl From<FrameHeaderError> for FrameDecoderError {
1195 fn from(val: FrameHeaderError) -> Self {
1196 Self::FrameHeaderError(val)
1197 }
1198}
1199
1200impl From<ReadFrameHeaderError> for FrameDecoderError {
1201 fn from(val: ReadFrameHeaderError) -> Self {
1202 Self::ReadFrameHeaderError(val)
1203 }
1204}
1205
1206#[derive(Debug)]
1207#[non_exhaustive]
1208pub enum DecompressLiteralsError {
1209 MissingCompressedSize,
1210 MissingNumStreams,
1211 GetBitsError(GetBitsError),
1212 HuffmanTableError(HuffmanTableError),
1213 HuffmanDecoderError(HuffmanDecoderError),
1214 UninitializedHuffmanTable,
1215 MissingBytesForJumpHeader { got: usize },
1216 MissingBytesForLiterals { got: usize, needed: usize },
1217 ExtraPadding { skipped_bits: i32 },
1218 BitstreamReadMismatch { read_til: isize, expected: isize },
1219 DecodedLiteralCountMismatch { decoded: usize, expected: usize },
1220}
1221
1222#[cfg(feature = "std")]
1223impl std::error::Error for DecompressLiteralsError {
1224 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1225 match self {
1226 DecompressLiteralsError::GetBitsError(source) => Some(source),
1227 DecompressLiteralsError::HuffmanTableError(source) => Some(source),
1228 DecompressLiteralsError::HuffmanDecoderError(source) => Some(source),
1229 _ => None,
1230 }
1231 }
1232}
1233impl core::fmt::Display for DecompressLiteralsError {
1234 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1235 match self {
1236 DecompressLiteralsError::MissingCompressedSize => {
1237 write!(
1238 f,
1239 "compressed size was none even though it must be set to something for compressed literals",
1240 )
1241 }
1242 DecompressLiteralsError::MissingNumStreams => {
1243 write!(
1244 f,
1245 "num_streams was none even though it must be set to something (1 or 4) for compressed literals",
1246 )
1247 }
1248 DecompressLiteralsError::GetBitsError(e) => write!(f, "{e:?}"),
1249 DecompressLiteralsError::HuffmanTableError(e) => write!(f, "{e:?}"),
1250 DecompressLiteralsError::HuffmanDecoderError(e) => write!(f, "{e:?}"),
1251 DecompressLiteralsError::UninitializedHuffmanTable => {
1252 write!(
1253 f,
1254 "Tried to reuse huffman table but it was never initialized",
1255 )
1256 }
1257 DecompressLiteralsError::MissingBytesForJumpHeader { got } => {
1258 write!(f, "Need 6 bytes to decode jump header, got {got} bytes",)
1259 }
1260 DecompressLiteralsError::MissingBytesForLiterals { got, needed } => {
1261 write!(
1262 f,
1263 "Need at least {needed} bytes to decode literals. Have: {got} bytes",
1264 )
1265 }
1266 DecompressLiteralsError::ExtraPadding { skipped_bits } => {
1267 write!(
1268 f,
1269 "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
1270 )
1271 }
1272 DecompressLiteralsError::BitstreamReadMismatch { read_til, expected } => {
1273 write!(
1274 f,
1275 "Bitstream was read till: {read_til}, should have been: {expected}",
1276 )
1277 }
1278 DecompressLiteralsError::DecodedLiteralCountMismatch { decoded, expected } => {
1279 write!(
1280 f,
1281 "Did not decode enough literals: {decoded}, Should have been: {expected}",
1282 )
1283 }
1284 }
1285 }
1286}
1287
1288impl From<HuffmanDecoderError> for DecompressLiteralsError {
1289 fn from(val: HuffmanDecoderError) -> Self {
1290 Self::HuffmanDecoderError(val)
1291 }
1292}
1293
1294impl From<GetBitsError> for DecompressLiteralsError {
1295 fn from(val: GetBitsError) -> Self {
1296 Self::GetBitsError(val)
1297 }
1298}
1299
1300impl From<HuffmanTableError> for DecompressLiteralsError {
1301 fn from(val: HuffmanTableError) -> Self {
1302 Self::HuffmanTableError(val)
1303 }
1304}
1305
1306#[derive(Debug)]
1307#[non_exhaustive]
1308pub enum ExecuteSequencesError {
1309 DecodebufferError(DecodeBufferError),
1310 NotEnoughBytesForSequence {
1311 wanted: usize,
1312 have: usize,
1313 },
1314 ZeroOffset,
1315 OutputBufferOverflow {
1325 tail: usize,
1326 requested: usize,
1327 capacity: usize,
1328 },
1329}
1330
1331impl core::fmt::Display for ExecuteSequencesError {
1332 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1333 match self {
1334 ExecuteSequencesError::DecodebufferError(e) => {
1335 write!(f, "{e:?}")
1336 }
1337 ExecuteSequencesError::NotEnoughBytesForSequence { wanted, have } => {
1338 write!(
1339 f,
1340 "Sequence wants to copy up to byte {wanted}. Bytes in literalsbuffer: {have}"
1341 )
1342 }
1343 ExecuteSequencesError::ZeroOffset => {
1344 write!(f, "Illegal offset: 0 found")
1345 }
1346 ExecuteSequencesError::OutputBufferOverflow {
1347 tail,
1348 requested,
1349 capacity,
1350 } => {
1351 write!(
1352 f,
1353 "Inline sequence would write past the output buffer: tail={tail}, requested={requested}, capacity={capacity}"
1354 )
1355 }
1356 }
1357 }
1358}
1359
1360#[cfg(feature = "std")]
1361impl std::error::Error for ExecuteSequencesError {
1362 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1363 match self {
1364 ExecuteSequencesError::DecodebufferError(source) => Some(source),
1365 _ => None,
1366 }
1367 }
1368}
1369
1370impl From<DecodeBufferError> for ExecuteSequencesError {
1371 fn from(val: DecodeBufferError) -> Self {
1372 Self::DecodebufferError(val)
1373 }
1374}
1375
1376impl From<crate::decoding::buffer_backend::BackendOverflow> for ExecuteSequencesError {
1377 fn from(val: crate::decoding::buffer_backend::BackendOverflow) -> Self {
1378 Self::OutputBufferOverflow {
1379 tail: val.tail,
1380 requested: val.requested,
1381 capacity: val.capacity,
1382 }
1383 }
1384}
1385
1386impl ExecuteSequencesError {
1387 pub(crate) fn output_overflow_requested(&self) -> Option<usize> {
1401 match self {
1402 ExecuteSequencesError::OutputBufferOverflow { requested, .. } => Some(*requested),
1403 ExecuteSequencesError::DecodebufferError(DecodeBufferError::OutputBufferOverflow {
1404 requested,
1405 ..
1406 }) => Some(*requested),
1407 _ => None,
1408 }
1409 }
1410}
1411
1412#[derive(Debug)]
1413#[non_exhaustive]
1414pub enum DecodeSequenceError {
1415 GetBitsError(GetBitsError),
1416 FSEDecoderError(FSEDecoderError),
1417 FSETableError(FSETableError),
1418 ExtraPadding {
1419 skipped_bits: i32,
1420 },
1421 UnsupportedOffset {
1422 offset_code: u8,
1423 },
1424 ZeroOffset,
1425 NotEnoughBytesForNumSequences,
1426 ExtraBits {
1427 bits_remaining: isize,
1428 },
1429 MissingCompressionMode,
1430 MissingByteForRleLlTable,
1431 MissingByteForRleOfTable,
1432 MissingByteForRleMlTable,
1433 InvalidRleCode {
1437 axis: &'static str,
1438 code: u8,
1439 },
1440}
1441
1442#[cfg(feature = "std")]
1443impl std::error::Error for DecodeSequenceError {
1444 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1445 match self {
1446 DecodeSequenceError::GetBitsError(source) => Some(source),
1447 DecodeSequenceError::FSEDecoderError(source) => Some(source),
1448 DecodeSequenceError::FSETableError(source) => Some(source),
1449 _ => None,
1450 }
1451 }
1452}
1453
1454impl core::fmt::Display for DecodeSequenceError {
1455 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1456 match self {
1457 DecodeSequenceError::GetBitsError(e) => write!(f, "{e:?}"),
1458 DecodeSequenceError::FSEDecoderError(e) => write!(f, "{e:?}"),
1459 DecodeSequenceError::FSETableError(e) => write!(f, "{e:?}"),
1460 DecodeSequenceError::ExtraPadding { skipped_bits } => {
1461 write!(
1462 f,
1463 "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
1464 )
1465 }
1466 DecodeSequenceError::UnsupportedOffset { offset_code } => {
1467 write!(
1468 f,
1469 "Do not support offsets bigger than 1<<32; got: {offset_code}",
1470 )
1471 }
1472 DecodeSequenceError::ZeroOffset => write!(
1473 f,
1474 "Read an offset == 0. That is an illegal value for offsets"
1475 ),
1476 DecodeSequenceError::NotEnoughBytesForNumSequences => write!(
1477 f,
1478 "Bytestream did not contain enough bytes to decode num_sequences"
1479 ),
1480 DecodeSequenceError::ExtraBits { bits_remaining } => write!(f, "{bits_remaining}"),
1481 DecodeSequenceError::MissingCompressionMode => write!(
1482 f,
1483 "compression modes are none but they must be set to something"
1484 ),
1485 DecodeSequenceError::MissingByteForRleLlTable => {
1486 write!(f, "Need a byte to read for RLE ll table")
1487 }
1488 DecodeSequenceError::MissingByteForRleOfTable => {
1489 write!(f, "Need a byte to read for RLE of table")
1490 }
1491 DecodeSequenceError::MissingByteForRleMlTable => {
1492 write!(f, "Need a byte to read for RLE ml table")
1493 }
1494 DecodeSequenceError::InvalidRleCode { axis, code } => {
1495 write!(f, "RLE {axis} table code {code} is out of range")
1496 }
1497 }
1498 }
1499}
1500
1501impl From<GetBitsError> for DecodeSequenceError {
1502 fn from(val: GetBitsError) -> Self {
1503 Self::GetBitsError(val)
1504 }
1505}
1506
1507impl From<FSETableError> for DecodeSequenceError {
1508 fn from(val: FSETableError) -> Self {
1509 Self::FSETableError(val)
1510 }
1511}
1512
1513impl From<FSEDecoderError> for DecodeSequenceError {
1514 fn from(val: FSEDecoderError) -> Self {
1515 Self::FSEDecoderError(val)
1516 }
1517}
1518
1519#[derive(Debug)]
1520#[non_exhaustive]
1521pub enum LiteralsSectionParseError {
1522 IllegalLiteralSectionType { got: u8 },
1523 GetBitsError(GetBitsError),
1524 NotEnoughBytes { have: usize, need: u8 },
1525}
1526
1527#[cfg(feature = "std")]
1528impl std::error::Error for LiteralsSectionParseError {
1529 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1530 match self {
1531 LiteralsSectionParseError::GetBitsError(source) => Some(source),
1532 _ => None,
1533 }
1534 }
1535}
1536impl core::fmt::Display for LiteralsSectionParseError {
1537 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1538 match self {
1539 LiteralsSectionParseError::IllegalLiteralSectionType { got } => {
1540 write!(
1541 f,
1542 "Illegal literalssectiontype. Is: {got}, must be in: 0, 1, 2, 3"
1543 )
1544 }
1545 LiteralsSectionParseError::GetBitsError(e) => write!(f, "{e:?}"),
1546 LiteralsSectionParseError::NotEnoughBytes { have, need } => {
1547 write!(
1548 f,
1549 "Not enough byte to parse the literals section header. Have: {have}, Need: {need}",
1550 )
1551 }
1552 }
1553 }
1554}
1555
1556impl From<GetBitsError> for LiteralsSectionParseError {
1557 fn from(val: GetBitsError) -> Self {
1558 Self::GetBitsError(val)
1559 }
1560}
1561
1562impl core::fmt::Display for LiteralsSectionType {
1563 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
1564 match self {
1565 LiteralsSectionType::Compressed => write!(f, "Compressed"),
1566 LiteralsSectionType::Raw => write!(f, "Raw"),
1567 LiteralsSectionType::RLE => write!(f, "RLE"),
1568 LiteralsSectionType::Treeless => write!(f, "Treeless"),
1569 }
1570 }
1571}
1572
1573#[derive(Debug)]
1574#[non_exhaustive]
1575pub enum SequencesHeaderParseError {
1576 NotEnoughBytes { need_at_least: u8, got: usize },
1577}
1578
1579#[cfg(feature = "std")]
1580impl std::error::Error for SequencesHeaderParseError {}
1581
1582impl core::fmt::Display for SequencesHeaderParseError {
1583 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1584 match self {
1585 SequencesHeaderParseError::NotEnoughBytes { need_at_least, got } => {
1586 write!(
1587 f,
1588 "source must have at least {need_at_least} bytes to parse header; got {got} bytes",
1589 )
1590 }
1591 }
1592 }
1593}
1594
1595#[derive(Debug)]
1596#[non_exhaustive]
1597pub enum FSETableError {
1598 AccLogIsZero,
1599 AccLogTooBig {
1600 got: u8,
1601 max: u8,
1602 },
1603 GetBitsError(GetBitsError),
1604 ProbabilityCounterMismatch {
1605 got: u32,
1606 expected_sum: u32,
1607 symbol_probabilities: Vec<i32>,
1608 },
1609 TooManySymbols {
1610 got: usize,
1611 },
1612 InvalidProbability {
1617 value: i32,
1618 table_size: u32,
1619 accuracy_log: u8,
1620 },
1621 TableInvariantViolation {
1629 prob: i32,
1630 symbol: u8,
1631 num_bits: u8,
1632 accuracy_log: u8,
1633 },
1634}
1635
1636#[cfg(feature = "std")]
1637impl std::error::Error for FSETableError {
1638 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1639 match self {
1640 FSETableError::GetBitsError(source) => Some(source),
1641 _ => None,
1642 }
1643 }
1644}
1645
1646impl core::fmt::Display for FSETableError {
1647 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1648 match self {
1649 FSETableError::AccLogIsZero => write!(f, "Acclog must be at least 1"),
1650 FSETableError::AccLogTooBig { got, max } => {
1651 write!(
1652 f,
1653 "Found FSE acc_log: {got} bigger than allowed maximum in this case: {max}"
1654 )
1655 }
1656 FSETableError::GetBitsError(e) => write!(f, "{e:?}"),
1657 FSETableError::ProbabilityCounterMismatch {
1658 got,
1659 expected_sum,
1660 symbol_probabilities,
1661 } => {
1662 write!(
1663 f,
1664 "FSE probability sum mismatch: got {got}, expected {expected_sum}. Indicates corrupted data or an invalid distribution\n {symbol_probabilities:?}",
1665 )
1666 }
1667 FSETableError::TooManySymbols { got } => {
1668 write!(
1669 f,
1670 "There are too many symbols in this distribution: {got}. Max: 256",
1671 )
1672 }
1673 FSETableError::InvalidProbability {
1674 value,
1675 table_size,
1676 accuracy_log,
1677 } => {
1678 write!(
1679 f,
1680 "FSE probability value {value} is outside the RFC 8878 allowed set (must be -1, 0, or in 1..={table_size}; accuracy_log={accuracy_log})",
1681 )
1682 }
1683 FSETableError::TableInvariantViolation {
1684 prob,
1685 symbol,
1686 num_bits,
1687 accuracy_log,
1688 } => {
1689 write!(
1690 f,
1691 "FSE table invariant violation: symbol {symbol} (prob {prob}) produced num_bits {num_bits} > accuracy_log {accuracy_log}",
1692 )
1693 }
1694 }
1695 }
1696}
1697
1698impl From<GetBitsError> for FSETableError {
1699 fn from(val: GetBitsError) -> Self {
1700 Self::GetBitsError(val)
1701 }
1702}
1703
1704#[derive(Debug)]
1705#[non_exhaustive]
1706pub enum FSEDecoderError {
1707 GetBitsError(GetBitsError),
1708 TableIsUninitialized,
1709 InvalidTableShape {
1715 decode_len: usize,
1716 accuracy_log: u8,
1717 },
1718}
1719
1720#[cfg(feature = "std")]
1721impl std::error::Error for FSEDecoderError {
1722 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1723 match self {
1724 FSEDecoderError::GetBitsError(source) => Some(source),
1725 _ => None,
1726 }
1727 }
1728}
1729
1730impl core::fmt::Display for FSEDecoderError {
1731 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1732 match self {
1733 FSEDecoderError::GetBitsError(e) => write!(f, "{e:?}"),
1734 FSEDecoderError::TableIsUninitialized => {
1735 write!(f, "Tried to use an uninitialized table!")
1736 }
1737 FSEDecoderError::InvalidTableShape {
1738 decode_len,
1739 accuracy_log,
1740 } => match 1usize.checked_shl((*accuracy_log).into()) {
1741 Some(expected) => write!(
1742 f,
1743 "FSETable shape invariant violated: decode.len() = {decode_len}, expected 1 << accuracy_log = {expected} (accuracy_log = {accuracy_log})",
1744 ),
1745 None => write!(
1746 f,
1747 "FSETable shape invariant violated: decode.len() = {decode_len}, accuracy_log = {accuracy_log} overflows 1 << accuracy_log for usize",
1748 ),
1749 },
1750 }
1751 }
1752}
1753
1754impl From<GetBitsError> for FSEDecoderError {
1755 fn from(val: GetBitsError) -> Self {
1756 Self::GetBitsError(val)
1757 }
1758}
1759
1760#[derive(Debug)]
1761#[non_exhaustive]
1762pub enum HuffmanTableError {
1763 GetBitsError(GetBitsError),
1764 FSEDecoderError(FSEDecoderError),
1765 FSETableError(FSETableError),
1766 SourceIsEmpty,
1767 NotEnoughBytesForWeights {
1768 got_bytes: usize,
1769 expected_bytes: u8,
1770 },
1771 ExtraPadding {
1772 skipped_bits: i32,
1773 },
1774 TooManyWeights {
1775 got: usize,
1776 },
1777 MissingWeights,
1778 LeftoverIsNotAPowerOf2 {
1779 got: u32,
1780 },
1781 NotEnoughBytesToDecompressWeights {
1782 have: usize,
1783 need: usize,
1784 },
1785 FSETableUsedTooManyBytes {
1786 used: usize,
1787 available_bytes: u8,
1788 },
1789 NotEnoughBytesInSource {
1790 got: usize,
1791 need: usize,
1792 },
1793 WeightBiggerThanMaxNumBits {
1794 got: u8,
1795 },
1796 MaxBitsTooHigh {
1797 got: u8,
1798 },
1799}
1800
1801#[cfg(feature = "std")]
1802impl StdError for HuffmanTableError {
1803 fn source(&self) -> Option<&(dyn StdError + 'static)> {
1804 match self {
1805 HuffmanTableError::GetBitsError(source) => Some(source),
1806 HuffmanTableError::FSEDecoderError(source) => Some(source),
1807 HuffmanTableError::FSETableError(source) => Some(source),
1808 _ => None,
1809 }
1810 }
1811}
1812
1813impl core::fmt::Display for HuffmanTableError {
1814 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1815 match self {
1816 HuffmanTableError::GetBitsError(e) => write!(f, "{e:?}"),
1817 HuffmanTableError::FSEDecoderError(e) => write!(f, "{e:?}"),
1818 HuffmanTableError::FSETableError(e) => write!(f, "{e:?}"),
1819 HuffmanTableError::SourceIsEmpty => write!(f, "Source needs to have at least one byte"),
1820 HuffmanTableError::NotEnoughBytesForWeights {
1821 got_bytes,
1822 expected_bytes,
1823 } => {
1824 write!(
1825 f,
1826 "Header says there should be {expected_bytes} bytes for the weights but there are only {got_bytes} bytes in the stream"
1827 )
1828 }
1829 HuffmanTableError::ExtraPadding { skipped_bits } => {
1830 write!(
1831 f,
1832 "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
1833 )
1834 }
1835 HuffmanTableError::TooManyWeights { got } => {
1836 write!(
1837 f,
1838 "More than 255 weights decoded (got {got} weights). Stream is probably corrupted",
1839 )
1840 }
1841 HuffmanTableError::MissingWeights => {
1842 write!(f, "Can\'t build huffman table without any weights")
1843 }
1844 HuffmanTableError::LeftoverIsNotAPowerOf2 { got } => {
1845 write!(f, "Leftover must be power of two but is: {got}")
1846 }
1847 HuffmanTableError::NotEnoughBytesToDecompressWeights { have, need } => {
1848 write!(
1849 f,
1850 "Not enough bytes in stream to decompress weights. Is: {have}, Should be: {need}",
1851 )
1852 }
1853 HuffmanTableError::FSETableUsedTooManyBytes {
1854 used,
1855 available_bytes,
1856 } => {
1857 write!(
1858 f,
1859 "FSE table used more bytes: {used} than were meant to be used for the whole stream of huffman weights ({available_bytes})",
1860 )
1861 }
1862 HuffmanTableError::NotEnoughBytesInSource { got, need } => {
1863 write!(f, "Source needs to have at least {need} bytes, got: {got}",)
1864 }
1865 HuffmanTableError::WeightBiggerThanMaxNumBits { got } => {
1866 write!(
1867 f,
1868 "Cant have weight: {} bigger than max_num_bits: {}",
1869 got,
1870 crate::huff0::MAX_MAX_NUM_BITS,
1871 )
1872 }
1873 HuffmanTableError::MaxBitsTooHigh { got } => {
1874 write!(
1875 f,
1876 "max_bits derived from weights is: {} should be lower than: {}",
1877 got,
1878 crate::huff0::MAX_MAX_NUM_BITS,
1879 )
1880 }
1881 }
1882 }
1883}
1884
1885impl From<GetBitsError> for HuffmanTableError {
1886 fn from(val: GetBitsError) -> Self {
1887 Self::GetBitsError(val)
1888 }
1889}
1890
1891impl From<FSEDecoderError> for HuffmanTableError {
1892 fn from(val: FSEDecoderError) -> Self {
1893 Self::FSEDecoderError(val)
1894 }
1895}
1896
1897impl From<FSETableError> for HuffmanTableError {
1898 fn from(val: FSETableError) -> Self {
1899 Self::FSETableError(val)
1900 }
1901}
1902
1903#[derive(Debug)]
1904#[non_exhaustive]
1905pub enum HuffmanDecoderError {
1906 GetBitsError(GetBitsError),
1907}
1908
1909impl core::fmt::Display for HuffmanDecoderError {
1910 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1911 match self {
1912 HuffmanDecoderError::GetBitsError(e) => write!(f, "{e:?}"),
1913 }
1914 }
1915}
1916
1917#[cfg(feature = "std")]
1918impl StdError for HuffmanDecoderError {
1919 fn source(&self) -> Option<&(dyn StdError + 'static)> {
1920 match self {
1921 HuffmanDecoderError::GetBitsError(source) => Some(source),
1922 }
1923 }
1924}
1925
1926impl From<GetBitsError> for HuffmanDecoderError {
1927 fn from(val: GetBitsError) -> Self {
1928 Self::GetBitsError(val)
1929 }
1930}
1931
1932#[cfg(test)]
1933mod tests;