#![allow(dead_code)]
use std::{
io::{IoSlice, IoSliceMut},
slice,
};
use compio_buf::{IoBuf, IoBufMut, IoVectoredBuf, IoVectoredBufMut};
cfg_if::cfg_if! {
if #[cfg(unix)] {
use std::mem::MaybeUninit;
use libc::iovec as Inner;
fn new(ptr: *mut MaybeUninit<u8>, len: usize) -> Inner {
Inner {
iov_base: ptr as *mut libc::c_void,
iov_len: len,
}
}
} else if #[cfg(windows)] {
use std::mem::MaybeUninit;
use windows_sys::Win32::Networking::WinSock::WSABUF as Inner;
fn new(ptr: *mut MaybeUninit<u8>, len: usize) -> Inner {
Inner {
len: len.try_into().unwrap_or(u32::MAX),
buf: ptr as _,
}
}
} else {
type Inner = ();
fn new(_: *mut MaybeUninit<u8>, _: usize) -> Inner {
unreachable!("SysSlice will not be used on platforms other than unix and windows")
}
}
}
#[repr(transparent)]
pub(crate) struct SysSlice(Inner);
impl Default for SysSlice {
fn default() -> Self {
Self::null()
}
}
impl SysSlice {
pub fn null() -> Self {
Self(new(std::ptr::null_mut(), 0))
}
fn from_slice(slice: &[u8]) -> Self {
Self(new(
slice.as_ptr() as *mut std::mem::MaybeUninit<u8>,
slice.len(),
))
}
fn from_uninit(value: &mut [std::mem::MaybeUninit<u8>]) -> Self {
Self(new(value.as_mut_ptr(), value.len()))
}
pub fn into_inner(self) -> Inner {
self.0
}
pub fn ptr(&self) -> *mut std::mem::MaybeUninit<u8> {
#[cfg(unix)]
return self.0.iov_base as *mut std::mem::MaybeUninit<u8>;
#[cfg(windows)]
return self.0.buf as *mut std::mem::MaybeUninit<u8>;
}
pub fn len(&self) -> usize {
#[cfg(unix)]
return self.0.iov_len;
#[cfg(windows)]
return self.0.len as usize;
}
}
pub(crate) trait IoBufExt: IoBuf {
fn sys_slice(&self) -> SysSlice {
SysSlice::from_slice(self.as_init())
}
}
impl<T: IoBuf + ?Sized> IoBufExt for T {}
pub(crate) trait IoBufMutExt: IoBufMut {
fn sys_slice_mut(&mut self) -> SysSlice {
SysSlice::from_uninit(self.as_uninit())
}
}
impl<T: IoBufMut + ?Sized> IoBufMutExt for T {}
pub(crate) trait IoVectoredBufExt: IoVectoredBuf {
fn sys_slices(&self) -> Vec<SysSlice> {
self.iter_slice().map(SysSlice::from_slice).collect()
}
}
impl<T: IoVectoredBuf + ?Sized> IoVectoredBufExt for T {}
pub(crate) trait IoVectoredBufMutExt: IoVectoredBufMut {
fn sys_slices_mut(&mut self) -> Vec<SysSlice> {
self.iter_uninit_slice()
.map(SysSlice::from_uninit)
.collect()
}
}
impl<T: IoVectoredBufMut + ?Sized> IoVectoredBufMutExt for T {}
pub fn io_slice(slices: &[SysSlice]) -> &[IoSlice<'_>] {
unsafe { slice::from_raw_parts(slices.as_ptr().cast(), slices.len()) }
}
pub fn io_slice_mut(slices: &mut [SysSlice]) -> &mut [IoSliceMut<'_>] {
unsafe { slice::from_raw_parts_mut(slices.as_mut_ptr().cast(), slices.len()) }
}