|
1 | 1 | use super::chars::{Char16, Char8, NUL_16, NUL_8};
|
| 2 | +use super::UnalignedSlice; |
2 | 3 | use core::fmt;
|
3 | 4 | use core::iter::Iterator;
|
4 | 5 | use core::marker::PhantomData;
|
@@ -261,6 +262,31 @@ impl CStr16 {
|
261 | 262 | })
|
262 | 263 | }
|
263 | 264 |
|
| 265 | + /// Create a [`CStr16`] from an [`UnalignedSlice`] using an aligned |
| 266 | + /// buffer for storage. The lifetime of the output is tied to `buf`, |
| 267 | + /// not `src`. |
| 268 | + pub fn from_unaligned_slice<'buf>( |
| 269 | + src: &UnalignedSlice<'_, u16>, |
| 270 | + buf: &'buf mut [MaybeUninit<u16>], |
| 271 | + ) -> Result<&'buf CStr16, UnalignedCStr16Error> { |
| 272 | + // The input `buf` might be longer than needed, so get a |
| 273 | + // subslice of the required length. |
| 274 | + let buf = buf |
| 275 | + .get_mut(..src.len()) |
| 276 | + .ok_or(UnalignedCStr16Error::BufferTooSmall)?; |
| 277 | + |
| 278 | + src.copy_to_maybe_uninit(buf); |
| 279 | + let buf = unsafe { |
| 280 | + // Safety: `copy_buf` fully initializes the slice. |
| 281 | + MaybeUninit::slice_assume_init_ref(buf) |
| 282 | + }; |
| 283 | + CStr16::from_u16_with_nul(buf).map_err(|e| match e { |
| 284 | + FromSliceWithNulError::InvalidChar(v) => UnalignedCStr16Error::InvalidChar(v), |
| 285 | + FromSliceWithNulError::InteriorNul(v) => UnalignedCStr16Error::InteriorNul(v), |
| 286 | + FromSliceWithNulError::NotNulTerminated => UnalignedCStr16Error::NotNulTerminated, |
| 287 | + }) |
| 288 | + } |
| 289 | + |
264 | 290 | /// Returns the inner pointer to this C string
|
265 | 291 | pub fn as_ptr(&self) -> *const Char16 {
|
266 | 292 | self.0.as_ptr()
|
@@ -485,6 +511,18 @@ impl<'a> UnalignedCStr16<'a> {
|
485 | 511 | }
|
486 | 512 | }
|
487 | 513 |
|
| 514 | +impl<'a> UnalignedSlice<'a, u16> { |
| 515 | + /// Create a [`CStr16`] from an [`UnalignedSlice`] using an aligned |
| 516 | + /// buffer for storage. The lifetime of the output is tied to `buf`, |
| 517 | + /// not `self`. |
| 518 | + pub fn to_cstr16<'buf>( |
| 519 | + &self, |
| 520 | + buf: &'buf mut [MaybeUninit<u16>], |
| 521 | + ) -> Result<&'buf CStr16, UnalignedCStr16Error> { |
| 522 | + CStr16::from_unaligned_slice(self, buf) |
| 523 | + } |
| 524 | +} |
| 525 | + |
488 | 526 | /// Trait that helps to compare Rust strings against CStr16 types.
|
489 | 527 | /// A generic implementation of this trait enables us that we only have to
|
490 | 528 | /// implement one direction (`left.eq_str_until_nul(&right)`) and we get
|
|
0 commit comments