Skip to content

Commit 85a48e5

Browse files
Drop UnalignedCStr16 in favor of UnalignedSlice
This should mostly be transparent to callers. An `UnalignedSlice<u16>` slice provides the same `to_cstr16` and `to_cstring16` methods that `UnalignedCStr16` did.
1 parent d27db94 commit 85a48e5

File tree

4 files changed

+17
-119
lines changed

4 files changed

+17
-119
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
- The `Revision` type now implements `Display` with correct formatting
2525
for all UEFI versions. The custom `Debug` impl has been removed and
2626
replaced with a derived `Debug` impl.
27+
28+
### Removed
29+
30+
- Removed `UnalignedCStr16`; use `UnalignedSlice` instead. An
31+
`UnalignedSlice<u16>` can be converted to a string with `to_cstr16` or
32+
`to_cstring16`.
2733

2834
## uefi-macros - [Unreleased]
2935

src/data_types/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,7 @@ mod enums;
129129

130130
mod strs;
131131
pub use self::strs::{
132-
CStr16, CStr8, EqStrUntilNul, FromSliceWithNulError, FromStrWithBufError, UnalignedCStr16,
133-
UnalignedCStr16Error,
132+
CStr16, CStr8, EqStrUntilNul, FromSliceWithNulError, FromStrWithBufError, UnalignedCStr16Error,
134133
};
135134

136135
#[cfg(feature = "exts")]

src/data_types/strs.rs

Lines changed: 5 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ use super::chars::{Char16, Char8, NUL_16, NUL_8};
22
use super::UnalignedSlice;
33
use core::fmt;
44
use core::iter::Iterator;
5-
use core::marker::PhantomData;
65
use core::mem::MaybeUninit;
76
use core::result::Result;
87
use core::slice;
8+
99
#[cfg(feature = "exts")]
10-
use {super::CString16, crate::alloc_api::vec::Vec};
10+
use super::CString16;
1111

1212
/// Errors which can occur during checked `[uN]` -> `CStrN` conversions
1313
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -22,7 +22,7 @@ pub enum FromSliceWithNulError {
2222
NotNulTerminated,
2323
}
2424

25-
/// Error returned by [`UnalignedCStr16::to_cstr16`].
25+
/// Error returned by [`CStr16::from_unaligned_slice`].
2626
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2727
pub enum UnalignedCStr16Error {
2828
/// An invalid character was encountered.
@@ -404,113 +404,6 @@ impl PartialEq<CString16> for &CStr16 {
404404
}
405405
}
406406

