use std::ffi::c_void;
use std::fmt;
use std::fmt::Debug;
use std::marker::PhantomData;
use std::slice;
use libc::iovec;
pub type IoBuf = iovec;
pub fn create_iobuf(addr: *mut u8, len: usize) -> IoBuf {
iovec {
iov_base: addr as *mut c_void,
iov_len: len,
}
}
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct IoBufMut<'a> {
iov: iovec,
phantom: PhantomData<&'a mut [u8]>,
}
impl<'a> IoBufMut<'a> {
pub fn new(buf: &mut [u8]) -> IoBufMut<'a> {
unsafe { Self::from_raw_parts(buf.as_mut_ptr(), buf.len()) }
}
pub unsafe fn from_raw_parts(addr: *mut u8, len: usize) -> IoBufMut<'a> {
IoBufMut {
iov: iovec {
iov_base: addr as *mut c_void,
iov_len: len,
},
phantom: PhantomData,
}
}
pub unsafe fn from_iobuf(iobuf: IoBuf) -> IoBufMut<'a> {
IoBufMut {
iov: iobuf,
phantom: PhantomData,
}
}
pub fn advance(&mut self, count: usize) {
assert!(count <= self.len());
self.iov.iov_len -= count;
self.iov.iov_base = unsafe { self.iov.iov_base.add(count) };
}
pub fn truncate(&mut self, len: usize) {
if len < self.len() {
self.iov.iov_len = len;
}
}
#[inline]
pub fn len(&self) -> usize {
self.iov.iov_len as usize
}
#[inline]
pub fn is_empty(&self) -> bool {
self.iov.iov_len == 0
}
#[inline]
pub fn as_ptr(&self) -> *const u8 {
self.iov.iov_base as *const u8
}
#[inline]
pub fn as_mut_ptr(&self) -> *mut u8 {
self.iov.iov_base as *mut u8
}
#[allow(clippy::wrong_self_convention)]
#[inline]
pub fn as_iobufs<'slice>(iovs: &'slice [IoBufMut<'_>]) -> &'slice [iovec] {
unsafe { slice::from_raw_parts(iovs.as_ptr() as *const libc::iovec, iovs.len()) }
}
}
impl<'a> AsRef<libc::iovec> for IoBufMut<'a> {
fn as_ref(&self) -> &libc::iovec {
&self.iov
}
}
impl<'a> AsMut<libc::iovec> for IoBufMut<'a> {
fn as_mut(&mut self) -> &mut libc::iovec {
&mut self.iov
}
}
unsafe impl<'a> Send for IoBufMut<'a> {}
unsafe impl<'a> Sync for IoBufMut<'a> {}
struct DebugIovec(iovec);
impl Debug for DebugIovec {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("iovec")
.field("iov_base", &self.0.iov_base)
.field("iov_len", &self.0.iov_len)
.finish()
}
}
impl<'a> Debug for IoBufMut<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("IoBufMut")
.field("iov", &DebugIovec(self.iov))
.field("phantom", &self.phantom)
.finish()
}
}