1 | pub struct SequencesHeader { |
2 | pub num_sequences: u32, |
3 | pub modes: Option<CompressionModes>, |
4 | } |
5 | |
6 | #[derive (Clone, Copy)] |
7 | pub struct Sequence { |
8 | pub ll: u32, |
9 | pub ml: u32, |
10 | pub of: u32, |
11 | } |
12 | |
13 | impl core::fmt::Display for Sequence { |
14 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { |
15 | write!(f, "LL: {}, ML: {}, OF: {}" , self.ll, self.ml, self.of) |
16 | } |
17 | } |
18 | |
19 | #[derive (Copy, Clone)] |
20 | pub struct CompressionModes(u8); |
21 | pub enum ModeType { |
22 | Predefined, |
23 | RLE, |
24 | FSECompressed, |
25 | Repeat, |
26 | } |
27 | |
28 | impl CompressionModes { |
29 | pub fn decode_mode(m: u8) -> ModeType { |
30 | match m { |
31 | 0 => ModeType::Predefined, |
32 | 1 => ModeType::RLE, |
33 | 2 => ModeType::FSECompressed, |
34 | 3 => ModeType::Repeat, |
35 | _ => panic!("This can never happen" ), |
36 | } |
37 | } |
38 | |
39 | pub fn ll_mode(self) -> ModeType { |
40 | Self::decode_mode(self.0 >> 6) |
41 | } |
42 | |
43 | pub fn of_mode(self) -> ModeType { |
44 | Self::decode_mode((self.0 >> 4) & 0x3) |
45 | } |
46 | |
47 | pub fn ml_mode(self) -> ModeType { |
48 | Self::decode_mode((self.0 >> 2) & 0x3) |
49 | } |
50 | } |
51 | |
52 | impl Default for SequencesHeader { |
53 | fn default() -> Self { |
54 | Self::new() |
55 | } |
56 | } |
57 | |
58 | #[derive (Debug, derive_more::Display)] |
59 | #[cfg_attr (feature = "std" , derive(derive_more::Error))] |
60 | #[non_exhaustive ] |
61 | pub enum SequencesHeaderParseError { |
62 | #[display( |
63 | fmt = "source must have at least {need_at_least} bytes to parse header; got {got} bytes" |
64 | )] |
65 | NotEnoughBytes { need_at_least: u8, got: usize }, |
66 | } |
67 | |
68 | impl SequencesHeader { |
69 | pub fn new() -> SequencesHeader { |
70 | SequencesHeader { |
71 | num_sequences: 0, |
72 | modes: None, |
73 | } |
74 | } |
75 | |
76 | pub fn parse_from_header(&mut self, source: &[u8]) -> Result<u8, SequencesHeaderParseError> { |
77 | let mut bytes_read = 0; |
78 | if source.is_empty() { |
79 | return Err(SequencesHeaderParseError::NotEnoughBytes { |
80 | need_at_least: 1, |
81 | got: 0, |
82 | }); |
83 | } |
84 | |
85 | let source = match source[0] { |
86 | 0 => { |
87 | self.num_sequences = 0; |
88 | return Ok(1); |
89 | } |
90 | 1..=127 => { |
91 | if source.len() < 2 { |
92 | return Err(SequencesHeaderParseError::NotEnoughBytes { |
93 | need_at_least: 2, |
94 | got: source.len(), |
95 | }); |
96 | } |
97 | self.num_sequences = u32::from(source[0]); |
98 | bytes_read += 1; |
99 | &source[1..] |
100 | } |
101 | 128..=254 => { |
102 | if source.len() < 3 { |
103 | return Err(SequencesHeaderParseError::NotEnoughBytes { |
104 | need_at_least: 3, |
105 | got: source.len(), |
106 | }); |
107 | } |
108 | self.num_sequences = ((u32::from(source[0]) - 128) << 8) + u32::from(source[1]); |
109 | bytes_read += 2; |
110 | &source[2..] |
111 | } |
112 | 255 => { |
113 | if source.len() < 4 { |
114 | return Err(SequencesHeaderParseError::NotEnoughBytes { |
115 | need_at_least: 4, |
116 | got: source.len(), |
117 | }); |
118 | } |
119 | self.num_sequences = u32::from(source[1]) + (u32::from(source[2]) << 8) + 0x7F00; |
120 | bytes_read += 3; |
121 | &source[3..] |
122 | } |
123 | }; |
124 | |
125 | self.modes = Some(CompressionModes(source[0])); |
126 | bytes_read += 1; |
127 | |
128 | Ok(bytes_read) |
129 | } |
130 | } |
131 | |