Skip to content

Commit d45a98c

Browse files
committed
device_path: make device paths suck less (part 2)
1 parent 66babb2 commit d45a98c

File tree

3 files changed

+69
-2
lines changed

3 files changed

+69
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Changelog
22

33
## uefi - [Unreleased]
4+
- added `DevicePath::to_boxed`, `DevicePath::to_owned`, and `DevicePath::raw`
5+
- added `DevicePathInstance::to_boxed`, `DevicePathInstance::to_owned`, and `DevicePathInstance::raw`
46

57
## uefi-macros - [Unreleased]
68

uefi/src/fs/file_system/error.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use crate::fs::{PathBuf, PathError};
22
use alloc::string::FromUtf8Error;
3-
use core::fmt::Debug;
4-
use core::fmt::{self, Display, Formatter};
3+
use core::fmt::{self, Debug, Display, Formatter};
54

65
/// All errors that can happen when working with the [`FileSystem`].
76
///

uefi/src/proto/device_path/mod.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ mod device_path_gen;
8080
pub use device_path_gen::{
8181
acpi, bios_boot_spec, end, hardware, media, messaging, DevicePathNodeEnum,
8282
};
83+
#[cfg(feature = "alloc")]
84+
use {alloc::borrow::ToOwned, alloc::boxed::Box};
8385

8486
use crate::proto::{unsafe_protocol, ProtocolPointer};
8587
use core::ffi::c_void;
@@ -226,6 +228,21 @@ impl DevicePathInstance {
226228
stop_condition: StopCondition::AnyEndNode,
227229
}
228230
}
231+
232+
/// Returns a copy to the underlying slice of bytes.
233+
#[must_use]
234+
pub const fn raw(&self) -> &[u8] {
235+
&self.data
236+
}
237+
238+
/// Returns a boxed copy of that value.
239+
#[cfg(feature = "alloc")]
240+
#[must_use]
241+
pub fn to_boxed(&self) -> Box<Self> {
242+
let data = self.data.to_owned();
243+
let data = data.into_boxed_slice();
244+
unsafe { mem::transmute(data) }
245+
}
229246
}
230247

231248
impl Debug for DevicePathInstance {
@@ -242,6 +259,15 @@ impl PartialEq for DevicePathInstance {
242259
}
243260
}
244261

262+
#[cfg(feature = "alloc")]
263+
impl ToOwned for DevicePathInstance {
264+
type Owned = Box<DevicePathInstance>;
265+
266+
fn to_owned(&self) -> Self::Owned {
267+
self.to_boxed()
268+
}
269+
}
270+
245271
/// Device path protocol.
246272
///
247273
/// A device path contains one or more device path instances made of up
@@ -326,6 +352,21 @@ impl DevicePath {
326352
stop_condition: StopCondition::EndEntireNode,
327353
}
328354
}
355+
356+
/// Returns a copy to the underlying slice of bytes.
357+
#[must_use]
358+
pub const fn raw(&self) -> &[u8] {
359+
&self.data
360+
}
361+
362+
/// Returns a boxed copy of that value.
363+
#[cfg(feature = "alloc")]
364+
#[must_use]
365+
pub fn to_boxed(&self) -> Box<Self> {
366+
let data = self.data.to_owned();
367+
let data = data.into_boxed_slice();
368+
unsafe { mem::transmute(data) }
369+
}
329370
}
330371

331372
impl Debug for DevicePath {
@@ -342,6 +383,15 @@ impl PartialEq for DevicePath {
342383
}
343384
}
344385

386+
#[cfg(feature = "alloc")]
387+
impl ToOwned for DevicePath {
388+
type Owned = Box<DevicePath>;
389+
390+
fn to_owned(&self) -> Self::Owned {
391+
self.to_boxed()
392+
}
393+
}
394+
345395
/// Iterator over the [`DevicePathInstance`]s in a [`DevicePath`].
346396
///
347397
/// This struct is returned by [`DevicePath::instance_iter`].
@@ -644,6 +694,7 @@ impl Deref for LoadedImageDevicePath {
644694
mod tests {
645695
use super::*;
646696
use alloc::vec::Vec;
697+
use core::mem::{size_of, size_of_val};
647698

648699
/// Create a node to `path` from raw data.
649700
fn add_node(path: &mut Vec<u8>, device_type: u8, sub_type: u8, node_data: &[u8]) {
@@ -748,4 +799,19 @@ mod tests {
748799
// Only two instances.
749800
assert!(iter.next().is_none());
750801
}
802+
803+
#[test]
804+
fn test_to_owned() {
805+
// Relevant assertion to verify the transmute is fine.
806+
assert_eq!(size_of::<&DevicePath>(), size_of::<&[u8]>());
807+
808+
let raw_data = create_raw_device_path();
809+
let dp = unsafe { DevicePath::from_ffi_ptr(raw_data.as_ptr().cast()) };
810+
// Relevant assertion to verify the transmute is fine.
811+
assert_eq!(size_of_val(&dp), size_of_val(&db.data));
812+
813+
let owned_dp = dp.to_owned();
814+
let owned_dp_ref = &*owned_dp;
815+
assert_eq!(owned_dp_ref, dp)
816+
}
751817
}

0 commit comments

Comments
 (0)