Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 80b5e7a

Browse files
phip1611nicholasbishop
authored andcommitted
device_path: enhance device path structs with convenient methods
1 parent 2720436 commit 80b5e7a

File tree

3 files changed

+89
-4
lines changed

3 files changed

+89
-4
lines changed

‎CHANGELOG.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
## uefi - [Unreleased]
44

5+
### Added
6+
- `DevicePath::to_boxed`, `DevicePath::to_owned`, and `DevicePath::as_bytes`
7+
- `DevicePathInstance::to_boxed`, `DevicePathInstance::to_owned`, and `DevicePathInstance::as_bytes`
8+
- `DevicePathNode::data`
9+
10+
### Changed
11+
12+
### Removed
13+
514
## uefi-macros - [Unreleased]
615

716
## uefi-services - [Unreleased]

‎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: 79 additions & 2 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;
@@ -176,6 +178,12 @@ impl DevicePathNode {
176178
self.full_type() == (DeviceType::END, DeviceSubType::END_ENTIRE)
177179
}
178180

181+
/// Returns the payload data of this node.
182+
#[must_use]
183+
pub fn data(&self) -> &[u8] {
184+
&self.data
185+
}
186+
179187
/// Convert from a generic [`DevicePathNode`] reference to an enum
180188
/// of more specific node types.
181189
pub fn as_enum(&self) -> Result<DevicePathNodeEnum, NodeConversionError> {
@@ -226,6 +234,21 @@ impl DevicePathInstance {
226234
stop_condition: StopCondition::AnyEndNode,
227235
}
228236
}
237+
238+
/// Returns a slice of the underlying bytes.
239+
#[must_use]
240+
pub const fn as_bytes(&self) -> &[u8] {
241+
&self.data
242+
}
243+
244+
/// Returns a boxed copy of that value.
245+
#[cfg(feature = "alloc")]
246+
#[must_use]
247+
pub fn to_boxed(&self) -> Box<Self> {
248+
let data = self.data.to_owned();
249+
let data = data.into_boxed_slice();
250+
unsafe { mem::transmute(data) }
251+
}
229252
}
230253

231254
impl Debug for DevicePathInstance {
@@ -242,10 +265,23 @@ impl PartialEq for DevicePathInstance {
242265
}
243266
}
244267

268+
#[cfg(feature = "alloc")]
269+
impl ToOwned for DevicePathInstance {
270+
type Owned = Box<DevicePathInstance>;
271+
272+
fn to_owned(&self) -> Self::Owned {
273+
self.to_boxed()
274+
}
275+
}
276+
245277
/// Device path protocol.
246278
///
247-
/// A device path contains one or more device path instances made of up
248-
/// variable-length nodes. It ends with an [`END_ENTIRE`] node.
279+
/// Can be used on any device handle to obtain generic path/location information
280+
/// concerning the physical device or logical device. If the handle does not
281+
/// logically map to a physical device, the handle may not necessarily support
282+
/// the device path protocol. The device path describes the location of the
283+
/// device the handle is for. The size of the Device Path can be determined from
284+
/// the structures that make up the Device Path.
249285
///
250286
/// See the [module-level documentation] for more details.
251287
///
@@ -326,6 +362,21 @@ impl DevicePath {
326362
stop_condition: StopCondition::EndEntireNode,
327363
}
328364
}
365+
366+
/// Returns a slice of the underlying bytes.
367+
#[must_use]
368+
pub const fn as_bytes(&self) -> &[u8] {
369+
&self.data
370+
}
371+
372+
/// Returns a boxed copy of that value.
373+
#[cfg(feature = "alloc")]
374+
#[must_use]
375+
pub fn to_boxed(&self) -> Box<Self> {
376+
let data = self.data.to_owned();
377+
let data = data.into_boxed_slice();
378+
unsafe { mem::transmute(data) }
379+
}
329380
}
330381

331382
impl Debug for DevicePath {
@@ -342,6 +393,15 @@ impl PartialEq for DevicePath {
342393
}
343394
}
344395

396+
#[cfg(feature = "alloc")]
397+
impl ToOwned for DevicePath {
398+
type Owned = Box<DevicePath>;
399+
400+
fn to_owned(&self) -> Self::Owned {
401+
self.to_boxed()
402+
}
403+
}
404+
345405
/// Iterator over the [`DevicePathInstance`]s in a [`DevicePath`].
346406
///
347407
/// This struct is returned by [`DevicePath::instance_iter`].
@@ -644,6 +704,7 @@ impl Deref for LoadedImageDevicePath {
644704
mod tests {
645705
use super::*;
646706
use alloc::vec::Vec;
707+
use core::mem::{size_of, size_of_val};
647708

648709
/// Create a node to `path` from raw data.
649710
fn add_node(path: &mut Vec<u8>, device_type: u8, sub_type: u8, node_data: &[u8]) {
@@ -748,4 +809,20 @@ mod tests {
748809
// Only two instances.
749810
assert!(iter.next().is_none());
750811
}
812+
813+
#[test]
814+
fn test_to_owned() {
815+
// Relevant assertion to verify the transmute is fine.
816+
assert_eq!(size_of::<&DevicePath>(), size_of::<&[u8]>());
817+
818+
let raw_data = create_raw_device_path();
819+
let dp = unsafe { DevicePath::from_ffi_ptr(raw_data.as_ptr().cast()) };
820+
821+
// Relevant assertion to verify the transmute is fine.
822+
assert_eq!(size_of_val(dp), size_of_val(&dp.data));
823+
824+
let owned_dp = dp.to_owned();
825+
let owned_dp_ref = &*owned_dp;
826+
assert_eq!(owned_dp_ref, dp)
827+
}
751828
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /