2020-12-25 01:21:37 +09:00
|
|
|
use std::ops::{Deref, DerefMut};
|
2020-10-11 23:15:58 +09:00
|
|
|
use std::os::raw::c_void;
|
2020-06-21 20:10:06 +09:00
|
|
|
use std::ptr;
|
2021-01-06 00:27:01 +09:00
|
|
|
use std::slice;
|
2020-06-21 20:10:06 +09:00
|
|
|
|
2021-11-02 21:36:34 +09:00
|
|
|
use crate::bindgen_runtime::TypeName;
|
2021-01-07 12:13:47 +09:00
|
|
|
use crate::{check_status, sys, JsUnknown, NapiValue, Ref, Result, Value, ValueType};
|
2020-09-30 19:22:48 +09:00
|
|
|
|
|
|
|
pub struct JsArrayBuffer(pub(crate) Value);
|
2020-06-21 20:10:06 +09:00
|
|
|
|
2021-11-02 21:36:34 +09:00
|
|
|
impl TypeName for JsArrayBuffer {
|
|
|
|
fn type_name() -> &'static str {
|
|
|
|
"ArrayBuffer"
|
|
|
|
}
|
|
|
|
|
|
|
|
fn value_type() -> ValueType {
|
|
|
|
ValueType::Object
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-30 19:22:48 +09:00
|
|
|
pub struct JsArrayBufferValue {
|
|
|
|
pub(crate) value: JsArrayBuffer,
|
2021-05-25 00:53:08 +09:00
|
|
|
len: usize,
|
|
|
|
data: *mut c_void,
|
2020-06-21 20:10:06 +09:00
|
|
|
}
|
|
|
|
|
2020-10-10 19:54:05 +09:00
|
|
|
pub struct JsTypedArray(pub(crate) Value);
|
|
|
|
|
2021-11-02 21:36:34 +09:00
|
|
|
impl TypeName for JsTypedArray {
|
|
|
|
fn type_name() -> &'static str {
|
|
|
|
"TypedArray"
|
|
|
|
}
|
|
|
|
|
|
|
|
fn value_type() -> ValueType {
|
|
|
|
ValueType::Object
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-11 23:15:58 +09:00
|
|
|
pub struct JsTypedArrayValue {
|
2020-10-10 19:54:05 +09:00
|
|
|
pub arraybuffer: JsArrayBuffer,
|
2021-01-06 00:27:01 +09:00
|
|
|
data: *mut c_void,
|
2020-10-10 19:54:05 +09:00
|
|
|
pub byte_offset: u64,
|
|
|
|
pub length: u64,
|
|
|
|
pub typedarray_type: TypedArrayType,
|
|
|
|
}
|
|
|
|
|
2020-10-11 23:15:58 +09:00
|
|
|
pub struct JsDataView(pub(crate) Value);
|
|
|
|
|
2021-11-02 21:36:34 +09:00
|
|
|
impl TypeName for JsDataView {
|
|
|
|
fn type_name() -> &'static str {
|
|
|
|
"DataView"
|
|
|
|
}
|
|
|
|
|
|
|
|
fn value_type() -> ValueType {
|
|
|
|
ValueType::Object
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-11 23:15:58 +09:00
|
|
|
pub struct JsDataViewValue {
|
|
|
|
pub arraybuffer: JsArrayBuffer,
|
2020-11-25 18:42:14 +09:00
|
|
|
_data: *mut c_void,
|
2020-10-11 23:15:58 +09:00
|
|
|
pub byte_offset: u64,
|
|
|
|
pub length: u64,
|
|
|
|
}
|
|
|
|
|
2020-11-11 13:15:13 +09:00
|
|
|
#[repr(i32)]
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
2021-05-25 00:53:08 +09:00
|
|
|
#[non_exhaustive]
|
2020-10-10 19:54:05 +09:00
|
|
|
pub enum TypedArrayType {
|
2020-11-11 13:15:13 +09:00
|
|
|
Int8 = 0,
|
2020-10-10 19:54:05 +09:00
|
|
|
Uint8,
|
|
|
|
Uint8Clamped,
|
|
|
|
Int16,
|
|
|
|
Uint16,
|
|
|
|
Int32,
|
|
|
|
Uint32,
|
|
|
|
Float32,
|
|
|
|
Float64,
|
2021-05-25 00:53:08 +09:00
|
|
|
#[cfg(feature = "napi6")]
|
2020-10-10 19:54:05 +09:00
|
|
|
BigInt64,
|
2021-05-25 00:53:08 +09:00
|
|
|
#[cfg(feature = "napi6")]
|
2020-10-10 19:54:05 +09:00
|
|
|
BigUint64,
|
|
|
|
|
2020-11-11 13:15:13 +09:00
|
|
|
/// compatible with higher versions
|
|
|
|
Unknown = 1024,
|
|
|
|
}
|
2020-11-03 12:23:41 +09:00
|
|
|
|
2020-11-11 13:15:13 +09:00
|
|
|
impl From<sys::napi_typedarray_type> for TypedArrayType {
|
|
|
|
fn from(value: sys::napi_typedarray_type) -> Self {
|
2020-10-10 19:54:05 +09:00
|
|
|
match value {
|
2021-11-29 13:52:42 +09:00
|
|
|
sys::TypedarrayType::int8_array => Self::Int8,
|
|
|
|
sys::TypedarrayType::uint8_array => Self::Uint8,
|
|
|
|
sys::TypedarrayType::uint8_clamped_array => Self::Uint8Clamped,
|
|
|
|
sys::TypedarrayType::int16_array => Self::Int16,
|
|
|
|
sys::TypedarrayType::uint16_array => Self::Uint16,
|
|
|
|
sys::TypedarrayType::int32_array => Self::Int32,
|
|
|
|
sys::TypedarrayType::uint32_array => Self::Uint32,
|
|
|
|
sys::TypedarrayType::float32_array => Self::Float32,
|
|
|
|
sys::TypedarrayType::float64_array => Self::Float64,
|
2021-05-25 00:53:08 +09:00
|
|
|
#[cfg(feature = "napi6")]
|
2021-11-29 13:52:42 +09:00
|
|
|
sys::TypedarrayType::bigint64_array => Self::BigInt64,
|
2021-05-25 00:53:08 +09:00
|
|
|
#[cfg(feature = "napi6")]
|
2021-11-29 13:52:42 +09:00
|
|
|
sys::TypedarrayType::biguint64_array => Self::BigUint64,
|
2020-11-11 13:15:13 +09:00
|
|
|
_ => Self::Unknown,
|
2020-10-10 19:54:05 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<TypedArrayType> for sys::napi_typedarray_type {
|
2020-11-11 13:15:13 +09:00
|
|
|
fn from(value: TypedArrayType) -> sys::napi_typedarray_type {
|
2021-05-25 00:53:08 +09:00
|
|
|
value as i32
|
2020-10-10 19:54:05 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-18 03:00:48 +09:00
|
|
|
impl JsArrayBuffer {
|
2020-11-10 12:09:25 +09:00
|
|
|
#[cfg(feature = "napi7")]
|
2020-10-11 23:26:09 +09:00
|
|
|
pub fn detach(self) -> Result<()> {
|
2020-11-25 18:42:14 +09:00
|
|
|
check_status!(unsafe { sys::napi_detach_arraybuffer(self.0.env, self.0.value) })
|
2020-10-11 23:26:09 +09:00
|
|
|
}
|
|
|
|
|
2020-11-10 12:09:25 +09:00
|
|
|
#[cfg(feature = "napi7")]
|
2020-10-11 23:26:09 +09:00
|
|
|
pub fn is_detached(&self) -> Result<bool> {
|
|
|
|
let mut is_detached = false;
|
2020-11-25 18:42:14 +09:00
|
|
|
check_status!(unsafe {
|
2020-10-11 23:26:09 +09:00
|
|
|
sys::napi_is_detached_arraybuffer(self.0.env, self.0.value, &mut is_detached)
|
|
|
|
})?;
|
|
|
|
Ok(is_detached)
|
|
|
|
}
|
|
|
|
|
2020-09-30 19:22:48 +09:00
|
|
|
pub fn into_value(self) -> Result<JsArrayBufferValue> {
|
|
|
|
let mut data = ptr::null_mut();
|
2020-11-04 23:52:13 +09:00
|
|
|
let mut len: usize = 0;
|
2020-11-25 18:42:14 +09:00
|
|
|
check_status!(unsafe {
|
2021-05-25 00:53:08 +09:00
|
|
|
sys::napi_get_arraybuffer_info(self.0.env, self.0.value, &mut data, &mut len as *mut usize)
|
2020-09-03 01:35:47 +09:00
|
|
|
})?;
|
2020-09-30 19:22:48 +09:00
|
|
|
Ok(JsArrayBufferValue {
|
2021-05-25 00:53:08 +09:00
|
|
|
data,
|
2020-09-30 19:22:48 +09:00
|
|
|
value: self,
|
2021-05-25 00:53:08 +09:00
|
|
|
len,
|
2020-09-30 19:22:48 +09:00
|
|
|
})
|
2020-09-03 01:35:47 +09:00
|
|
|
}
|
|
|
|
|
2020-10-11 23:15:58 +09:00
|
|
|
pub fn into_typedarray(
|
|
|
|
self,
|
2020-10-10 19:54:05 +09:00
|
|
|
typedarray_type: TypedArrayType,
|
2020-12-02 19:39:20 +09:00
|
|
|
length: usize,
|
|
|
|
byte_offset: usize,
|
2020-10-10 19:54:05 +09:00
|
|
|
) -> Result<JsTypedArray> {
|
|
|
|
let mut typedarray_value = ptr::null_mut();
|
2020-11-25 18:42:14 +09:00
|
|
|
check_status!(unsafe {
|
2020-10-10 19:54:05 +09:00
|
|
|
sys::napi_create_typedarray(
|
|
|
|
self.0.env,
|
|
|
|
typedarray_type.into(),
|
2020-12-02 19:39:20 +09:00
|
|
|
length,
|
2020-10-10 19:54:05 +09:00
|
|
|
self.0.value,
|
2020-12-02 19:39:20 +09:00
|
|
|
byte_offset,
|
2020-10-10 19:54:05 +09:00
|
|
|
&mut typedarray_value,
|
|
|
|
)
|
|
|
|
})?;
|
|
|
|
Ok(JsTypedArray(Value {
|
|
|
|
env: self.0.env,
|
|
|
|
value: typedarray_value,
|
|
|
|
value_type: ValueType::Object,
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
2020-12-02 19:39:20 +09:00
|
|
|
pub fn into_dataview(self, length: usize, byte_offset: usize) -> Result<JsDataView> {
|
2020-10-11 23:15:58 +09:00
|
|
|
let mut dataview_value = ptr::null_mut();
|
2020-11-25 18:42:14 +09:00
|
|
|
check_status!(unsafe {
|
2020-10-11 23:15:58 +09:00
|
|
|
sys::napi_create_dataview(
|
|
|
|
self.0.env,
|
2020-12-02 19:39:20 +09:00
|
|
|
length,
|
2020-10-11 23:15:58 +09:00
|
|
|
self.0.value,
|
2020-12-02 19:39:20 +09:00
|
|
|
byte_offset,
|
2020-10-11 23:15:58 +09:00
|
|
|
&mut dataview_value,
|
|
|
|
)
|
|
|
|
})?;
|
|
|
|
Ok(JsDataView(Value {
|
|
|
|
env: self.0.env,
|
|
|
|
value: dataview_value,
|
|
|
|
value_type: ValueType::Object,
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
2020-09-30 19:22:48 +09:00
|
|
|
pub fn into_ref(self) -> Result<Ref<JsArrayBufferValue>> {
|
|
|
|
Ref::new(self.0, 1, self.into_value()?)
|
2020-09-03 01:35:47 +09:00
|
|
|
}
|
2020-09-30 19:22:48 +09:00
|
|
|
}
|
2020-09-03 01:35:47 +09:00
|
|
|
|
2020-09-30 19:22:48 +09:00
|
|
|
impl JsArrayBufferValue {
|
2021-05-25 00:53:08 +09:00
|
|
|
pub fn new(value: JsArrayBuffer, data: *mut c_void, len: usize) -> Self {
|
|
|
|
JsArrayBufferValue { value, len, data }
|
2020-09-03 01:35:47 +09:00
|
|
|
}
|
|
|
|
|
2020-09-30 19:22:48 +09:00
|
|
|
pub fn into_raw(self) -> JsArrayBuffer {
|
|
|
|
self.value
|
2020-09-03 01:35:47 +09:00
|
|
|
}
|
|
|
|
|
2020-10-03 00:23:21 +09:00
|
|
|
pub fn into_unknown(self) -> JsUnknown {
|
2020-11-20 01:07:13 +09:00
|
|
|
unsafe { JsUnknown::from_raw_unchecked(self.value.0.env, self.value.0.value) }
|
2020-09-03 01:35:47 +09:00
|
|
|
}
|
2020-07-18 03:00:48 +09:00
|
|
|
}
|
|
|
|
|
2020-09-30 19:22:48 +09:00
|
|
|
impl AsRef<[u8]> for JsArrayBufferValue {
|
|
|
|
fn as_ref(&self) -> &[u8] {
|
2021-05-25 00:53:08 +09:00
|
|
|
unsafe { slice::from_raw_parts(self.data as *const u8, self.len) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsMut<[u8]> for JsArrayBufferValue {
|
|
|
|
fn as_mut(&mut self) -> &mut [u8] {
|
|
|
|
unsafe { slice::from_raw_parts_mut(self.data as *mut u8, self.len) }
|
2020-09-07 18:26:28 +09:00
|
|
|
}
|
2020-06-21 20:10:06 +09:00
|
|
|
}
|
2020-08-26 01:07:27 +09:00
|
|
|
|
2020-09-30 19:22:48 +09:00
|
|
|
impl Deref for JsArrayBufferValue {
|
|
|
|
type Target = [u8];
|
|
|
|
|
|
|
|
fn deref(&self) -> &[u8] {
|
2021-05-25 00:53:08 +09:00
|
|
|
self.as_ref()
|
2020-08-26 01:07:27 +09:00
|
|
|
}
|
|
|
|
}
|
2020-10-10 19:54:05 +09:00
|
|
|
|
2020-12-25 01:21:37 +09:00
|
|
|
impl DerefMut for JsArrayBufferValue {
|
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
2021-05-25 00:53:08 +09:00
|
|
|
self.as_mut()
|
2020-12-25 01:21:37 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-10 19:54:05 +09:00
|
|
|
impl JsTypedArray {
|
|
|
|
/// get TypeArray info
|
2021-11-23 15:47:37 +09:00
|
|
|
/// <https://nodejs.org/api/n-api.html#n_api_napi_get_typedarray_info>
|
2020-10-10 19:54:05 +09:00
|
|
|
///
|
|
|
|
/// ***Warning***: Use caution while using this API since the underlying data buffer is managed by the VM.
|
2020-10-11 23:15:58 +09:00
|
|
|
pub fn into_value(self) -> Result<JsTypedArrayValue> {
|
2020-11-11 13:15:13 +09:00
|
|
|
let mut typedarray_type = 0;
|
2020-10-10 19:54:05 +09:00
|
|
|
let mut len = 0u64;
|
|
|
|
let mut data = ptr::null_mut();
|
2020-10-11 23:15:58 +09:00
|
|
|
let mut arraybuffer_value = ptr::null_mut();
|
2020-10-10 19:54:05 +09:00
|
|
|
let mut byte_offset = 0u64;
|
2020-11-25 18:42:14 +09:00
|
|
|
check_status!(unsafe {
|
2020-10-10 19:54:05 +09:00
|
|
|
sys::napi_get_typedarray_info(
|
|
|
|
self.0.env,
|
|
|
|
self.0.value,
|
|
|
|
&mut typedarray_type,
|
2020-11-04 23:52:13 +09:00
|
|
|
&mut len as *mut u64 as *mut _,
|
2020-10-10 19:54:05 +09:00
|
|
|
&mut data,
|
2020-10-11 23:15:58 +09:00
|
|
|
&mut arraybuffer_value,
|
2021-05-25 00:53:08 +09:00
|
|
|
&mut byte_offset as *mut u64 as *mut usize,
|
2020-10-10 19:54:05 +09:00
|
|
|
)
|
|
|
|
})?;
|
|
|
|
|
|
|
|
Ok(JsTypedArrayValue {
|
2021-01-06 00:27:01 +09:00
|
|
|
data,
|
2020-10-10 19:54:05 +09:00
|
|
|
length: len,
|
|
|
|
byte_offset,
|
2020-11-11 13:15:13 +09:00
|
|
|
typedarray_type: typedarray_type.into(),
|
2020-11-20 01:07:13 +09:00
|
|
|
arraybuffer: unsafe { JsArrayBuffer::from_raw_unchecked(self.0.env, arraybuffer_value) },
|
2020-10-11 23:15:58 +09:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-25 00:53:08 +09:00
|
|
|
macro_rules! impl_as_ref {
|
|
|
|
($ref_type:ident) => {
|
|
|
|
impl AsRef<[$ref_type]> for JsTypedArrayValue {
|
|
|
|
fn as_ref(&self) -> &[$ref_type] {
|
|
|
|
unsafe { slice::from_raw_parts(self.data as *const $ref_type, self.length as usize) }
|
|
|
|
}
|
|
|
|
}
|
2021-01-06 00:27:01 +09:00
|
|
|
|
2021-05-25 00:53:08 +09:00
|
|
|
impl AsMut<[$ref_type]> for JsTypedArrayValue {
|
|
|
|
fn as_mut(&mut self) -> &mut [$ref_type] {
|
|
|
|
unsafe { slice::from_raw_parts_mut(self.data as *mut $ref_type, self.length as usize) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2021-01-06 00:27:01 +09:00
|
|
|
}
|
|
|
|
|
2021-05-25 00:53:08 +09:00
|
|
|
impl_as_ref!(u8);
|
|
|
|
impl_as_ref!(i8);
|
|
|
|
impl_as_ref!(u16);
|
|
|
|
impl_as_ref!(i16);
|
|
|
|
impl_as_ref!(u32);
|
|
|
|
impl_as_ref!(i32);
|
|
|
|
impl_as_ref!(f32);
|
|
|
|
impl_as_ref!(f64);
|
|
|
|
#[cfg(feature = "napi6")]
|
|
|
|
impl_as_ref!(i64);
|
|
|
|
#[cfg(feature = "napi6")]
|
|
|
|
impl_as_ref!(u64);
|
2021-01-06 00:27:01 +09:00
|
|
|
|
2020-10-11 23:15:58 +09:00
|
|
|
impl JsDataView {
|
|
|
|
pub fn into_value(self) -> Result<JsDataViewValue> {
|
|
|
|
let mut length = 0u64;
|
|
|
|
let mut byte_offset = 0u64;
|
|
|
|
let mut arraybuffer_value = ptr::null_mut();
|
|
|
|
let mut data = ptr::null_mut();
|
|
|
|
|
2020-11-25 18:42:14 +09:00
|
|
|
check_status!(unsafe {
|
2020-10-11 23:15:58 +09:00
|
|
|
sys::napi_get_dataview_info(
|
|
|
|
self.0.env,
|
|
|
|
self.0.value,
|
2020-11-04 23:52:13 +09:00
|
|
|
&mut length as *mut u64 as *mut _,
|
2020-10-11 23:15:58 +09:00
|
|
|
&mut data,
|
|
|
|
&mut arraybuffer_value,
|
2020-11-04 23:52:13 +09:00
|
|
|
&mut byte_offset as *mut u64 as *mut _,
|
2020-10-11 23:15:58 +09:00
|
|
|
)
|
|
|
|
})?;
|
|
|
|
Ok(JsDataViewValue {
|
2020-11-20 01:07:13 +09:00
|
|
|
arraybuffer: unsafe { JsArrayBuffer::from_raw_unchecked(self.0.env, arraybuffer_value) },
|
2020-10-11 23:15:58 +09:00
|
|
|
byte_offset,
|
|
|
|
length,
|
2020-11-25 18:42:14 +09:00
|
|
|
_data: data,
|
2020-10-10 19:54:05 +09:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|