feat(napi): Env::create_arraybuffer_with_borrowed_data

This commit is contained in:
LongYinan 2021-01-05 23:27:01 +08:00
parent a17377779d
commit 911a0c139d
No known key found for this signature in database
GPG key ID: C3666B7FC82ADAD7
3 changed files with 73 additions and 13 deletions

View file

@ -410,7 +410,7 @@ impl Env {
Ok(JsArrayBufferValue::new(
unsafe { JsArrayBuffer::from_raw_unchecked(self.0, raw_value) },
data,
mem::ManuallyDrop::new(data),
))
}
@ -436,7 +436,50 @@ impl Env {
value: raw_value,
value_type: ValueType::Object,
}),
data,
mem::ManuallyDrop::new(data),
))
}
#[inline]
/// # Safety
/// Mostly the same with `create_arraybuffer_with_data`
///
/// Provided `finalize_callback` will be called when `Buffer` got dropped.
///
/// You can pass in `noop_finalize` if you have nothing to do in finalize phase.
pub unsafe fn create_arraybuffer_with_borrowed_data<Hint, Finalize>(
&self,
data: *const u8,
length: usize,
hint: Hint,
finalize_callback: Finalize,
) -> Result<JsArrayBufferValue>
where
Finalize: FnOnce(Hint, Env),
{
let mut raw_value = ptr::null_mut();
check_status!(sys::napi_create_external_arraybuffer(
self.0,
data as *mut c_void,
length,
Some(
raw_finalize_with_custom_callback::<Hint, Finalize>
as unsafe extern "C" fn(
env: sys::napi_env,
finalize_data: *mut c_void,
finalize_hint: *mut c_void,
)
),
Box::into_raw(Box::new((hint, finalize_callback))) as *mut c_void,
&mut raw_value,
))?;
Ok(JsArrayBufferValue::new(
JsArrayBuffer(Value {
env: self.0,
value: raw_value,
value_type: ValueType::Object,
}),
mem::ManuallyDrop::new(Vec::from_raw_parts(data as *mut u8, length, length)),
))
}

View file

@ -2,10 +2,10 @@ use std::mem;
use std::ops::{Deref, DerefMut};
use std::os::raw::c_void;
use std::ptr;
use std::slice;
use super::{Value, ValueType};
use crate::check_status;
use crate::{sys, JsUnknown, NapiValue, Ref, Result};
use crate::{check_status, sys, JsUnknown, NapiValue, Ref, Result};
pub struct JsArrayBuffer(pub(crate) Value);
@ -18,7 +18,7 @@ pub struct JsTypedArray(pub(crate) Value);
pub struct JsTypedArrayValue {
pub arraybuffer: JsArrayBuffer,
_data: *mut c_void,
data: *mut c_void,
pub byte_offset: u64,
pub length: u64,
pub typedarray_type: TypedArrayType,
@ -164,11 +164,8 @@ impl JsArrayBuffer {
impl JsArrayBufferValue {
#[inline]
pub fn new(value: JsArrayBuffer, data: Vec<u8>) -> Self {
JsArrayBufferValue {
value,
data: mem::ManuallyDrop::new(data),
}
pub fn new(value: JsArrayBuffer, data: mem::ManuallyDrop<Vec<u8>>) -> Self {
JsArrayBufferValue { value, data }
}
#[inline]
@ -227,7 +224,7 @@ impl JsTypedArray {
})?;
Ok(JsTypedArrayValue {
_data: data,
data,
length: len,
byte_offset,
typedarray_type: typedarray_type.into(),
@ -236,6 +233,27 @@ impl JsTypedArray {
}
}
impl JsTypedArrayValue {
#[inline(always)]
fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.data as *const u8, self.length as usize) }
}
}
impl AsRef<[u8]> for JsTypedArrayValue {
fn as_ref(&self) -> &[u8] {
self.as_slice()
}
}
impl Deref for JsTypedArrayValue {
type Target = [u8];
fn deref(&self) -> &[u8] {
self.as_slice()
}
}
impl JsDataView {
#[inline]
pub fn into_value(self) -> Result<JsDataViewValue> {

View file

@ -2,8 +2,7 @@ use std::convert::TryFrom;
use std::ffi::CString;
use std::ptr;
use crate::check_status;
use crate::{sys, Callback, Error, Result, Status};
use crate::{check_status, sys, Callback, Error, Result, Status};
#[cfg(feature = "serde-json")]
mod de;