1#[derive(Clone, Copy, Debug)]
2#[repr(transparent)]
3pub struct IoVec {
4 raw: libc::iovec,
5}
6
7impl IoVec {
8 #[must_use]
9 pub const fn empty() -> Self {
10 Self {
11 raw: libc::iovec {
12 iov_base: std::ptr::null_mut(),
13 iov_len: 0,
14 },
15 }
16 }
17
18 #[must_use]
19 pub fn from_slice(buf: &[u8], off: usize) -> Self {
20 let start = off.min(buf.len());
21 let tail = &buf[start..];
22 Self {
23 raw: libc::iovec {
24 iov_base: tail.as_ptr() as *mut libc::c_void,
25 iov_len: tail.len(),
26 },
27 }
28 }
29
30 #[inline(always)]
31 #[must_use]
32 pub fn raw(ptr: *const u8, len: usize) -> libc::iovec {
33 libc::iovec {
34 iov_base: ptr as *mut libc::c_void,
35 iov_len: len,
36 }
37 }
38
39 #[must_use]
40 pub fn from_mut_slice(buf: &mut [u8]) -> Self {
41 Self {
42 raw: libc::iovec {
43 iov_base: buf.as_mut_ptr() as *mut libc::c_void,
44 iov_len: buf.len(),
45 },
46 }
47 }
48
49 pub fn set_len(&mut self, len: usize) {
50 self.raw.iov_len = len;
51 }
52
53 pub fn len(&self) -> usize {
54 self.raw.iov_len
55 }
56
57 pub fn is_empty(&self) -> bool {
58 self.raw.iov_len == 0
59 }
60
61 pub fn as_ptr(&self) -> *const u8 {
62 self.raw.iov_base.cast()
63 }
64
65 #[inline(always)]
66 pub fn as_libc(&self) -> libc::iovec {
67 self.raw
68 }
69
70 pub fn advance(&mut self, n: usize) {
71 let step = n.min(self.raw.iov_len);
72 self.raw.iov_base = unsafe { (self.raw.iov_base as *mut u8).add(step) }.cast();
73 self.raw.iov_len -= step;
74 }
75}