1#![allow(unused_variables)]
4use core::{mem::MaybeUninit, sync::atomic::AtomicU64};
5
6use crate::{
7 bindings::wait_kind,
8 error::RawTwzError,
9 fd::{RawFd, SocketAddress},
10 nk, Result,
11};
12
13bitflags::bitflags! {
14 #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
16 pub struct IoFlags : crate::bindings::io_flags {
17 const NONBLOCKING = crate::bindings::IO_NONBLOCKING;
19 const PEEK = crate::bindings::IO_PEEK;
21 const WAITALL = crate::bindings::IO_WAITALL;
23 const OOB = crate::bindings::IO_OOB;
25 }
26}
27
28pub enum SeekFrom {
30 Start(u64),
31 End(i64),
32 Current(i64),
33}
34
35fn optoff(off: Option<u64>) -> crate::bindings::optional_offset {
36 match off {
37 Some(o) => o.try_into().unwrap_or(crate::bindings::FD_POS),
38 None => crate::bindings::FD_POS,
39 }
40}
41
42impl Into<Result<usize>> for crate::bindings::io_result {
43 fn into(self) -> Result<usize> {
44 let raw = RawTwzError::new(self.err);
45 if raw.is_success() {
46 Ok(self.val)
47 } else {
48 Err(raw.error())
49 }
50 }
51}
52
53impl From<Result<usize>> for crate::bindings::io_result {
54 fn from(value: Result<usize>) -> Self {
55 match value {
56 Ok(v) => Self {
57 val: v,
58 err: RawTwzError::success().raw(),
59 },
60 Err(e) => Self {
61 val: 0,
62 err: e.raw(),
63 },
64 }
65 }
66}
67
68#[derive(Clone, Copy)]
69#[repr(transparent)]
70pub struct IoCtx(crate::bindings::io_ctx);
71
72impl Default for IoCtx {
73 fn default() -> Self {
74 Self::new(None, IoFlags::empty(), None)
75 }
76}
77
78impl IoCtx {
79 pub fn new(pos: Option<u64>, flags: IoFlags, timeout: Option<core::time::Duration>) -> Self {
80 Self(crate::bindings::io_ctx {
81 offset: optoff(pos),
82 flags: flags.bits(),
83 timeout: timeout.into(),
84 })
85 }
86
87 pub fn offset(mut self, offset: Option<u64>) -> Self {
88 self.0.offset = optoff(offset);
89 self
90 }
91
92 pub fn flags(mut self, flags: IoFlags) -> Self {
93 self.0.flags = flags.bits();
94 self
95 }
96
97 pub fn timeout(mut self, timeout: Option<core::time::Duration>) -> Self {
98 self.0.timeout = timeout.into();
99 self
100 }
101
102 pub fn nonblocking(mut self, val: bool) -> Self {
103 if val {
104 self.0.flags |= IoFlags::NONBLOCKING.bits();
105 } else {
106 self.0.flags &= !IoFlags::NONBLOCKING.bits();
107 }
108 self
109 }
110}
111
112pub fn twz_rt_fd_pread(fd: RawFd, buf: &mut [u8], ctx: &mut IoCtx) -> Result<usize> {
115 unsafe {
116 nk!(
117 crate::bindings::twz_rt_fd_pread(fd, buf.as_mut_ptr().cast(), buf.len(), &mut ctx.0)
118 .into()
119 )
120 }
121}
122
123pub fn twz_rt_fd_pwrite(fd: RawFd, buf: &[u8], ctx: &mut IoCtx) -> Result<usize> {
126 unsafe {
127 nk!(
128 crate::bindings::twz_rt_fd_pwrite(fd, buf.as_ptr().cast(), buf.len(), &mut ctx.0)
129 .into()
130 )
131 }
132}
133
134pub fn twz_rt_fd_seek(fd: RawFd, seek: SeekFrom) -> Result<usize> {
136 let (whence, off) = match seek {
137 SeekFrom::Start(s) => (crate::bindings::WHENCE_START, s as i64),
138 SeekFrom::End(s) => (crate::bindings::WHENCE_END, s),
139 SeekFrom::Current(s) => (crate::bindings::WHENCE_CURRENT, s),
140 };
141 unsafe { nk!(crate::bindings::twz_rt_fd_seek(fd, whence, off).into()) }
142}
143
144#[derive(Copy, Clone)]
145#[repr(transparent)]
146pub struct Endpoint(crate::bindings::endpoint);
147
148impl Endpoint {
149 fn new_socket(sock: super::fd::SocketAddress) -> Self {
150 Self(crate::bindings::endpoint {
151 kind: crate::bindings::endpoint_kind_Endpoint_Socket,
152 addr: crate::bindings::endpoint_addrs {
153 socket_addr: sock.0,
154 },
155 })
156 }
157}
158
159#[repr(u32)]
160pub enum EndpointKind {
161 Unspecified = crate::bindings::endpoint_kind_Endpoint_Unspecified,
162 Socket = crate::bindings::endpoint_kind_Endpoint_Socket,
163}
164
165impl From<crate::bindings::endpoint> for Endpoint {
166 fn from(value: crate::bindings::endpoint) -> Self {
167 Self(value)
168 }
169}
170
171impl From<SocketAddress> for Endpoint {
172 fn from(value: SocketAddress) -> Self {
173 Self::new_socket(value)
174 }
175}
176
177impl TryFrom<Endpoint> for SocketAddress {
178 type Error = crate::error::TwzError;
179
180 fn try_from(value: Endpoint) -> Result<Self> {
181 match value.0.kind {
182 crate::bindings::endpoint_kind_Endpoint_Socket => {
183 let addr = unsafe { value.0.addr.socket_addr };
184 Ok(SocketAddress(addr))
185 }
186 _ => Err(crate::error::TwzError::INVALID_ARGUMENT),
187 }
188 }
189}
190
191pub fn twz_rt_fd_pread_from(
194 fd: RawFd,
195 buf: &mut [u8],
196 ctx: &mut IoCtx,
197) -> Result<(usize, Endpoint)> {
198 let mut endpoint = core::mem::MaybeUninit::uninit();
199 unsafe {
200 let len: Result<_> = nk!(crate::bindings::twz_rt_fd_pread_from(
201 fd,
202 buf.as_mut_ptr().cast(),
203 buf.len(),
204 &mut ctx.0,
205 endpoint.as_mut_ptr(),
206 ))
207 .into();
208 let len = len?;
209 Ok((len, endpoint.assume_init().into()))
210 }
211}
212
213pub fn twz_rt_fd_pwrite_to(
216 fd: RawFd,
217 buf: &[u8],
218 ctx: &mut IoCtx,
219 mut ep: Endpoint,
220) -> Result<usize> {
221 unsafe {
222 nk!(crate::bindings::twz_rt_fd_pwrite_to(
223 fd,
224 buf.as_ptr().cast(),
225 buf.len(),
226 &mut ctx.0,
227 &mut ep.0,
228 ))
229 .into()
230 }
231}
232
233pub type IoSlice = crate::bindings::iovec;
235
236pub fn twz_rt_fd_preadv(fd: RawFd, ios: &[IoSlice], ctx: &mut IoCtx) -> Result<usize> {
241 unsafe {
242 nk!(crate::bindings::twz_rt_fd_pwritev(fd, ios.as_ptr(), ios.len(), &mut ctx.0).into())
243 }
244}
245
246pub fn twz_rt_fd_pwritev(fd: RawFd, ios: &[IoSlice], ctx: &mut IoCtx) -> Result<usize> {
251 unsafe {
252 nk!(crate::bindings::twz_rt_fd_pwritev(fd, ios.as_ptr(), ios.len(), &mut ctx.0).into())
253 }
254}
255
256pub fn twz_rt_fd_get_config<T>(fd: RawFd, reg: u32) -> Result<T> {
257 let mut val = core::mem::MaybeUninit::<T>::uninit();
258 let e = unsafe {
259 nk!(crate::bindings::twz_rt_fd_get_config(
260 fd,
261 reg,
262 val.as_mut_ptr().cast(),
263 core::mem::size_of::<T>(),
264 ))
265 };
266 let raw = RawTwzError::new(e);
267 if !raw.is_success() {
268 return Err(raw.error());
269 }
270 Ok(unsafe { val.assume_init() })
271}
272
273pub fn twz_rt_fd_set_config<T>(fd: RawFd, reg: u32, val: T) -> Result<()> {
274 let e = unsafe {
275 nk!(crate::bindings::twz_rt_fd_set_config(
276 fd,
277 reg,
278 ((&val) as *const T).cast(),
279 core::mem::size_of::<T>(),
280 ))
281 };
282 let raw = RawTwzError::new(e);
283 if !raw.is_success() {
284 return Err(raw.error());
285 }
286 Ok(())
287}
288
289pub fn twz_rt_fd_waitpoint(fd: RawFd, kind: wait_kind) -> Result<(*const AtomicU64, u64, bool)> {
290 let mut pt = MaybeUninit::uninit();
291 let mut val = MaybeUninit::uninit();
292 let mut ready = MaybeUninit::uninit();
293 let e = unsafe {
294 nk!(crate::bindings::twz_rt_fd_waitpoint(
295 fd,
296 kind,
297 pt.as_mut_ptr(),
298 val.as_mut_ptr(),
299 ready.as_mut_ptr()
300 ))
301 };
302 let raw = RawTwzError::new(e);
303 if !raw.is_success() {
304 return Err(raw.error());
305 }
306 Ok((
307 unsafe { pt.assume_init().cast() },
308 unsafe { val.assume_init() },
309 unsafe { ready.assume_init() },
310 ))
311}