1use super::super::decoding::bit_reader::{BitReader, GetBitsError};
2
3pub struct LiteralsSection {
4 pub regenerated_size: u32,
5 pub compressed_size: Option<u32>,
6 pub num_streams: Option<u8>,
7 pub ls_type: LiteralsSectionType,
8}
9
10pub enum LiteralsSectionType {
11 Raw,
12 RLE,
13 Compressed,
14 Treeless,
15}
16
17#[derive(Debug, derive_more::Display, derive_more::From)]
18#[cfg_attr(feature = "std", derive(derive_more::Error))]
19#[non_exhaustive]
20pub enum LiteralsSectionParseError {
21 #[display(fmt = "Illegal literalssectiontype. Is: {got}, must be in: 0, 1, 2, 3")]
22 IllegalLiteralSectionType { got: u8 },
23 #[display(fmt = "{_0:?}")]
24 #[from]
25 GetBitsError(GetBitsError),
26 #[display(
27 fmt = "Not enough byte to parse the literals section header. Have: {have}, Need: {need}"
28 )]
29 NotEnoughBytes { have: usize, need: u8 },
30}
31
32impl core::fmt::Display for LiteralsSectionType {
33 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
34 match self {
35 LiteralsSectionType::Compressed => write!(f, "Compressed"),
36 LiteralsSectionType::Raw => write!(f, "Raw"),
37 LiteralsSectionType::RLE => write!(f, "RLE"),
38 LiteralsSectionType::Treeless => write!(f, "Treeless"),
39 }
40 }
41}
42
43impl Default for LiteralsSection {
44 fn default() -> Self {
45 Self::new()
46 }
47}
48
49impl LiteralsSection {
50 pub fn new() -> LiteralsSection {
51 LiteralsSection {
52 regenerated_size: 0,
53 compressed_size: None,
54 num_streams: None,
55 ls_type: LiteralsSectionType::Raw,
56 }
57 }
58
59 pub fn header_bytes_needed(&self, first_byte: u8) -> Result<u8, LiteralsSectionParseError> {
60 let ls_type = Self::section_type(first_byte)?;
61 let size_format = (first_byte >> 2) & 0x3;
62 match ls_type {
63 LiteralsSectionType::RLE | LiteralsSectionType::Raw => {
64 match size_format {
65 0 | 2 => {
66 //size_format actually only uses one bit
67 //regenerated_size uses 5 bits
68 Ok(1)
69 }
70 1 => {
71 //size_format uses 2 bit
72 //regenerated_size uses 12 bits
73 Ok(2)
74 }
75 3 => {
76 //size_format uses 2 bit
77 //regenerated_size uses 20 bits
78 Ok(3)
79 }
80 _ => panic!(
81 "This is a bug in the program. There should only be values between 0..3"
82 ),
83 }
84 }
85 LiteralsSectionType::Compressed | LiteralsSectionType::Treeless => {
86 match size_format {
87 0 | 1 => {
88 //Only differ in num_streams
89 //both regenerated and compressed sizes use 10 bit
90 Ok(3)
91 }
92 2 => {
93 //both regenerated and compressed sizes use 14 bit
94 Ok(4)
95 }
96 3 => {
97 //both regenerated and compressed sizes use 18 bit
98 Ok(5)
99 }
100
101 _ => panic!(
102 "This is a bug in the program. There should only be values between 0..3"
103 ),
104 }
105 }
106 }
107 }
108
109 pub fn parse_from_header(&mut self, raw: &[u8]) -> Result<u8, LiteralsSectionParseError> {
110 let mut br = BitReader::new(raw);
111 let t = br.get_bits(2)? as u8;
112 self.ls_type = Self::section_type(t)?;
113 let size_format = br.get_bits(2)? as u8;
114
115 let byte_needed = self.header_bytes_needed(raw[0])?;
116 if raw.len() < byte_needed as usize {
117 return Err(LiteralsSectionParseError::NotEnoughBytes {
118 have: raw.len(),
119 need: byte_needed,
120 });
121 }
122
123 match self.ls_type {
124 LiteralsSectionType::RLE | LiteralsSectionType::Raw => {
125 self.compressed_size = None;
126 match size_format {
127 0 | 2 => {
128 //size_format actually only uses one bit
129 //regenerated_size uses 5 bits
130 self.regenerated_size = u32::from(raw[0]) >> 3;
131 Ok(1)
132 }
133 1 => {
134 //size_format uses 2 bit
135 //regenerated_size uses 12 bits
136 self.regenerated_size = (u32::from(raw[0]) >> 4) + (u32::from(raw[1]) << 4);
137 Ok(2)
138 }
139 3 => {
140 //size_format uses 2 bit
141 //regenerated_size uses 20 bits
142 self.regenerated_size = (u32::from(raw[0]) >> 4)
143 + (u32::from(raw[1]) << 4)
144 + (u32::from(raw[2]) << 12);
145 Ok(3)
146 }
147 _ => panic!(
148 "This is a bug in the program. There should only be values between 0..3"
149 ),
150 }
151 }
152 LiteralsSectionType::Compressed | LiteralsSectionType::Treeless => {
153 match size_format {
154 0 => {
155 self.num_streams = Some(1);
156 }
157 1..=3 => {
158 self.num_streams = Some(4);
159 }
160 _ => panic!(
161 "This is a bug in the program. There should only be values between 0..3"
162 ),
163 };
164
165 match size_format {
166 0 | 1 => {
167 //Differ in num_streams see above
168 //both regenerated and compressed sizes use 10 bit
169
170 //4 from the first, six from the second byte
171 self.regenerated_size =
172 (u32::from(raw[0]) >> 4) + ((u32::from(raw[1]) & 0x3f) << 4);
173
174 // 2 from the second, full last byte
175 self.compressed_size =
176 Some(u32::from(raw[1] >> 6) + (u32::from(raw[2]) << 2));
177 Ok(3)
178 }
179 2 => {
180 //both regenerated and compressed sizes use 14 bit
181
182 //4 from first, full second, 2 from the third byte
183 self.regenerated_size = (u32::from(raw[0]) >> 4)
184 + (u32::from(raw[1]) << 4)
185 + ((u32::from(raw[2]) & 0x3) << 12);
186
187 //6 from the third, full last byte
188 self.compressed_size =
189 Some((u32::from(raw[2]) >> 2) + (u32::from(raw[3]) << 6));
190 Ok(4)
191 }
192 3 => {
193 //both regenerated and compressed sizes use 18 bit
194
195 //4 from first, full second, six from third byte
196 self.regenerated_size = (u32::from(raw[0]) >> 4)
197 + (u32::from(raw[1]) << 4)
198 + ((u32::from(raw[2]) & 0x3F) << 12);
199
200 //2 from third, full fourth, full fifth byte
201 self.compressed_size = Some(
202 (u32::from(raw[2]) >> 6)
203 + (u32::from(raw[3]) << 2)
204 + (u32::from(raw[4]) << 10),
205 );
206 Ok(5)
207 }
208
209 _ => panic!(
210 "This is a bug in the program. There should only be values between 0..3"
211 ),
212 }
213 }
214 }
215 }
216
217 fn section_type(raw: u8) -> Result<LiteralsSectionType, LiteralsSectionParseError> {
218 let t = raw & 0x3;
219 match t {
220 0 => Ok(LiteralsSectionType::Raw),
221 1 => Ok(LiteralsSectionType::RLE),
222 2 => Ok(LiteralsSectionType::Compressed),
223 3 => Ok(LiteralsSectionType::Treeless),
224 other => Err(LiteralsSectionParseError::IllegalLiteralSectionType { got: other }),
225 }
226 }
227}
228