Decode DoubleDelta-compressed bytes back to i64 values.
(data: &[u8])
| 153 | |
| 154 | /// Decode DoubleDelta-compressed bytes back to i64 values. |
| 155 | pub fn decode(data: &[u8]) -> Result<Vec<i64>, CodecError> { |
| 156 | if data.len() < 4 { |
| 157 | return Err(CodecError::Truncated { |
| 158 | expected: 4, |
| 159 | actual: data.len(), |
| 160 | }); |
| 161 | } |
| 162 | |
| 163 | let count = u32::from_le_bytes(data[0..4].try_into().map_err(|_| CodecError::Corrupt { |
| 164 | detail: "invalid header".into(), |
| 165 | })?) as usize; |
| 166 | |
| 167 | if count == 0 { |
| 168 | return Ok(Vec::new()); |
| 169 | } |
| 170 | |
| 171 | if data.len() < 12 { |
| 172 | return Err(CodecError::Truncated { |
| 173 | expected: 12, |
| 174 | actual: data.len(), |
| 175 | }); |
| 176 | } |
| 177 | |
| 178 | let first_value = |
| 179 | i64::from_le_bytes(data[4..12].try_into().map_err(|_| CodecError::Corrupt { |
| 180 | detail: "invalid first value".into(), |
| 181 | })?); |
| 182 | |
| 183 | let mut values = Vec::with_capacity(count); |
| 184 | values.push(first_value); |
| 185 | |
| 186 | if count == 1 { |
| 187 | return Ok(values); |
| 188 | } |
| 189 | |
| 190 | if data.len() < 20 { |
| 191 | return Err(CodecError::Truncated { |
| 192 | expected: 20, |
| 193 | actual: data.len(), |
| 194 | }); |
| 195 | } |
| 196 | |
| 197 | let first_delta = |
| 198 | i64::from_le_bytes(data[12..20].try_into().map_err(|_| CodecError::Corrupt { |
| 199 | detail: "invalid first delta".into(), |
| 200 | })?); |
| 201 | values.push(first_value.wrapping_add(first_delta)); |
| 202 | |
| 203 | if count == 2 { |
| 204 | return Ok(values); |
| 205 | } |
| 206 | |
| 207 | let mut reader = BitReader::new(&data[20..]); |
| 208 | let mut prev_delta = first_delta; |
| 209 | |
| 210 | for _ in 2..count { |
| 211 | let dod = decode_dod(&mut reader)?; |
| 212 | let delta = prev_delta.wrapping_add(dod); |