mirror of
https://github.com/napi-rs/napi-rs.git
synced 2025-12-08 19:56:07 +00:00
refactor(napi): allow create BufferSlice from external data (#2263)
- also refactor the enum codegen, now we will not emit #[derive(Copy, Clone)] for the original enums. - also refacotr the fn codegen, now #[napi] fn can accept env: &Env as argument, this is useful when the return type contains lifetime
This commit is contained in:
parent
cea16807da
commit
521ef58f59
@ -92,12 +92,10 @@ impl TryToTokens for NapiFn {
|
||||
};
|
||||
let native_call = if !self.is_async {
|
||||
quote! {
|
||||
napi::bindgen_prelude::within_runtime_if_available(move || {
|
||||
let #receiver_ret_name = {
|
||||
#receiver(#(#arg_names),*)
|
||||
};
|
||||
#ret
|
||||
})
|
||||
let #receiver_ret_name = {
|
||||
#receiver(#(#arg_names),*)
|
||||
};
|
||||
#ret
|
||||
}
|
||||
} else {
|
||||
let call = if self.is_ret_result {
|
||||
@ -127,6 +125,7 @@ impl TryToTokens for NapiFn {
|
||||
|
||||
let function_call_inner = quote! {
|
||||
napi::bindgen_prelude::CallbackInfo::<#args_len>::new(env, cb, None, #use_after_async).and_then(|mut cb| {
|
||||
let __wrapped_env = napi::bindgen_prelude::Env::from(env);
|
||||
#build_ref_container
|
||||
#(#arg_conversions)*
|
||||
#native_call
|
||||
@ -253,7 +252,7 @@ impl NapiFn {
|
||||
match &arg.kind {
|
||||
NapiFnArgKind::PatType(path) => {
|
||||
if &path.ty.to_token_stream().to_string() == "Env" {
|
||||
args.push(quote! { napi::bindgen_prelude::Env::from(env) });
|
||||
args.push(quote! { __wrapped_env });
|
||||
skipped_arg_count += 1;
|
||||
} else {
|
||||
let is_in_class = self.parent.is_some();
|
||||
@ -357,6 +356,11 @@ impl NapiFn {
|
||||
if arg_type.is_ref() {
|
||||
refs.push(make_ref(quote! { cb.get_arg(#i) }));
|
||||
}
|
||||
if arg_type == NapiArgType::Env {
|
||||
args.push(quote! { &__wrapped_env });
|
||||
skipped_arg_count += 1;
|
||||
continue;
|
||||
}
|
||||
arg_conversions.push(arg_conversion);
|
||||
args.push(quote! { #ident });
|
||||
}
|
||||
@ -454,6 +458,13 @@ impl NapiFn {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let syn::Type::Path(ele) = &**elem {
|
||||
if let Some(syn::PathSegment { ident, .. }) = ele.path.segments.last() {
|
||||
if ident == "Env" {
|
||||
return Ok((quote! {}, NapiArgType::Env));
|
||||
}
|
||||
}
|
||||
}
|
||||
quote! {
|
||||
let #arg_name = {
|
||||
#type_check
|
||||
@ -702,6 +713,7 @@ enum NapiArgType {
|
||||
Ref,
|
||||
MutRef,
|
||||
Value,
|
||||
Env,
|
||||
}
|
||||
|
||||
impl NapiArgType {
|
||||
|
||||
@ -185,6 +185,15 @@ impl NapiFn {
|
||||
if ty_string == "Env" {
|
||||
return None;
|
||||
}
|
||||
if let syn::Type::Reference(syn::TypeReference { elem, .. }) = &*path.ty {
|
||||
if let syn::Type::Path(path) = elem.as_ref() {
|
||||
if let Some(PathSegment { ident, .. }) = path.path.segments.last() {
|
||||
if ident == "Env" {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let syn::Type::Path(path) = path.ty.as_ref() {
|
||||
if let Some(PathSegment { ident, arguments }) = path.path.segments.last() {
|
||||
if ident == "Reference" || ident == "WeakReference" {
|
||||
|
||||
@ -1203,8 +1203,6 @@ impl ConvertToAST for syn::ItemEnum {
|
||||
});
|
||||
}
|
||||
|
||||
self.attrs.push(parse_quote!(#[derive(Copy, Clone)]));
|
||||
|
||||
let variants = match opts.string_enum() {
|
||||
Some(case) => {
|
||||
let case = case.map(|c| Ok::<Case, Diagnostic>(match c.0.as_str() {
|
||||
|
||||
@ -11,7 +11,7 @@ use std::sync::Mutex;
|
||||
|
||||
#[cfg(all(feature = "napi4", not(feature = "noop"), not(target_family = "wasm")))]
|
||||
use crate::bindgen_prelude::{CUSTOM_GC_TSFN, CUSTOM_GC_TSFN_DESTROYED, THREADS_CAN_ACCESS_ENV};
|
||||
use crate::{bindgen_prelude::*, check_status, sys, Result, ValueType};
|
||||
use crate::{bindgen_prelude::*, check_status, env::EMPTY_VEC, sys, Result, ValueType};
|
||||
|
||||
#[cfg(all(debug_assertions, not(windows)))]
|
||||
thread_local! {
|
||||
@ -26,6 +26,150 @@ pub struct BufferSlice<'scope> {
|
||||
raw_value: sys::napi_value,
|
||||
}
|
||||
|
||||
impl<'scope> BufferSlice<'scope> {
|
||||
/// Create a new `BufferSlice` from a `Vec<u8>`.
|
||||
///
|
||||
/// While this is still a fully-supported data structure, in most cases using a `Uint8Array` will suffice.
|
||||
pub fn from_data<D: Into<Vec<u8>>>(env: &Env, data: D) -> Result<Self> {
|
||||
let mut buf = ptr::null_mut();
|
||||
let mut data = data.into();
|
||||
let inner_ptr = data.as_mut_ptr();
|
||||
#[cfg(all(debug_assertions, not(windows)))]
|
||||
{
|
||||
let is_existed = BUFFER_DATA.with(|buffer_data| {
|
||||
let buffer = buffer_data.lock().expect("Unlock buffer data failed");
|
||||
buffer.contains(&inner_ptr)
|
||||
});
|
||||
if is_existed {
|
||||
panic!("Share the same data between different buffers is not allowed, see: https://github.com/nodejs/node/issues/32463#issuecomment-631974747");
|
||||
}
|
||||
}
|
||||
let len = data.len();
|
||||
let mut status = unsafe {
|
||||
sys::napi_create_external_buffer(
|
||||
env.0,
|
||||
len,
|
||||
inner_ptr.cast(),
|
||||
Some(drop_buffer_slice),
|
||||
Box::into_raw(Box::new(len)).cast(),
|
||||
&mut buf,
|
||||
)
|
||||
};
|
||||
status = if status == sys::Status::napi_no_external_buffers_allowed {
|
||||
unsafe {
|
||||
sys::napi_create_buffer_copy(
|
||||
env.0,
|
||||
len,
|
||||
data.as_mut_ptr().cast(),
|
||||
ptr::null_mut(),
|
||||
&mut buf,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
status
|
||||
};
|
||||
mem::forget(data);
|
||||
check_status!(status, "Failed to create buffer slice from data")?;
|
||||
Ok(Self {
|
||||
inner: unsafe { slice::from_raw_parts_mut(buf.cast(), len) },
|
||||
raw_value: buf,
|
||||
})
|
||||
}
|
||||
|
||||
/// ## Safety
|
||||
///
|
||||
/// Mostly the same with `from_data`
|
||||
///
|
||||
/// Provided `finalize_callback` will be called when `BufferSlice` got dropped.
|
||||
///
|
||||
/// You can pass in `noop_finalize` if you have nothing to do in finalize phase.
|
||||
///
|
||||
/// ### Notes
|
||||
///
|
||||
/// JavaScript may mutate the data passed in to this buffer when writing the buffer.
|
||||
/// However, some JavaScript runtimes do not support external buffers (notably electron!)
|
||||
/// in which case modifications may be lost.
|
||||
///
|
||||
/// If you need to support these runtimes, you should create a buffer by other means and then
|
||||
/// later copy the data back out.
|
||||
pub unsafe fn from_external<T: 'scope, F: FnOnce(T, Env)>(
|
||||
env: &Env,
|
||||
data: *mut u8,
|
||||
len: usize,
|
||||
finalize_hint: T,
|
||||
finalize_callback: F,
|
||||
) -> Result<Self> {
|
||||
let mut buf = ptr::null_mut();
|
||||
if data.is_null() || data as *const u8 == EMPTY_VEC.as_ptr() {
|
||||
return Err(Error::new(
|
||||
Status::InvalidArg,
|
||||
"Borrowed data should not be null".to_owned(),
|
||||
));
|
||||
}
|
||||
#[cfg(all(debug_assertions, not(windows)))]
|
||||
{
|
||||
let is_existed = BUFFER_DATA.with(|buffer_data| {
|
||||
let buffer = buffer_data.lock().expect("Unlock buffer data failed");
|
||||
buffer.contains(&data)
|
||||
});
|
||||
if is_existed {
|
||||
panic!("Share the same data between different buffers is not allowed, see: https://github.com/nodejs/node/issues/32463#issuecomment-631974747");
|
||||
}
|
||||
}
|
||||
let hint_ptr = Box::into_raw(Box::new((finalize_hint, finalize_callback)));
|
||||
let mut status = unsafe {
|
||||
sys::napi_create_external_buffer(
|
||||
env.0,
|
||||
len,
|
||||
data.cast(),
|
||||
Some(crate::env::raw_finalize_with_custom_callback::<T, F>),
|
||||
hint_ptr.cast(),
|
||||
&mut buf,
|
||||
)
|
||||
};
|
||||
status = if status == sys::Status::napi_no_external_buffers_allowed {
|
||||
let (hint, finalize) = *Box::from_raw(hint_ptr);
|
||||
let status =
|
||||
unsafe { sys::napi_create_buffer_copy(env.0, len, data.cast(), ptr::null_mut(), &mut buf) };
|
||||
finalize(hint, *env);
|
||||
status
|
||||
} else {
|
||||
status
|
||||
};
|
||||
check_status!(status, "Failed to create buffer slice from data")?;
|
||||
Ok(Self {
|
||||
inner: unsafe { slice::from_raw_parts_mut(buf.cast(), len) },
|
||||
raw_value: buf,
|
||||
})
|
||||
}
|
||||
|
||||
/// Copy data from a `&[u8]` and create a `BufferSlice` from it.
|
||||
pub fn copy_from<D: AsRef<[u8]>>(env: &Env, data: D) -> Result<Self> {
|
||||
let data = data.as_ref();
|
||||
let len = data.len();
|
||||
let data_ptr = data.as_ptr();
|
||||
let mut buf = ptr::null_mut();
|
||||
let mut result_ptr = ptr::null_mut();
|
||||
check_status!(
|
||||
unsafe {
|
||||
sys::napi_create_buffer_copy(env.0, len, data_ptr.cast(), &mut result_ptr, &mut buf)
|
||||
},
|
||||
"Faild to create a buffer from copied data"
|
||||
)?;
|
||||
Ok(Self {
|
||||
inner: unsafe { slice::from_raw_parts_mut(result_ptr.cast(), len) },
|
||||
raw_value: buf,
|
||||
})
|
||||
}
|
||||
|
||||
/// Convert a `BufferSlice` to a `Buffer`
|
||||
///
|
||||
/// This will perform a `napi_create_reference` internally.
|
||||
pub fn into_buffer(self, env: &Env) -> Result<Buffer> {
|
||||
unsafe { Buffer::from_napi_value(env.0, self.raw_value) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'scope> FromNapiValue for BufferSlice<'scope> {
|
||||
unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
|
||||
let mut buf = ptr::null_mut();
|
||||
@ -171,8 +315,8 @@ impl Drop for Buffer {
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: This is undefined behavior, as the JS side may always modify the underlying buffer,
|
||||
// without synchronization. Also see the docs for the `AsMut` impl.
|
||||
/// SAFETY: This is undefined behavior, as the JS side may always modify the underlying buffer,
|
||||
/// without synchronization. Also see the docs for the `AsMut` impl.
|
||||
unsafe impl Send for Buffer {}
|
||||
|
||||
impl Clone for Buffer {
|
||||
@ -351,9 +495,9 @@ impl ToNapiValue for Buffer {
|
||||
sys::napi_create_external_buffer(
|
||||
env,
|
||||
len,
|
||||
value_ptr as *mut c_void,
|
||||
value_ptr.cast(),
|
||||
Some(drop_buffer),
|
||||
val_box_ptr as *mut c_void,
|
||||
val_box_ptr.cast(),
|
||||
&mut ret,
|
||||
)
|
||||
};
|
||||
|
||||
@ -88,3 +88,25 @@ pub unsafe extern "C" fn drop_buffer(
|
||||
drop(Box::from_raw(finalize_hint as *mut Buffer));
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// called when node buffer slice is ready for gc
|
||||
#[doc(hidden)]
|
||||
pub unsafe extern "C" fn drop_buffer_slice(
|
||||
_env: sys::napi_env,
|
||||
finalize_data: *mut c_void,
|
||||
finalize_hint: *mut c_void,
|
||||
) {
|
||||
let len = *unsafe { Box::from_raw(finalize_hint.cast()) };
|
||||
#[cfg(all(debug_assertions, not(windows)))]
|
||||
{
|
||||
js_values::BUFFER_DATA.with(|buffer_data| {
|
||||
let mut buffer = buffer_data.lock().expect("Unlock Buffer data failed");
|
||||
buffer.remove(&(finalize_data as *mut u8));
|
||||
});
|
||||
}
|
||||
unsafe {
|
||||
drop(Vec::from_raw_parts(finalize_data, len, len));
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,6 +273,7 @@ impl Env {
|
||||
))
|
||||
}
|
||||
|
||||
#[deprecated(since = "3.0.0", note = "Use `BufferSlice::from_data` instead")]
|
||||
/// This API allocates a node::Buffer object and initializes it with data backed by the passed in buffer.
|
||||
///
|
||||
/// While this is still a fully-supported data structure, in most cases using a TypedArray will suffice.
|
||||
@ -324,6 +325,7 @@ impl Env {
|
||||
))
|
||||
}
|
||||
|
||||
#[deprecated(since = "3.0.0", note = "Use `BufferSlice::from_external` instead")]
|
||||
/// # Safety
|
||||
/// Mostly the same with `create_buffer_with_data`
|
||||
///
|
||||
@ -361,15 +363,8 @@ impl Env {
|
||||
let status = sys::napi_create_external_buffer(
|
||||
self.0,
|
||||
length,
|
||||
data as *mut c_void,
|
||||
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,
|
||||
),
|
||||
),
|
||||
data.cast(),
|
||||
Some(raw_finalize_with_custom_callback::<Hint, Finalize>),
|
||||
hint_ptr.cast(),
|
||||
&mut raw_value,
|
||||
);
|
||||
@ -418,6 +413,7 @@ impl Env {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
#[deprecated(since = "3.0.0", note = "Use `BufferSlice::copy_from` instead")]
|
||||
/// This API allocates a node::Buffer object and initializes it with data copied from the passed-in buffer.
|
||||
///
|
||||
/// While this is still a fully-supported data structure, in most cases using a TypedArray will suffice.
|
||||
@ -1392,7 +1388,7 @@ impl Env {
|
||||
}
|
||||
}
|
||||
|
||||
/// This function could be used for `create_buffer_with_borrowed_data` and want do noting when Buffer finalized.
|
||||
/// This function could be used for `BufferSlice::from_external` and want do noting when Buffer finalized.
|
||||
pub fn noop_finalize<Hint>(_hint: Hint, _env: Env) {}
|
||||
|
||||
unsafe extern "C" fn drop_buffer(
|
||||
@ -1452,7 +1448,7 @@ unsafe extern "C" fn cleanup_env<T: 'static>(hook_data: *mut c_void) {
|
||||
(cleanup_env_hook.hook)(cleanup_env_hook.data);
|
||||
}
|
||||
|
||||
unsafe extern "C" fn raw_finalize_with_custom_callback<Hint, Finalize>(
|
||||
pub(crate) unsafe extern "C" fn raw_finalize_with_custom_callback<Hint, Finalize>(
|
||||
env: sys::napi_env,
|
||||
_finalize_data: *mut c_void,
|
||||
finalize_hint: *mut c_void,
|
||||
|
||||
@ -394,8 +394,12 @@ Generated by [AVA](https://avajs.dev).
|
||||
␊
|
||||
export declare function createBigIntI64(): bigint␊
|
||||
␊
|
||||
export declare function createBufferSliceFromCopiedData(): Buffer␊
|
||||
␊
|
||||
export declare function createExternal(size: number): ExternalObject<number>␊
|
||||
␊
|
||||
export declare function createExternalBufferSlice(): Buffer␊
|
||||
␊
|
||||
export declare function createExternalString(content: string): ExternalObject<string>␊
|
||||
␊
|
||||
export declare function createExternalTypedArray(): Uint32Array␊
|
||||
@ -485,6 +489,8 @@ Generated by [AVA](https://avajs.dev).
|
||||
␊
|
||||
export declare function getBuffer(): Buffer␊
|
||||
␊
|
||||
export declare function getBufferSlice(): Buffer␊
|
||||
␊
|
||||
export declare function getCwd(callback: (arg0: string) => void): void␊
|
||||
␊
|
||||
export declare function getEmptyBuffer(): Buffer␊
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -190,6 +190,9 @@ import {
|
||||
StructuredKind,
|
||||
validateStructuredEnum,
|
||||
createArraybuffer,
|
||||
getBufferSlice,
|
||||
createExternalBufferSlice,
|
||||
createBufferSliceFromCopiedData,
|
||||
} from '../index.cjs'
|
||||
|
||||
import { test } from './test.framework.js'
|
||||
@ -782,6 +785,9 @@ test('buffer', (t) => {
|
||||
t.is(buf.toString('utf-8'), 'Hello world')
|
||||
buf = appendBuffer(buf)
|
||||
t.is(buf.toString('utf-8'), 'Hello world!')
|
||||
t.is(getBufferSlice().toString('utf-8'), 'Hello world')
|
||||
t.is(createExternalBufferSlice().toString('utf-8'), 'Hello world')
|
||||
t.is(createBufferSliceFromCopiedData().toString('utf-8'), 'Hello world')
|
||||
|
||||
const a = getEmptyBuffer()
|
||||
const b = getEmptyBuffer()
|
||||
|
||||
@ -339,34 +339,37 @@ function __napi_rs_initialize_modules(__napiInstance) {
|
||||
__napiInstance.exports['__napi_register__Pet_struct_341']?.()
|
||||
__napiInstance.exports['__napi_register__tsfn_in_either_342']?.()
|
||||
__napiInstance.exports['__napi_register__get_buffer_343']?.()
|
||||
__napiInstance.exports['__napi_register__append_buffer_344']?.()
|
||||
__napiInstance.exports['__napi_register__get_empty_buffer_345']?.()
|
||||
__napiInstance.exports['__napi_register__get_empty_typed_array_346']?.()
|
||||
__napiInstance.exports['__napi_register__convert_u32_array_347']?.()
|
||||
__napiInstance.exports['__napi_register__create_external_typed_array_348']?.()
|
||||
__napiInstance.exports['__napi_register__mutate_typed_array_349']?.()
|
||||
__napiInstance.exports['__napi_register__deref_uint8_array_350']?.()
|
||||
__napiInstance.exports['__napi_register__buffer_pass_through_351']?.()
|
||||
__napiInstance.exports['__napi_register__array_buffer_pass_through_352']?.()
|
||||
__napiInstance.exports['__napi_register__accept_slice_353']?.()
|
||||
__napiInstance.exports['__napi_register__accept_arraybuffer_354']?.()
|
||||
__napiInstance.exports['__napi_register__create_arraybuffer_355']?.()
|
||||
__napiInstance.exports['__napi_register__u8_array_to_array_356']?.()
|
||||
__napiInstance.exports['__napi_register__i8_array_to_array_357']?.()
|
||||
__napiInstance.exports['__napi_register__u16_array_to_array_358']?.()
|
||||
__napiInstance.exports['__napi_register__i16_array_to_array_359']?.()
|
||||
__napiInstance.exports['__napi_register__u32_array_to_array_360']?.()
|
||||
__napiInstance.exports['__napi_register__i32_array_to_array_361']?.()
|
||||
__napiInstance.exports['__napi_register__f32_array_to_array_362']?.()
|
||||
__napiInstance.exports['__napi_register__f64_array_to_array_363']?.()
|
||||
__napiInstance.exports['__napi_register__u64_array_to_array_364']?.()
|
||||
__napiInstance.exports['__napi_register__i64_array_to_array_365']?.()
|
||||
__napiInstance.exports['__napi_register__accept_uint8_clamped_slice_366']?.()
|
||||
__napiInstance.exports['__napi_register__accept_uint8_clamped_slice_and_buffer_slice_367']?.()
|
||||
__napiInstance.exports['__napi_register__AsyncBuffer_impl_368']?.()
|
||||
__napiInstance.exports['__napi_register__async_reduce_buffer_369']?.()
|
||||
__napiInstance.exports['__napi_register__async_buffer_to_array_370']?.()
|
||||
__napiInstance.exports['__napi_register__u_init8_array_from_string_371']?.()
|
||||
__napiInstance.exports['__napi_register__get_buffer_slice_344']?.()
|
||||
__napiInstance.exports['__napi_register__append_buffer_345']?.()
|
||||
__napiInstance.exports['__napi_register__get_empty_buffer_346']?.()
|
||||
__napiInstance.exports['__napi_register__create_external_buffer_slice_347']?.()
|
||||
__napiInstance.exports['__napi_register__create_buffer_slice_from_copied_data_348']?.()
|
||||
__napiInstance.exports['__napi_register__get_empty_typed_array_349']?.()
|
||||
__napiInstance.exports['__napi_register__convert_u32_array_350']?.()
|
||||
__napiInstance.exports['__napi_register__create_external_typed_array_351']?.()
|
||||
__napiInstance.exports['__napi_register__mutate_typed_array_352']?.()
|
||||
__napiInstance.exports['__napi_register__deref_uint8_array_353']?.()
|
||||
__napiInstance.exports['__napi_register__buffer_pass_through_354']?.()
|
||||
__napiInstance.exports['__napi_register__array_buffer_pass_through_355']?.()
|
||||
__napiInstance.exports['__napi_register__accept_slice_356']?.()
|
||||
__napiInstance.exports['__napi_register__accept_arraybuffer_357']?.()
|
||||
__napiInstance.exports['__napi_register__create_arraybuffer_358']?.()
|
||||
__napiInstance.exports['__napi_register__u8_array_to_array_359']?.()
|
||||
__napiInstance.exports['__napi_register__i8_array_to_array_360']?.()
|
||||
__napiInstance.exports['__napi_register__u16_array_to_array_361']?.()
|
||||
__napiInstance.exports['__napi_register__i16_array_to_array_362']?.()
|
||||
__napiInstance.exports['__napi_register__u32_array_to_array_363']?.()
|
||||
__napiInstance.exports['__napi_register__i32_array_to_array_364']?.()
|
||||
__napiInstance.exports['__napi_register__f32_array_to_array_365']?.()
|
||||
__napiInstance.exports['__napi_register__f64_array_to_array_366']?.()
|
||||
__napiInstance.exports['__napi_register__u64_array_to_array_367']?.()
|
||||
__napiInstance.exports['__napi_register__i64_array_to_array_368']?.()
|
||||
__napiInstance.exports['__napi_register__accept_uint8_clamped_slice_369']?.()
|
||||
__napiInstance.exports['__napi_register__accept_uint8_clamped_slice_and_buffer_slice_370']?.()
|
||||
__napiInstance.exports['__napi_register__AsyncBuffer_impl_371']?.()
|
||||
__napiInstance.exports['__napi_register__async_reduce_buffer_372']?.()
|
||||
__napiInstance.exports['__napi_register__async_buffer_to_array_373']?.()
|
||||
__napiInstance.exports['__napi_register__u_init8_array_from_string_374']?.()
|
||||
}
|
||||
export const Animal = __napiModule.exports.Animal
|
||||
export const AnimalWithDefaultConstructor = __napiModule.exports.AnimalWithDefaultConstructor
|
||||
@ -469,7 +472,9 @@ export const convertU32Array = __napiModule.exports.convertU32Array
|
||||
export const createArraybuffer = __napiModule.exports.createArraybuffer
|
||||
export const createBigInt = __napiModule.exports.createBigInt
|
||||
export const createBigIntI64 = __napiModule.exports.createBigIntI64
|
||||
export const createBufferSliceFromCopiedData = __napiModule.exports.createBufferSliceFromCopiedData
|
||||
export const createExternal = __napiModule.exports.createExternal
|
||||
export const createExternalBufferSlice = __napiModule.exports.createExternalBufferSlice
|
||||
export const createExternalString = __napiModule.exports.createExternalString
|
||||
export const createExternalTypedArray = __napiModule.exports.createExternalTypedArray
|
||||
export const createObj = __napiModule.exports.createObj
|
||||
@ -500,6 +505,7 @@ export const fibonacci = __napiModule.exports.fibonacci
|
||||
export const fnReceivedAliased = __napiModule.exports.fnReceivedAliased
|
||||
export const getBtreeMapping = __napiModule.exports.getBtreeMapping
|
||||
export const getBuffer = __napiModule.exports.getBuffer
|
||||
export const getBufferSlice = __napiModule.exports.getBufferSlice
|
||||
export const getCwd = __napiModule.exports.getCwd
|
||||
export const getEmptyBuffer = __napiModule.exports.getEmptyBuffer
|
||||
export const getEmptyTypedArray = __napiModule.exports.getEmptyTypedArray
|
||||
|
||||
@ -363,34 +363,37 @@ function __napi_rs_initialize_modules(__napiInstance) {
|
||||
__napiInstance.exports['__napi_register__Pet_struct_341']?.()
|
||||
__napiInstance.exports['__napi_register__tsfn_in_either_342']?.()
|
||||
__napiInstance.exports['__napi_register__get_buffer_343']?.()
|
||||
__napiInstance.exports['__napi_register__append_buffer_344']?.()
|
||||
__napiInstance.exports['__napi_register__get_empty_buffer_345']?.()
|
||||
__napiInstance.exports['__napi_register__get_empty_typed_array_346']?.()
|
||||
__napiInstance.exports['__napi_register__convert_u32_array_347']?.()
|
||||
__napiInstance.exports['__napi_register__create_external_typed_array_348']?.()
|
||||
__napiInstance.exports['__napi_register__mutate_typed_array_349']?.()
|
||||
__napiInstance.exports['__napi_register__deref_uint8_array_350']?.()
|
||||
__napiInstance.exports['__napi_register__buffer_pass_through_351']?.()
|
||||
__napiInstance.exports['__napi_register__array_buffer_pass_through_352']?.()
|
||||
__napiInstance.exports['__napi_register__accept_slice_353']?.()
|
||||
__napiInstance.exports['__napi_register__accept_arraybuffer_354']?.()
|
||||
__napiInstance.exports['__napi_register__create_arraybuffer_355']?.()
|
||||
__napiInstance.exports['__napi_register__u8_array_to_array_356']?.()
|
||||
__napiInstance.exports['__napi_register__i8_array_to_array_357']?.()
|
||||
__napiInstance.exports['__napi_register__u16_array_to_array_358']?.()
|
||||
__napiInstance.exports['__napi_register__i16_array_to_array_359']?.()
|
||||
__napiInstance.exports['__napi_register__u32_array_to_array_360']?.()
|
||||
__napiInstance.exports['__napi_register__i32_array_to_array_361']?.()
|
||||
__napiInstance.exports['__napi_register__f32_array_to_array_362']?.()
|
||||
__napiInstance.exports['__napi_register__f64_array_to_array_363']?.()
|
||||
__napiInstance.exports['__napi_register__u64_array_to_array_364']?.()
|
||||
__napiInstance.exports['__napi_register__i64_array_to_array_365']?.()
|
||||
__napiInstance.exports['__napi_register__accept_uint8_clamped_slice_366']?.()
|
||||
__napiInstance.exports['__napi_register__accept_uint8_clamped_slice_and_buffer_slice_367']?.()
|
||||
__napiInstance.exports['__napi_register__AsyncBuffer_impl_368']?.()
|
||||
__napiInstance.exports['__napi_register__async_reduce_buffer_369']?.()
|
||||
__napiInstance.exports['__napi_register__async_buffer_to_array_370']?.()
|
||||
__napiInstance.exports['__napi_register__u_init8_array_from_string_371']?.()
|
||||
__napiInstance.exports['__napi_register__get_buffer_slice_344']?.()
|
||||
__napiInstance.exports['__napi_register__append_buffer_345']?.()
|
||||
__napiInstance.exports['__napi_register__get_empty_buffer_346']?.()
|
||||
__napiInstance.exports['__napi_register__create_external_buffer_slice_347']?.()
|
||||
__napiInstance.exports['__napi_register__create_buffer_slice_from_copied_data_348']?.()
|
||||
__napiInstance.exports['__napi_register__get_empty_typed_array_349']?.()
|
||||
__napiInstance.exports['__napi_register__convert_u32_array_350']?.()
|
||||
__napiInstance.exports['__napi_register__create_external_typed_array_351']?.()
|
||||
__napiInstance.exports['__napi_register__mutate_typed_array_352']?.()
|
||||
__napiInstance.exports['__napi_register__deref_uint8_array_353']?.()
|
||||
__napiInstance.exports['__napi_register__buffer_pass_through_354']?.()
|
||||
__napiInstance.exports['__napi_register__array_buffer_pass_through_355']?.()
|
||||
__napiInstance.exports['__napi_register__accept_slice_356']?.()
|
||||
__napiInstance.exports['__napi_register__accept_arraybuffer_357']?.()
|
||||
__napiInstance.exports['__napi_register__create_arraybuffer_358']?.()
|
||||
__napiInstance.exports['__napi_register__u8_array_to_array_359']?.()
|
||||
__napiInstance.exports['__napi_register__i8_array_to_array_360']?.()
|
||||
__napiInstance.exports['__napi_register__u16_array_to_array_361']?.()
|
||||
__napiInstance.exports['__napi_register__i16_array_to_array_362']?.()
|
||||
__napiInstance.exports['__napi_register__u32_array_to_array_363']?.()
|
||||
__napiInstance.exports['__napi_register__i32_array_to_array_364']?.()
|
||||
__napiInstance.exports['__napi_register__f32_array_to_array_365']?.()
|
||||
__napiInstance.exports['__napi_register__f64_array_to_array_366']?.()
|
||||
__napiInstance.exports['__napi_register__u64_array_to_array_367']?.()
|
||||
__napiInstance.exports['__napi_register__i64_array_to_array_368']?.()
|
||||
__napiInstance.exports['__napi_register__accept_uint8_clamped_slice_369']?.()
|
||||
__napiInstance.exports['__napi_register__accept_uint8_clamped_slice_and_buffer_slice_370']?.()
|
||||
__napiInstance.exports['__napi_register__AsyncBuffer_impl_371']?.()
|
||||
__napiInstance.exports['__napi_register__async_reduce_buffer_372']?.()
|
||||
__napiInstance.exports['__napi_register__async_buffer_to_array_373']?.()
|
||||
__napiInstance.exports['__napi_register__u_init8_array_from_string_374']?.()
|
||||
}
|
||||
module.exports.Animal = __napiModule.exports.Animal
|
||||
module.exports.AnimalWithDefaultConstructor = __napiModule.exports.AnimalWithDefaultConstructor
|
||||
@ -493,7 +496,9 @@ module.exports.convertU32Array = __napiModule.exports.convertU32Array
|
||||
module.exports.createArraybuffer = __napiModule.exports.createArraybuffer
|
||||
module.exports.createBigInt = __napiModule.exports.createBigInt
|
||||
module.exports.createBigIntI64 = __napiModule.exports.createBigIntI64
|
||||
module.exports.createBufferSliceFromCopiedData = __napiModule.exports.createBufferSliceFromCopiedData
|
||||
module.exports.createExternal = __napiModule.exports.createExternal
|
||||
module.exports.createExternalBufferSlice = __napiModule.exports.createExternalBufferSlice
|
||||
module.exports.createExternalString = __napiModule.exports.createExternalString
|
||||
module.exports.createExternalTypedArray = __napiModule.exports.createExternalTypedArray
|
||||
module.exports.createObj = __napiModule.exports.createObj
|
||||
@ -524,6 +529,7 @@ module.exports.fibonacci = __napiModule.exports.fibonacci
|
||||
module.exports.fnReceivedAliased = __napiModule.exports.fnReceivedAliased
|
||||
module.exports.getBtreeMapping = __napiModule.exports.getBtreeMapping
|
||||
module.exports.getBuffer = __napiModule.exports.getBuffer
|
||||
module.exports.getBufferSlice = __napiModule.exports.getBufferSlice
|
||||
module.exports.getCwd = __napiModule.exports.getCwd
|
||||
module.exports.getEmptyBuffer = __napiModule.exports.getEmptyBuffer
|
||||
module.exports.getEmptyTypedArray = __napiModule.exports.getEmptyTypedArray
|
||||
|
||||
@ -462,7 +462,9 @@ module.exports.convertU32Array = nativeBinding.convertU32Array
|
||||
module.exports.createArraybuffer = nativeBinding.createArraybuffer
|
||||
module.exports.createBigInt = nativeBinding.createBigInt
|
||||
module.exports.createBigIntI64 = nativeBinding.createBigIntI64
|
||||
module.exports.createBufferSliceFromCopiedData = nativeBinding.createBufferSliceFromCopiedData
|
||||
module.exports.createExternal = nativeBinding.createExternal
|
||||
module.exports.createExternalBufferSlice = nativeBinding.createExternalBufferSlice
|
||||
module.exports.createExternalString = nativeBinding.createExternalString
|
||||
module.exports.createExternalTypedArray = nativeBinding.createExternalTypedArray
|
||||
module.exports.createObj = nativeBinding.createObj
|
||||
@ -493,6 +495,7 @@ module.exports.fibonacci = nativeBinding.fibonacci
|
||||
module.exports.fnReceivedAliased = nativeBinding.fnReceivedAliased
|
||||
module.exports.getBtreeMapping = nativeBinding.getBtreeMapping
|
||||
module.exports.getBuffer = nativeBinding.getBuffer
|
||||
module.exports.getBufferSlice = nativeBinding.getBufferSlice
|
||||
module.exports.getCwd = nativeBinding.getCwd
|
||||
module.exports.getEmptyBuffer = nativeBinding.getEmptyBuffer
|
||||
module.exports.getEmptyTypedArray = nativeBinding.getEmptyTypedArray
|
||||
|
||||
@ -384,8 +384,12 @@ export declare function createBigInt(): bigint
|
||||
|
||||
export declare function createBigIntI64(): bigint
|
||||
|
||||
export declare function createBufferSliceFromCopiedData(): Buffer
|
||||
|
||||
export declare function createExternal(size: number): ExternalObject<number>
|
||||
|
||||
export declare function createExternalBufferSlice(): Buffer
|
||||
|
||||
export declare function createExternalString(content: string): ExternalObject<string>
|
||||
|
||||
export declare function createExternalTypedArray(): Uint32Array
|
||||
@ -475,6 +479,8 @@ export declare function getBtreeMapping(): Record<string, number>
|
||||
|
||||
export declare function getBuffer(): Buffer
|
||||
|
||||
export declare function getBufferSlice(): Buffer
|
||||
|
||||
export declare function getCwd(callback: (arg0: string) => void): void
|
||||
|
||||
export declare function getEmptyBuffer(): Buffer
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/// default enum values are continuos i32s start from 0
|
||||
#[napi]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Kind {
|
||||
/// Barks
|
||||
Dog,
|
||||
|
||||
@ -5,6 +5,11 @@ fn get_buffer() -> Buffer {
|
||||
String::from("Hello world").as_bytes().into()
|
||||
}
|
||||
|
||||
#[napi]
|
||||
fn get_buffer_slice(env: &Env) -> Result<BufferSlice> {
|
||||
BufferSlice::from_data(env, String::from("Hello world").as_bytes().to_vec())
|
||||
}
|
||||
|
||||
#[napi]
|
||||
fn append_buffer(buf: Buffer) -> Buffer {
|
||||
let mut buf = Vec::<u8>::from(buf);
|
||||
@ -17,6 +22,25 @@ fn get_empty_buffer() -> Buffer {
|
||||
vec![].into()
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn create_external_buffer_slice(env: &Env) -> Result<BufferSlice> {
|
||||
let mut data = String::from("Hello world").as_bytes().to_vec();
|
||||
let data_ptr = data.as_mut_ptr();
|
||||
let len = data.len();
|
||||
// Mock the ffi data that not managed by Rust
|
||||
std::mem::forget(data);
|
||||
unsafe {
|
||||
BufferSlice::from_external(env, data_ptr, len, data_ptr, |ptr, _| {
|
||||
std::mem::drop(Vec::from_raw_parts(ptr, len, len));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn create_buffer_slice_from_copied_data(env: &Env) -> Result<BufferSlice> {
|
||||
BufferSlice::copy_from(env, String::from("Hello world").as_bytes())
|
||||
}
|
||||
|
||||
#[napi]
|
||||
fn get_empty_typed_array() -> Uint8Array {
|
||||
vec![].into()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user