@@ -80,6 +80,8 @@ mod device_path_gen;
80
80
pub use device_path_gen:: {
81
81
acpi, bios_boot_spec, end, hardware, media, messaging, DevicePathNodeEnum ,
82
82
} ;
83
+ #[ cfg( feature = "alloc" ) ]
84
+ use { alloc:: borrow:: ToOwned , alloc:: boxed:: Box } ;
83
85
84
86
use crate :: proto:: { unsafe_protocol, ProtocolPointer } ;
85
87
use core:: ffi:: c_void;
@@ -226,6 +228,21 @@ impl DevicePathInstance {
226
228
stop_condition : StopCondition :: AnyEndNode ,
227
229
}
228
230
}
231
+
232
+ /// Returns a slice of the underlying bytes.
233
+ #[ must_use]
234
+ pub const fn as_bytes ( & 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
+ }
229
246
}
230
247
231
248
impl Debug for DevicePathInstance {
@@ -242,10 +259,23 @@ impl PartialEq for DevicePathInstance {
242
259
}
243
260
}
244
261
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
+
245
271
/// Device path protocol.
246
272
///
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.
273
+ /// Can be used on any device handle to obtain generic path/location information
274
+ /// concerning the physical device or logical device. If the handle does not
275
+ /// logically map to a physical device, the handle may not necessarily support
276
+ /// the device path protocol. The device path describes the location of the
277
+ /// device the handle is for. The size of the Device Path can be determined from
278
+ /// the structures that make up the Device Path.
249
279
///
250
280
/// See the [module-level documentation] for more details.
251
281
///
@@ -326,6 +356,21 @@ impl DevicePath {
326
356
stop_condition : StopCondition :: EndEntireNode ,
327
357
}
328
358
}
359
+
360
+ /// Returns a slice of the underlying bytes.
361
+ #[ must_use]
362
+ pub const fn as_bytes ( & self ) -> & [ u8 ] {
363
+ & self . data
364
+ }
365
+
366
+ /// Returns a boxed copy of that value.
367
+ #[ cfg( feature = "alloc" ) ]
368
+ #[ must_use]
369
+ pub fn to_boxed ( & self ) -> Box < Self > {
370
+ let data = self . data . to_owned ( ) ;
371
+ let data = data. into_boxed_slice ( ) ;
372
+ unsafe { mem:: transmute ( data) }
373
+ }
329
374
}
330
375
331
376
impl Debug for DevicePath {
@@ -342,6 +387,15 @@ impl PartialEq for DevicePath {
342
387
}
343
388
}
344
389
390
+ #[ cfg( feature = "alloc" ) ]
391
+ impl ToOwned for DevicePath {
392
+ type Owned = Box < DevicePath > ;
393
+
394
+ fn to_owned ( & self ) -> Self :: Owned {
395
+ self . to_boxed ( )
396
+ }
397
+ }
398
+
345
399
/// Iterator over the [`DevicePathInstance`]s in a [`DevicePath`].
346
400
///
347
401
/// This struct is returned by [`DevicePath::instance_iter`].
@@ -644,6 +698,7 @@ impl Deref for LoadedImageDevicePath {
644
698
mod tests {
645
699
use super :: * ;
646
700
use alloc:: vec:: Vec ;
701
+ use core:: mem:: { size_of, size_of_val} ;
647
702
648
703
/// Create a node to `path` from raw data.
649
704
fn add_node ( path : & mut Vec < u8 > , device_type : u8 , sub_type : u8 , node_data : & [ u8 ] ) {
@@ -748,4 +803,20 @@ mod tests {
748
803
// Only two instances.
749
804
assert ! ( iter. next( ) . is_none( ) ) ;
750
805
}
806
+
807
+ #[ test]
808
+ fn test_to_owned ( ) {
809
+ // Relevant assertion to verify the transmute is fine.
810
+ assert_eq ! ( size_of:: <& DevicePath >( ) , size_of:: <& [ u8 ] >( ) ) ;
811
+
812
+ let raw_data = create_raw_device_path ( ) ;
813
+ let dp = unsafe { DevicePath :: from_ffi_ptr ( raw_data. as_ptr ( ) . cast ( ) ) } ;
814
+
815
+ // Relevant assertion to verify the transmute is fine.
816
+ assert_eq ! ( size_of_val( dp) , size_of_val( & dp. data) ) ;
817
+
818
+ let owned_dp = dp. to_owned ( ) ;
819
+ let owned_dp_ref = & * owned_dp;
820
+ assert_eq ! ( owned_dp_ref, dp)
821
+ }
751
822
}
0 commit comments