use super::*;
pub struct Data {
ptr: *mut u8,
len: usize,
}
impl Data {
pub fn new(len: usize) -> Self {
unsafe {
let bytes = Self::alloc(len);
if len > 0 {
core::ptr::write_bytes(bytes.ptr, 0, len);
}
bytes
}
}
pub fn as_wide(&self) -> &[u16] {
if self.ptr.is_null() {
&[]
} else {
unsafe { core::slice::from_raw_parts(self.ptr as *const u16, self.len / 2) }
}
}
pub fn from_slice(slice: &[u8]) -> Self {
unsafe {
let bytes = Self::alloc(slice.len());
if !slice.is_empty() {
core::ptr::copy_nonoverlapping(slice.as_ptr(), bytes.ptr, slice.len());
}
bytes
}
}
unsafe fn alloc(len: usize) -> Self {
if len == 0 {
Self {
ptr: null_mut(),
len: 0,
}
} else {
let ptr = HeapAlloc(GetProcessHeap(), 0, len) as *mut u8;
if ptr.is_null() {
panic!("allocation failed");
}
Self { ptr, len }
}
}
}
impl Drop for Data {
fn drop(&mut self) {
if !self.ptr.is_null() {
unsafe {
HeapFree(GetProcessHeap(), 0, self.ptr as *mut _);
}
}
}
}
impl Deref for Data {
type Target = [u8];
fn deref(&self) -> &[u8] {
if self.ptr.is_null() {
&[]
} else {
unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
}
}
}
impl core::ops::DerefMut for Data {
fn deref_mut(&mut self) -> &mut [u8] {
if self.ptr.is_null() {
&mut []
} else {
unsafe { core::slice::from_raw_parts_mut(self.ptr, self.len) }
}
}
}
impl Clone for Data {
fn clone(&self) -> Self {
Self::from_slice(self)
}
}
impl PartialEq for Data {
fn eq(&self, other: &Self) -> bool {
self.deref() == other.deref()
}
}
impl Eq for Data {}
impl core::fmt::Debug for Data {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.deref().fmt(f)
}
}
impl<const N: usize> From<[u8; N]> for Data {
fn from(from: [u8; N]) -> Self {
Self::from_slice(&from)
}
}