use std::ptr::null;
#[cfg(windows)]
use windows_sys::Win32::Networking::WinSock::WSABUF;
use super::{IoBuf, IoBufMut, IoVecBuf, IoVecBufMut};
pub struct RawBuf {
ptr: *const u8,
len: usize,
}
impl RawBuf {
#[inline]
pub unsafe fn uninit() -> Self {
Self {
ptr: null(),
len: 0,
}
}
#[inline]
pub const unsafe fn new(ptr: *const u8, len: usize) -> Self {
Self { ptr, len }
}
}
unsafe impl IoBuf for RawBuf {
#[inline]
fn read_ptr(&self) -> *const u8 {
self.ptr
}
#[inline]
fn bytes_init(&self) -> usize {
self.len
}
}
unsafe impl IoBufMut for RawBuf {
#[inline]
fn write_ptr(&mut self) -> *mut u8 {
self.ptr as *mut u8
}
#[inline]
fn bytes_total(&mut self) -> usize {
self.len
}
#[inline]
unsafe fn set_init(&mut self, _pos: usize) {}
}
impl RawBuf {
#[inline]
pub unsafe fn new_from_iovec_mut<T: IoVecBufMut>(data: &mut T) -> Option<Self> {
#[cfg(unix)]
{
if data.write_iovec_len() == 0 {
return None;
}
let iovec = *data.write_iovec_ptr();
Some(Self::new(iovec.iov_base as *const u8, iovec.iov_len))
}
#[cfg(windows)]
{
if data.write_wsabuf_len() == 0 {
return None;
}
let wsabuf = *data.write_wsabuf_ptr();
Some(Self::new(wsabuf.buf as *const u8, wsabuf.len as _))
}
}
#[inline]
pub unsafe fn new_from_iovec<T: IoVecBuf>(data: &T) -> Option<Self> {
#[cfg(unix)]
{
if data.read_iovec_len() == 0 {
return None;
}
let iovec = *data.read_iovec_ptr();
Some(Self::new(iovec.iov_base as *const u8, iovec.iov_len))
}
#[cfg(windows)]
{
if data.read_wsabuf_len() == 0 {
return None;
}
let wsabuf = *data.read_wsabuf_ptr();
Some(Self::new(wsabuf.buf as *const u8, wsabuf.len as _))
}
}
}
pub struct RawBufVectored {
#[cfg(unix)]
ptr: *const libc::iovec,
#[cfg(windows)]
ptr: *const WSABUF,
len: usize,
}
impl RawBufVectored {
#[cfg(unix)]
#[inline]
pub const unsafe fn new(ptr: *const libc::iovec, len: usize) -> Self {
Self { ptr, len }
}
#[cfg(windows)]
#[inline]
pub const unsafe fn new(ptr: *const WSABUF, len: usize) -> Self {
Self { ptr, len }
}
}
unsafe impl IoVecBuf for RawBufVectored {
#[cfg(unix)]
#[inline]
fn read_iovec_ptr(&self) -> *const libc::iovec {
self.ptr
}
#[cfg(unix)]
#[inline]
fn read_iovec_len(&self) -> usize {
self.len
}
#[cfg(windows)]
#[inline]
fn read_wsabuf_ptr(&self) -> *const WSABUF {
self.ptr
}
#[cfg(windows)]
#[inline]
fn read_wsabuf_len(&self) -> usize {
self.len
}
}
unsafe impl IoVecBufMut for RawBufVectored {
#[cfg(unix)]
fn write_iovec_ptr(&mut self) -> *mut libc::iovec {
self.ptr as *mut libc::iovec
}
#[cfg(unix)]
fn write_iovec_len(&mut self) -> usize {
self.len
}
#[cfg(windows)]
#[inline]
fn write_wsabuf_ptr(&mut self) -> *mut WSABUF {
self.ptr as *mut WSABUF
}
#[cfg(windows)]
#[inline]
fn write_wsabuf_len(&mut self) -> usize {
self.len
}
unsafe fn set_init(&mut self, _pos: usize) {}
}