1use crate::{
2 CID, Error, MemoryMessage, MemoryRange, MemorySize, Message, Result, map_memory, send_message,
3 unmap_memory,
4};
5
6pub struct StringBuffer<'a> {
8 bytes: Option<&'a mut [u8]>,
11
12 length: u32,
14
15 should_free: bool,
19
20 memory_message: Option<&'a mut MemoryMessage>,
24}
25
26impl<'a> StringBuffer<'a> {
27 pub fn new() -> Self { StringBuffer { bytes: None, length: 0, should_free: true, memory_message: None } }
30
31 pub fn with_capacity(capacity: usize) -> Self {
34 let remainder =
35 if ((capacity & 0xFFF) == 0) && (capacity > 0) { 0 } else { 0x1000 - (capacity & 0xFFF) };
36
37 let flags = crate::MemoryFlags::R | crate::MemoryFlags::W;
38
39 let new_mem = map_memory(
41 None,
42 None,
43 capacity + remainder,
45 flags,
46 )
47 .expect("Buffer: error in new()/map_memory");
48
49 StringBuffer {
50 bytes: Some(unsafe {
51 core::slice::from_raw_parts_mut(new_mem.as_mut_ptr(), capacity + remainder)
52 }),
53 length: 0,
54 should_free: true,
55 memory_message: None,
56 }
57 }
58
59 fn resize(&mut self, new_capacity: usize) {
60 if self.memory_message.is_some() {
62 return;
63 }
64
65 let remainder = if ((new_capacity & 0xFFF) == 0) && (new_capacity > 0) {
66 0
67 } else {
68 0x1000 - (new_capacity & 0xFFF)
69 };
70
71 let rounded_new_capacity = new_capacity + remainder;
73 if rounded_new_capacity == self.bytes.as_ref().map(|b| b.len()).unwrap_or(0) {
74 return;
75 }
76
77 let flags = crate::MemoryFlags::R | crate::MemoryFlags::W;
78
79 let new_slice = if rounded_new_capacity > 0 {
81 let new_mem = map_memory(None, None, rounded_new_capacity, flags)
82 .expect("Buffer: error in new()/map_memory");
83 let new_slice =
84 unsafe { core::slice::from_raw_parts_mut(new_mem.as_mut_ptr(), rounded_new_capacity) };
85 for (dest_byte, src_byte) in new_slice.iter_mut().zip(self.as_bytes()[0..self.len()].iter()) {
87 *dest_byte = *src_byte;
88 }
89 Some(new_slice)
90 } else {
91 None
92 };
93
94 if let Some(old_slice) = self.bytes.take() {
95 let old_addr = old_slice.as_ptr();
96 let old_length = old_slice.len();
97 unmap_memory(unsafe { MemoryRange::new(old_addr as usize, old_length).unwrap() }).unwrap();
98 }
99 self.bytes = new_slice;
100
101 if new_capacity < self.len() {
103 self.length = new_capacity as u32;
104 }
105 }
106
107 pub fn as_bytes(&self) -> &[u8] { if let Some(bytes) = &self.bytes { bytes } else { &[] } }
108
109 pub fn as_bytes_mut(&mut self) -> &mut [u8] {
110 if let Some(bytes) = self.bytes.as_mut() { bytes } else { &mut [] }
111 }
112
113 pub fn as_str(&self) -> core::result::Result<&str, core::str::Utf8Error> {
114 if let Some(bytes) = &self.bytes { core::str::from_utf8(&bytes[0..self.len()]) } else { Ok("") }
115 }
116
117 pub fn len(&self) -> usize { self.length as usize }
118
119 pub fn is_empty(&self) -> bool { self.length == 0 }
120
121 pub fn clear(&mut self) {
123 self.length = 0;
124 if let Some(mm) = self.memory_message.as_mut() {
125 mm.valid = None;
126 }
127 }
128
129 pub fn to_str(&self) -> &str {
130 if let Some(bytes) = &self.bytes {
131 unsafe { core::str::from_utf8_unchecked(&bytes[0..self.len()]) }
132 } else {
133 ""
134 }
135 }
136
137 fn create_memory_message(&self, id: u32) -> MemoryMessage {
138 if let Some(bytes) = &self.bytes {
139 let backing_store = unsafe { MemoryRange::new(bytes.as_ptr() as _, bytes.len()).unwrap() };
140 MemoryMessage {
141 id: id as usize,
142 buf: backing_store,
143 offset: None,
144 valid: MemorySize::new(self.len()),
145 }
146 } else {
147 panic!("Tried to create a memory message with no string!");
148 }
149 }
150
151 pub unsafe fn from_memory_message(mem: &'a MemoryMessage) -> Self {
156 StringBuffer {
157 bytes: Some(core::slice::from_raw_parts_mut(mem.buf.as_mut_ptr(), mem.buf.len())),
159 length: mem.valid.map(|v| v.get()).unwrap_or(0) as u32,
160 should_free: false,
162 memory_message: None,
163 }
164 }
165
166 pub unsafe fn from_memory_message_mut(mem: &'a mut MemoryMessage) -> Self {
171 StringBuffer {
172 bytes: Some(core::slice::from_raw_parts_mut(mem.buf.as_mut_ptr(), mem.buf.len())),
174 length: mem.valid.map(|v| v.get()).unwrap_or(0) as u32,
175 should_free: false,
178 memory_message: Some(mem),
179 }
180 }
181
182 pub fn lend_mut(&mut self, connection: CID, id: u32) -> core::result::Result<Result, Error> {
184 let msg = self.create_memory_message(id);
185
186 let result = send_message(connection, Message::MutableBorrow(msg));
188 if let Ok(Result::MemoryReturned(_offset, valid)) = result {
189 self.length = valid.map(|v| v.get()).unwrap_or(0) as u32;
190 }
191
192 result
193 }
194
195 pub fn lend(&self, connection: CID, id: u32) -> core::result::Result<Result, Error> {
196 let msg = self.create_memory_message(id);
197 send_message(connection, Message::Borrow(msg))
198 }
199
200 pub fn send(mut self, connection: CID, id: u32) -> core::result::Result<Result, Error> {
201 let msg = self.create_memory_message(id);
202 let result = send_message(connection, Message::Move(msg))?;
203
204 self.should_free = false;
206 Ok(result)
207 }
208}
209
210impl<'a> core::str::FromStr for StringBuffer<'a> {
211 type Err = &'static str;
212
213 fn from_str(src: &str) -> core::result::Result<StringBuffer<'a>, &'static str> {
214 let mut s = Self::with_capacity(src.len());
215 for (dest_byte, src_byte) in s.bytes.as_mut().unwrap().iter_mut().zip(src.as_bytes()) {
217 *dest_byte = *src_byte;
218 }
219 s.length = s.as_bytes().len().min(src.as_bytes().len()) as u32;
222
223 if s.as_str().is_err() {
225 s.length = 0;
226 }
227
228 Ok(s)
229 }
230}
231
232impl<'a> Default for StringBuffer<'a> {
233 fn default() -> Self { Self::new() }
234}
235
236impl<'a> core::fmt::Display for StringBuffer<'a> {
237 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "{}", self.to_str()) }
238}
239
240impl<'a> core::fmt::Write for StringBuffer<'a> {
241 fn write_str(&mut self, s: &str) -> core::result::Result<(), core::fmt::Error> {
242 self.resize(self.len() + s.len());
244
245 let length = self.len();
247 for (dest, src) in self.as_bytes_mut()[length..].iter_mut().zip(s.as_bytes()) {
248 *dest = *src;
249 }
250 self.length += s.len() as u32;
251 if let Some(mm) = self.memory_message.as_mut() {
252 mm.valid = MemorySize::new(self.length as _).or(None);
253 }
254 Ok(())
255 }
256}
257
258impl<'a> core::fmt::Debug for StringBuffer<'a> {
259 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "{}", self.to_str()) }
260}
261
262impl<'a> core::convert::AsRef<str> for StringBuffer<'a> {
263 fn as_ref(&self) -> &str { self.to_str() }
264}
265
266impl<'a> PartialEq for StringBuffer<'a> {
267 fn eq(&self, other: &Self) -> bool {
268 self.length == other.length && self.as_bytes()[..self.len()] == other.as_bytes()[..other.len()]
269 }
270}
271
272impl<'a> Eq for StringBuffer<'a> {}
273
274impl<'a> Drop for StringBuffer<'a> {
275 fn drop(&mut self) {
276 if self.should_free && !self.as_bytes().is_empty() {
277 let range =
278 unsafe { MemoryRange::new(self.as_bytes().as_ptr() as _, self.as_bytes().len()).unwrap() };
279 unmap_memory(range).expect("Buffer: failed to drop memory");
280 }
281 }
282}