Decode ALP-compressed bytes back to f64 values.
(data: &[u8])
| 152 | |
| 153 | /// Decode ALP-compressed bytes back to f64 values. |
| 154 | pub fn decode(data: &[u8]) -> Result<Vec<f64>, CodecError> { |
| 155 | const HEADER_SIZE: usize = 11; // 4 + 1 + 1 + 1 + 4 |
| 156 | |
| 157 | if data.len() < HEADER_SIZE { |
| 158 | return Err(CodecError::Truncated { |
| 159 | expected: HEADER_SIZE, |
| 160 | actual: data.len(), |
| 161 | }); |
| 162 | } |
| 163 | |
| 164 | let count = u32::from_le_bytes([data[0], data[1], data[2], data[3]]) as usize; |
| 165 | let _encode_exp = data[4]; |
| 166 | let decode_exp = data[5]; |
| 167 | let mode = match data[6] { |
| 168 | 0 => DecodeMode::MultiplyInverse, |
| 169 | 1 => DecodeMode::DivideByFactor, |
| 170 | m => { |
| 171 | return Err(CodecError::Corrupt { |
| 172 | detail: format!("invalid ALP decode mode {m}"), |
| 173 | }); |
| 174 | } |
| 175 | }; |
| 176 | let exception_count = u32::from_le_bytes([data[7], data[8], data[9], data[10]]) as usize; |
| 177 | |
| 178 | if count == 0 { |
| 179 | return Ok(Vec::new()); |
| 180 | } |
| 181 | |
| 182 | if decode_exp > MAX_EXPONENT { |
| 183 | return Err(CodecError::Corrupt { |
| 184 | detail: format!("invalid ALP decode_exp {decode_exp}"), |
| 185 | }); |
| 186 | } |
| 187 | |
| 188 | // Read exceptions. |
| 189 | let exceptions_size = exception_count * 12; |
| 190 | let exceptions_end = HEADER_SIZE + exceptions_size; |
| 191 | if data.len() < exceptions_end { |
| 192 | return Err(CodecError::Truncated { |
| 193 | expected: exceptions_end, |
| 194 | actual: data.len(), |
| 195 | }); |
| 196 | } |
| 197 | |
| 198 | let mut exceptions = Vec::with_capacity(exception_count); |
| 199 | let mut pos = HEADER_SIZE; |
| 200 | for _ in 0..exception_count { |
| 201 | let idx = |
| 202 | u32::from_le_bytes([data[pos], data[pos + 1], data[pos + 2], data[pos + 3]]) as usize; |
| 203 | let bits = u64::from_le_bytes([ |
| 204 | data[pos + 4], |
| 205 | data[pos + 5], |
| 206 | data[pos + 6], |
| 207 | data[pos + 7], |
| 208 | data[pos + 8], |
| 209 | data[pos + 9], |
| 210 | data[pos + 10], |
| 211 | data[pos + 11], |