Skip to content

Commit ea6b259

Browse files
committed
better CStr16 to String and str
1 parent a1c61c8 commit ea6b259

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

src/data_types/strs.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use core::convert::TryInto;
33
use core::fmt;
44
use core::iter::Iterator;
55
use core::result::Result;
6+
#[cfg(feature = "exts")]
7+
use crate::alloc_api::string::String;
68
use core::slice;
79

810
/// Errors which can occur during checked `[uN]` -> `CStrN` conversions
@@ -162,6 +164,45 @@ impl CStr16 {
162164
pos: 0,
163165
}
164166
}
167+
168+
/// Write a string slice into the provided buffer. If it fails, then most probably, because
169+
/// the buffer is not big enough. In that case, the buffer will contain the correct string
170+
/// until the point, where the size was not enough.
171+
///
172+
/// ## Example
173+
///
174+
/// ```rust
175+
/// use uefi::data_types::ArrayString;
176+
/// use uefi::{CStr16, Char16};
177+
/// let firmware_vendor_c16_str: CStr16 = ...;
178+
/// // crate "arrayvec" uses stack-allocated arrays for Strings => no heap
179+
/// let mut buf = arrayvec::ArrayString::<128>::new();
180+
/// firmware_vendor_c16_str.as_str_in_buf(&mut buf);
181+
/// log::info!("as rust str: {}", buf.as_str());
182+
/// ```
183+
pub fn as_str_in_buf(&self, buf: &mut dyn core::fmt::Write) -> Result<(), ()> {
184+
for c16 in self.iter() {
185+
let res = buf.write_char(char::from(*c16));
186+
if let Err(err) = res {
187+
log::error!("Failed to write CStr16 as &str into buffer. Buffer too small? ({})", err);
188+
return Err(())
189+
}
190+
}
191+
Ok(())
192+
}
193+
194+
/// Transforms the C16Str to a regular Rust String.
195+
/// **WARNING** This will require **heap allocation**, i.e. you need an global allocator.
196+
/// If the UEFI boot services are exited, your OS/Kernel needs to provide another allocation
197+
/// mechanism!
198+
#[cfg(feature = "exts")]
199+
pub fn as_string(&self) -> String {
200+
let mut buf = String::with_capacity(self.0.len() * 2);
201+
for c16 in self.iter() {
202+
buf.push(char::from(*c16));
203+
}
204+
buf
205+
}
165206
}
166207

167208
/// An iterator over `CStr16`.

0 commit comments

Comments
 (0)