use std::{mem::MaybeUninit, ptr::null};
use monoio::buf::{IoBuf, IoBufMut};
pub(crate) struct RawBuf {
ptr: *const u8,
len: usize,
}
impl RawBuf {
pub(crate) fn uninit() -> Self {
Self {
ptr: null(),
len: 0,
}
}
pub(crate) fn new(ptr: *const u8, len: usize) -> Self {
Self { ptr, len }
}
}
unsafe impl IoBuf for RawBuf {
fn read_ptr(&self) -> *const u8 {
self.ptr
}
fn bytes_init(&self) -> usize {
self.len
}
}
unsafe impl IoBufMut for RawBuf {
fn write_ptr(&mut self) -> *mut u8 {
self.ptr as *mut u8
}
fn bytes_total(&mut self) -> usize {
self.len
}
unsafe fn set_init(&mut self, _pos: usize) {}
}
pub(crate) struct Buf {
data: Box<[MaybeUninit<u8>]>,
offset: usize,
init: usize,
capacity: usize,
}
unsafe impl IoBuf for Buf {
fn read_ptr(&self) -> *const u8 {
unsafe { self.data.as_ptr().add(self.offset) as *const u8 }
}
fn bytes_init(&self) -> usize {
self.init - self.offset
}
}
unsafe impl IoBufMut for Buf {
fn write_ptr(&mut self) -> *mut u8 {
self.data.as_ptr() as *mut u8
}
fn bytes_total(&mut self) -> usize {
self.capacity
}
unsafe fn set_init(&mut self, init: usize) {
self.offset = 0;
self.init = init;
}
}
impl Buf {
pub(crate) fn new(size: usize) -> Self {
let mut buf = Vec::with_capacity(size);
unsafe { buf.set_len(size) };
let data = buf.into_boxed_slice();
Self {
data,
offset: 0,
init: 0,
capacity: size,
}
}
pub(crate) fn uninit() -> Self {
let buf = Vec::new();
let data = buf.into_boxed_slice();
Self {
data,
offset: 0,
init: 0,
capacity: 0,
}
}
pub(crate) fn is_empty(&self) -> bool {
self.offset == self.init
}
pub(crate) fn buf_to_read(&self, max: usize) -> &[u8] {
let ptr = self.data.as_ptr() as *const u8;
let len = max.min(self.init - self.offset);
unsafe { std::slice::from_raw_parts(ptr, len) }
}
pub(crate) unsafe fn advance_offset(&mut self, len: usize) {
self.offset += len;
debug_assert!(self.offset <= self.init);
}
#[allow(clippy::mut_from_ref)]
pub(crate) fn buf_to_write(&mut self) -> &mut [u8] {
let ptr = self.data.as_ptr() as *mut u8;
unsafe { std::slice::from_raw_parts_mut(ptr, self.capacity) }
}
}