arrs_buffer/
buffer_ref.rs

1use std::sync::Arc;
2
3use crate::Buffer;
4
5/// An immutable reference to a buffer. Can be used for shared zero copy views
6///  into a single buffer.
7#[derive(Clone)]
8pub struct BufferRef {
9    inner: Arc<Buffer>,
10    start: usize,
11    len: usize,
12}
13
14impl BufferRef {
15    /// Creates a shared reference to given buffer.
16    ///
17    /// # Panics
18    ///
19    /// Panics if start + len overflows or if start + len is greater than inner.len().
20    pub fn new(inner: Arc<Buffer>, start: usize, len: usize) -> Self {
21        assert!(start.checked_add(len).unwrap() <= inner.len());
22
23        Self { inner, start, len }
24    }
25
26    /// Slices into this ref.
27    ///
28    /// # Panics
29    ///
30    /// Panics if start + len overflows or if start + len is greater than self.len().
31    /// Or if self.start + start overflows.
32    pub fn slice(&self, start: usize, len: usize) -> Self {
33        assert!(start.checked_add(len).unwrap() <= self.len);
34
35        Self {
36            inner: self.inner.clone(),
37            start: self.start.checked_add(start).unwrap(),
38            len,
39        }
40    }
41
42    /// Length of the reference
43    pub fn len(&self) -> usize {
44        self.len
45    }
46
47    /// Returns if length of buffer is zero
48    pub fn is_empty(&self) -> bool {
49        self.len == 0
50    }
51
52    /// Length of the underlying buffer
53    pub fn inner_len(&self) -> usize {
54        self.inner.len()
55    }
56
57    /// Start index of this reference relative to the inner buffer.
58    pub fn start(&self) -> usize {
59        self.start
60    }
61
62    /// Return a pointer to the underlying memory at offset
63    pub fn as_ptr(&self) -> *const u8 {
64        unsafe { self.inner.as_ptr().add(self.start) }
65    }
66
67    /// Get a slice
68    pub fn as_slice(&self) -> &[u8] {
69        unsafe { std::slice::from_raw_parts(self.as_ptr(), self.len) }
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn from_buffer() {
79        unsafe {
80            let mut buffer = Buffer::new(32);
81            *buffer.as_mut_ptr().add(17) = 69;
82
83            let buf_ref = buffer.into_ref();
84            let buf_ref = buf_ref.slice(16, 3);
85
86            assert_eq!(*buf_ref.as_ptr().add(1), 69);
87
88            assert_eq!(buf_ref.as_slice()[1], 69);
89        }
90    }
91}