use super::{IoBuf, IoBufMut, Slice};
use std::ops;
use std::ptr;
pub trait BoundedBuf: Unpin + 'static {
type Buf: IoBuf;
type Bounds: ops::RangeBounds<usize>;
fn slice(self, range: impl ops::RangeBounds<usize>) -> Slice<Self::Buf>;
fn slice_full(self) -> Slice<Self::Buf>;
fn get_buf(&self) -> &Self::Buf;
fn bounds(&self) -> Self::Bounds;
fn from_buf_bounds(buf: Self::Buf, bounds: Self::Bounds) -> Self;
fn stable_ptr(&self) -> *const u8;
fn bytes_init(&self) -> usize;
fn bytes_total(&self) -> usize;
}
impl<T: IoBuf> BoundedBuf for T {
type Buf = Self;
type Bounds = ops::RangeFull;
fn slice(self, range: impl ops::RangeBounds<usize>) -> Slice<Self> {
use ops::Bound;
let begin = match range.start_bound() {
Bound::Included(&n) => n,
Bound::Excluded(&n) => n.checked_add(1).expect("out of range"),
Bound::Unbounded => 0,
};
assert!(begin < self.bytes_total());
let end = match range.end_bound() {
Bound::Included(&n) => n.checked_add(1).expect("out of range"),
Bound::Excluded(&n) => n,
Bound::Unbounded => self.bytes_total(),
};
assert!(end <= self.bytes_total());
assert!(begin <= self.bytes_init());
Slice::new(self, begin, end)
}
fn slice_full(self) -> Slice<Self> {
let end = self.bytes_total();
Slice::new(self, 0, end)
}
fn get_buf(&self) -> &Self {
self
}
fn bounds(&self) -> Self::Bounds {
..
}
fn from_buf_bounds(buf: Self, _: ops::RangeFull) -> Self {
buf
}
fn stable_ptr(&self) -> *const u8 {
IoBuf::stable_ptr(self)
}
fn bytes_init(&self) -> usize {
IoBuf::bytes_init(self)
}
fn bytes_total(&self) -> usize {
IoBuf::bytes_total(self)
}
}
pub trait BoundedBufMut: BoundedBuf<Buf = Self::BufMut> {
type BufMut: IoBufMut;
fn stable_mut_ptr(&mut self) -> *mut u8;
unsafe fn set_init(&mut self, pos: usize);
fn put_slice(&mut self, src: &[u8]) {
assert!(self.bytes_total() >= src.len());
let dst = self.stable_mut_ptr();
unsafe {
ptr::copy_nonoverlapping(src.as_ptr(), dst, src.len());
self.set_init(src.len());
}
}
}
impl<T: IoBufMut> BoundedBufMut for T {
type BufMut = T;
fn stable_mut_ptr(&mut self) -> *mut u8 {
IoBufMut::stable_mut_ptr(self)
}
unsafe fn set_init(&mut self, pos: usize) {
IoBufMut::set_init(self, pos)
}
}