refactor(napi): create_buffer_with_borrowed_data now accepted raw ptr
This commit is contained in:
parent
9e73837635
commit
530359421c
3 changed files with 70 additions and 9 deletions
|
@ -320,20 +320,19 @@ impl Env {
|
||||||
/// Provided `finalize_callback` will be called when `Buffer` got dropped.
|
/// Provided `finalize_callback` will be called when `Buffer` got dropped.
|
||||||
pub unsafe fn create_buffer_with_borrowed_data<Hint, Finalize>(
|
pub unsafe fn create_buffer_with_borrowed_data<Hint, Finalize>(
|
||||||
&self,
|
&self,
|
||||||
data: &[u8],
|
data: *const u8,
|
||||||
|
length: usize,
|
||||||
hint: Hint,
|
hint: Hint,
|
||||||
finalize_callback: Option<Finalize>,
|
finalize_callback: Option<Finalize>,
|
||||||
) -> Result<JsBufferValue>
|
) -> Result<JsBufferValue>
|
||||||
where
|
where
|
||||||
Finalize: FnOnce(Env, Hint),
|
Finalize: FnOnce(Hint, Env),
|
||||||
{
|
{
|
||||||
let length = data.len();
|
|
||||||
let mut raw_value = ptr::null_mut();
|
let mut raw_value = ptr::null_mut();
|
||||||
let data_ptr = data.as_ptr();
|
|
||||||
check_status!(sys::napi_create_external_buffer(
|
check_status!(sys::napi_create_external_buffer(
|
||||||
self.0,
|
self.0,
|
||||||
length,
|
length,
|
||||||
data_ptr as *mut c_void,
|
data as *mut c_void,
|
||||||
Some(
|
Some(
|
||||||
raw_finalize_with_custom_callback::<Hint, Finalize>
|
raw_finalize_with_custom_callback::<Hint, Finalize>
|
||||||
as unsafe extern "C" fn(
|
as unsafe extern "C" fn(
|
||||||
|
@ -351,7 +350,7 @@ impl Env {
|
||||||
value: raw_value,
|
value: raw_value,
|
||||||
value_type: ValueType::Object,
|
value_type: ValueType::Object,
|
||||||
}),
|
}),
|
||||||
mem::ManuallyDrop::new(Vec::from_raw_parts(data_ptr as *mut u8, length, length)),
|
mem::ManuallyDrop::new(Vec::from_raw_parts(data as *mut u8, length, length)),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1065,6 +1064,9 @@ impl Env {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This function could be used for `create_buffer_with_borrowed_data` and want do noting when Buffer finalized.
|
||||||
|
pub fn noop_finalize<Hint>(_hint: Hint, _env: Env) {}
|
||||||
|
|
||||||
unsafe extern "C" fn drop_buffer(
|
unsafe extern "C" fn drop_buffer(
|
||||||
_env: sys::napi_env,
|
_env: sys::napi_env,
|
||||||
finalize_data: *mut c_void,
|
finalize_data: *mut c_void,
|
||||||
|
@ -1125,10 +1127,10 @@ unsafe extern "C" fn raw_finalize_with_custom_callback<Hint, Finalize>(
|
||||||
_finalize_data: *mut c_void,
|
_finalize_data: *mut c_void,
|
||||||
finalize_hint: *mut c_void,
|
finalize_hint: *mut c_void,
|
||||||
) where
|
) where
|
||||||
Finalize: FnOnce(Env, Hint),
|
Finalize: FnOnce(Hint, Env),
|
||||||
{
|
{
|
||||||
let (hint, maybe_callback) = *Box::from_raw(finalize_hint as *mut (Hint, Option<Finalize>));
|
let (hint, maybe_callback) = *Box::from_raw(finalize_hint as *mut (Hint, Option<Finalize>));
|
||||||
if let Some(callback) = maybe_callback {
|
if let Some(callback) = maybe_callback {
|
||||||
callback(Env::from_raw(env), hint);
|
callback(hint, Env::from_raw(env));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,3 +18,17 @@ test('should copy', (t) => {
|
||||||
t.deepEqual(copyBuffer, fixture)
|
t.deepEqual(copyBuffer, fixture)
|
||||||
t.not(fixture, copyBuffer)
|
t.not(fixture, copyBuffer)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('should create borrowed buffer with noop finalize', (t) => {
|
||||||
|
t.deepEqual(
|
||||||
|
bindings.createBorrowedBufferWithNoopFinalize(),
|
||||||
|
Buffer.from([1, 2, 3]),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should create borrowed buffer with finalize', (t) => {
|
||||||
|
t.deepEqual(
|
||||||
|
bindings.createBorrowedBufferWithFinalize(),
|
||||||
|
Buffer.from([1, 2, 3]),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
use std::mem::ManuallyDrop;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
use napi::{CallContext, Error, JsBuffer, JsNumber, JsObject, JsString, Result, Status};
|
use napi::{
|
||||||
|
noop_finalize, CallContext, ContextlessResult, Env, Error, JsBuffer, JsNumber, JsObject,
|
||||||
|
JsString, Result, Status,
|
||||||
|
};
|
||||||
|
|
||||||
#[js_function(1)]
|
#[js_function(1)]
|
||||||
pub fn get_buffer_length(ctx: CallContext) -> Result<JsNumber> {
|
pub fn get_buffer_length(ctx: CallContext) -> Result<JsNumber> {
|
||||||
|
@ -22,9 +26,50 @@ pub fn copy_buffer(ctx: CallContext) -> Result<JsBuffer> {
|
||||||
ctx.env.create_buffer_copy(buffer).map(|b| b.into_raw())
|
ctx.env.create_buffer_copy(buffer).map(|b| b.into_raw())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[contextless_function]
|
||||||
|
pub fn create_borrowed_buffer_with_noop_finalize(env: Env) -> ContextlessResult<JsBuffer> {
|
||||||
|
let data = vec![1, 2, 3];
|
||||||
|
let data_ptr = data.as_ptr();
|
||||||
|
let length = data.len();
|
||||||
|
let manually_drop = ManuallyDrop::new(data);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
env.create_buffer_with_borrowed_data(data_ptr, length, manually_drop, Some(noop_finalize))
|
||||||
|
}
|
||||||
|
.map(|b| Some(b.into_raw()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[contextless_function]
|
||||||
|
pub fn create_borrowed_buffer_with_finalize(env: Env) -> ContextlessResult<JsBuffer> {
|
||||||
|
let data = vec![1, 2, 3];
|
||||||
|
let data_ptr = data.as_ptr();
|
||||||
|
let length = data.len();
|
||||||
|
let manually_drop = ManuallyDrop::new(data);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
env.create_buffer_with_borrowed_data(
|
||||||
|
data_ptr,
|
||||||
|
length,
|
||||||
|
manually_drop,
|
||||||
|
Some(|mut hint: ManuallyDrop<Vec<u8>>, _| {
|
||||||
|
ManuallyDrop::drop(&mut hint);
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.map(|b| Some(b.into_raw()))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn register_js(exports: &mut JsObject) -> Result<()> {
|
pub fn register_js(exports: &mut JsObject) -> Result<()> {
|
||||||
exports.create_named_method("getBufferLength", get_buffer_length)?;
|
exports.create_named_method("getBufferLength", get_buffer_length)?;
|
||||||
exports.create_named_method("bufferToString", buffer_to_string)?;
|
exports.create_named_method("bufferToString", buffer_to_string)?;
|
||||||
exports.create_named_method("copyBuffer", copy_buffer)?;
|
exports.create_named_method("copyBuffer", copy_buffer)?;
|
||||||
|
exports.create_named_method(
|
||||||
|
"createBorrowedBufferWithNoopFinalize",
|
||||||
|
create_borrowed_buffer_with_noop_finalize,
|
||||||
|
)?;
|
||||||
|
exports.create_named_method(
|
||||||
|
"createBorrowedBufferWithFinalize",
|
||||||
|
create_borrowed_buffer_with_finalize,
|
||||||
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue