use super::FixedBuffers;
use crate::buf::{IoBuf, IoBufMut};
use libc::iovec;
use std::cell::RefCell;
use std::fmt::{self, Debug};
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
pub(crate) struct CheckedOutBuf {
pub iovec: iovec,
pub init_len: usize,
pub index: u16,
}
pub struct FixedBuf {
registry: Rc<RefCell<dyn FixedBuffers>>,
buf: CheckedOutBuf,
}
impl Drop for FixedBuf {
fn drop(&mut self) {
let mut registry = self.registry.borrow_mut();
unsafe {
registry.check_in(self.buf.index, 0);
}
}
}
impl FixedBuf {
pub(super) unsafe fn new(registry: Rc<RefCell<dyn FixedBuffers>>, buf: CheckedOutBuf) -> Self {
FixedBuf { registry, buf }
}
pub fn buf_index(&self) -> u16 {
self.buf.index
}
}
unsafe impl IoBuf for FixedBuf {
fn stable_ptr(&self) -> *const u8 {
self.buf.iovec.iov_base as _
}
fn bytes_init(&self) -> usize {
self.buf.init_len
}
fn bytes_total(&self) -> usize {
self.buf.iovec.iov_len
}
}
unsafe impl IoBufMut for FixedBuf {
fn stable_mut_ptr(&mut self) -> *mut u8 {
self.buf.iovec.iov_base as _
}
unsafe fn set_init(&mut self, pos: usize) {
if self.buf.init_len < pos {
self.buf.init_len = pos
}
}
}
impl Deref for FixedBuf {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe { std::slice::from_raw_parts(self.buf.iovec.iov_base as _, self.buf.init_len) }
}
}
impl DerefMut for FixedBuf {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe { std::slice::from_raw_parts_mut(self.buf.iovec.iov_base as _, self.buf.init_len) }
}
}
impl Debug for FixedBuf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let buf: &[u8] = self;
f.debug_struct("FixedBuf")
.field("buf", &buf) .field("index", &self.buf.index)
.finish_non_exhaustive()
}
}