|
10 | 10 |
|
11 | 11 | //! Define the ByteValued trait to mark that it is safe to instantiate the struct with random data.
|
12 | 12 |
|
| 13 | +use crate::VolatileSlice; |
13 | 14 | use std::io::{Read, Write};
|
14 | 15 | use std::mem::size_of;
|
15 | 16 | use std::result::Result;
|
@@ -100,6 +101,22 @@ pub unsafe trait ByteValued: Copy + Default + Send + Sync {
|
100 | 101 | // borrowing the given mutable reference.
|
101 | 102 | unsafe { from_raw_parts_mut(self as *mut Self as *mut u8, size_of::<Self>()) }
|
102 | 103 | }
|
| 104 | + |
| 105 | + /// Converts a mutable reference to `self` into a VolatileSlice. This is |
| 106 | + /// useful because `VolatileSlice` provides a `Bytes<usize>` implementation. |
| 107 | + /// |
| 108 | + /// # Safety |
| 109 | + /// |
| 110 | + /// Unlike most VolatileMemory implementation, this method requires an exclusive |
| 111 | + /// reference to `self`; this trivially fulfills `VolatileSlice::new`'s requirement |
| 112 | + /// that all accesses to `self` use volatile accesses (because there can |
| 113 | + /// be no other accesses). |
| 114 | + fn as_bytes(&mut self) -> VolatileSlice { |
| 115 | + unsafe { |
| 116 | + // This is safe because the lifetime is the same as self |
| 117 | + VolatileSlice::new(self as *mut Self as usize as *mut _, size_of::<Self>()) |
| 118 | + } |
| 119 | + } |
103 | 120 | }
|
104 | 121 |
|
105 | 122 | // All intrinsic types and arrays of intrinsic types are ByteValued. They are just numbers.
|
@@ -405,4 +422,22 @@ mod tests {
|
405 | 422 | .is_err());
|
406 | 423 | assert!(bytes.read_obj::<u64>(MOCK_BYTES_CONTAINER_SIZE).is_err());
|
407 | 424 | }
|
| 425 | + |
| 426 | + #[repr(C)] |
| 427 | + #[derive(Copy, Clone, Default)] |
| 428 | + struct S { |
| 429 | + a: u32, |
| 430 | + b: u32, |
| 431 | + } |
| 432 | + |
| 433 | + unsafe impl ByteValued for S {} |
| 434 | + |
| 435 | + #[test] |
| 436 | + fn byte_valued_slice() { |
| 437 | + let a: [u8; 8] = [0, 0, 0, 0, 1, 1, 1, 1]; |
| 438 | + let mut s: S = Default::default(); |
| 439 | + s.as_bytes().copy_from(&a); |
| 440 | + assert_eq!(s.a, 0); |
| 441 | + assert_eq!(s.b, 0x1010101); |
| 442 | + } |
408 | 443 | }
|
0 commit comments