monoio/buf/
raw_buf.rs

1use std::ptr::null;
2
3#[cfg(windows)]
4use windows_sys::Win32::Networking::WinSock::WSABUF;
5
6use super::{IoBuf, IoBufMut, IoVecBuf, IoVecBufMut};
7
8/// RawBuf is not a real buf. It only hold the pointer of the buffer.
9/// Users must make sure the buffer behind the pointer is always valid.
10/// Which means, user must:
11/// 1. await the future with RawBuf Ready before drop the real buffer
12/// 2. make sure the pointer and length is valid before the future Ready
13pub struct RawBuf {
14    ptr: *const u8,
15    len: usize,
16}
17
18impl RawBuf {
19    /// Create a empty RawBuf.
20    /// # Safety
21    /// do not use uninitialized RawBuf directly.
22    #[inline]
23    pub unsafe fn uninit() -> Self {
24        Self {
25            ptr: null(),
26            len: 0,
27        }
28    }
29
30    /// Create a new RawBuf with given pointer and length.
31    /// # Safety
32    /// make sure the pointer and length is valid when RawBuf is used.
33    #[inline]
34    pub const unsafe fn new(ptr: *const u8, len: usize) -> Self {
35        Self { ptr, len }
36    }
37}
38
39unsafe impl IoBuf for RawBuf {
40    #[inline]
41    fn read_ptr(&self) -> *const u8 {
42        self.ptr
43    }
44
45    #[inline]
46    fn bytes_init(&self) -> usize {
47        self.len
48    }
49}
50
51unsafe impl IoBufMut for RawBuf {
52    #[inline]
53    fn write_ptr(&mut self) -> *mut u8 {
54        self.ptr as *mut u8
55    }
56
57    #[inline]
58    fn bytes_total(&mut self) -> usize {
59        self.len
60    }
61
62    #[inline]
63    unsafe fn set_init(&mut self, _pos: usize) {}
64}
65
66impl RawBuf {
67    /// Create a new RawBuf with the first iovec part.
68    /// # Safety
69    /// make sure the pointer and length is valid when RawBuf is used.
70    #[inline]
71    pub unsafe fn new_from_iovec_mut<T: IoVecBufMut>(data: &mut T) -> Option<Self> {
72        #[cfg(unix)]
73        {
74            if data.write_iovec_len() == 0 {
75                return None;
76            }
77            let iovec = *data.write_iovec_ptr();
78            Some(Self::new(iovec.iov_base as *const u8, iovec.iov_len))
79        }
80        #[cfg(windows)]
81        {
82            if data.write_wsabuf_len() == 0 {
83                return None;
84            }
85            let wsabuf = *data.write_wsabuf_ptr();
86            Some(Self::new(wsabuf.buf as *const u8, wsabuf.len as _))
87        }
88    }
89
90    /// Create a new RawBuf with the first iovec part.
91    /// # Safety
92    /// make sure the pointer and length is valid when RawBuf is used.
93    #[inline]
94    pub unsafe fn new_from_iovec<T: IoVecBuf>(data: &T) -> Option<Self> {
95        #[cfg(unix)]
96        {
97            if data.read_iovec_len() == 0 {
98                return None;
99            }
100            let iovec = *data.read_iovec_ptr();
101            Some(Self::new(iovec.iov_base as *const u8, iovec.iov_len))
102        }
103        #[cfg(windows)]
104        {
105            if data.read_wsabuf_len() == 0 {
106                return None;
107            }
108            let wsabuf = *data.read_wsabuf_ptr();
109            Some(Self::new(wsabuf.buf as *const u8, wsabuf.len as _))
110        }
111    }
112}
113
114/// RawBufVectored behaves like RawBuf.
115/// And user must obey the following restrictions:
116/// 1. await the future with RawBuf Ready before drop the real buffer
117/// 2. make sure the pointer and length is valid before the future Ready
118pub struct RawBufVectored {
119    #[cfg(unix)]
120    ptr: *const libc::iovec,
121    #[cfg(windows)]
122    ptr: *const WSABUF,
123    len: usize,
124}
125
126impl RawBufVectored {
127    /// Create a new RawBuf with given pointer and length.
128    /// # Safety
129    /// make sure the pointer and length is valid when RawBuf is used.
130    #[cfg(unix)]
131    #[inline]
132    pub const unsafe fn new(ptr: *const libc::iovec, len: usize) -> Self {
133        Self { ptr, len }
134    }
135
136    /// Create a new RawBuf with given pointer and length.
137    /// # Safety
138    /// make sure the pointer and length is valid when RawBuf is used.
139    #[cfg(windows)]
140    #[inline]
141    pub const unsafe fn new(ptr: *const WSABUF, len: usize) -> Self {
142        Self { ptr, len }
143    }
144}
145
146unsafe impl IoVecBuf for RawBufVectored {
147    #[cfg(unix)]
148    #[inline]
149    fn read_iovec_ptr(&self) -> *const libc::iovec {
150        self.ptr
151    }
152
153    #[cfg(unix)]
154    #[inline]
155    fn read_iovec_len(&self) -> usize {
156        self.len
157    }
158
159    #[cfg(windows)]
160    #[inline]
161    fn read_wsabuf_ptr(&self) -> *const WSABUF {
162        self.ptr
163    }
164
165    #[cfg(windows)]
166    #[inline]
167    fn read_wsabuf_len(&self) -> usize {
168        self.len
169    }
170}
171
172unsafe impl IoVecBufMut for RawBufVectored {
173    #[cfg(unix)]
174    fn write_iovec_ptr(&mut self) -> *mut libc::iovec {
175        self.ptr as *mut libc::iovec
176    }
177
178    #[cfg(unix)]
179    fn write_iovec_len(&mut self) -> usize {
180        self.len
181    }
182
183    #[cfg(windows)]
184    #[inline]
185    fn write_wsabuf_ptr(&mut self) -> *mut WSABUF {
186        self.ptr as *mut WSABUF
187    }
188
189    #[cfg(windows)]
190    #[inline]
191    fn write_wsabuf_len(&mut self) -> usize {
192        self.len
193    }
194
195    unsafe fn set_init(&mut self, _pos: usize) {}
196}