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 { step: BlockType, source: Error },
351 DecompressBlockError(DecompressBlockError),
352}
353
354#[cfg(feature = "std")]
355impl std::error::Error for DecodeBlockContentError {
356 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
357 match self {
358 DecodeBlockContentError::ReadError { step: _, source } => Some(source),
359 DecodeBlockContentError::DecompressBlockError(source) => Some(source),
360 _ => None,
361 }
362 }
363}
364
365impl core::fmt::Display for DecodeBlockContentError {
366 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
367 match self {
368 DecodeBlockContentError::DecoderStateIsFailed => {
369 write!(
370 f,
371 "Can't decode next block if failed along the way. Results will be nonsense",
372 )
373 }
374 DecodeBlockContentError::ExpectedHeaderOfPreviousBlock => {
375 write!(
376 f,
377 "Can't decode next block body, while expecting to decode the header of the previous block. Results will be nonsense",
378 )
379 }
380 DecodeBlockContentError::ReadError { step, source } => {
381 write!(f, "Error while reading bytes for {step}: {source}",)
382 }
383 DecodeBlockContentError::DecompressBlockError(e) => write!(f, "{e:?}"),
384 }
385 }
386}
387
388impl From<DecompressBlockError> for DecodeBlockContentError {
389 fn from(val: DecompressBlockError) -> Self {
390 Self::DecompressBlockError(val)
391 }
392}
393
394#[derive(Debug)]
395#[non_exhaustive]
396pub enum DecodeBufferError {
397 NotEnoughBytesInDictionary { got: usize, need: usize },
398 OffsetTooBig { offset: usize, buf_len: usize },
399}
400
401#[cfg(feature = "std")]
402impl std::error::Error for DecodeBufferError {}
403
404impl core::fmt::Display for DecodeBufferError {
405 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
406 match self {
407 DecodeBufferError::NotEnoughBytesInDictionary { got, need } => {
408 write!(
409 f,
410 "Need {need} bytes from the dictionary but it is only {got} bytes long",
411 )
412 }
413 DecodeBufferError::OffsetTooBig { offset, buf_len } => {
414 write!(f, "offset: {offset} bigger than buffer: {buf_len}",)
415 }
416 }
417 }
418}
419
420#[derive(Debug)]
421#[non_exhaustive]
422pub enum DictionaryDecodeError {
423 BadMagicNum { got: [u8; 4] },
424 FSETableError(FSETableError),
425 HuffmanTableError(HuffmanTableError),
426}
427
428#[cfg(feature = "std")]
429impl std::error::Error for DictionaryDecodeError {
430 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
431 match self {
432 DictionaryDecodeError::FSETableError(source) => Some(source),
433 DictionaryDecodeError::HuffmanTableError(source) => Some(source),
434 _ => None,
435 }
436 }
437}
438
439impl core::fmt::Display for DictionaryDecodeError {
440 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
441 match self {
442 DictionaryDecodeError::BadMagicNum { got } => {
443 write!(
444 f,
445 "Bad magic_num at start of the dictionary; Got: {:#04X?}, Expected: {:#04x?}",
446 got,
447 crate::decoding::dictionary::MAGIC_NUM,
448 )
449 }
450 DictionaryDecodeError::FSETableError(e) => write!(f, "{e:?}"),
451 DictionaryDecodeError::HuffmanTableError(e) => write!(f, "{e:?}"),
452 }
453 }
454}
455
456impl From<FSETableError> for DictionaryDecodeError {
457 fn from(val: FSETableError) -> Self {
458 Self::FSETableError(val)
459 }
460}
461
462impl From<HuffmanTableError> for DictionaryDecodeError {
463 fn from(val: HuffmanTableError) -> Self {
464 Self::HuffmanTableError(val)
465 }
466}
467
468#[derive(Debug)]
469#[non_exhaustive]
470pub enum FrameDecoderError {
471 ReadFrameHeaderError(ReadFrameHeaderError),
472 FrameHeaderError(FrameHeaderError),
473 WindowSizeTooBig { requested: u64 },
474 DictionaryDecodeError(DictionaryDecodeError),
475 FailedToReadBlockHeader(BlockHeaderReadError),
476 FailedToReadBlockBody(DecodeBlockContentError),
477 FailedToReadChecksum(Error),
478 NotYetInitialized,
479 FailedToInitialize(FrameHeaderError),
480 FailedToDrainDecodebuffer(Error),
481 FailedToSkipFrame,
482 TargetTooSmall,
483 DictNotProvided { dict_id: u32 },
484}
485
486#[cfg(feature = "std")]
487impl StdError for FrameDecoderError {
488 fn source(&self) -> Option<&(dyn StdError + 'static)> {
489 match self {
490 FrameDecoderError::ReadFrameHeaderError(source) => Some(source),
491 FrameDecoderError::FrameHeaderError(source) => Some(source),
492 FrameDecoderError::DictionaryDecodeError(source) => Some(source),
493 FrameDecoderError::FailedToReadBlockHeader(source) => Some(source),
494 FrameDecoderError::FailedToReadBlockBody(source) => Some(source),
495 FrameDecoderError::FailedToReadChecksum(source) => Some(source),
496 FrameDecoderError::FailedToInitialize(source) => Some(source),
497 FrameDecoderError::FailedToDrainDecodebuffer(source) => Some(source),
498 _ => None,
499 }
500 }
501}
502
503impl core::fmt::Display for FrameDecoderError {
504 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> ::core::fmt::Result {
505 match self {
506 FrameDecoderError::ReadFrameHeaderError(e) => {
507 write!(f, "{e:?}")
508 }
509 FrameDecoderError::FrameHeaderError(e) => {
510 write!(f, "{e:?}")
511 }
512 FrameDecoderError::WindowSizeTooBig { requested } => {
513 write!(
514 f,
515 "Specified window_size is too big; Requested: {}, Max: {}",
516 requested,
517 crate::common::MAX_WINDOW_SIZE,
518 )
519 }
520 FrameDecoderError::DictionaryDecodeError(e) => {
521 write!(f, "{e:?}")
522 }
523 FrameDecoderError::FailedToReadBlockHeader(e) => {
524 write!(f, "Failed to parse/decode block body: {e}")
525 }
526 FrameDecoderError::FailedToReadBlockBody(e) => {
527 write!(f, "Failed to parse block header: {e}")
528 }
529 FrameDecoderError::FailedToReadChecksum(e) => {
530 write!(f, "Failed to read checksum: {e}")
531 }
532 FrameDecoderError::NotYetInitialized => {
533 write!(f, "Decoder must initialized or reset before using it",)
534 }
535 FrameDecoderError::FailedToInitialize(e) => {
536 write!(f, "Decoder encountered error while initializing: {e}")
537 }
538 FrameDecoderError::FailedToDrainDecodebuffer(e) => {
539 write!(
540 f,
541 "Decoder encountered error while draining the decodebuffer: {e}",
542 )
543 }
544 FrameDecoderError::FailedToSkipFrame => {
545 write!(
546 f,
547 "Failed to skip bytes for the length given in the frame header"
548 )
549 }
550 FrameDecoderError::TargetTooSmall => {
551 write!(
552 f,
553 "Target must have at least as many bytes as the content size reported by the frame"
554 )
555 }
556 FrameDecoderError::DictNotProvided { dict_id } => {
557 write!(
558 f,
559 "Frame header specified dictionary id 0x{dict_id:X} that wasn't provided via add_dict() or reset_with_dict()"
560 )
561 }
562 }
563 }
564}
565
566impl From<DictionaryDecodeError> for FrameDecoderError {
567 fn from(val: DictionaryDecodeError) -> Self {
568 Self::DictionaryDecodeError(val)
569 }
570}
571
572impl From<BlockHeaderReadError> for FrameDecoderError {
573 fn from(val: BlockHeaderReadError) -> Self {
574 Self::FailedToReadBlockHeader(val)
575 }
576}
577
578impl From<FrameHeaderError> for FrameDecoderError {
579 fn from(val: FrameHeaderError) -> Self {
580 Self::FrameHeaderError(val)
581 }
582}
583
584impl From<ReadFrameHeaderError> for FrameDecoderError {
585 fn from(val: ReadFrameHeaderError) -> Self {
586 Self::ReadFrameHeaderError(val)
587 }
588}
589
590#[derive(Debug)]
591#[non_exhaustive]
592pub enum DecompressLiteralsError {
593 MissingCompressedSize,
594 MissingNumStreams,
595 GetBitsError(GetBitsError),
596 HuffmanTableError(HuffmanTableError),
597 HuffmanDecoderError(HuffmanDecoderError),
598 UninitializedHuffmanTable,
599 MissingBytesForJumpHeader { got: usize },
600 MissingBytesForLiterals { got: usize, needed: usize },
601 ExtraPadding { skipped_bits: i32 },
602 BitstreamReadMismatch { read_til: isize, expected: isize },
603 DecodedLiteralCountMismatch { decoded: usize, expected: usize },
604}
605
606#[cfg(feature = "std")]
607impl std::error::Error for DecompressLiteralsError {
608 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
609 match self {
610 DecompressLiteralsError::GetBitsError(source) => Some(source),
611 DecompressLiteralsError::HuffmanTableError(source) => Some(source),
612 DecompressLiteralsError::HuffmanDecoderError(source) => Some(source),
613 _ => None,
614 }
615 }
616}
617impl core::fmt::Display for DecompressLiteralsError {
618 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
619 match self {
620 DecompressLiteralsError::MissingCompressedSize => {
621 write!(
622 f,
623 "compressed size was none even though it must be set to something for compressed literals",
624 )
625 }
626 DecompressLiteralsError::MissingNumStreams => {
627 write!(
628 f,
629 "num_streams was none even though it must be set to something (1 or 4) for compressed literals",
630 )
631 }
632 DecompressLiteralsError::GetBitsError(e) => write!(f, "{e:?}"),
633 DecompressLiteralsError::HuffmanTableError(e) => write!(f, "{e:?}"),
634 DecompressLiteralsError::HuffmanDecoderError(e) => write!(f, "{e:?}"),
635 DecompressLiteralsError::UninitializedHuffmanTable => {
636 write!(
637 f,
638 "Tried to reuse huffman table but it was never initialized",
639 )
640 }
641 DecompressLiteralsError::MissingBytesForJumpHeader { got } => {
642 write!(f, "Need 6 bytes to decode jump header, got {got} bytes",)
643 }
644 DecompressLiteralsError::MissingBytesForLiterals { got, needed } => {
645 write!(
646 f,
647 "Need at least {needed} bytes to decode literals. Have: {got} bytes",
648 )
649 }
650 DecompressLiteralsError::ExtraPadding { skipped_bits } => {
651 write!(
652 f,
653 "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
654 )
655 }
656 DecompressLiteralsError::BitstreamReadMismatch { read_til, expected } => {
657 write!(
658 f,
659 "Bitstream was read till: {read_til}, should have been: {expected}",
660 )
661 }
662 DecompressLiteralsError::DecodedLiteralCountMismatch { decoded, expected } => {
663 write!(
664 f,
665 "Did not decode enough literals: {decoded}, Should have been: {expected}",
666 )
667 }
668 }
669 }
670}
671
672impl From<HuffmanDecoderError> for DecompressLiteralsError {
673 fn from(val: HuffmanDecoderError) -> Self {
674 Self::HuffmanDecoderError(val)
675 }
676}
677
678impl From<GetBitsError> for DecompressLiteralsError {
679 fn from(val: GetBitsError) -> Self {
680 Self::GetBitsError(val)
681 }
682}
683
684impl From<HuffmanTableError> for DecompressLiteralsError {
685 fn from(val: HuffmanTableError) -> Self {
686 Self::HuffmanTableError(val)
687 }
688}
689
690#[derive(Debug)]
691#[non_exhaustive]
692pub enum ExecuteSequencesError {
693 DecodebufferError(DecodeBufferError),
694 NotEnoughBytesForSequence { wanted: usize, have: usize },
695 ZeroOffset,
696}
697
698impl core::fmt::Display for ExecuteSequencesError {
699 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
700 match self {
701 ExecuteSequencesError::DecodebufferError(e) => {
702 write!(f, "{e:?}")
703 }
704 ExecuteSequencesError::NotEnoughBytesForSequence { wanted, have } => {
705 write!(
706 f,
707 "Sequence wants to copy up to byte {wanted}. Bytes in literalsbuffer: {have}"
708 )
709 }
710 ExecuteSequencesError::ZeroOffset => {
711 write!(f, "Illegal offset: 0 found")
712 }
713 }
714 }
715}
716
717#[cfg(feature = "std")]
718impl std::error::Error for ExecuteSequencesError {
719 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
720 match self {
721 ExecuteSequencesError::DecodebufferError(source) => Some(source),
722 _ => None,
723 }
724 }
725}
726
727impl From<DecodeBufferError> for ExecuteSequencesError {
728 fn from(val: DecodeBufferError) -> Self {
729 Self::DecodebufferError(val)
730 }
731}
732
733#[derive(Debug)]
734#[non_exhaustive]
735pub enum DecodeSequenceError {
736 GetBitsError(GetBitsError),
737 FSEDecoderError(FSEDecoderError),
738 FSETableError(FSETableError),
739 ExtraPadding { skipped_bits: i32 },
740 UnsupportedOffset { offset_code: u8 },
741 ZeroOffset,
742 NotEnoughBytesForNumSequences,
743 ExtraBits { bits_remaining: isize },
744 MissingCompressionMode,
745 MissingByteForRleLlTable,
746 MissingByteForRleOfTable,
747 MissingByteForRleMlTable,
748}
749
750#[cfg(feature = "std")]
751impl std::error::Error for DecodeSequenceError {
752 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
753 match self {
754 DecodeSequenceError::GetBitsError(source) => Some(source),
755 DecodeSequenceError::FSEDecoderError(source) => Some(source),
756 DecodeSequenceError::FSETableError(source) => Some(source),
757 _ => None,
758 }
759 }
760}
761
762impl core::fmt::Display for DecodeSequenceError {
763 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
764 match self {
765 DecodeSequenceError::GetBitsError(e) => write!(f, "{e:?}"),
766 DecodeSequenceError::FSEDecoderError(e) => write!(f, "{e:?}"),
767 DecodeSequenceError::FSETableError(e) => write!(f, "{e:?}"),
768 DecodeSequenceError::ExtraPadding { skipped_bits } => {
769 write!(
770 f,
771 "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
772 )
773 }
774 DecodeSequenceError::UnsupportedOffset { offset_code } => {
775 write!(
776 f,
777 "Do not support offsets bigger than 1<<32; got: {offset_code}",
778 )
779 }
780 DecodeSequenceError::ZeroOffset => write!(
781 f,
782 "Read an offset == 0. That is an illegal value for offsets"
783 ),
784 DecodeSequenceError::NotEnoughBytesForNumSequences => write!(
785 f,
786 "Bytestream did not contain enough bytes to decode num_sequences"
787 ),
788 DecodeSequenceError::ExtraBits { bits_remaining } => write!(f, "{bits_remaining}"),
789 DecodeSequenceError::MissingCompressionMode => write!(
790 f,
791 "compression modes are none but they must be set to something"
792 ),
793 DecodeSequenceError::MissingByteForRleLlTable => {
794 write!(f, "Need a byte to read for RLE ll table")
795 }
796 DecodeSequenceError::MissingByteForRleOfTable => {
797 write!(f, "Need a byte to read for RLE of table")
798 }
799 DecodeSequenceError::MissingByteForRleMlTable => {
800 write!(f, "Need a byte to read for RLE ml table")
801 }
802 }
803 }
804}
805
806impl From<GetBitsError> for DecodeSequenceError {
807 fn from(val: GetBitsError) -> Self {
808 Self::GetBitsError(val)
809 }
810}
811
812impl From<FSETableError> for DecodeSequenceError {
813 fn from(val: FSETableError) -> Self {
814 Self::FSETableError(val)
815 }
816}
817
818impl From<FSEDecoderError> for DecodeSequenceError {
819 fn from(val: FSEDecoderError) -> Self {
820 Self::FSEDecoderError(val)
821 }
822}
823
824#[derive(Debug)]
825#[non_exhaustive]
826pub enum LiteralsSectionParseError {
827 IllegalLiteralSectionType { got: u8 },
828 GetBitsError(GetBitsError),
829 NotEnoughBytes { have: usize, need: u8 },
830}
831
832#[cfg(feature = "std")]
833impl std::error::Error for LiteralsSectionParseError {
834 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
835 match self {
836 LiteralsSectionParseError::GetBitsError(source) => Some(source),
837 _ => None,
838 }
839 }
840}
841impl core::fmt::Display for LiteralsSectionParseError {
842 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
843 match self {
844 LiteralsSectionParseError::IllegalLiteralSectionType { got } => {
845 write!(
846 f,
847 "Illegal literalssectiontype. Is: {got}, must be in: 0, 1, 2, 3"
848 )
849 }
850 LiteralsSectionParseError::GetBitsError(e) => write!(f, "{e:?}"),
851 LiteralsSectionParseError::NotEnoughBytes { have, need } => {
852 write!(
853 f,
854 "Not enough byte to parse the literals section header. Have: {have}, Need: {need}",
855 )
856 }
857 }
858 }
859}
860
861impl From<GetBitsError> for LiteralsSectionParseError {
862 fn from(val: GetBitsError) -> Self {
863 Self::GetBitsError(val)
864 }
865}
866
867impl core::fmt::Display for LiteralsSectionType {
868 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
869 match self {
870 LiteralsSectionType::Compressed => write!(f, "Compressed"),
871 LiteralsSectionType::Raw => write!(f, "Raw"),
872 LiteralsSectionType::RLE => write!(f, "RLE"),
873 LiteralsSectionType::Treeless => write!(f, "Treeless"),
874 }
875 }
876}
877
878#[derive(Debug)]
879#[non_exhaustive]
880pub enum SequencesHeaderParseError {
881 NotEnoughBytes { need_at_least: u8, got: usize },
882}
883
884#[cfg(feature = "std")]
885impl std::error::Error for SequencesHeaderParseError {}
886
887impl core::fmt::Display for SequencesHeaderParseError {
888 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
889 match self {
890 SequencesHeaderParseError::NotEnoughBytes { need_at_least, got } => {
891 write!(
892 f,
893 "source must have at least {need_at_least} bytes to parse header; got {got} bytes",
894 )
895 }
896 }
897 }
898}
899
900#[derive(Debug)]
901#[non_exhaustive]
902pub enum FSETableError {
903 AccLogIsZero,
904 AccLogTooBig {
905 got: u8,
906 max: u8,
907 },
908 GetBitsError(GetBitsError),
909 ProbabilityCounterMismatch {
910 got: u32,
911 expected_sum: u32,
912 symbol_probabilities: Vec<i32>,
913 },
914 TooManySymbols {
915 got: usize,
916 },
917}
918
919#[cfg(feature = "std")]
920impl std::error::Error for FSETableError {
921 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
922 match self {
923 FSETableError::GetBitsError(source) => Some(source),
924 _ => None,
925 }
926 }
927}
928
929impl core::fmt::Display for FSETableError {
930 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
931 match self {
932 FSETableError::AccLogIsZero => write!(f, "Acclog must be at least 1"),
933 FSETableError::AccLogTooBig { got, max } => {
934 write!(
935 f,
936 "Found FSE acc_log: {got} bigger than allowed maximum in this case: {max}"
937 )
938 }
939 FSETableError::GetBitsError(e) => write!(f, "{e:?}"),
940 FSETableError::ProbabilityCounterMismatch {
941 got,
942 expected_sum,
943 symbol_probabilities,
944 } => {
945 write!(
946 f,
947 "The counter ({got}) exceeded the expected sum: {expected_sum}. This means an error or corrupted data \n {symbol_probabilities:?}",
948 )
949 }
950 FSETableError::TooManySymbols { got } => {
951 write!(
952 f,
953 "There are too many symbols in this distribution: {got}. Max: 256",
954 )
955 }
956 }
957 }
958}
959
960impl From<GetBitsError> for FSETableError {
961 fn from(val: GetBitsError) -> Self {
962 Self::GetBitsError(val)
963 }
964}
965
966#[derive(Debug)]
967#[non_exhaustive]
968pub enum FSEDecoderError {
969 GetBitsError(GetBitsError),
970 TableIsUninitialized,
971}
972
973#[cfg(feature = "std")]
974impl std::error::Error for FSEDecoderError {
975 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
976 match self {
977 FSEDecoderError::GetBitsError(source) => Some(source),
978 _ => None,
979 }
980 }
981}
982
983impl core::fmt::Display for FSEDecoderError {
984 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
985 match self {
986 FSEDecoderError::GetBitsError(e) => write!(f, "{e:?}"),
987 FSEDecoderError::TableIsUninitialized => {
988 write!(f, "Tried to use an uninitialized table!")
989 }
990 }
991 }
992}
993
994impl From<GetBitsError> for FSEDecoderError {
995 fn from(val: GetBitsError) -> Self {
996 Self::GetBitsError(val)
997 }
998}
999
1000#[derive(Debug)]
1001#[non_exhaustive]
1002pub enum HuffmanTableError {
1003 GetBitsError(GetBitsError),
1004 FSEDecoderError(FSEDecoderError),
1005 FSETableError(FSETableError),
1006 SourceIsEmpty,
1007 NotEnoughBytesForWeights {
1008 got_bytes: usize,
1009 expected_bytes: u8,
1010 },
1011 ExtraPadding {
1012 skipped_bits: i32,
1013 },
1014 TooManyWeights {
1015 got: usize,
1016 },
1017 MissingWeights,
1018 LeftoverIsNotAPowerOf2 {
1019 got: u32,
1020 },
1021 NotEnoughBytesToDecompressWeights {
1022 have: usize,
1023 need: usize,
1024 },
1025 FSETableUsedTooManyBytes {
1026 used: usize,
1027 available_bytes: u8,
1028 },
1029 NotEnoughBytesInSource {
1030 got: usize,
1031 need: usize,
1032 },
1033 WeightBiggerThanMaxNumBits {
1034 got: u8,
1035 },
1036 MaxBitsTooHigh {
1037 got: u8,
1038 },
1039}
1040
1041#[cfg(feature = "std")]
1042impl StdError for HuffmanTableError {
1043 fn source(&self) -> Option<&(dyn StdError + 'static)> {
1044 match self {
1045 HuffmanTableError::GetBitsError(source) => Some(source),
1046 HuffmanTableError::FSEDecoderError(source) => Some(source),
1047 HuffmanTableError::FSETableError(source) => Some(source),
1048 _ => None,
1049 }
1050 }
1051}
1052
1053impl core::fmt::Display for HuffmanTableError {
1054 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1055 match self {
1056 HuffmanTableError::GetBitsError(e) => write!(f, "{e:?}"),
1057 HuffmanTableError::FSEDecoderError(e) => write!(f, "{e:?}"),
1058 HuffmanTableError::FSETableError(e) => write!(f, "{e:?}"),
1059 HuffmanTableError::SourceIsEmpty => write!(f, "Source needs to have at least one byte"),
1060 HuffmanTableError::NotEnoughBytesForWeights {
1061 got_bytes,
1062 expected_bytes,
1063 } => {
1064 write!(
1065 f,
1066 "Header says there should be {expected_bytes} bytes for the weights but there are only {got_bytes} bytes in the stream"
1067 )
1068 }
1069 HuffmanTableError::ExtraPadding { skipped_bits } => {
1070 write!(
1071 f,
1072 "Padding at the end of the sequence_section was more than a byte long: {skipped_bits} bits. Probably caused by data corruption",
1073 )
1074 }
1075 HuffmanTableError::TooManyWeights { got } => {
1076 write!(
1077 f,
1078 "More than 255 weights decoded (got {got} weights). Stream is probably corrupted",
1079 )
1080 }
1081 HuffmanTableError::MissingWeights => {
1082 write!(f, "Can\'t build huffman table without any weights")
1083 }
1084 HuffmanTableError::LeftoverIsNotAPowerOf2 { got } => {
1085 write!(f, "Leftover must be power of two but is: {got}")
1086 }
1087 HuffmanTableError::NotEnoughBytesToDecompressWeights { have, need } => {
1088 write!(
1089 f,
1090 "Not enough bytes in stream to decompress weights. Is: {have}, Should be: {need}",
1091 )
1092 }
1093 HuffmanTableError::FSETableUsedTooManyBytes {
1094 used,
1095 available_bytes,
1096 } => {
1097 write!(
1098 f,
1099 "FSE table used more bytes: {used} than were meant to be used for the whole stream of huffman weights ({available_bytes})",
1100 )
1101 }
1102 HuffmanTableError::NotEnoughBytesInSource { got, need } => {
1103 write!(f, "Source needs to have at least {need} bytes, got: {got}",)
1104 }
1105 HuffmanTableError::WeightBiggerThanMaxNumBits { got } => {
1106 write!(
1107 f,
1108 "Cant have weight: {} bigger than max_num_bits: {}",
1109 got,
1110 crate::huff0::MAX_MAX_NUM_BITS,
1111 )
1112 }
1113 HuffmanTableError::MaxBitsTooHigh { got } => {
1114 write!(
1115 f,
1116 "max_bits derived from weights is: {} should be lower than: {}",
1117 got,
1118 crate::huff0::MAX_MAX_NUM_BITS,
1119 )
1120 }
1121 }
1122 }
1123}
1124
1125impl From<GetBitsError> for HuffmanTableError {
1126 fn from(val: GetBitsError) -> Self {
1127 Self::GetBitsError(val)
1128 }
1129}
1130
1131impl From<FSEDecoderError> for HuffmanTableError {
1132 fn from(val: FSEDecoderError) -> Self {
1133 Self::FSEDecoderError(val)
1134 }
1135}
1136
1137impl From<FSETableError> for HuffmanTableError {
1138 fn from(val: FSETableError) -> Self {
1139 Self::FSETableError(val)
1140 }
1141}
1142
1143#[derive(Debug)]
1144#[non_exhaustive]
1145pub enum HuffmanDecoderError {
1146 GetBitsError(GetBitsError),
1147}
1148
1149impl core::fmt::Display for HuffmanDecoderError {
1150 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1151 match self {
1152 HuffmanDecoderError::GetBitsError(e) => write!(f, "{e:?}"),
1153 }
1154 }
1155}
1156
1157#[cfg(feature = "std")]
1158impl StdError for HuffmanDecoderError {
1159 fn source(&self) -> Option<&(dyn StdError + 'static)> {
1160 match self {
1161 HuffmanDecoderError::GetBitsError(source) => Some(source),
1162 }
1163 }
1164}
1165
1166impl From<GetBitsError> for HuffmanDecoderError {
1167 fn from(val: GetBitsError) -> Self {
1168 Self::GetBitsError(val)
1169 }
1170}
1171
1172#[cfg(test)]
1173mod tests {
1174 use alloc::{string::ToString, vec};
1175
1176 use super::{
1177 BlockTypeError, DecodeBlockContentError, DecodeSequenceError, DecompressBlockError,
1178 DecompressLiteralsError, FSETableError, FrameDecoderError, HuffmanTableError,
1179 };
1180
1181 #[test]
1182 fn block_and_sequence_display_messages_are_specific() {
1183 assert_eq!(
1184 BlockTypeError::InvalidBlocktypeNumber { num: 7 }.to_string(),
1185 "Invalid Blocktype number. Is: 7. Should be one of: 0, 1, 2, 3 (3 is reserved)."
1186 );
1187 assert_eq!(
1188 DecompressBlockError::MalformedSectionHeader {
1189 expected_len: 12,
1190 remaining_bytes: 3,
1191 }
1192 .to_string(),
1193 "Malformed section header. Says literals would be this long: 12 but there are only 3 bytes left"
1194 );
1195 assert_eq!(
1196 DecodeBlockContentError::ExpectedHeaderOfPreviousBlock.to_string(),
1197 "Can't decode next block body, while expecting to decode the header of the previous block. Results will be nonsense"
1198 );
1199 assert_eq!(
1200 DecodeSequenceError::ExtraPadding { skipped_bits: 11 }.to_string(),
1201 "Padding at the end of the sequence_section was more than a byte long: 11 bits. Probably caused by data corruption"
1202 );
1203 }
1204
1205 #[test]
1206 fn frame_decoder_display_messages_are_specific() {
1207 assert_eq!(
1208 FrameDecoderError::TargetTooSmall.to_string(),
1209 "Target must have at least as many bytes as the content size reported by the frame"
1210 );
1211 assert_eq!(
1212 FrameDecoderError::DictNotProvided { dict_id: 0xABCD }.to_string(),
1213 "Frame header specified dictionary id 0xABCD that wasn't provided via add_dict() or reset_with_dict()"
1214 );
1215 }
1216
1217 #[test]
1218 fn literal_display_messages_are_specific() {
1219 assert_eq!(
1220 DecompressLiteralsError::MissingCompressedSize.to_string(),
1221 "compressed size was none even though it must be set to something for compressed literals"
1222 );
1223 assert_eq!(
1224 DecompressLiteralsError::MissingNumStreams.to_string(),
1225 "num_streams was none even though it must be set to something (1 or 4) for compressed literals"
1226 );
1227 assert_eq!(
1228 DecompressLiteralsError::ExtraPadding { skipped_bits: 9 }.to_string(),
1229 "Padding at the end of the sequence_section was more than a byte long: 9 bits. Probably caused by data corruption"
1230 );
1231 }
1232
1233 #[test]
1234 fn fse_and_huffman_display_messages_are_specific() {
1235 assert_eq!(
1236 FSETableError::ProbabilityCounterMismatch {
1237 got: 4,
1238 expected_sum: 3,
1239 symbol_probabilities: vec![1, -1],
1240 }
1241 .to_string(),
1242 "The counter (4) exceeded the expected sum: 3. This means an error or corrupted data \n [1, -1]"
1243 );
1244 assert_eq!(
1245 HuffmanTableError::NotEnoughBytesForWeights {
1246 got_bytes: 2,
1247 expected_bytes: 5,
1248 }
1249 .to_string(),
1250 "Header says there should be 5 bytes for the weights but there are only 2 bytes in the stream"
1251 );
1252 assert_eq!(
1253 HuffmanTableError::ExtraPadding { skipped_bits: 13 }.to_string(),
1254 "Padding at the end of the sequence_section was more than a byte long: 13 bits. Probably caused by data corruption"
1255 );
1256 assert_eq!(
1257 HuffmanTableError::FSETableUsedTooManyBytes {
1258 used: 7,
1259 available_bytes: 6,
1260 }
1261 .to_string(),
1262 "FSE table used more bytes: 7 than were meant to be used for the whole stream of huffman weights (6)"
1263 );
1264 }
1265}