mod immutable;
mod iterator;
use std::ops::Deref;
use crate::ffi::InternalArrowArray;
pub(crate) enum BytesAllocator {
#[allow(dead_code)]
InternalArrowArray(InternalArrowArray),
#[cfg(feature = "arrow_rs")]
#[allow(dead_code)]
Arrow(arrow_buffer::Buffer),
}
pub(crate) type BytesInner<T> = foreign_vec::ForeignVec<BytesAllocator, T>;
#[repr(transparent)]
pub struct Bytes<T>(BytesInner<T>);
impl<T> Bytes<T> {
#[inline]
pub(crate) unsafe fn from_foreign(ptr: *const T, length: usize, owner: BytesAllocator) -> Self {
Self(BytesInner::from_foreign(ptr, length, owner))
}
#[inline]
pub(crate) fn get_vec(&mut self) -> Option<&mut Vec<T>> {
self.0.get_vec()
}
}
impl<T> Deref for Bytes<T> {
type Target = [T];
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> From<Vec<T>> for Bytes<T> {
#[inline]
fn from(data: Vec<T>) -> Self {
let inner: BytesInner<T> = data.into();
Bytes(inner)
}
}
impl<T> From<BytesInner<T>> for Bytes<T> {
#[inline]
fn from(value: BytesInner<T>) -> Self {
Self(value)
}
}
#[cfg(feature = "arrow_rs")]
pub(crate) fn to_buffer<T: crate::types::NativeType>(
value: std::sync::Arc<Bytes<T>>,
) -> arrow_buffer::Buffer {
let ptr = std::ptr::NonNull::new(value.as_ptr() as _).unwrap();
let len = value.len() * std::mem::size_of::<T>();
unsafe { arrow_buffer::Buffer::from_custom_allocation(ptr, len, value) }
}
#[cfg(feature = "arrow_rs")]
pub(crate) fn to_bytes<T: crate::types::NativeType>(value: arrow_buffer::Buffer) -> Bytes<T> {
let ptr = value.as_ptr();
let align = ptr.align_offset(std::mem::align_of::<T>());
assert_eq!(align, 0, "not aligned");
let len = value.len() / std::mem::size_of::<T>();
let ptr = value.as_ptr() as *const T;
let owner = crate::buffer::BytesAllocator::Arrow(value);
unsafe { Bytes::from_foreign(ptr, len, owner) }
}
pub use immutable::Buffer;
pub(super) use iterator::IntoIter;