| 189 | /// Writes `val` in `SIZE` blocks with the appropriate continuation tokens |
| 190 | #[inline] |
| 191 | fn encode_blocks<const SIZE: usize>(out: &mut [u8], val: &[u8]) -> usize { |
| 192 | let block_count = ceil(val.len(), SIZE); |
| 193 | let end_offset = block_count * (SIZE + 1); |
| 194 | let to_write = &mut out[..end_offset]; |
| 195 | |
| 196 | let chunks = val.chunks_exact(SIZE); |
| 197 | let remainder = chunks.remainder(); |
| 198 | for (input, output) in chunks.clone().zip(to_write.chunks_exact_mut(SIZE + 1)) { |
| 199 | let input: &[u8; SIZE] = input.try_into().unwrap(); |
| 200 | let out_block: &mut [u8; SIZE] = (&mut output[..SIZE]).try_into().unwrap(); |
| 201 | |
| 202 | *out_block = *input; |
| 203 | |
| 204 | // Indicate that there are further blocks to follow |
| 205 | output[SIZE] = BLOCK_CONTINUATION; |
| 206 | } |
| 207 | |
| 208 | if !remainder.is_empty() { |
| 209 | let start_offset = (block_count - 1) * (SIZE + 1); |
| 210 | to_write[start_offset..start_offset + remainder.len()].copy_from_slice(remainder); |
| 211 | *to_write.last_mut().unwrap() = remainder.len() as u8; |
| 212 | } else { |
| 213 | // We must overwrite the continuation marker written by the loop above |
| 214 | *to_write.last_mut().unwrap() = SIZE as u8; |
| 215 | } |
| 216 | end_offset |
| 217 | } |
| 218 | |
| 219 | /// Decodes a single block of data |
| 220 | /// The `f` function accepts a slice of the decoded data, it may be called multiple times |