Decode a single block from the byte stream. Returns the new offset after this block.
(
data: &[u8],
offset: usize,
values: &mut Vec<i64>,
block_idx: usize,
)
| 66 | /// |
| 67 | /// Returns the new offset after this block. |
| 68 | pub(super) fn decode_block( |
| 69 | data: &[u8], |
| 70 | offset: usize, |
| 71 | values: &mut Vec<i64>, |
| 72 | block_idx: usize, |
| 73 | ) -> Result<usize, CodecError> { |
| 74 | if offset + BLOCK_HEADER_SIZE > data.len() { |
| 75 | return Err(CodecError::Truncated { |
| 76 | expected: offset + BLOCK_HEADER_SIZE, |
| 77 | actual: data.len(), |
| 78 | }); |
| 79 | } |
| 80 | |
| 81 | let count = u16::from_le_bytes([data[offset], data[offset + 1]]) as usize; |
| 82 | let bit_width = data[offset + 2]; |
| 83 | let min_val = i64::from_le_bytes([ |
| 84 | data[offset + 3], |
| 85 | data[offset + 4], |
| 86 | data[offset + 5], |
| 87 | data[offset + 6], |
| 88 | data[offset + 7], |
| 89 | data[offset + 8], |
| 90 | data[offset + 9], |
| 91 | data[offset + 10], |
| 92 | ]); |
| 93 | |
| 94 | let mut pos = offset + BLOCK_HEADER_SIZE; |
| 95 | |
| 96 | if bit_width == 0 { |
| 97 | // All values are min_val. |
| 98 | values.extend(std::iter::repeat_n(min_val, count)); |
| 99 | return Ok(pos); |
| 100 | } |
| 101 | |
| 102 | if bit_width > 64 { |
| 103 | return Err(CodecError::Corrupt { |
| 104 | detail: format!("block {block_idx}: invalid bit_width {bit_width}"), |
| 105 | }); |
| 106 | } |
| 107 | |
| 108 | let packed_bytes = (count * bit_width as usize).div_ceil(8); |
| 109 | if pos + packed_bytes > data.len() { |
| 110 | return Err(CodecError::Truncated { |
| 111 | expected: pos + packed_bytes, |
| 112 | actual: data.len(), |
| 113 | }); |
| 114 | } |
| 115 | |
| 116 | let packed = &data[pos..pos + packed_bytes]; |
| 117 | let mask: u64 = if bit_width == 64 { |
| 118 | u64::MAX |
| 119 | } else { |
| 120 | (1u64 << bit_width) - 1 |
| 121 | }; |
| 122 | |
| 123 | // Unpack residuals and add min_val. |
| 124 | let mut bit_offset: usize = 0; |
| 125 | for _ in 0..count { |
no test coverage detected