Merge pull request #409 from napi-rs/arraybuffer-with-borrowed-data

feat(napi): Env::create_arraybuffer_with_borrowed_data
This commit is contained in:
LongYinan 2021-01-05 23:42:10 +08:00 committed by GitHub
commit 4a96169b2a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 13 deletions

View file

@ -410,7 +410,7 @@ impl Env {
Ok(JsArrayBufferValue::new( Ok(JsArrayBufferValue::new(
unsafe { JsArrayBuffer::from_raw_unchecked(self.0, raw_value) }, unsafe { JsArrayBuffer::from_raw_unchecked(self.0, raw_value) },
data, mem::ManuallyDrop::new(data),
)) ))
} }
@ -436,7 +436,50 @@ impl Env {
value: raw_value, value: raw_value,
value_type: ValueType::Object, 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::ops::{Deref, DerefMut};
use std::os::raw::c_void; use std::os::raw::c_void;
use std::ptr; use std::ptr;
use std::slice;
use super::{Value, ValueType}; use super::{Value, ValueType};
use crate::check_status; use crate::{check_status, sys, JsUnknown, NapiValue, Ref, Result};
use crate::{sys, JsUnknown, NapiValue, Ref, Result};
pub struct JsArrayBuffer(pub(crate) Value); pub struct JsArrayBuffer(pub(crate) Value);
@ -18,7 +18,7 @@ pub struct JsTypedArray(pub(crate) Value);
pub struct JsTypedArrayValue { pub struct JsTypedArrayValue {
pub arraybuffer: JsArrayBuffer, pub arraybuffer: JsArrayBuffer,
_data: *mut c_void, data: *mut c_void,
pub byte_offset: u64, pub byte_offset: u64,
pub length: u64, pub length: u64,
pub typedarray_type: TypedArrayType, pub typedarray_type: TypedArrayType,
@ -164,11 +164,8 @@ impl JsArrayBuffer {
impl JsArrayBufferValue { impl JsArrayBufferValue {
#[inline] #[inline]
pub fn new(value: JsArrayBuffer, data: Vec<u8>) -> Self { pub fn new(value: JsArrayBuffer, data: mem::ManuallyDrop<Vec<u8>>) -> Self {
JsArrayBufferValue { JsArrayBufferValue { value, data }
value,
data: mem::ManuallyDrop::new(data),
}
} }
#[inline] #[inline]
@ -227,7 +224,7 @@ impl JsTypedArray {
})?; })?;
Ok(JsTypedArrayValue { Ok(JsTypedArrayValue {
_data: data, data,
length: len, length: len,
byte_offset, byte_offset,
typedarray_type: typedarray_type.into(), 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 { impl JsDataView {
#[inline] #[inline]
pub fn into_value(self) -> Result<JsDataViewValue> { pub fn into_value(self) -> Result<JsDataViewValue> {

View file

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