Skip to content

Commit e4d8598

Browse files
committed
better CStr16 to String and str
1 parent 48e958d commit e4d8598

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
@@ -161,6 +163,45 @@ 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+
///
173+
/// ```rust
174+
/// use uefi::data_types::ArrayString;
175+
/// use uefi::{CStr16, Char16};
176+
/// let firmware_vendor_c16_str: CStr16 = ...;
177+
/// // crate "arrayvec" uses stack-allocated arrays for Strings => no heap
178+
/// let mut buf = arrayvec::ArrayString::<128>::new();
179+
/// firmware_vendor_c16_str.as_str_in_buf(&mut buf);
180+
/// log::info!("as rust str: {}", buf.as_str());
181+
/// ```
182+
pub fn as_str_in_buf(&self, buf: &mut dyn core::fmt::Write) -> Result<(), ()> {
183+
for c16 in self.iter() {
184+
let res = buf.write_char(char::from(*c16));
185+
if let Err(err) = res {
186+
log::error!("Failed to write CStr16 as &str into buffer. Buffer too small? ({})", err);
187+
return Err(())
188+
}
189+
}
190+
Ok(())
191+
}
192+
193+
/// Transforms the C16Str to a regular Rust String.
194+
/// **WARNING** This will require **heap allocation**, i.e. you need an global allocator.
195+
/// If the UEFI boot services are exited, your OS/Kernel needs to provide another allocation
196+
/// mechanism!
197+
#[cfg(feature = "exts")]
198+
pub fn as_string(&self) -> String {
199+
let mut buf = String::with_capacity(self.0.len() * 2);
200+
for c16 in self.iter() {
201+
buf.push(char::from(*c16));
202+
}
203+
buf
204+
}
164205
}
165206

166207
/// An iterator over `CStr16`.

0 commit comments

Comments
 (0)