Description
openedon Dec 14, 2018
When interfacing Rust with UEFI, one of the API mismatches that we need to take care of is that Rust uses UTF-8 Pascal-style strings while UEFI uses UCS-2 null-terminated strings.
Currently, we have...
- A little bit of code duplication on UTF-8 to UCS-2 conversions.
- The std-inspired
CStr16
type for handling borrowed UEFI strings more conveniently and safely. - Some API entry points that expect
&CStr16
. - Others that expect
&str
and silently convert to UCS-2.- In one occurence (
File::open
), this restricts possible inputs due to finite buffer size. - In all cases, this makes the API more confusing by mixing char conversions with other concerns.
- In a few cases like logging, we actually don't have any other choice.
- In one occurence (
I expect interoperability with UCS-2 to be a common problem in realistic UEFI application, so we may want to improve upon this situation by 1/standardizing conversions between UTF-8 and UCS-2 and 2/eliminating "hidden" conversions between the two whenever possible.
Coming from this perspective, here are some ideas at the core uefi-rs layer...
- One utility fn that takes an
&str
and an&mut [u16]
as an input, and returns a&CStr16
, a char conversion error, or a "buffer full" error as an output. - One reciprocal utility fn that goes from
&CStr16
+&mut [u8]
to&str
or similar errors as above.
...and more ideas for the convenience uefi-exts
layer, where allocations are allowed:
- A
TryFrom<&CStr16>
implementation forString
. - A
CString16
type with aTryFrom<&str>
implementation.
Once we have that, automagic conversion from &str
to UCS-2 should be eliminated whenever possible, in favor of taking a &CStr16
.
If the user has enabled uefi-services conveniences, then converting from &str
to &CStr16
is just a .try_from()
away. And if the user wants to stick with the core crate, calling the underlying conversion utilities is more involved, but not terribly difficult.