1 | use std::mem; |
2 | use std::ptr; |
3 | |
4 | use crate::bindgen_runtime::TypeName; |
5 | use crate::bindgen_runtime::ValidateNapiValue; |
6 | use crate::ValueType; |
7 | use crate::{check_status, sys, Result, Value}; |
8 | |
9 | pub use latin1::JsStringLatin1; |
10 | pub use utf16::JsStringUtf16; |
11 | pub use utf8::JsStringUtf8; |
12 | |
13 | mod latin1; |
14 | mod utf16; |
15 | mod utf8; |
16 | |
17 | #[derive (Clone, Copy)] |
18 | pub struct JsString(pub(crate) Value); |
19 | |
20 | impl TypeName for JsString { |
21 | fn type_name() -> &'static str { |
22 | "String" |
23 | } |
24 | |
25 | fn value_type() -> crate::ValueType { |
26 | ValueType::String |
27 | } |
28 | } |
29 | |
30 | impl ValidateNapiValue for JsString {} |
31 | |
32 | impl JsString { |
33 | pub fn utf8_len(&self) -> Result<usize> { |
34 | let mut length = 0; |
35 | check_status!(unsafe { |
36 | sys::napi_get_value_string_utf8(self.0.env, self.0.value, ptr::null_mut(), 0, &mut length) |
37 | })?; |
38 | Ok(length) |
39 | } |
40 | |
41 | pub fn utf16_len(&self) -> Result<usize> { |
42 | let mut length = 0; |
43 | check_status!(unsafe { |
44 | sys::napi_get_value_string_utf16(self.0.env, self.0.value, ptr::null_mut(), 0, &mut length) |
45 | })?; |
46 | Ok(length) |
47 | } |
48 | |
49 | pub fn latin1_len(&self) -> Result<usize> { |
50 | let mut length = 0; |
51 | check_status!(unsafe { |
52 | sys::napi_get_value_string_latin1(self.0.env, self.0.value, ptr::null_mut(), 0, &mut length) |
53 | })?; |
54 | Ok(length) |
55 | } |
56 | |
57 | pub fn into_utf8(self) -> Result<JsStringUtf8> { |
58 | let mut written_char_count = 0; |
59 | let len = self.utf8_len()? + 1; |
60 | let mut result = Vec::with_capacity(len); |
61 | let buf_ptr = result.as_mut_ptr(); |
62 | check_status!(unsafe { |
63 | sys::napi_get_value_string_utf8( |
64 | self.0.env, |
65 | self.0.value, |
66 | buf_ptr, |
67 | len, |
68 | &mut written_char_count, |
69 | ) |
70 | })?; |
71 | |
72 | Ok(JsStringUtf8 { |
73 | inner: self, |
74 | buf: result, |
75 | }) |
76 | } |
77 | |
78 | pub fn into_utf16(self) -> Result<JsStringUtf16> { |
79 | let mut written_char_count = 0usize; |
80 | let len = self.utf16_len()? + 1; |
81 | let mut result = vec![0; len]; |
82 | let buf_ptr = result.as_mut_ptr(); |
83 | check_status!(unsafe { |
84 | sys::napi_get_value_string_utf16( |
85 | self.0.env, |
86 | self.0.value, |
87 | buf_ptr, |
88 | len, |
89 | &mut written_char_count, |
90 | ) |
91 | })?; |
92 | |
93 | Ok(JsStringUtf16 { |
94 | inner: self, |
95 | buf: result, |
96 | }) |
97 | } |
98 | |
99 | pub fn into_latin1(self) -> Result<JsStringLatin1> { |
100 | let mut written_char_count = 0usize; |
101 | let len = self.latin1_len()? + 1; |
102 | let mut result = Vec::with_capacity(len); |
103 | let buf_ptr = result.as_mut_ptr(); |
104 | check_status!(unsafe { |
105 | sys::napi_get_value_string_latin1( |
106 | self.0.env, |
107 | self.0.value, |
108 | buf_ptr, |
109 | len, |
110 | &mut written_char_count, |
111 | ) |
112 | })?; |
113 | |
114 | mem::forget(result); |
115 | |
116 | Ok(JsStringLatin1 { |
117 | inner: self, |
118 | buf: mem::ManuallyDrop::new(unsafe { |
119 | Vec::from_raw_parts(buf_ptr as *mut _, written_char_count, written_char_count) |
120 | }), |
121 | }) |
122 | } |
123 | } |
124 | |