Skip to content

Commit 4c40dd0

Browse files
committed
better CStr16 to String and str
1 parent 5bcf9a2 commit 4c40dd0

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

src/data_types/strs.rs

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

166206
/// An iterator over `CStr16`.

0 commit comments

Comments
 (0)