use crate::{Buffer, Error};
#[derive(Copy, Clone, Eq, Debug)]
pub struct PtrBuffer {
pointer: *const u8,
size: usize,
}
impl PtrBuffer {
pub fn new(pointer: *const u8, size: usize) -> Self {
Self { pointer, size }
}
pub fn set_pointer(&mut self, pointer: *const u8) {
self.pointer = pointer;
}
pub fn set_size(&mut self, size: usize) {
self.size = size;
}
pub fn sub_buffer(&self, offset: usize, size: usize) -> Result<Self, Error> {
if offset >= self.len() {
return Err(Error::OutOfBounds(self.len(),offset));
}
if offset+size > self.len() {
return Err(Error::OutOfBounds(self.len(),offset+size));
}
unsafe { Ok(Self::new(self.as_ptr().add(offset), size)) }
}
pub fn split_at(&self, mid: usize) -> Result<(Self, Self), Error> {
if mid > self.len() { return Err(Error::OutOfBounds(self.len(),mid)); }
Ok((Self::new(self.as_ptr(),mid),
Self::new(unsafe { self.as_ptr().add(mid) }, self.len() - mid)))
}
}
impl Buffer for PtrBuffer {
fn len(&self) -> usize {
self.size
}
fn as_ptr(&self) -> *const u8 {
self.pointer
}
fn as_mut_ptr(&mut self) -> *mut u8 {
self.pointer as *mut u8
}
fn as_slice(&self) -> &[u8] {
unsafe { std::slice::from_raw_parts(self.pointer, self.size) }
}
fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { std::slice::from_raw_parts_mut(self.as_mut_ptr(), self.size) }
}
}
impl PartialEq<[u8]> for PtrBuffer {
fn eq(&self, other: &[u8]) -> bool {
self.as_slice() == other
}
}
impl<const N: usize> PartialEq<[u8; N]> for PtrBuffer {
fn eq(&self, other: &[u8; N]) -> bool {
self.as_slice() == other
}
}
impl PartialEq<Vec<u8>> for PtrBuffer {
fn eq(&self, other: &Vec<u8>) -> bool {
self.as_slice() == other.as_slice()
}
}
impl<T: Buffer> PartialEq<T> for PtrBuffer {
fn eq(&self, other: &T) -> bool {
self.as_slice() == other.as_slice()
}
}
impl<Idx: std::slice::SliceIndex<[u8]>> std::ops::Index<Idx> for PtrBuffer {
type Output = Idx::Output;
fn index(&self, index: Idx) -> &Self::Output {
self.as_slice().index(index)
}
}
impl<Idx: std::slice::SliceIndex<[u8]>> std::ops::IndexMut<Idx> for PtrBuffer {
fn index_mut(&mut self, index: Idx) -> &mut Self::Output {
self.as_mut_slice().index_mut(index)
}
}
impl std::convert::AsRef<[u8]> for PtrBuffer {
fn as_ref(&self) -> &[u8] {
self.as_slice()
}
}
impl std::convert::AsMut<[u8]> for PtrBuffer {
fn as_mut(&mut self) -> &mut [u8] {
self.as_mut_slice()
}
}
impl std::hash::Hash for PtrBuffer {
fn hash<H>(&self, state: &mut H)
where
H: std::hash::Hasher
{
self.as_slice().hash(state);
}
fn hash_slice<H>(data: &[Self], state: &mut H)
where
H: std::hash::Hasher
{
data.iter().for_each(|x| x.hash(state));
}
}
impl std::iter::IntoIterator for PtrBuffer {
type Item = u8;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.to_vec().into_iter()
}
}