embedded_shadow/staged/
patch.rs

1use heapless::Vec;
2
3use crate::{ShadowError, types::StagingBuffer};
4
5#[derive(Clone, Copy)]
6struct StagedWrite {
7    addr: u16,
8    len: u16,
9    off: u16, // offset into data vec
10}
11
12pub struct PatchStagingBuffer<const DC: usize, const EC: usize> {
13    data: Vec<u8, DC>,
14    entries: Vec<StagedWrite, EC>,
15}
16
17impl<const DC: usize, const EC: usize> PatchStagingBuffer<DC, EC> {
18    pub const fn new() -> Self {
19        Self {
20            data: Vec::new(),
21            entries: Vec::new(),
22        }
23    }
24
25    fn push_bytes(&mut self, bytes: &[u8]) -> Result<u16, ShadowError> {
26        let off = self.data.len();
27        if off + bytes.len() > DC {
28            return Err(ShadowError::StageFull);
29        }
30
31        self.data
32            .extend_from_slice(bytes)
33            .map_err(|_| ShadowError::StageFull)?;
34
35        Ok(off as u16)
36    }
37}
38
39impl<const DC: usize, const EC: usize> Default for PatchStagingBuffer<DC, EC> {
40    fn default() -> Self {
41        Self::new()
42    }
43}
44
45impl<const DC: usize, const EC: usize> StagingBuffer for PatchStagingBuffer<DC, EC> {
46    fn any_staged(&self) -> bool {
47        !self.entries.is_empty()
48    }
49
50    fn for_each_staged<F>(&self, mut f: F) -> Result<(), ShadowError>
51    where
52        F: FnMut(u16, &[u8]) -> Result<(), ShadowError>,
53    {
54        for e in self.entries.iter() {
55            let buf = &self.data[e.off as usize..(e.off + e.len) as usize];
56            f(e.addr, buf)?;
57        }
58        Ok(())
59    }
60
61    fn write_staged(&mut self, addr: u16, data: &[u8]) -> Result<(), ShadowError> {
62        let off = self.push_bytes(data)?;
63
64        let entry = StagedWrite {
65            addr,
66            len: data.len() as u16,
67            off,
68        };
69
70        self.entries
71            .push(entry)
72            .map_err(|_| ShadowError::StageFull)?;
73
74        Ok(())
75    }
76
77    fn apply_overlay(&self, addr: u16, out: &mut [u8]) -> Result<(), ShadowError> {
78        if !self.any_staged() {
79            return Ok(());
80        }
81
82        // overlay staged writes onto out
83        for e in self.entries.iter() {
84            let start = e.addr as usize;
85            let end = start + e.len as usize;
86            let out_start = addr as usize;
87            let out_end = out_start + out.len();
88
89            // Check for overlap
90            if end <= out_start || start >= out_end {
91                continue; // No overlap
92            }
93
94            // Calculate overlapping range
95            let overlap_start = start.max(out_start);
96            let overlap_end = end.min(out_end);
97
98            let data_i = overlap_start - start + e.off as usize;
99            let out_i = overlap_start - out_start;
100            let n = overlap_end - overlap_start;
101
102            // Write staged data into the output buffer
103            out[out_i..out_i + n].copy_from_slice(&self.data[data_i..data_i + n]);
104        }
105
106        Ok(())
107    }
108
109    fn clear_staged(&mut self) -> Result<(), ShadowError> {
110        self.data.clear();
111        self.entries.clear();
112        Ok(())
113    }
114}