1use crate::user_ptr::{UserInOutPtr, UserInPtr, UserOutPtr};
8use zerocopy::{FromBytes, Immutable, IntoBytes};
9use zx_status::Status;
10use zx_types::zx_iovec_t;
11
12#[repr(C)]
13#[derive(Debug, Copy, Clone, FromBytes, IntoBytes, Immutable, Default)]
14struct RawIovec {
15 buffer: usize,
16 capacity: usize,
17}
18
19#[derive(Debug, Copy, Clone)]
21pub struct UserInIovec {
22 vector: UserInPtr<zx_iovec_t>,
23 count: usize,
24}
25
26impl UserInIovec {
27 pub const fn new(vector: UserInPtr<zx_iovec_t>, count: usize) -> Self {
29 Self { vector, count }
30 }
31
32 pub fn is_null(&self) -> bool {
34 self.vector.is_null()
35 }
36
37 pub fn get_total_capacity(&self) -> Result<usize, Status> {
39 let mut total = 0usize;
40 let raw_vec = self.vector.reinterpret::<RawIovec>();
41 for i in 0..self.count {
42 let elem = raw_vec.element_offset(i).read()?;
43 total = total.checked_add(elem.capacity).ok_or(Status::INVALID_ARGS)?;
44 }
45 Ok(total)
46 }
47
48 pub fn for_each<F>(&self, mut cb: F) -> Result<(), Status>
50 where
51 F: FnMut(UserInPtr<u8>, usize) -> Result<(), Status>,
52 {
53 let raw_vec = self.vector.reinterpret::<RawIovec>();
54 for i in 0..self.count {
55 let elem = raw_vec.element_offset(i).read()?;
56 let ptr = UserInPtr::new(elem.buffer as *const u8);
57 cb(ptr, elem.capacity)?;
58 }
59 Ok(())
60 }
61}
62
63#[derive(Debug, Copy, Clone)]
65pub struct UserOutIovec {
66 vector: UserInPtr<zx_iovec_t>,
67 count: usize,
68}
69
70impl UserOutIovec {
71 pub const fn new(vector: UserInPtr<zx_iovec_t>, count: usize) -> Self {
73 Self { vector, count }
74 }
75
76 pub fn is_null(&self) -> bool {
78 self.vector.is_null()
79 }
80
81 pub fn get_total_capacity(&self) -> Result<usize, Status> {
83 let mut total = 0usize;
84 let raw_vec = self.vector.reinterpret::<RawIovec>();
85 for i in 0..self.count {
86 let elem = raw_vec.element_offset(i).read()?;
87 total = total.checked_add(elem.capacity).ok_or(Status::INVALID_ARGS)?;
88 }
89 Ok(total)
90 }
91
92 pub fn for_each<F>(&self, mut cb: F) -> Result<(), Status>
94 where
95 F: FnMut(UserOutPtr<u8>, usize) -> Result<(), Status>,
96 {
97 let raw_vec = self.vector.reinterpret::<RawIovec>();
98 for i in 0..self.count {
99 let elem = raw_vec.element_offset(i).read()?;
100 let ptr = UserOutPtr::new(elem.buffer as *mut u8);
101 cb(ptr, elem.capacity)?;
102 }
103 Ok(())
104 }
105}
106
107#[derive(Debug, Copy, Clone)]
109pub struct UserInOutIovec {
110 vector: UserInPtr<zx_iovec_t>,
111 count: usize,
112}
113
114impl UserInOutIovec {
115 pub const fn new(vector: UserInPtr<zx_iovec_t>, count: usize) -> Self {
117 Self { vector, count }
118 }
119
120 pub fn is_null(&self) -> bool {
122 self.vector.is_null()
123 }
124
125 pub fn get_total_capacity(&self) -> Result<usize, Status> {
127 let mut total = 0usize;
128 let raw_vec = self.vector.reinterpret::<RawIovec>();
129 for i in 0..self.count {
130 let elem = raw_vec.element_offset(i).read()?;
131 total = total.checked_add(elem.capacity).ok_or(Status::INVALID_ARGS)?;
132 }
133 Ok(total)
134 }
135
136 pub fn for_each<F>(&self, mut cb: F) -> Result<(), Status>
138 where
139 F: FnMut(UserInOutPtr<u8>, usize) -> Result<(), Status>,
140 {
141 let raw_vec = self.vector.reinterpret::<RawIovec>();
142 for i in 0..self.count {
143 let elem = raw_vec.element_offset(i).read()?;
144 let ptr = UserInOutPtr::new(elem.buffer as *mut u8);
145 cb(ptr, elem.capacity)?;
146 }
147 Ok(())
148 }
149}