embedded_shadow/view/
host.rs1use core::marker::PhantomData;
2
3use crate::{AccessPolicy, PersistTrigger, ShadowError, policy::PersistPolicy, table::ShadowTable};
4use bitmaps::{Bits, BitsImpl};
5
6pub struct HostView<'a, const TS: usize, const BS: usize, const BC: usize, AP, PP, PT, PK>
7where
8 BitsImpl<BC>: Bits,
9 AP: AccessPolicy,
10 PP: PersistPolicy<PK>,
11 PT: PersistTrigger<PK>,
12{
13 pub(crate) table: &'a mut ShadowTable<TS, BS, BC>,
14 pub(crate) access_policy: &'a AP,
15 pub(crate) persist_policy: &'a PP,
16 pub(crate) persist_trigger: &'a mut PT,
17 _phantom: PhantomData<PK>,
18}
19
20impl<'a, const TS: usize, const BS: usize, const BC: usize, AP, PP, PT, PK>
21 HostView<'a, TS, BS, BC, AP, PP, PT, PK>
22where
23 BitsImpl<BC>: Bits,
24 AP: AccessPolicy,
25 PP: PersistPolicy<PK>,
26 PT: PersistTrigger<PK>,
27{
28 pub(crate) fn new(
29 table: &'a mut ShadowTable<TS, BS, BC>,
30 access_policy: &'a AP,
31 persist_policy: &'a PP,
32 persist_trigger: &'a mut PT,
33 ) -> Self {
34 Self {
35 table,
36 access_policy,
37 persist_policy,
38 persist_trigger,
39 _phantom: PhantomData,
40 }
41 }
42
43 pub fn read_range(&self, addr: u16, out: &mut [u8]) -> Result<(), ShadowError> {
44 if !self.access_policy.can_read(addr, out.len()) {
45 return Err(ShadowError::Denied);
46 }
47 self.table.read_range(addr, out)
48 }
49
50 pub fn write_range(&mut self, addr: u16, data: &[u8]) -> Result<(), ShadowError> {
52 self.write_range_no_persist(addr, data)?;
53
54 let should_persist =
55 self.persist_policy
56 .push_persist_keys_for_range(addr, data.len(), |key| {
57 self.persist_trigger.push_key(key)
58 });
59
60 if should_persist {
61 self.persist_trigger.request_persist();
62 }
63
64 Ok(())
65 }
66
67 pub(crate) fn write_range_no_persist(
68 &mut self,
69 addr: u16,
70 data: &[u8],
71 ) -> Result<(), ShadowError> {
72 if !self.access_policy.can_write(addr, data.len()) {
73 return Err(ShadowError::Denied);
74 }
75
76 self.table.write_range(addr, data)?;
77 self.table.mark_dirty(addr, data.len())?;
78
79 Ok(())
80 }
81}