use crate::{Buffer, Error, PtrBuffer};
#[derive(Clone, Eq, Debug)]
pub struct VecBuffer {
data: Vec<u8>,
}
impl VecBuffer {
pub fn new() -> Self {
Self { data: Vec::<u8>::new() }
}
pub fn from_data<B: AsRef<[u8]>>(data: B) -> Self {
Self { data: data.as_ref().to_vec() }
}
pub fn from_file<P: AsRef<std::path::Path>>(filename: P) -> Result<Self, Error> {
let data = match std::fs::read(filename) {
Ok(d) => d,
Err(e) => return Err(Error::from(e)),
};
Ok(Self { data })
}
pub fn with_initial_size(size: usize) -> Self {
Self::from_data(&vec![0u8; size])
}
pub fn as_ptr_buffer(&self) -> PtrBuffer {
PtrBuffer::new(self.data.as_ptr(), self.data.len())
}
pub fn append<B: AsRef<[u8]>>(&mut self, data: B) {
self.data.append(&mut data.as_ref().to_vec());
}
pub fn append_val<T: Copy>(&mut self, data: &T) {
let size = std::mem::size_of::<T>();
let old_len = self.data.len();
self.data.resize(old_len + size, 0);
unsafe {
std::ptr::copy_nonoverlapping(data as *const T as *const u8, self.data.as_mut_ptr().add(old_len), size);
}
}
pub fn append_slice_val<T: Copy>(&mut self, data: &[T]) {
let item_size = std::mem::size_of::<T>();
let total_size = item_size * data.len();
let old_len = self.data.len();
self.data.resize(old_len + total_size, 0);
unsafe {
std::ptr::copy_nonoverlapping(data.as_ptr() as *const u8, self.data.as_mut_ptr().add(old_len), total_size);
}
}
pub fn insert(&mut self, offset: usize, element: u8) {
self.data.insert(offset, element);
}
pub fn remove(&mut self, offset: usize) {
self.data.remove(offset);
}
pub fn retain<F>(&mut self, f: F)
where
F: FnMut(&u8) -> bool
{
self.data.retain(f);
}
pub fn push(&mut self, v: u8) {
self.data.push(v);
}
pub fn pop(&mut self) -> Option<u8> {
self.data.pop()
}
pub fn clear(&mut self) {
self.data.clear();
}
pub fn split_off(&mut self, at: usize) -> Self {
let data = self.data.split_off(at);
Self::from_data(&data)
}
pub fn resize_with<F>(&mut self, new_len: usize, f: F)
where
F: FnMut() -> u8
{
self.data.resize_with(new_len, f);
}
pub fn resize(&mut self, new_len: usize, value: u8) {
self.data.resize(new_len, value);
}
pub fn truncate(&mut self, len: usize) {
self.data.truncate(len);
}
pub fn dedup(&mut self) {
self.data.dedup();
}
}
impl Buffer for VecBuffer {
fn len(&self) -> usize {
self.data.len()
}
fn as_ptr(&self) -> *const u8 {
self.data.as_ptr()
}
fn as_mut_ptr(&mut self) -> *mut u8 {
self.data.as_mut_ptr()
}
fn as_slice(&self) -> &[u8] {
self.data.as_slice()
}
fn as_mut_slice(&mut self) -> &mut [u8]
{
self.data.as_mut_slice()
}
}
impl PartialEq<[u8]> for VecBuffer {
fn eq(&self, other: &[u8]) -> bool {
self.as_slice() == other
}
}
impl<const N: usize> PartialEq<[u8; N]> for VecBuffer {
fn eq(&self, other: &[u8; N]) -> bool {
self.as_slice() == other
}
}
impl PartialEq<Vec<u8>> for VecBuffer {
fn eq(&self, other: &Vec<u8>) -> bool {
self.as_slice() == other.as_slice()
}
}
impl<T: Buffer> PartialEq<T> for VecBuffer {
fn eq(&self, other: &T) -> bool {
self.as_slice() == other.as_slice()
}
}
impl<Idx: std::slice::SliceIndex<[u8]>> std::ops::Index<Idx> for VecBuffer {
type Output = Idx::Output;
fn index(&self, index: Idx) -> &Self::Output {
self.data.index(index)
}
}
impl<Idx: std::slice::SliceIndex<[u8]>> std::ops::IndexMut<Idx> for VecBuffer {
fn index_mut(&mut self, index: Idx) -> &mut Self::Output {
self.data.index_mut(index)
}
}
impl std::convert::AsRef<[u8]> for VecBuffer {
fn as_ref(&self) -> &[u8] {
self.as_slice()
}
}
impl std::convert::AsMut<[u8]> for VecBuffer {
fn as_mut(&mut self) -> &mut [u8] {
self.as_mut_slice()
}
}
impl std::hash::Hash for VecBuffer {
fn hash<H>(&self, state: &mut H)
where
H: std::hash::Hasher
{
self.data.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 VecBuffer {
type Item = u8;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.to_vec().into_iter()
}
}