Skip to main content

leodos_protocols/transport/srspp/machine/receiver/utils/
slotmap.rs

1/// Fixed-size slot map with `N` slots of `SLOT` bytes each.
2pub struct SlotMap<const TOTAL: usize, const N: usize, const SLOT: usize> {
3    /// Flat byte storage for all slots.
4    data: [u8; TOTAL],
5    /// Per-slot payload lengths.
6    lens: [u16; N],
7}
8
9impl<const TOTAL: usize, const N: usize, const SLOT: usize>
10    SlotMap<TOTAL, N, SLOT>
11{
12    /// Create a new zeroed slot map.
13    pub fn new() -> Self {
14        Self {
15            data: [0u8; TOTAL],
16            lens: [0u16; N],
17        }
18    }
19
20    /// Write payload into slot `i`.
21    pub fn write(&mut self, i: usize, payload: &[u8]) {
22        debug_assert!(i < N);
23        debug_assert!(payload.len() <= SLOT);
24        let start = i * SLOT;
25        self.data[start..start + payload.len()].copy_from_slice(payload);
26        self.lens[i] = payload.len() as u16;
27    }
28
29    /// Copy slot `i` into `dst`, returning the number of bytes copied.
30    pub fn read(&self, i: usize, dst: &mut [u8]) -> usize {
31        debug_assert!(i < N);
32        let start = i * SLOT;
33        let len = self.lens[i] as usize;
34        dst[..len].copy_from_slice(&self.data[start..start + len]);
35        len
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn slotmap_write_read() {
45        let mut sm = SlotMap::<64, 4, 16>::new();
46        sm.write(0, &[1, 2, 3]);
47        sm.write(2, &[4, 5]);
48        let mut buf = [0u8; 16];
49        let len = sm.read(0, &mut buf);
50        assert_eq!(&buf[..len], &[1, 2, 3]);
51        let len = sm.read(2, &mut buf);
52        assert_eq!(&buf[..len], &[4, 5]);
53    }
54}