1#[cfg(feature = "external-buffers")]
2use std::os::raw::c_void;
3use std::{mem::MaybeUninit, slice};
4
5use super::{
6 bindings as napi,
7 raw::{Env, Local},
8};
9
10pub unsafe fn new(env: Env, len: usize) -> Result<Local, napi::Status> {
11 let (buf, bytes) = uninitialized(env, len)?;
12
13 std::ptr::write_bytes(bytes, 0, len);
14
15 Ok(buf)
16}
17
18pub unsafe fn uninitialized(env: Env, len: usize) -> Result<(Local, *mut u8), napi::Status> {
19 let mut buf = MaybeUninit::uninit();
20 let mut bytes = MaybeUninit::uninit();
21 let status = napi::create_buffer(env, len, bytes.as_mut_ptr(), buf.as_mut_ptr());
22
23 match status {
24 Err(err @ napi::Status::PendingException) => return Err(err),
25 status => status.unwrap(),
26 };
27
28 Ok((buf.assume_init(), bytes.assume_init().cast()))
29}
30
31#[cfg(feature = "external-buffers")]
32pub unsafe fn new_external<T>(env: Env, data: T) -> Local
33where
34 T: AsMut<[u8]> + Send,
35{
36 let mut data = Box::new(data);
38 let buf = data.as_mut().as_mut();
39 let length = buf.len();
40 let mut result = MaybeUninit::uninit();
41
42 napi::create_external_buffer(
43 env,
44 length,
45 buf.as_mut_ptr() as *mut _,
46 Some(drop_external::<T>),
47 Box::into_raw(data) as *mut _,
48 result.as_mut_ptr(),
49 )
50 .unwrap();
51
52 result.assume_init()
53}
54
55#[cfg(feature = "external-buffers")]
56unsafe extern "C" fn drop_external<T>(_env: Env, _data: *mut c_void, hint: *mut c_void) {
57 drop(Box::<T>::from_raw(hint as *mut _));
58}
59
60pub unsafe fn as_mut_slice<'a>(env: Env, buf: Local) -> &'a mut [u8] {
64 let mut data = MaybeUninit::uninit();
65 let mut size = 0usize;
66
67 napi::get_buffer_info(env, buf, data.as_mut_ptr(), &mut size as *mut _).unwrap();
68
69 if size == 0 {
70 return &mut [];
71 }
72
73 slice::from_raw_parts_mut(data.assume_init().cast(), size)
74}
75
76pub unsafe fn size(env: Env, buf: Local) -> usize {
79 let mut data = MaybeUninit::uninit();
80 let mut size = 0usize;
81
82 napi::get_buffer_info(env, buf, data.as_mut_ptr(), &mut size as *mut _).unwrap();
83
84 size
85}