use super::boxed::AscBox;
use std::{mem, slice};
#[derive(Clone)]
#[repr(transparent)]
pub struct AscArrayBuffer {
inner: AscBox<[u8]>,
}
impl AscArrayBuffer {
pub fn new(bytes: &[u8]) -> Self {
Self {
inner: AscBox::from_slice(bytes),
}
}
pub fn as_bytes(&self) -> &[u8] {
self.inner.as_asc_ref().as_slice()
}
pub fn as_ptr(&self) -> *const u8 {
self.as_bytes().as_ptr()
}
}
#[repr(C)]
pub struct AscTypedArray<T> {
buffer: AscArrayBuffer,
data_start: *const T,
byte_length: usize,
}
impl<T> AscTypedArray<T>
where
T: AscTypedArrayItem,
{
pub fn new(buffer: AscArrayBuffer) -> AscBox<Self> {
let len = buffer.as_bytes().len();
let trailing = len % mem::size_of::<T>();
let data_start = buffer.as_ptr().cast();
AscBox::new(Self {
buffer,
data_start,
byte_length: len - trailing,
})
}
pub fn as_slice(&self) -> &[T] {
unsafe { slice::from_raw_parts(self.data_start, self.byte_length / mem::size_of::<T>()) }
}
}
impl AscTypedArray<u8> {
pub fn from_bytes(bytes: &[u8]) -> AscBox<Self> {
AscTypedArray::new(AscArrayBuffer::new(bytes))
}
}
impl<T> Clone for AscTypedArray<T>
where
T: AscTypedArrayItem,
{
fn clone(&self) -> Self {
let buffer = self.buffer.clone();
let data_start = buffer.as_ptr().cast();
Self {
buffer,
data_start,
byte_length: self.byte_length,
}
}
}
pub unsafe trait AscTypedArrayItem {}
unsafe impl AscTypedArrayItem for u8 {}