1 | use std::mem; |
2 | use std::ops::{Deref, DerefMut}; |
3 | use std::ptr; |
4 | |
5 | use super::{Value, ValueType}; |
6 | use crate::bindgen_runtime::ValidateNapiValue; |
7 | use crate::{ |
8 | bindgen_runtime::TypeName, check_status, sys, Error, JsUnknown, NapiValue, Ref, Result, Status, |
9 | }; |
10 | |
11 | pub struct JsBuffer(pub(crate) Value); |
12 | |
13 | impl TypeName for JsBuffer { |
14 | fn type_name() -> &'static str { |
15 | "Buffer" |
16 | } |
17 | |
18 | fn value_type() -> ValueType { |
19 | ValueType::Object |
20 | } |
21 | } |
22 | |
23 | impl ValidateNapiValue for JsBuffer { |
24 | unsafe fn validate(env: sys::napi_env, napi_val: sys::napi_value) -> Result<sys::napi_value> { |
25 | let mut is_buffer: bool = false; |
26 | check_status!(unsafe { sys::napi_is_buffer(env, napi_val, &mut is_buffer) })?; |
27 | if !is_buffer { |
28 | return Err(Error::new( |
29 | Status::InvalidArg, |
30 | reason:"Value is not a buffer" .to_owned(), |
31 | )); |
32 | } |
33 | Ok(ptr::null_mut()) |
34 | } |
35 | } |
36 | |
37 | pub struct JsBufferValue { |
38 | pub(crate) value: JsBuffer, |
39 | data: mem::ManuallyDrop<Vec<u8>>, |
40 | } |
41 | |
42 | impl JsBuffer { |
43 | pub fn into_value(self) -> Result<JsBufferValue> { |
44 | let mut data: *mut c_void = ptr::null_mut(); |
45 | let mut len: usize = 0; |
46 | check_status!(unsafe { |
47 | sys::napi_get_buffer_info(self.0.env, self.0.value, &mut data, &mut len) |
48 | })?; |
49 | Ok(JsBufferValue { |
50 | data: mem::ManuallyDrop::new(unsafe { Vec::from_raw_parts(ptr:data as *mut _, length:len, capacity:len) }), |
51 | value: self, |
52 | }) |
53 | } |
54 | |
55 | pub fn into_ref(self) -> Result<Ref<JsBufferValue>> { |
56 | Ref::new(self.0, ref_count:1, self.into_value()?) |
57 | } |
58 | } |
59 | |
60 | impl JsBufferValue { |
61 | #[cfg (feature = "serde-json" )] |
62 | pub(crate) fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self> { |
63 | let mut data = ptr::null_mut(); |
64 | let mut len = 0usize; |
65 | check_status!(unsafe { |
66 | sys::napi_get_buffer_info(env, value, &mut data, &mut len as *mut usize as *mut _) |
67 | })?; |
68 | Ok(Self { |
69 | value: JsBuffer(Value { |
70 | env, |
71 | value, |
72 | value_type: ValueType::Object, |
73 | }), |
74 | data: mem::ManuallyDrop::new(unsafe { Vec::from_raw_parts(data as *mut _, len, len) }), |
75 | }) |
76 | } |
77 | |
78 | pub fn new(value: JsBuffer, data: mem::ManuallyDrop<Vec<u8>>) -> Self { |
79 | JsBufferValue { value, data } |
80 | } |
81 | |
82 | pub fn into_raw(self) -> JsBuffer { |
83 | self.value |
84 | } |
85 | |
86 | pub fn into_unknown(self) -> JsUnknown { |
87 | unsafe { JsUnknown::from_raw_unchecked(self.value.0.env, self.value.0.value) } |
88 | } |
89 | } |
90 | |
91 | impl AsRef<[u8]> for JsBufferValue { |
92 | fn as_ref(&self) -> &[u8] { |
93 | self.data.as_slice() |
94 | } |
95 | } |
96 | |
97 | impl AsMut<[u8]> for JsBufferValue { |
98 | fn as_mut(&mut self) -> &mut [u8] { |
99 | self.data.as_mut_slice() |
100 | } |
101 | } |
102 | |
103 | impl Deref for JsBufferValue { |
104 | type Target = [u8]; |
105 | |
106 | fn deref(&self) -> &Self::Target { |
107 | self.data.as_slice() |
108 | } |
109 | } |
110 | |
111 | impl DerefMut for JsBufferValue { |
112 | fn deref_mut(&mut self) -> &mut Self::Target { |
113 | self.data.as_mut_slice() |
114 | } |
115 | } |
116 | |