1 | //! Errors possible when decoding deflate/zlib/gzip |
2 | //! streams |
3 | |
4 | use alloc::string::String; |
5 | use alloc::vec; |
6 | use alloc::vec::Vec; |
7 | use core::fmt::{Debug, Display, Formatter}; |
8 | |
9 | /// A struct returned when decompression fails |
10 | /// |
11 | /// This struct contains two fields, |
12 | /// |
13 | /// - `error`:Tells you the error that actually occured. |
14 | /// - `data`: Gives you decoded data up until that point when |
15 | /// the error was encountered. |
16 | /// |
17 | /// One can recover data up to the error if they so wish but |
18 | /// guarantees about data state is not given |
19 | pub struct InflateDecodeErrors |
20 | { |
21 | /// reason why decompression fails |
22 | pub error: DecodeErrorStatus, |
23 | /// Decoded data up until that decompression error |
24 | pub data: Vec<u8> |
25 | } |
26 | |
27 | impl InflateDecodeErrors |
28 | { |
29 | /// Create a new decode wrapper with data being |
30 | /// how many bytes we actually decoded before hitting an error |
31 | /// |
32 | /// # Arguments |
33 | /// - `error`: Error encountered during decoding |
34 | /// - `data`: Data up to that point of decoding |
35 | /// |
36 | /// # Returns |
37 | /// Itself |
38 | pub fn new(error: DecodeErrorStatus, data: Vec<u8>) -> InflateDecodeErrors |
39 | { |
40 | InflateDecodeErrors { error, data } |
41 | } |
42 | /// Create a new decode wrapper with an empty vector |
43 | /// |
44 | /// # Arguments |
45 | /// - `error`: Error encountered during decoding. |
46 | pub fn new_with_error(error: DecodeErrorStatus) -> InflateDecodeErrors |
47 | { |
48 | InflateDecodeErrors::new(error, data:vec![]) |
49 | } |
50 | } |
51 | |
52 | impl Debug for InflateDecodeErrors |
53 | { |
54 | fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result |
55 | { |
56 | writeln!(f, " {:?}" , self.error) |
57 | } |
58 | } |
59 | |
60 | pub enum DecodeErrorStatus |
61 | { |
62 | /// Input data is not enough to construct |
63 | /// a full output |
64 | InsufficientData, |
65 | /// Anything that isn't significant |
66 | Generic(&'static str), |
67 | /// Anything that isn't significant but we need to |
68 | /// pass back information to the user as to what went wrong |
69 | GenericStr(String), |
70 | ///Input data was malformed. |
71 | CorruptData, |
72 | /// Limit set by the user was exceeded by |
73 | /// decompressed output |
74 | OutputLimitExceeded(usize, usize), |
75 | /// Output CRC does not match stored CRC. |
76 | /// |
77 | /// Only present for zlib |
78 | MismatchedCRC(u32, u32), |
79 | /// Output Adler does not match stored adler |
80 | /// |
81 | /// Only present for gzip |
82 | MismatchedAdler(u32, u32) |
83 | } |
84 | |
85 | impl Debug for DecodeErrorStatus |
86 | { |
87 | fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result |
88 | { |
89 | match self |
90 | { |
91 | Self::InsufficientData => writeln!(f, "Insufficient data" ), |
92 | Self::Generic(reason: &&str) => writeln!(f, " {reason}" ), |
93 | Self::GenericStr(reason: &String) => writeln!(f, " {reason}" ), |
94 | Self::CorruptData => writeln!(f, "Corrupt data" ), |
95 | Self::OutputLimitExceeded(limit: &usize, current: &usize) => writeln!( |
96 | f, |
97 | "Output limit exceeded, set limit was {limit} and output size is {current}" |
98 | ), |
99 | Self::MismatchedCRC(expected: &u32, found: &u32) => |
100 | { |
101 | writeln!(f, "Mismatched CRC, expected {expected} but found {found}" ) |
102 | } |
103 | Self::MismatchedAdler(expected: &u32, found: &u32) => |
104 | { |
105 | writeln!(f, "Mismatched Adler, expected {expected} but found {found}" ) |
106 | } |
107 | } |
108 | } |
109 | } |
110 | |
111 | impl Display for InflateDecodeErrors |
112 | { |
113 | #[allow (clippy::uninlined_format_args)] |
114 | fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result |
115 | { |
116 | writeln!(f, " {:?}" , self) |
117 | } |
118 | } |
119 | |
120 | #[cfg (feature = "std" )] |
121 | impl std::error::Error for InflateDecodeErrors {} |
122 | |