407-
/// An unaligned UCS-2 null-terminated string.
408-
///
409-
/// This wrapper type can be used with UEFI strings that are inside a
410-
/// [`repr(packed)`] struct. Creating a reference to a packed field is
411-
/// not allowed because it might not be properly aligned, so a
412-
/// [`CStr16`] can't be directly constructed. `UnalignedCStr16` instead
413-
/// takes a pointer to the unaligned field, which is allowed. The
414-
/// resulting unaligned string cannot be used directly, but must be
415-
/// converted to an aligned form first with [`to_cstr16`] or
416-
/// [`to_cstring16`].
417-
///
418-
/// [`repr(packed)`]: https://doc.rust-lang.org/nomicon/other-reprs.html#reprpacked
419-
/// [`to_cstr16`]: Self::to_cstr16
420-
/// [`to_cstring16`]: Self::to_cstring16
421-
#[derive(Debug)]
422-
pub struct UnalignedCStr16<'a> {
423-
data: *const u16,
424-
len: usize,
425-
_phantom_lifetime: PhantomData<&'a ()>,
426-
}
427-
428-
// While it's not unsafe to have an empty `UnalignedCStr16`, there's not
429-
// much point either since the string wouldn't be valid without a null
430-
// terminator. So skip adding an `is_empty` method.
431-
#[allow(clippy::len_without_is_empty)]
432-
impl<'a> UnalignedCStr16<'a> {
433-
/// Create an `UnalignedCStr16` from a `*const u16` pointer. The
434-
/// pointer must be valid but can be unaligned. The `len` parameter
435-
/// is the number of `u16` characters in the string (not the number
436-
/// of bytes), including the trailing null.
437-
///
438-
/// The `_lifetime` parameter is used to make it easy to set an
439-
/// appropriate lifetime for `'a`. The caller should pass in a
440-
/// reference to something tied to the lifetime of `data`. (The
441-
/// `data` parameter cannot itself be a reference because the
442-
/// pointer is allowed to be unaligned.)
443-
///
444-
/// # Safety
445-
///
446-
/// The `data` pointer cannot be dangling, and must remain valid for
447-
/// the lifetime of `'a`. There must be at least `len` `u16`
448-
/// elements starting with the the first character pointed to by
449-
/// `data`. These restrictions allow all other methods on
450-
/// `UnalignedCStr16` to be safe.
451-
pub unsafe fn new<T: ?Sized>(_lifetime: &'a T, data: *const u16, len: usize) -> Self {
452-
Self {
453-
data,
454-
len,
455-
_phantom_lifetime: PhantomData,
456-
}
457-
}
458-
459-
/// Number of `u16` elements in the string, including the trailing null.
460-
pub fn len(&self) -> usize {
461-
self.len
462-
}
463-
464-
/// Copy the data to an aligned buffer. Panics if the length of
465-
/// `dst` is not exactly the same as `self.len()`. Otherwise the
466-
/// function always succeeds, and initializes all elements of `dst`.
467-
pub fn copy_to(&self, dst: &mut [MaybeUninit<u16>]) {
468-
if dst.len() != self.len {
469-
panic!("incorrect buffer length");
470-
}
471-
472-
for (i, elem) in dst.iter_mut().enumerate() {
473-
unsafe { elem.write(self.data.add(i).read_unaligned()) };
474-
}
475-
}
476-
477-
/// Convert to a [`CStr16`] using an aligned buffer for storage. The
478-
/// lifetime of the output is tied to `buf`, not `self`.
479-
pub fn to_cstr16<'buf>(
480-
&self,
481-
buf: &'buf mut [MaybeUninit<u16>],
482-
) -> Result<&'buf CStr16, UnalignedCStr16Error> {
483-
// The input `buf` might be longer than needed, so get a
484-
// subslice of the required length.
485-
let buf = buf
486-
.get_mut(..self.len())
487-
.ok_or(UnalignedCStr16Error::BufferTooSmall)?;
488-
489-
self.copy_to(buf);
490-
let buf = unsafe {
491-
// Safety: `copy_buf` fully initializes the slice.
492-
MaybeUninit::slice_assume_init_ref(buf)
493-
};
494-
CStr16::from_u16_with_nul(buf).map_err(|e| match e {
495-
FromSliceWithNulError::InvalidChar(v) => UnalignedCStr16Error::InvalidChar(v),
496-
FromSliceWithNulError::InteriorNul(v) => UnalignedCStr16Error::InteriorNul(v),
497-
FromSliceWithNulError::NotNulTerminated => UnalignedCStr16Error::NotNulTerminated,
498-
})
499-
}
500-
501-
/// Convert to a [`CString16`]. Requires the `exts` feature.
502-
#[cfg(feature = "exts")]
503-
pub fn to_cstring16(&self) -> Result<CString16, FromSliceWithNulError> {
504-
let len = self.len();
505-
let mut v = Vec::with_capacity(len);
506-
unsafe {
507-
self.copy_to(v.spare_capacity_mut());
508-
v.set_len(len);
509-
}
510-
CString16::try_from(v)
511-
}
512-
}
513-
514407
impl<'a> UnalignedSlice<'a, u16> {
515408
/// Create a [`CStr16`] from an [`UnalignedSlice`] using an aligned
516409
/// buffer for storage. The lifetime of the output is tied to `buf`,
@@ -618,8 +511,8 @@ mod tests {
618511
ptr.add(3).write_unaligned(b't'.into());
619512
ptr.add(4).write_unaligned(b'\0'.into());
620513

621-
// Create the `UnalignedCStr16`.
622-
UnalignedCStr16::new(&buf, ptr, 5)
514+
// Create the `UnalignedSlice`.
515+
UnalignedSlice::new(ptr, 5)
623516
};
624517

625518
// Test `to_cstr16()` with too small of a buffer.

src/proto/device_path/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
6969
pub mod text;
7070

71-
use crate::data_types::UnalignedCStr16;
71+
use crate::data_types::UnalignedSlice;
7272
use crate::proto::{Protocol, ProtocolPointer};
7373
use crate::{unsafe_guid, Guid};
7474
use core::ffi::c_void;
@@ -578,18 +578,18 @@ pub struct FilePathMediaDevicePath {
578578
}
579579

580580
impl FilePathMediaDevicePath {
581-
/// Get the path. An [`UnalignedCStr16`] is returned since this is a
581+
/// Get the path. An [`UnalignedSlice`] is returned since this is a
582582
/// packed struct.
583-
pub fn path_name(&self) -> UnalignedCStr16<'_> {
584-
// Safety: creating this `UnalignedCStr16` is safe because the
583+
pub fn path_name(&self) -> UnalignedSlice<u16> {
584+
// Safety: creating this `UnalignedSlice` is safe because the
585585
// `path_name` pointer is valid (although potentially
586586
// unaligned), and the lifetime of the output is tied to `self`,
587587
// so there's no possibility of use-after-free.
588588
unsafe {
589589
// Use `addr_of` to avoid creating an unaligned reference.
590590
let ptr: *const [u16] = ptr::addr_of!(self.path_name);
591591
let (ptr, len): (*const (), usize) = ptr.to_raw_parts();
592-
UnalignedCStr16::new(self, ptr.cast::<u16>(), len)
592+
UnalignedSlice::new(ptr.cast::<u16>(), len)
593593
}
594594
}
595595
}

0 commit comments

Comments
 (0)