1use core::ffi::c_void;
4use core::ptr::NonNull;
5use alloc::vec::Vec;
6
7use super::allocator::{PoolAllocator, PoolTag, PoolType};
8use super::error::{KmError, KmResult};
9
10#[repr(C)]
12#[derive(Debug, Clone, Copy)]
13pub struct UnicodeStringRaw {
14 pub length: u16,
15 pub maximum_length: u16,
16 pub buffer: *mut u16,
17}
18
19impl Default for UnicodeStringRaw {
20 fn default() -> Self {
21 Self {
22 length: 0,
23 maximum_length: 0,
24 buffer: core::ptr::null_mut(),
25 }
26 }
27}
28
29pub struct UnicodeString {
31 inner: UnicodeStringRaw,
32 owned: bool,
33}
34
35impl UnicodeString {
36 pub const fn empty() -> Self {
38 Self {
39 inner: UnicodeStringRaw {
40 length: 0,
41 maximum_length: 0,
42 buffer: core::ptr::null_mut(),
43 },
44 owned: false,
45 }
46 }
47
48 pub const unsafe fn from_static(s: &'static [u16]) -> Self {
53 let len = (s.len() - 1) * 2; Self {
55 inner: UnicodeStringRaw {
56 length: len as u16,
57 maximum_length: (s.len() * 2) as u16,
58 buffer: s.as_ptr() as *mut u16,
59 },
60 owned: false,
61 }
62 }
63
64 pub fn from_str(s: &str) -> KmResult<Self> {
66 let wide: Vec<u16> = s.encode_utf16().chain(core::iter::once(0)).collect();
67 Self::from_wide_owned(wide)
68 }
69
70 pub fn from_wide_owned(mut wide: Vec<u16>) -> KmResult<Self> {
72 let len_bytes = (wide.len() - 1) * 2; let max_bytes = wide.len() * 2;
74
75 if wide.last() != Some(&0) {
77 wide.push(0);
78 }
79
80 let ptr = wide.as_mut_ptr();
81 core::mem::forget(wide); Ok(Self {
84 inner: UnicodeStringRaw {
85 length: len_bytes as u16,
86 maximum_length: max_bytes as u16,
87 buffer: ptr,
88 },
89 owned: true,
90 })
91 }
92
93 pub fn as_raw(&self) -> &UnicodeStringRaw {
95 &self.inner
96 }
97
98 pub fn as_raw_mut(&mut self) -> &mut UnicodeStringRaw {
100 &mut self.inner
101 }
102
103 pub fn as_ptr(&self) -> *const UnicodeStringRaw {
105 &self.inner
106 }
107
108 pub fn as_mut_ptr(&mut self) -> *mut UnicodeStringRaw {
110 &mut self.inner
111 }
112
113 pub fn len(&self) -> usize {
115 self.inner.length as usize
116 }
117
118 pub fn is_empty(&self) -> bool {
120 self.inner.length == 0
121 }
122
123 pub fn as_wide(&self) -> &[u16] {
125 if self.inner.buffer.is_null() || self.inner.length == 0 {
126 return &[];
127 }
128 unsafe {
130 core::slice::from_raw_parts(
131 self.inner.buffer,
132 (self.inner.length / 2) as usize,
133 )
134 }
135 }
136}
137
138impl Drop for UnicodeString {
139 fn drop(&mut self) {
140 if self.owned && !self.inner.buffer.is_null() {
141 let cap = (self.inner.maximum_length / 2) as usize;
143 let len = cap; unsafe {
146 let _ = Vec::from_raw_parts(self.inner.buffer, len, cap);
147 }
148 }
149 }
150}
151
152#[repr(C)]
154#[derive(Debug, Clone, Copy)]
155pub struct AnsiStringRaw {
156 pub length: u16,
157 pub maximum_length: u16,
158 pub buffer: *mut u8,
159}
160
161impl Default for AnsiStringRaw {
162 fn default() -> Self {
163 Self {
164 length: 0,
165 maximum_length: 0,
166 buffer: core::ptr::null_mut(),
167 }
168 }
169}
170
171pub struct AnsiString {
173 inner: AnsiStringRaw,
174 owned: bool,
175}
176
177impl AnsiString {
178 pub const fn empty() -> Self {
180 Self {
181 inner: AnsiStringRaw {
182 length: 0,
183 maximum_length: 0,
184 buffer: core::ptr::null_mut(),
185 },
186 owned: false,
187 }
188 }
189
190 pub const unsafe fn from_static(s: &'static [u8]) -> Self {
195 let len = s.len() - 1; Self {
197 inner: AnsiStringRaw {
198 length: len as u16,
199 maximum_length: s.len() as u16,
200 buffer: s.as_ptr() as *mut u8,
201 },
202 owned: false,
203 }
204 }
205
206 pub fn from_str(s: &str) -> KmResult<Self> {
208 let mut bytes: Vec<u8> = s.as_bytes().to_vec();
209 bytes.push(0); let len = s.len();
212 let max_len = bytes.len();
213 let ptr = bytes.as_mut_ptr();
214 core::mem::forget(bytes);
215
216 Ok(Self {
217 inner: AnsiStringRaw {
218 length: len as u16,
219 maximum_length: max_len as u16,
220 buffer: ptr,
221 },
222 owned: true,
223 })
224 }
225
226 pub fn as_raw(&self) -> &AnsiStringRaw {
228 &self.inner
229 }
230
231 pub fn as_bytes(&self) -> &[u8] {
233 if self.inner.buffer.is_null() || self.inner.length == 0 {
234 return &[];
235 }
236 unsafe {
238 core::slice::from_raw_parts(self.inner.buffer, self.inner.length as usize)
239 }
240 }
241}
242
243impl Drop for AnsiString {
244 fn drop(&mut self) {
245 if self.owned && !self.inner.buffer.is_null() {
246 let cap = self.inner.maximum_length as usize;
247 unsafe {
249 let _ = Vec::from_raw_parts(self.inner.buffer, cap, cap);
250 }
251 }
252 }
253}
254
255#[macro_export]
257macro_rules! unicode_str {
258 ($s:literal) => {{
259 const WIDE: &[u16] = &$crate::km::string::encode_wide_const($s);
260 unsafe { $crate::km::string::UnicodeString::from_static(WIDE) }
262 }};
263}
264
265pub const fn encode_wide_const<const N: usize>(s: &str) -> [u16; N] {
267 let bytes = s.as_bytes();
268 let mut result = [0u16; N];
269 let mut i = 0;
270 while i < bytes.len() && i < N - 1 {
271 result[i] = bytes[i] as u16;
272 i += 1;
273 }
274 result
275}