use std::marker::PhantomData;
use libc::{sockaddr_storage, socklen_t};
use socket2::SockAddr;
#[cfg(doc)]
use crate::op::*;
use crate::{
buf::{AsIoSlices, AsIoSlicesMut, IntoInner, IoBuf, IoBufMut},
driver::RawFd,
};
pub struct ReadAt<'arena, T: IoBufMut<'arena>> {
pub(crate) fd: RawFd,
pub(crate) offset: usize,
pub(crate) buffer: T,
_lifetime: PhantomData<&'arena ()>,
}
impl<'arena, T: IoBufMut<'arena>> ReadAt<'arena, T> {
pub fn new(fd: RawFd, offset: usize, buffer: T) -> Self {
Self {
fd,
offset,
buffer,
_lifetime: PhantomData,
}
}
}
impl<'arena, T: IoBufMut<'arena>> IntoInner for ReadAt<'arena, T> {
type Inner = T;
fn into_inner(self) -> Self::Inner {
self.buffer
}
}
pub struct WriteAt<'arena, T: IoBuf<'arena>> {
pub(crate) fd: RawFd,
pub(crate) offset: usize,
pub(crate) buffer: T,
_lifetime: PhantomData<&'arena ()>,
}
impl<'arena, T: IoBuf<'arena>> WriteAt<'arena, T> {
pub fn new(fd: RawFd, offset: usize, buffer: T) -> Self {
Self {
fd,
offset,
buffer,
_lifetime: PhantomData,
}
}
}
impl<'arena, T: IoBuf<'arena>> IntoInner for WriteAt<'arena, T> {
type Inner = T;
fn into_inner(self) -> Self::Inner {
self.buffer
}
}
pub struct Connect {
pub(crate) fd: RawFd,
pub(crate) addr: SockAddr,
}
impl Connect {
pub fn new(fd: RawFd, addr: SockAddr) -> Self {
Self { fd, addr }
}
}
pub struct Accept {
pub(crate) fd: RawFd,
pub(crate) buffer: sockaddr_storage,
pub(crate) addr_len: socklen_t,
}
impl Accept {
pub fn new(fd: RawFd) -> Self {
Self {
fd,
buffer: unsafe { std::mem::zeroed() },
addr_len: std::mem::size_of::<sockaddr_storage>() as _,
}
}
pub fn into_addr(self) -> SockAddr {
unsafe { SockAddr::new(self.buffer, self.addr_len) }
}
}
pub struct Sync {
pub(crate) fd: RawFd,
#[allow(dead_code)]
pub(crate) datasync: bool,
}
impl Sync {
pub fn new(fd: RawFd, datasync: bool) -> Self {
Self { fd, datasync }
}
}
pub struct RecvImpl<'arena, T: AsIoSlicesMut<'arena>> {
pub(crate) fd: RawFd,
pub(crate) buffer: T,
_lifetime: PhantomData<&'arena ()>,
}
impl<'arena, T: AsIoSlicesMut<'arena>> RecvImpl<'arena, T> {
pub fn new(fd: RawFd, buffer: T) -> Self {
Self {
fd,
buffer,
_lifetime: PhantomData,
}
}
}
impl<'arena, T: AsIoSlicesMut<'arena>> IntoInner for RecvImpl<'arena, T> {
type Inner = T;
fn into_inner(self) -> Self::Inner {
self.buffer
}
}
pub struct SendImpl<'arena, T: AsIoSlices<'arena>> {
pub(crate) fd: RawFd,
pub(crate) buffer: T,
_lifetime: PhantomData<&'arena ()>,
}
impl<'arena, T: AsIoSlices<'arena>> SendImpl<'arena, T> {
pub fn new(fd: RawFd, buffer: T) -> Self {
Self {
fd,
buffer,
_lifetime: PhantomData,
}
}
}
impl<'arena, T: AsIoSlices<'arena>> IntoInner for SendImpl<'arena, T> {
type Inner = T;
fn into_inner(self) -> Self::Inner {
self.buffer
}
}
pub struct RecvFromImpl<'arena, T: AsIoSlicesMut<'arena>> {
pub(crate) fd: RawFd,
pub(crate) buffer: T,
pub(crate) addr: sockaddr_storage,
pub(crate) msg: libc::msghdr,
_lifetime: PhantomData<&'arena ()>,
}
impl<'arena, T: AsIoSlicesMut<'arena>> RecvFromImpl<'arena, T> {
pub fn new(fd: RawFd, buffer: T) -> Self {
Self {
fd,
buffer,
addr: unsafe { std::mem::zeroed() },
msg: unsafe { std::mem::zeroed() },
_lifetime: PhantomData,
}
}
pub(crate) fn set_msg(&mut self) -> &mut libc::msghdr {
let (slices, len) = unsafe {
let slices = self.buffer.as_io_slices_mut();
let len = slices.len();
(slices.as_mut_ptr(), len)
};
self.msg = libc::msghdr {
msg_name: &mut self.addr as *mut _ as _,
msg_namelen: std::mem::size_of_val(&self.addr) as _,
msg_iov: slices as _,
msg_iovlen: len as _,
msg_control: std::ptr::null_mut(),
msg_controllen: 0,
msg_flags: 0,
};
&mut self.msg
}
}
impl<'arena, T: AsIoSlicesMut<'arena>> IntoInner for RecvFromImpl<'arena, T> {
type Inner = (T, sockaddr_storage, socklen_t);
fn into_inner(self) -> Self::Inner {
(self.buffer, self.addr, self.msg.msg_namelen)
}
}
pub struct SendToImpl<'arena, T: AsIoSlices<'arena>> {
pub(crate) fd: RawFd,
pub(crate) buffer: T,
pub(crate) addr: SockAddr,
pub(crate) msg: libc::msghdr,
_lifetime: PhantomData<&'arena ()>,
}
impl<'arena, T: AsIoSlices<'arena>> SendToImpl<'arena, T> {
pub fn new(fd: RawFd, buffer: T, addr: SockAddr) -> Self {
Self {
fd,
buffer,
addr,
msg: unsafe { std::mem::zeroed() },
_lifetime: PhantomData,
}
}
pub(crate) fn set_msg(&mut self) -> &libc::msghdr {
let (slices, len) = unsafe {
let slices = self.buffer.as_io_slices();
let len = slices.len();
(slices.as_ptr(), len)
};
self.msg = libc::msghdr {
msg_name: self.addr.as_ptr() as _,
msg_namelen: self.addr.len(),
msg_iov: slices as _,
msg_iovlen: len as _,
msg_control: std::ptr::null_mut(),
msg_controllen: 0,
msg_flags: 0,
};
&self.msg
}
}
impl<'arena, T: AsIoSlices<'arena>> IntoInner for SendToImpl<'arena, T> {
type Inner = T;
fn into_inner(self) -> Self::Inner {
self.buffer
}
}