pkbuffer/
ptr.rs

1use crate::{Buffer, Error};
2
3/// A [`Buffer`](Buffer) object backed by a pointer/size pair. Use this buffer type
4/// when accessing unowned memory or arbitrary allocated memory.
5#[derive(Copy, Clone, Eq, Debug)]
6pub struct PtrBuffer {
7    pointer: *const u8,
8    size: usize,
9}
10impl PtrBuffer {
11    /// Create a new buffer object with a given *pointer* and *size*. Just make sure the pointer outlives
12    /// the object and not the other way around.
13    pub fn new(pointer: *const u8, size: usize) -> Self {
14        Self { pointer, size }
15    }
16    /// Set the new pointer of this buffer.
17    pub fn set_pointer(&mut self, pointer: *const u8) {
18        self.pointer = pointer;
19    }
20    /// Set the new size of this buffer.
21    pub fn set_size(&mut self, size: usize) {
22        self.size = size;
23    }
24    /// Create a new `PtrBuffer` object within the bounds of the current buffer.
25    pub fn sub_buffer(&self, offset: usize, size: usize) -> Result<Self, Error> {
26        if offset >= self.len() {
27            return Err(Error::OutOfBounds(self.len(),offset));
28        }
29
30        if offset+size > self.len() {
31            return Err(Error::OutOfBounds(self.len(),offset+size));
32        }
33
34        unsafe { Ok(Self::new(self.as_ptr().add(offset), size)) }
35    }
36    /// Split this buffer into two separate buffers at the given splitpoint *mid*.
37    ///
38    /// Returns an [`Error::OutOfBounds`](Error::OutOfBounds) error if this split goes out of bounds of the buffer.
39    pub fn split_at(&self, mid: usize) -> Result<(Self, Self), Error> {
40        if mid > self.len() { return Err(Error::OutOfBounds(self.len(),mid)); }
41        
42        Ok((Self::new(self.as_ptr(),mid),
43            Self::new(unsafe { self.as_ptr().add(mid) }, self.len() - mid)))
44    }
45}
46impl Buffer for PtrBuffer {
47    /// Get the length of this `PtrBuffer` object.
48    fn len(&self) -> usize {
49        self.size
50    }
51    /// Get the `PtrBuffer` object as a pointer.
52    fn as_ptr(&self) -> *const u8 {
53        self.pointer
54    }
55    /// Get the `PtrBuffer` object as a mutable pointer.
56    fn as_mut_ptr(&mut self) -> *mut u8 {
57        self.pointer as *mut u8
58    }
59    /// Get the `PtrBuffer` object as a slice.
60    fn as_slice(&self) -> &[u8] {
61        unsafe { std::slice::from_raw_parts(self.pointer, self.size) }
62    }
63    /// Get the `PtrBuffer` object as a mutable slice.
64    fn as_mut_slice(&mut self) -> &mut [u8] {
65        unsafe { std::slice::from_raw_parts_mut(self.as_mut_ptr(), self.size) }
66    }
67}
68impl PartialEq<[u8]> for PtrBuffer {
69    fn eq(&self, other: &[u8]) -> bool {
70        self.as_slice() == other
71    }
72}
73impl<const N: usize> PartialEq<[u8; N]> for PtrBuffer {
74    fn eq(&self, other: &[u8; N]) -> bool {
75        self.as_slice() == other
76    }
77}
78impl PartialEq<Vec<u8>> for PtrBuffer {
79    fn eq(&self, other: &Vec<u8>) -> bool {
80        self.as_slice() == other.as_slice()
81    }
82}
83impl<T: Buffer> PartialEq<T> for PtrBuffer {
84    fn eq(&self, other: &T) -> bool {
85        self.as_slice() == other.as_slice()
86    }
87}
88impl<Idx: std::slice::SliceIndex<[u8]>> std::ops::Index<Idx> for PtrBuffer {
89    type Output = Idx::Output;
90
91    fn index(&self, index: Idx) -> &Self::Output {
92        self.as_slice().index(index)
93    }
94}
95impl<Idx: std::slice::SliceIndex<[u8]>> std::ops::IndexMut<Idx> for PtrBuffer {
96    fn index_mut(&mut self, index: Idx) -> &mut Self::Output {
97        self.as_mut_slice().index_mut(index)
98    }
99}
100impl std::convert::AsRef<[u8]> for PtrBuffer {
101    fn as_ref(&self) -> &[u8] {
102        self.as_slice()
103    }
104}
105impl std::convert::AsMut<[u8]> for PtrBuffer {
106    fn as_mut(&mut self) -> &mut [u8] {
107        self.as_mut_slice()
108    }
109}
110impl std::hash::Hash for PtrBuffer {
111    fn hash<H>(&self, state: &mut H)
112    where
113        H: std::hash::Hasher
114    {
115        self.as_slice().hash(state);
116    }
117    fn hash_slice<H>(data: &[Self], state: &mut H)
118    where
119        H: std::hash::Hasher
120    {
121        data.iter().for_each(|x| x.hash(state));
122    }
123}
124impl std::iter::IntoIterator for PtrBuffer {
125    type Item = u8;
126    type IntoIter = std::vec::IntoIter<Self::Item>;
127
128    fn into_iter(self) -> Self::IntoIter {
129        self.to_vec().into_iter()
130    }
131}