yuuang_test_napi/js_values/
arraybuffer.rs1use std::ops::{Deref, DerefMut};
2use std::os::raw::c_void;
3use std::ptr;
4use std::slice;
5
6use crate::{check_status, sys, JsUnknown, NapiValue, Ref, Result, Value, ValueType};
7
8pub struct JsArrayBuffer(pub(crate) Value);
9
10pub struct JsArrayBufferValue {
11 pub(crate) value: JsArrayBuffer,
12 len: usize,
13 data: *mut c_void,
14}
15
16pub struct JsTypedArray(pub(crate) Value);
17
18pub struct JsTypedArrayValue {
19 pub arraybuffer: JsArrayBuffer,
20 data: *mut c_void,
21 pub byte_offset: u64,
22 pub length: u64,
23 pub typedarray_type: TypedArrayType,
24}
25
26pub struct JsDataView(pub(crate) Value);
27
28pub struct JsDataViewValue {
29 pub arraybuffer: JsArrayBuffer,
30 _data: *mut c_void,
31 pub byte_offset: u64,
32 pub length: u64,
33}
34
35#[repr(i32)]
36#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
37#[non_exhaustive]
38pub enum TypedArrayType {
39 Int8 = 0,
40 Uint8,
41 Uint8Clamped,
42 Int16,
43 Uint16,
44 Int32,
45 Uint32,
46 Float32,
47 Float64,
48 #[cfg(feature = "napi6")]
49 BigInt64,
50 #[cfg(feature = "napi6")]
51 BigUint64,
52
53 Unknown = 1024,
55}
56
57impl From<sys::napi_typedarray_type> for TypedArrayType {
58 fn from(value: sys::napi_typedarray_type) -> Self {
59 match value {
60 sys::TypedarrayType::napi_int8_array => Self::Int8,
61 sys::TypedarrayType::napi_uint8_array => Self::Uint8,
62 sys::TypedarrayType::napi_uint8_clamped_array => Self::Uint8Clamped,
63 sys::TypedarrayType::napi_int16_array => Self::Int16,
64 sys::TypedarrayType::napi_uint16_array => Self::Uint16,
65 sys::TypedarrayType::napi_int32_array => Self::Int32,
66 sys::TypedarrayType::napi_uint32_array => Self::Uint32,
67 sys::TypedarrayType::napi_float32_array => Self::Float32,
68 sys::TypedarrayType::napi_float64_array => Self::Float64,
69 #[cfg(feature = "napi6")]
70 sys::TypedarrayType::napi_bigint64_array => Self::BigInt64,
71 #[cfg(feature = "napi6")]
72 sys::TypedarrayType::napi_biguint64_array => Self::BigUint64,
73 _ => Self::Unknown,
74 }
75 }
76}
77
78impl From<TypedArrayType> for sys::napi_typedarray_type {
79 fn from(value: TypedArrayType) -> sys::napi_typedarray_type {
80 value as i32
81 }
82}
83
84impl JsArrayBuffer {
85 #[cfg(feature = "napi7")]
86 #[inline]
87 pub fn detach(self) -> Result<()> {
88 check_status!(unsafe { sys::napi_detach_arraybuffer(self.0.env, self.0.value) })
89 }
90
91 #[cfg(feature = "napi7")]
92 #[inline]
93 pub fn is_detached(&self) -> Result<bool> {
94 let mut is_detached = false;
95 check_status!(unsafe {
96 sys::napi_is_detached_arraybuffer(self.0.env, self.0.value, &mut is_detached)
97 })?;
98 Ok(is_detached)
99 }
100
101 #[inline]
102 pub fn into_value(self) -> Result<JsArrayBufferValue> {
103 let mut data = ptr::null_mut();
104 let mut len: usize = 0;
105 check_status!(unsafe {
106 sys::napi_get_arraybuffer_info(self.0.env, self.0.value, &mut data, &mut len as *mut usize)
107 })?;
108 Ok(JsArrayBufferValue {
109 data,
110 value: self,
111 len,
112 })
113 }
114
115 #[inline]
116 pub fn into_typedarray(
117 self,
118 typedarray_type: TypedArrayType,
119 length: usize,
120 byte_offset: usize,
121 ) -> Result<JsTypedArray> {
122 let mut typedarray_value = ptr::null_mut();
123 check_status!(unsafe {
124 sys::napi_create_typedarray(
125 self.0.env,
126 typedarray_type.into(),
127 length,
128 self.0.value,
129 byte_offset,
130 &mut typedarray_value,
131 )
132 })?;
133 Ok(JsTypedArray(Value {
134 env: self.0.env,
135 value: typedarray_value,
136 value_type: ValueType::Object,
137 }))
138 }
139
140 #[inline]
141 pub fn into_dataview(self, length: usize, byte_offset: usize) -> Result<JsDataView> {
142 let mut dataview_value = ptr::null_mut();
143 check_status!(unsafe {
144 sys::napi_create_dataview(
145 self.0.env,
146 length,
147 self.0.value,
148 byte_offset,
149 &mut dataview_value,
150 )
151 })?;
152 Ok(JsDataView(Value {
153 env: self.0.env,
154 value: dataview_value,
155 value_type: ValueType::Object,
156 }))
157 }
158
159 #[inline]
160 pub fn into_ref(self) -> Result<Ref<JsArrayBufferValue>> {
161 Ref::new(self.0, 1, self.into_value()?)
162 }
163}
164
165impl JsArrayBufferValue {
166 #[inline]
167 pub fn new(value: JsArrayBuffer, data: *mut c_void, len: usize) -> Self {
168 JsArrayBufferValue { value, len, data }
169 }
170
171 #[inline]
172 pub fn into_raw(self) -> JsArrayBuffer {
173 self.value
174 }
175
176 #[inline]
177 pub fn into_unknown(self) -> JsUnknown {
178 unsafe { JsUnknown::from_raw_unchecked(self.value.0.env, self.value.0.value) }
179 }
180}
181
182impl AsRef<[u8]> for JsArrayBufferValue {
183 fn as_ref(&self) -> &[u8] {
184 unsafe { slice::from_raw_parts(self.data as *const u8, self.len) }
185 }
186}
187
188impl AsMut<[u8]> for JsArrayBufferValue {
189 fn as_mut(&mut self) -> &mut [u8] {
190 unsafe { slice::from_raw_parts_mut(self.data as *mut u8, self.len) }
191 }
192}
193
194impl Deref for JsArrayBufferValue {
195 type Target = [u8];
196
197 fn deref(&self) -> &[u8] {
198 self.as_ref()
199 }
200}
201
202impl DerefMut for JsArrayBufferValue {
203 fn deref_mut(&mut self) -> &mut Self::Target {
204 self.as_mut()
205 }
206}
207
208impl JsTypedArray {
209 #[inline]
214 pub fn into_value(self) -> Result<JsTypedArrayValue> {
215 let mut typedarray_type = 0;
216 let mut len = 0u64;
217 let mut data = ptr::null_mut();
218 let mut arraybuffer_value = ptr::null_mut();
219 let mut byte_offset = 0u64;
220 check_status!(unsafe {
221 sys::napi_get_typedarray_info(
222 self.0.env,
223 self.0.value,
224 &mut typedarray_type,
225 &mut len as *mut u64 as *mut _,
226 &mut data,
227 &mut arraybuffer_value,
228 &mut byte_offset as *mut u64 as *mut usize,
229 )
230 })?;
231
232 Ok(JsTypedArrayValue {
233 data,
234 length: len,
235 byte_offset,
236 typedarray_type: typedarray_type.into(),
237 arraybuffer: unsafe { JsArrayBuffer::from_raw_unchecked(self.0.env, arraybuffer_value) },
238 })
239 }
240}
241
242macro_rules! impl_as_ref {
243 ($ref_type:ident) => {
244 impl AsRef<[$ref_type]> for JsTypedArrayValue {
245 fn as_ref(&self) -> &[$ref_type] {
246 unsafe { slice::from_raw_parts(self.data as *const $ref_type, self.length as usize) }
247 }
248 }
249
250 impl AsMut<[$ref_type]> for JsTypedArrayValue {
251 fn as_mut(&mut self) -> &mut [$ref_type] {
252 unsafe { slice::from_raw_parts_mut(self.data as *mut $ref_type, self.length as usize) }
253 }
254 }
255 };
256}
257
258impl_as_ref!(u8);
259impl_as_ref!(i8);
260impl_as_ref!(u16);
261impl_as_ref!(i16);
262impl_as_ref!(u32);
263impl_as_ref!(i32);
264impl_as_ref!(f32);
265impl_as_ref!(f64);
266#[cfg(feature = "napi6")]
267impl_as_ref!(i64);
268#[cfg(feature = "napi6")]
269impl_as_ref!(u64);
270
271impl JsDataView {
272 #[inline]
273 pub fn into_value(self) -> Result<JsDataViewValue> {
274 let mut length = 0u64;
275 let mut byte_offset = 0u64;
276 let mut arraybuffer_value = ptr::null_mut();
277 let mut data = ptr::null_mut();
278
279 check_status!(unsafe {
280 sys::napi_get_dataview_info(
281 self.0.env,
282 self.0.value,
283 &mut length as *mut u64 as *mut _,
284 &mut data,
285 &mut arraybuffer_value,
286 &mut byte_offset as *mut u64 as *mut _,
287 )
288 })?;
289 Ok(JsDataViewValue {
290 arraybuffer: unsafe { JsArrayBuffer::from_raw_unchecked(self.0.env, arraybuffer_value) },
291 byte_offset,
292 length,
293 _data: data,
294 })
295 }
296}