use std::sync::Arc;
use crate::Buffer;
#[derive(Clone)]
pub struct BufferRef {
inner: Arc<Buffer>,
start: usize,
len: usize,
}
impl BufferRef {
pub fn new(inner: Arc<Buffer>, start: usize, len: usize) -> Self {
assert!(start.checked_add(len).unwrap() <= inner.len());
Self { inner, start, len }
}
pub fn slice(&self, start: usize, len: usize) -> Self {
assert!(start.checked_add(len).unwrap() <= self.len);
Self {
inner: self.inner.clone(),
start: self.start.checked_add(start).unwrap(),
len,
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn inner_len(&self) -> usize {
self.inner.len()
}
pub fn start(&self) -> usize {
self.start
}
pub fn as_ptr(&self) -> *const u8 {
unsafe { self.inner.as_ptr().add(self.start) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe { std::slice::from_raw_parts(self.as_ptr(), self.len) }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_buffer() {
unsafe {
let mut buffer = Buffer::new(32);
*buffer.as_mut_ptr().add(17) = 69;
let buf_ref = buffer.into_ref();
let buf_ref = buf_ref.slice(16, 3);
assert_eq!(*buf_ref.as_ptr().add(1), 69);
assert_eq!(buf_ref.as_slice()[1], 69);
}
}
}