rclrust_msg_core/
string.rs1use std::{
2 ffi::{CStr, CString},
3 mem::ManuallyDrop,
4 os::raw::c_char,
5};
6
7use crate::ffi::uint_least16_t;
8use crate::traits::{FFIFromRust, FFIToRust, ZeroInit};
9
10#[repr(C)]
12#[derive(Debug)]
13pub struct FFIString {
14 data: *mut c_char,
15 size: usize,
16 capacity: usize,
17}
18
19impl FFIString {
20 pub const fn len(&self) -> usize {
22 self.size
23 }
24
25 pub const fn is_empty(&self) -> bool {
27 self.len() == 0
28 }
29}
30
31impl ZeroInit for FFIString {
32 fn zero_init() -> Self {
33 Self {
34 data: std::ptr::null_mut(),
35 size: 0,
36 capacity: 0,
37 }
38 }
39}
40
41impl FFIToRust for FFIString {
42 type Target = String;
43
44 fn to_rust(&self) -> Self::Target {
45 if self.is_empty() {
46 "".to_string()
47 } else {
48 unsafe { CStr::from_ptr(self.data) }
49 .to_str()
50 .expect("CStr::to_str failed")
51 .to_string()
52 }
53 }
54}
55
56#[repr(C)]
57#[derive(Debug)]
58pub struct OwnedFFIString {
59 data: *mut c_char,
60 size: usize,
61 capacity: usize,
62}
63
64impl OwnedFFIString {
65 pub const fn len(&self) -> usize {
67 self.size
68 }
69
70 pub const fn is_empty(&self) -> bool {
72 self.len() == 0
73 }
74}
75
76impl ZeroInit for OwnedFFIString {
77 fn zero_init() -> Self {
78 Self {
79 data: std::ptr::null_mut(),
80 size: 0,
81 capacity: 0,
82 }
83 }
84}
85
86impl FFIFromRust for OwnedFFIString {
87 type From = String;
88
89 unsafe fn from_rust(string: &Self::From) -> Self {
90 let cstring = CString::new(string.clone()).expect("CString::new failed");
91 let len = cstring.as_bytes().len();
92 Self {
93 data: cstring.into_raw(),
94 size: len,
95 capacity: len + 1,
96 }
97 }
98}
99
100impl Drop for OwnedFFIString {
101 fn drop(&mut self) {
102 unsafe {
103 CString::from_raw(self.data);
104 }
105 }
106}
107
108#[repr(C)]
111#[derive(Debug)]
112pub struct FFIWString {
113 data: *mut uint_least16_t,
114 size: usize,
115 capacity: usize,
116}
117
118impl FFIWString {
119 pub const fn len(&self) -> usize {
121 self.size
122 }
123
124 pub const fn is_empty(&self) -> bool {
126 self.len() == 0
127 }
128}
129
130impl ZeroInit for FFIWString {
131 fn zero_init() -> Self {
132 Self {
133 data: std::ptr::null_mut(),
134 size: 0,
135 capacity: 0,
136 }
137 }
138}
139
140impl FFIToRust for FFIWString {
141 type Target = Vec<u16>;
142
143 fn to_rust(&self) -> Self::Target {
144 unsafe { std::slice::from_raw_parts(self.data, self.len()) }
145 .iter()
146 .map(|&v| v as u16)
147 .collect::<Vec<_>>()
148 }
149}
150
151#[repr(C)]
152#[derive(Debug)]
153pub struct OwnedFFIWString {
154 data: *mut uint_least16_t,
155 size: usize,
156 capacity: usize,
157}
158
159impl OwnedFFIWString {
160 pub const fn len(&self) -> usize {
162 self.size
163 }
164
165 pub const fn is_empty(&self) -> bool {
167 self.len() == 0
168 }
169}
170
171impl ZeroInit for OwnedFFIWString {
172 fn zero_init() -> Self {
173 Self {
174 data: std::ptr::null_mut(),
175 size: 0,
176 capacity: 0,
177 }
178 }
179}
180
181impl FFIFromRust for OwnedFFIWString {
182 type From = Vec<u16>;
183
184 unsafe fn from_rust(string: &Self::From) -> Self {
185 let mut string = string.clone();
186 string.push(0);
187 string.shrink_to_fit();
188 assert_eq!(string.len(), string.capacity());
189 let mut string = ManuallyDrop::new(string);
190 Self {
191 data: string.as_mut_ptr(),
192 size: string.len() - 1,
193 capacity: string.len(),
194 }
195 }
196}
197
198impl Drop for OwnedFFIWString {
199 fn drop(&mut self) {
200 unsafe { Vec::from_raw_parts(self.data, self.capacity, self.capacity) };
201 }
202}