@@ -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;
@@ -176,6 +178,12 @@ impl DevicePathNode {
176
178
self . full_type ( ) == ( DeviceType :: END , DeviceSubType :: END_ENTIRE )
177
179
}
178
180
181
+ /// Returns the payload data of this node.
182
+ #[ must_use]
183
+ pub fn data ( & self ) -> & [ u8 ] {
184
+ & self . data
185
+ }
186
+
179
187
/// Convert from a generic [`DevicePathNode`] reference to an enum
180
188
/// of more specific node types.
181
189
pub fn as_enum ( & self ) -> Result < DevicePathNodeEnum , NodeConversionError > {
@@ -226,6 +234,21 @@ impl DevicePathInstance {
226
234
stop_condition : StopCondition :: AnyEndNode ,
227
235
}
228
236
}
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
+ }
229
252
}
230
253
231
254
impl Debug for DevicePathInstance {
@@ -242,10 +265,23 @@ impl PartialEq for DevicePathInstance {
242
265
}
243
266
}
244
267
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
+
245
277
/// Device path protocol.
246
278
///
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.
249
285
///
250
286
/// See the [module-level documentation] for more details.
251
287
///
@@ -326,6 +362,21 @@ impl DevicePath {
326
362
stop_condition : StopCondition :: EndEntireNode ,
327
363
}
328
364
}
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
+ }
329
380
}
330
381
331
382
impl Debug for DevicePath {
@@ -342,6 +393,15 @@ impl PartialEq for DevicePath {
342
393
}
343
394
}
344
395
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
+
345
405
/// Iterator over the [`DevicePathInstance`]s in a [`DevicePath`].
346
406
///
347
407
/// This struct is returned by [`DevicePath::instance_iter`].
@@ -644,6 +704,7 @@ impl Deref for LoadedImageDevicePath {
644
704
mod tests {
645
705
use super :: * ;
646
706
use alloc:: vec:: Vec ;
707
+ use core:: mem:: { size_of, size_of_val} ;
647
708
648
709
/// Create a node to `path` from raw data.
649
710
fn add_node ( path : & mut Vec < u8 > , device_type : u8 , sub_type : u8 , node_data : & [ u8 ] ) {
@@ -748,4 +809,20 @@ mod tests {
748
809
// Only two instances.
749
810
assert ! ( iter. next( ) . is_none( ) ) ;
750
811
}
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
+ }
751
828
}
0 commit comments