Merge pull request #1144 from mischnic/empty-buffer
This commit is contained in:
commit
eee42e92e7
10 changed files with 105 additions and 6 deletions
|
@ -180,7 +180,14 @@ macro_rules! impl_typed_array {
|
||||||
unsafe {
|
unsafe {
|
||||||
sys::napi_create_external_arraybuffer(
|
sys::napi_create_external_arraybuffer(
|
||||||
env,
|
env,
|
||||||
val.data as *mut c_void,
|
if length == 0 {
|
||||||
|
// Rust uses 0x1 as the data pointer for empty buffers,
|
||||||
|
// but NAPI/V8 only allows multiple buffers to have
|
||||||
|
// the same data pointer if it's 0x0.
|
||||||
|
ptr::null_mut()
|
||||||
|
} else {
|
||||||
|
val.data as *mut c_void
|
||||||
|
},
|
||||||
length,
|
length,
|
||||||
Some(finalizer::<$rust_type>),
|
Some(finalizer::<$rust_type>),
|
||||||
hint_ptr as *mut c_void,
|
hint_ptr as *mut c_void,
|
||||||
|
|
|
@ -176,7 +176,14 @@ impl ToNapiValue for Buffer {
|
||||||
sys::napi_create_external_buffer(
|
sys::napi_create_external_buffer(
|
||||||
env,
|
env,
|
||||||
len,
|
len,
|
||||||
val.inner.as_mut_ptr() as *mut _,
|
if len == 0 {
|
||||||
|
// Rust uses 0x1 as the data pointer for empty buffers,
|
||||||
|
// but NAPI/V8 only allows multiple buffers to have
|
||||||
|
// the same data pointer if it's 0x0.
|
||||||
|
ptr::null_mut()
|
||||||
|
} else {
|
||||||
|
val.inner.as_mut_ptr() as *mut _
|
||||||
|
},
|
||||||
Some(drop_buffer),
|
Some(drop_buffer),
|
||||||
Box::into_raw(Box::new((len, val.capacity))) as *mut _,
|
Box::into_raw(Box::new((len, val.capacity))) as *mut _,
|
||||||
&mut ret,
|
&mut ret,
|
||||||
|
|
|
@ -264,7 +264,14 @@ impl Env {
|
||||||
sys::napi_create_external_buffer(
|
sys::napi_create_external_buffer(
|
||||||
self.0,
|
self.0,
|
||||||
length,
|
length,
|
||||||
data_ptr as *mut c_void,
|
if length == 0 {
|
||||||
|
// Rust uses 0x1 as the data pointer for empty buffers,
|
||||||
|
// but NAPI/V8 only allows multiple buffers to have
|
||||||
|
// the same data pointer if it's 0x0.
|
||||||
|
ptr::null_mut()
|
||||||
|
} else {
|
||||||
|
data_ptr as *mut c_void
|
||||||
|
},
|
||||||
Some(drop_buffer),
|
Some(drop_buffer),
|
||||||
Box::into_raw(Box::new((length, data.capacity()))) as *mut c_void,
|
Box::into_raw(Box::new((length, data.capacity()))) as *mut c_void,
|
||||||
&mut raw_value,
|
&mut raw_value,
|
||||||
|
@ -301,7 +308,14 @@ impl Env {
|
||||||
sys::napi_create_external_buffer(
|
sys::napi_create_external_buffer(
|
||||||
self.0,
|
self.0,
|
||||||
length,
|
length,
|
||||||
data as *mut c_void,
|
if length == 0 {
|
||||||
|
// Rust uses 0x1 as the data pointer for empty buffers,
|
||||||
|
// but NAPI/V8 only allows multiple buffers to have
|
||||||
|
// the same data pointer if it's 0x0.
|
||||||
|
ptr::null_mut()
|
||||||
|
} else {
|
||||||
|
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(
|
||||||
|
@ -386,7 +400,14 @@ impl Env {
|
||||||
check_status!(unsafe {
|
check_status!(unsafe {
|
||||||
sys::napi_create_external_arraybuffer(
|
sys::napi_create_external_arraybuffer(
|
||||||
self.0,
|
self.0,
|
||||||
data_ptr as *mut c_void,
|
if length == 0 {
|
||||||
|
// Rust uses 0x1 as the data pointer for empty buffers,
|
||||||
|
// but NAPI/V8 only allows multiple buffers to have
|
||||||
|
// the same data pointer if it's 0x0.
|
||||||
|
ptr::null_mut()
|
||||||
|
} else {
|
||||||
|
data_ptr as *mut c_void
|
||||||
|
},
|
||||||
length,
|
length,
|
||||||
Some(drop_buffer),
|
Some(drop_buffer),
|
||||||
Box::into_raw(Box::new((length, data.capacity()))) as *mut c_void,
|
Box::into_raw(Box::new((length, data.capacity()))) as *mut c_void,
|
||||||
|
@ -426,7 +447,14 @@ impl Env {
|
||||||
check_status!(unsafe {
|
check_status!(unsafe {
|
||||||
sys::napi_create_external_arraybuffer(
|
sys::napi_create_external_arraybuffer(
|
||||||
self.0,
|
self.0,
|
||||||
data as *mut c_void,
|
if length == 0 {
|
||||||
|
// Rust uses 0x1 as the data pointer for empty buffers,
|
||||||
|
// but NAPI/V8 only allows multiple buffers to have
|
||||||
|
// the same data pointer if it's 0x0.
|
||||||
|
ptr::null_mut()
|
||||||
|
} else {
|
||||||
|
data as *mut c_void
|
||||||
|
},
|
||||||
length,
|
length,
|
||||||
Some(
|
Some(
|
||||||
raw_finalize_with_custom_callback::<Hint, Finalize>
|
raw_finalize_with_custom_callback::<Hint, Finalize>
|
||||||
|
|
|
@ -33,6 +33,16 @@ test('should create borrowed buffer with finalize', (t) => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('should create empty borrowed buffer with finalize', (t) => {
|
||||||
|
t.is(bindings.createEmptyBorrowedBufferWithFinalize().toString(), '')
|
||||||
|
t.is(bindings.createEmptyBorrowedBufferWithFinalize().toString(), '')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should create empty buffer', (t) => {
|
||||||
|
t.is(bindings.createEmptyBuffer().toString(), '')
|
||||||
|
t.is(bindings.createEmptyBuffer().toString(), '')
|
||||||
|
})
|
||||||
|
|
||||||
test('should be able to mutate buffer', (t) => {
|
test('should be able to mutate buffer', (t) => {
|
||||||
const fixture = Buffer.from([0, 1])
|
const fixture = Buffer.from([0, 1])
|
||||||
bindings.mutateBuffer(fixture)
|
bindings.mutateBuffer(fixture)
|
||||||
|
|
|
@ -57,6 +57,35 @@ pub fn create_borrowed_buffer_with_finalize(env: Env) -> ContextlessResult<JsBuf
|
||||||
.map(|b| Some(b.into_raw()))
|
.map(|b| Some(b.into_raw()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[contextless_function]
|
||||||
|
pub fn create_empty_borrowed_buffer_with_finalize(env: Env) -> ContextlessResult<JsBuffer> {
|
||||||
|
let data = vec![];
|
||||||
|
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,
|
||||||
|
|mut hint: ManuallyDrop<Vec<u8>>, _| {
|
||||||
|
ManuallyDrop::drop(&mut hint);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.map(|b| Some(b.into_raw()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[contextless_function]
|
||||||
|
pub fn create_empty_buffer(env: Env) -> ContextlessResult<JsBuffer> {
|
||||||
|
let data = vec![];
|
||||||
|
|
||||||
|
env
|
||||||
|
.create_buffer_with_data(data)
|
||||||
|
.map(|b| Some(b.into_raw()))
|
||||||
|
}
|
||||||
|
|
||||||
#[js_function(1)]
|
#[js_function(1)]
|
||||||
fn mutate_buffer(ctx: CallContext) -> Result<JsUndefined> {
|
fn mutate_buffer(ctx: CallContext) -> Result<JsUndefined> {
|
||||||
let buffer = &mut ctx.get::<JsBuffer>(0)?.into_value()?;
|
let buffer = &mut ctx.get::<JsBuffer>(0)?.into_value()?;
|
||||||
|
@ -76,6 +105,11 @@ pub fn register_js(exports: &mut JsObject) -> Result<()> {
|
||||||
"createBorrowedBufferWithFinalize",
|
"createBorrowedBufferWithFinalize",
|
||||||
create_borrowed_buffer_with_finalize,
|
create_borrowed_buffer_with_finalize,
|
||||||
)?;
|
)?;
|
||||||
|
exports.create_named_method(
|
||||||
|
"createEmptyBorrowedBufferWithFinalize",
|
||||||
|
create_empty_borrowed_buffer_with_finalize,
|
||||||
|
)?;
|
||||||
|
exports.create_named_method("createEmptyBuffer", create_empty_buffer)?;
|
||||||
exports.create_named_method("mutateBuffer", mutate_buffer)?;
|
exports.create_named_method("mutateBuffer", mutate_buffer)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,6 +168,7 @@ Generated by [AVA](https://avajs.dev).
|
||||||
export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void␊
|
export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void␊
|
||||||
export function getBuffer(): Buffer␊
|
export function getBuffer(): Buffer␊
|
||||||
export function appendBuffer(buf: Buffer): Buffer␊
|
export function appendBuffer(buf: Buffer): Buffer␊
|
||||||
|
export function getEmptyBuffer(): Buffer␊
|
||||||
export function convertU32Array(input: Uint32Array): Array<number>␊
|
export function convertU32Array(input: Uint32Array): Array<number>␊
|
||||||
export function createExternalTypedArray(): Uint32Array␊
|
export function createExternalTypedArray(): Uint32Array␊
|
||||||
export function mutateTypedArray(input: Float32Array): void␊
|
export function mutateTypedArray(input: Float32Array): void␊
|
||||||
|
|
Binary file not shown.
|
@ -33,6 +33,7 @@ import {
|
||||||
readPackageJson,
|
readPackageJson,
|
||||||
getPackageJsonName,
|
getPackageJsonName,
|
||||||
getBuffer,
|
getBuffer,
|
||||||
|
getEmptyBuffer,
|
||||||
readFileAsync,
|
readFileAsync,
|
||||||
eitherStringOrNumber,
|
eitherStringOrNumber,
|
||||||
returnEither,
|
returnEither,
|
||||||
|
@ -369,6 +370,11 @@ test('buffer', (t) => {
|
||||||
t.is(buf.toString('utf-8'), 'Hello world')
|
t.is(buf.toString('utf-8'), 'Hello world')
|
||||||
buf = appendBuffer(buf)
|
buf = appendBuffer(buf)
|
||||||
t.is(buf.toString('utf-8'), 'Hello world!')
|
t.is(buf.toString('utf-8'), 'Hello world!')
|
||||||
|
|
||||||
|
const a = getEmptyBuffer()
|
||||||
|
const b = getEmptyBuffer()
|
||||||
|
t.is(a.toString(), '')
|
||||||
|
t.is(b.toString(), '')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('convert typedarray to vec', (t) => {
|
test('convert typedarray to vec', (t) => {
|
||||||
|
|
1
examples/napi/index.d.ts
vendored
1
examples/napi/index.d.ts
vendored
|
@ -158,6 +158,7 @@ export function threadsafeFunctionFatalMode(cb: (...args: any[]) => any): void
|
||||||
export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void
|
export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void
|
||||||
export function getBuffer(): Buffer
|
export function getBuffer(): Buffer
|
||||||
export function appendBuffer(buf: Buffer): Buffer
|
export function appendBuffer(buf: Buffer): Buffer
|
||||||
|
export function getEmptyBuffer(): Buffer
|
||||||
export function convertU32Array(input: Uint32Array): Array<number>
|
export function convertU32Array(input: Uint32Array): Array<number>
|
||||||
export function createExternalTypedArray(): Uint32Array
|
export function createExternalTypedArray(): Uint32Array
|
||||||
export function mutateTypedArray(input: Float32Array): void
|
export function mutateTypedArray(input: Float32Array): void
|
||||||
|
|
|
@ -12,6 +12,11 @@ fn append_buffer(buf: Buffer) -> Buffer {
|
||||||
buf.into()
|
buf.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
fn get_empty_buffer() -> Buffer {
|
||||||
|
vec![].into()
|
||||||
|
}
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
fn convert_u32_array(input: Uint32Array) -> Vec<u32> {
|
fn convert_u32_array(input: Uint32Array) -> Vec<u32> {
|
||||||
input.to_vec()
|
input.to_vec()
|
||||||
|
|
Loading…
Reference in a new issue