1use std::fmt::Debug;
2use std::iter::repeat_n;
3
4use num_traits::{PrimInt, ToPrimitive as _};
5
6use crate::MltError::{ParsingLogicalTechnique, RleRunLenInvalid, UnsupportedLogicalEncoding};
7use crate::codecs::zigzag::{decode_componentwise_delta_vec2s, decode_zigzag, decode_zigzag_delta};
8use crate::decoder::{LogicalEncoding, LogicalTechnique, LogicalValue, RleMeta, StreamMeta};
9use crate::errors::{AsMltError as _, fail_if_invalid_stream_size};
10use crate::utils::AsUsize as _;
11use crate::{Decoder, MltResult};
12
13impl RleMeta {
14 pub fn decode<T: PrimInt + Debug>(self, data: &[T], dec: &mut Decoder) -> MltResult<Vec<T>> {
17 let expected_len = self.runs.as_usize().checked_mul(2).or_overflow()?;
18 fail_if_invalid_stream_size(data.len(), expected_len)?;
19
20 let (run_lens, values) = data.split_at(self.runs.as_usize());
21 fail_if_invalid_stream_size(self.num_rle_values, Self::calc_size(run_lens)?)?;
22
23 let alloc_size = self.num_rle_values.as_usize();
24 let mut result = dec.alloc(alloc_size)?;
25 for (&run_len, &val) in run_lens.iter().zip(values.iter()) {
26 let run = run_len
27 .to_usize()
28 .ok_or_else(|| RleRunLenInvalid(run_len.to_i128().unwrap_or_default()))?;
29 result.extend(repeat_n(val, run));
30 }
31 dec.adjust_alloc(&result, alloc_size)?;
32 Ok(result)
33 }
34
35 fn calc_size<T: PrimInt + Debug>(run_lens: &[T]) -> MltResult<u32> {
36 run_lens
37 .iter()
38 .try_fold(T::zero(), |a, v| a.checked_add(v))
39 .and_then(|v| v.to_u32())
40 .ok_or_else(|| RleRunLenInvalid(run_lens.len().to_i128().unwrap_or_default()))
41 }
42}
43
44impl LogicalTechnique {
45 pub fn parse(value: u8) -> MltResult<Self> {
46 Self::try_from(value).or(Err(ParsingLogicalTechnique(value)))
47 }
48}
49
50impl LogicalValue {
51 #[must_use]
52 pub fn new(meta: StreamMeta) -> Self {
53 Self { meta }
54 }
55
56 pub fn decode_i32(self, data: &[u32], dec: &mut Decoder) -> MltResult<Vec<i32>> {
61 match self.meta.encoding.logical {
62 LogicalEncoding::None => decode_zigzag(data, dec),
63 LogicalEncoding::Rle(v) => decode_zigzag(&v.decode(data, dec)?, dec),
64 LogicalEncoding::ComponentwiseDelta => decode_componentwise_delta_vec2s(data, dec),
65 LogicalEncoding::Delta => decode_zigzag_delta::<i32, _>(data, dec),
66 LogicalEncoding::DeltaRle(v) => {
67 let expanded = v.decode(data, dec)?;
68 decode_zigzag_delta::<i32, _>(&expanded, dec)
69 }
70 LogicalEncoding::Morton(v) => v.decode_codes(data, dec),
71 LogicalEncoding::MortonDelta(v) => v.decode_delta(data, dec),
72 LogicalEncoding::MortonRle(_) => Err(UnsupportedLogicalEncoding(
73 self.meta.encoding.logical,
74 "i32 (MortonRle)",
75 )),
76 LogicalEncoding::PseudoDecimal => Err(UnsupportedLogicalEncoding(
77 self.meta.encoding.logical,
78 "i32",
79 )),
80 }
81 }
82
83 pub fn decode_u32(self, data: &[u32], dec: &mut Decoder) -> MltResult<Vec<u32>> {
88 let num = self.meta.num_values.as_usize();
89 match self.meta.encoding.logical {
90 LogicalEncoding::None => {
91 dec.consume_items::<u32>(num)?;
93 Ok(data.to_vec())
94 }
95 LogicalEncoding::Rle(rle) => rle.decode(data, dec),
96 LogicalEncoding::Delta => decode_zigzag_delta::<i32, _>(data, dec),
97 LogicalEncoding::DeltaRle(rle) => {
98 decode_zigzag_delta::<i32, _>(&rle.decode(data, dec)?, dec)
99 }
100 _ => Err(UnsupportedLogicalEncoding(
101 self.meta.encoding.logical,
102 "u32",
103 )),
104 }
105 }
106
107 pub fn decode_i64(self, data: &[u64], dec: &mut Decoder) -> MltResult<Vec<i64>> {
112 match self.meta.encoding.logical {
113 LogicalEncoding::None => decode_zigzag(data, dec),
114 LogicalEncoding::Delta => decode_zigzag_delta::<i64, _>(data, dec),
115 LogicalEncoding::DeltaRle(rle) => {
116 let expanded = rle.decode(data, dec)?;
117 decode_zigzag_delta::<i64, _>(&expanded, dec)
118 }
119 LogicalEncoding::Rle(rle) => {
120 let expanded = rle.decode(data, dec)?;
122 decode_zigzag(&expanded, dec)
123 }
124 _ => Err(UnsupportedLogicalEncoding(
125 self.meta.encoding.logical,
126 "i64",
127 )),
128 }
129 }
130
131 pub fn decode_u64(self, data: &[u64], dec: &mut Decoder) -> MltResult<Vec<u64>> {
136 let num = self.meta.num_values.as_usize();
137 match self.meta.encoding.logical {
138 LogicalEncoding::None => {
139 dec.consume_items::<u64>(num)?;
141 Ok(data.to_vec())
142 }
143 LogicalEncoding::Rle(rle) => rle.decode(data, dec),
144 LogicalEncoding::Delta => decode_zigzag_delta::<i64, _>(data, dec),
145 LogicalEncoding::DeltaRle(rle) => {
146 let expanded = rle.decode(data, dec)?;
147 decode_zigzag_delta::<i64, _>(&expanded, dec)
148 }
149 _ => Err(UnsupportedLogicalEncoding(
150 self.meta.encoding.logical,
151 "u64",
152 )),
153 }
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use super::*;
160 use crate::MltError::InvalidDecodingStreamSize;
161 use crate::test_helpers::dec;
162
163 #[test]
164 fn test_decode_rle_empty() {
165 let rle = RleMeta {
166 runs: 0,
167 num_rle_values: 0,
168 };
169 assert!(rle.decode::<u32>(&[], &mut dec()).unwrap().is_empty());
170 }
171
172 #[test]
173 fn test_decode_rle_invalid_stream_size() {
174 let rle = RleMeta {
176 runs: 2,
177 num_rle_values: 3,
178 };
179 let data = [1u32, 2, 3];
180 let err = rle.decode::<u32>(&data, &mut dec()).unwrap_err();
181 assert!(matches!(err, InvalidDecodingStreamSize(3, 4)));
182 }
183}