pub(crate) struct IoVec<'a>(&'a [&'a[u8]], usize);
impl<'a> IoVec<'a> {
pub fn new(buf: &'a [&'a [u8]], off: usize) -> Self {
Self(buf, 0).next_bytes(off)
}
pub fn next_bytes(&self, bytes_off: usize) -> Self {
let mut off = bytes_off + self.1;
for (index, item) in self.0.iter().enumerate() {
if off < item.len() {
return Self(&self.0[index..], off);
}
off -= item.len();
}
Self(&self.0[0..0], 0)
}
pub fn next_iovec(&self, iovec_off: usize) -> Self {
if iovec_off < self.0.len() {
Self(&self.0[iovec_off..], 0)
} else {
Self(&self.0[0..0], 0)
}
}
pub fn to_iovec(&self, iov: &mut [libc::iovec]) -> Option<(*const libc::iovec, i32, usize)> {
let mut size = 0_usize;
let mut cnt = 0_i32;
let mut off = self.1;
for (index, (iovec, buf)) in iov.iter_mut().zip(self.0.iter()).enumerate() {
if off == 0 {
iovec.iov_base = buf.as_ptr().cast_mut().cast::<libc::c_void>();
iovec.iov_len = buf.len();
} else {
iovec.iov_base = buf[off..].as_ptr().cast_mut().cast::<libc::c_void>();
iovec.iov_len = buf.len() - off;
off = 0;
}
size += iovec.iov_len;
cnt = index as i32;
}
if size > 0 {
Some((&iov[0], cnt + 1, size))
} else {
None
}
}
}
pub(crate) struct IoVecMut<'a>(&'a [&'a mut [u8]], usize);
impl<'a> IoVecMut<'a> {
pub fn new(buf: &'a [&'a mut [u8]], off: usize) -> Self {
Self(buf, 0).next_bytes(off)
}
pub fn next_bytes(&self, bytes_off: usize) -> Self {
let mut off = bytes_off + self.1;
for (index, item) in self.0.iter().enumerate() {
if off < item.len() {
return Self(&self.0[index..], off);
}
off -= item.len();
}
Self(&self.0[0..0], 0)
}
pub fn next_iovec(&self, iovec_off: usize) -> Self {
if iovec_off < self.0.len() {
Self(&self.0[iovec_off..], 0)
} else {
Self(&self.0[0..0], 0)
}
}
pub fn to_iovec(&self, iov: &mut [libc::iovec]) -> Option<(*const libc::iovec, i32, usize)> {
let mut size = 0_usize;
let mut cnt = 0_i32;
let mut off = self.1;
for (index, (iovec, buf)) in iov.iter_mut().zip(self.0.iter()).enumerate() {
if off == 0 {
iovec.iov_base = buf.as_ptr().cast_mut().cast::<libc::c_void>();
iovec.iov_len = buf.len();
} else {
iovec.iov_base = buf[off..].as_ptr().cast_mut().cast::<libc::c_void>();
iovec.iov_len = buf.len() - off;
off = 0;
}
size += iovec.iov_len;
cnt = index as i32;
}
if size > 0 {
Some((&iov[0], cnt + 1, size))
} else {
None
}
}
}