inspect_format/container/
fuchsia.rs1use crate::{BlockContainer, CopyBytes, ReadBytes, WriteBytes};
6
7#[derive(Debug)]
8pub struct Container {
9 buffer_addr: usize,
10 vmo_size: usize,
11}
12
13impl Container {
14 pub fn read_and_write(size: usize) -> Result<(Self, zx::Vmo), zx::Status> {
15 let vmo = zx::Vmo::create(size as u64)?;
16 let flags = zx::VmarFlags::PERM_READ
17 | zx::VmarFlags::MAP_RANGE
18 | zx::VmarFlags::REQUIRE_NON_RESIZABLE
19 | zx::VmarFlags::PERM_WRITE;
20 let buffer_addr = Self::map_vmo(&vmo, size, flags)?;
21 Ok((Self { buffer_addr, vmo_size: size }, vmo))
22 }
23
24 pub fn read_only(vmo: &zx::Vmo) -> Result<Self, zx::Status> {
25 let vmo_size = vmo.get_size()? as usize;
26 let flags = zx::VmarFlags::PERM_READ | zx::VmarFlags::REQUIRE_NON_RESIZABLE;
27 let buffer_addr = Self::map_vmo(vmo, vmo_size, flags)?;
28 Ok(Self { buffer_addr, vmo_size })
29 }
30
31 fn map_vmo(vmo: &zx::Vmo, vmo_size: usize, flags: zx::VmarFlags) -> Result<usize, zx::Status> {
32 let buffer_addr = fuchsia_runtime::vmar_root_self().map(0, vmo, 0, vmo_size, flags)?;
33 Ok(buffer_addr)
34 }
35}
36
37impl Drop for Container {
38 fn drop(&mut self) {
39 unsafe {
42 fuchsia_runtime::vmar_root_self()
43 .unmap(self.buffer_addr, self.vmo_size)
44 .expect("failed to unmap Container");
45 }
46 }
47}
48
49impl BlockContainer for Container {
50 type Data = zx::Vmo;
51 type ShareableData = zx::Vmo;
52
53 #[inline]
54 fn len(&self) -> usize {
55 self.vmo_size
56 }
57}
58
59impl ReadBytes for Container {
60 #[inline]
63 fn get_slice_at(&self, offset: usize, size: usize) -> Option<&[u8]> {
64 if offset >= self.len() {
65 return None;
66 }
67 let upper_bound = offset.checked_add(size)?;
68 if upper_bound > self.len() {
69 return None;
70 }
71 let ptr = (self.buffer_addr + offset) as *const u8;
72 unsafe { Some(std::slice::from_raw_parts(ptr, size)) }
76 }
77}
78
79impl CopyBytes for Container {
80 #[inline]
81 fn copy_bytes_at(&self, offset: usize, dst: &mut [u8]) {
82 if let Some(slice) = self.get_slice_at(offset, dst.len()) {
83 dst.copy_from_slice(slice);
84 }
85 }
86}
87
88impl WriteBytes for Container {
89 #[inline]
92 fn get_slice_mut_at(&mut self, offset: usize, size: usize) -> Option<&mut [u8]> {
93 if offset >= self.len() {
94 return None;
95 }
96 let upper_bound = offset.checked_add(size)?;
97 if upper_bound > self.len() {
98 return None;
99 }
100 let ptr = (self.buffer_addr + offset) as *mut u8;
101 unsafe { Some(std::slice::from_raw_parts_mut(ptr, size)) }
105 }
106}
107
108impl BlockContainer for zx::Vmo {
109 type Data = Self;
110 type ShareableData = Self;
111
112 #[inline]
113 fn len(&self) -> usize {
114 self.get_size().ok().unwrap() as usize
115 }
116}
117
118impl CopyBytes for zx::Vmo {
119 #[inline]
120 fn copy_bytes_at(&self, offset: usize, dst: &mut [u8]) {
121 self.read(dst, offset as u64).ok();
122 }
123}