embedded_shadow/staged/
patch.rs1use heapless::Vec;
2
3use crate::{ShadowError, types::StagingBuffer};
4
5#[derive(Clone, Copy)]
6struct StagedWrite {
7 addr: u16,
8 len: u16,
9 off: u16, }
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 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 if end <= out_start || start >= out_end {
91 continue; }
93
94 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 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}