@@ -56,6 +56,7 @@ use core::fmt::{self, Debug, Display, Formatter};
56
56
use core:: marker:: PhantomData ;
57
57
use core:: mem;
58
58
use core:: ops:: { Deref , DerefMut } ;
59
+ use core:: ptr;
59
60
use core:: slice;
60
61
61
62
// This is a hack to allow derives of FromBytes, AsBytes, and Unaligned to work
@@ -186,6 +187,43 @@ pub unsafe trait FromBytes {
186
187
where
187
188
Self : Sized ;
188
189
190
+ /// Reads a copy of `Self` from `bytes`.
191
+ ///
192
+ /// If `bytes.len() != size_of::<Self>()`, `read_from` returns `None`.
193
+ fn read_from < B : ByteSlice > ( bytes : B ) -> Option < Self >
194
+ where
195
+ Self : Sized ,
196
+ {
197
+ let lv = LayoutVerified :: < _ , Unalign < Self > > :: new_unaligned ( bytes) ?;
198
+ Some ( lv. read ( ) . into_inner ( ) )
199
+ }
200
+
201
+ /// Reads a copy of `Self` from the prefix of `bytes`.
202
+ ///
203
+ /// `read_from_prefix` reads a `Self` from the first `size_of::<Self>()`
204
+ /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()`, it returns
205
+ /// `None`.
206
+ fn read_from_prefix < B : ByteSlice > ( bytes : B ) -> Option < Self >
207
+ where
208
+ Self : Sized ,
209
+ {
210
+ let ( lv, _suffix) = LayoutVerified :: < _ , Unalign < Self > > :: new_unaligned_from_prefix ( bytes) ?;
211
+ Some ( lv. read ( ) . into_inner ( ) )
212
+ }
213
+
214
+ /// Reads a copy of `Self` from the suffix of `bytes`.
215
+ ///
216
+ /// `read_from_suffix` reads a `Self` from the last `size_of::<Self>()`
217
+ /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()`, it returns
218
+ /// `None`.
219
+ fn read_from_suffix < B : ByteSlice > ( bytes : B ) -> Option < Self >
220
+ where
221
+ Self : Sized ,
222
+ {
223
+ let ( _prefix, lv) = LayoutVerified :: < _ , Unalign < Self > > :: new_unaligned_from_suffix ( bytes) ?;
224
+ Some ( lv. read ( ) . into_inner ( ) )
225
+ }
226
+
189
227
/// Creates an instance of `Self` from zeroed bytes.
190
228
fn new_zeroed ( ) -> Self
191
229
where
@@ -379,6 +417,42 @@ pub unsafe trait AsBytes {
379
417
slice:: from_raw_parts_mut ( self as * mut Self as * mut u8 , len)
380
418
}
381
419
}
420
+
421
+ /// Writes a copy of `self` to `bytes`.
422
+ ///
423
+ /// If `bytes.len() != size_of_val(self)`, `write_to` returns `None`.
424
+ fn write_to < B : ByteSliceMut > ( & self , mut bytes : B ) -> Option < ( ) > {
425
+ if bytes. len ( ) != mem:: size_of_val ( self ) {
426
+ return None ;
427
+ }
428
+
429
+ bytes. copy_from_slice ( self . as_bytes ( ) ) ;
430
+ Some ( ( ) )
431
+ }
432
+
433
+ /// Writes a copy of `self` to the prefix of `bytes`.
434
+ ///
435
+ /// `write_to_prefix` writes `self` to the first `size_of_val(self)` bytes
436
+ /// of `bytes`. If `bytes.len() < size_of_val(self)`, it returns `None`.
437
+ fn write_to_prefix < B : ByteSliceMut > ( & self , mut bytes : B ) -> Option < ( ) > {
438
+ let size = mem:: size_of_val ( self ) ;
439
+ if bytes. len ( ) < size {
440
+ return None ;
441
+ }
442
+
443
+ bytes[ ..size] . copy_from_slice ( self . as_bytes ( ) ) ;
444
+ Some ( ( ) )
445
+ }
446
+
447
+ /// Writes a copy of `self` to the suffix of `bytes`.
448
+ ///
449
+ /// `write_to_suffix` writes `self` to the last `size_of_val(self)` bytes
450
+ /// of `bytes`. If `bytes.len() < size_of_val(self)`, it returns `None`.
451
+ fn write_to_suffix < B : ByteSliceMut > ( & self , mut bytes : B ) -> Option < ( ) > {
452
+ let start = bytes. len ( ) . checked_sub ( mem:: size_of_val ( self ) ) ?;
453
+ bytes[ start..] . copy_from_slice ( self . as_bytes ( ) ) ;
454
+ Some ( ( ) )
455
+ }
382
456
}
383
457
384
458
// Special case for bool (it is not included in `impl_for_primitives!`).
@@ -543,6 +617,103 @@ mod simd {
543
617
) ;
544
618
}
545
619
620
+ /// A type with no alignment requirement.
621
+ ///
622
+ /// A `Unalign` wraps a `T`, removing any alignment requirement. `Unalign<T>`
623
+ /// has the same size and ABI as `T`, but not necessarily the same alignment.
624
+ /// This is useful if a type with an alignment requirement needs to be read from
625
+ /// a chunk of memory which provides no alignment guarantees.
626
+ ///
627
+ /// Since `Unalign` has no alignment requirement, the inner `T` may not be
628
+ /// properly aligned in memory, and so `Unalign` provides no way of getting a
629
+ /// reference to the inner `T`. Instead, the `T` may only be obtained by value
630
+ /// (see [`get`] and [`into_inner`]).
631
+ ///
632
+ /// [`get`]: Unalign::get
633
+ /// [`into_inner`]: Unalign::into_inner
634
+ #[ derive( FromBytes , Unaligned , Copy ) ]
635
+ #[ repr( C , packed) ]
636
+ pub struct Unalign < T > ( T ) ;
637
+
638
+ // Note that `Unalign: Clone` only if `T: Copy`. Since the inner `T` may not be
639
+ // aligned, there's no way to safely call `T::clone`, and so a `T: Clone` bound
640
+ // is not sufficient to implement `Clone` for `Unalign`.
641
+ impl < T : Copy > Clone for Unalign < T > {
642
+ fn clone ( & self ) -> Unalign < T > {
643
+ * self
644
+ }
645
+ }
646
+
647
+ impl < T > Unalign < T > {
648
+ /// Constructs a new `Unalign`.
649
+ pub fn new ( val : T ) -> Unalign < T > {
650
+ Unalign ( val)
651
+ }
652
+
653
+ /// Consumes `self`, returning the inner `T`.
654
+ pub fn into_inner ( self ) -> T {
655
+ let Unalign ( val) = self ;
656
+ val
657
+ }
658
+
659
+ /// Gets an unaligned raw pointer to the inner `T`.
660
+ ///
661
+ /// # Safety
662
+ ///
663
+ /// The returned raw pointer is not necessarily aligned to
664
+ /// `align_of::<T>()`. Most functions which operate on raw pointers require
665
+ /// those pointers to be aligned, so calling those functions with the result
666
+ /// of `get_ptr` will be undefined behavior if alignment is not guaranteed
667
+ /// using some out-of-band mechanism. In general, the only functions which
668
+ /// are safe to call with this pointer are which that are explicitly
669
+ /// documented as being sound to use with an unaligned pointer, such as
670
+ /// [`read_unaligned`].
671
+ ///
672
+ /// [`read_unaligned`]: core::ptr::read_unaligned
673
+ pub fn get_ptr ( & self ) -> * const T {
674
+ ptr:: addr_of!( self . 0 )
675
+ }
676
+
677
+ /// Gets an unaligned mutable raw pointer to the inner `T`.
678
+ ///
679
+ /// # Safety
680
+ ///
681
+ /// The returned raw pointer is not necessarily aligned to
682
+ /// `align_of::<T>()`. Most functions which operate on raw pointers require
683
+ /// those pointers to be aligned, so calling those functions with the result
684
+ /// of `get_ptr` will be undefined behavior if alignment is not guaranteed
685
+ /// using some out-of-band mechanism. In general, the only functions which
686
+ /// are safe to call with this pointer are those which are explicitly
687
+ /// documented as being sound to use with an unaligned pointer, such as
688
+ /// [`read_unaligned`].
689
+ ///
690
+ /// [`read_unaligned`]: core::ptr::read_unaligned
691
+ pub fn get_mut_ptr ( & mut self ) -> * mut T {
692
+ ptr:: addr_of_mut!( self . 0 )
693
+ }
694
+ }
695
+
696
+ impl < T : Copy > Unalign < T > {
697
+ /// Gets a copy of the inner `T`.
698
+ pub fn get ( & self ) -> T {
699
+ let Unalign ( val) = * self ;
700
+ val
701
+ }
702
+ }
703
+
704
+ // SAFETY: Since `T: AsBytes`, we know that it's safe to construct a `&[u8]`
705
+ // from an aligned `&T`. Since `&[u8]` itself has no alignment requirements, it
706
+ // must also be safe to construct a `&[u8]` from a `&T` at any address. Since
707
+ // `Unalign<T>` is `#[repr(packed)]`, everything about its layout except for its
708
+ // alignment is the same as `T`'s layout.
709
+ unsafe impl < T : AsBytes > AsBytes for Unalign < T > {
710
+ fn only_derive_is_allowed_to_implement_this_trait ( )
711
+ where
712
+ Self : Sized ,
713
+ {
714
+ }
715
+ }
716
+
546
717
// Used in `transmute!` below.
547
718
#[ doc( hidden) ]
548
719
pub use core:: mem:: transmute as __real_transmute;
@@ -1397,6 +1568,39 @@ where
1397
1568
}
1398
1569
}
1399
1570
1571
+ impl < B , T > LayoutVerified < B , T >
1572
+ where
1573
+ B : ByteSlice ,
1574
+ T : FromBytes ,
1575
+ {
1576
+ /// Reads a copy of `T`.
1577
+ #[ inline]
1578
+ pub fn read ( & self ) -> T {
1579
+ // SAFETY: Because of the invariants on `LayoutVerified`, we know that
1580
+ // `self.0` is at least `size_of::<T>()` bytes long, and that it is at
1581
+ // least as aligned as `align_of::<T>()`. Because `T: FromBytes`, it is
1582
+ // sound to interpret these bytes as a `T`.
1583
+ unsafe { ptr:: read ( self . 0 . as_ptr ( ) as * const T ) }
1584
+ }
1585
+ }
1586
+
1587
+ impl < B , T > LayoutVerified < B , T >
1588
+ where
1589
+ B : ByteSliceMut ,
1590
+ T : AsBytes ,
1591
+ {
1592
+ /// Writes the bytes of `t` and then forgets `t`.
1593
+ #[ inline]
1594
+ pub fn write ( & mut self , t : T ) {
1595
+ // SAFETY: Because of the invariants on `LayoutVerified`, we know that
1596
+ // `self.0` is at least `size_of::<T>()` bytes long, and that it is at
1597
+ // least as aligned as `align_of::<T>()`. Writing `t` to the buffer will
1598
+ // allow all of the bytes of `t` to be accessed as a `[u8]`, but because
1599
+ // `T: AsBytes`, we know this is sound.
1600
+ unsafe { ptr:: write ( self . 0 . as_mut_ptr ( ) as * mut T , t) }
1601
+ }
1602
+ }
1603
+
1400
1604
impl < B , T > Deref for LayoutVerified < B , T >
1401
1605
where
1402
1606
B : ByteSlice ,
@@ -1760,7 +1964,6 @@ mod tests {
1760
1964
#![ allow( clippy:: unreadable_literal) ]
1761
1965
1762
1966
use core:: ops:: Deref ;
1763
- use core:: ptr;
1764
1967
1765
1968
use super :: * ;
1766
1969
@@ -1783,6 +1986,43 @@ mod tests {
1783
1986
unsafe { ptr:: read ( & u as * const u64 as * const [ u8 ; 8 ] ) }
1784
1987
}
1785
1988
1989
+ #[ test]
1990
+ fn test_read_write ( ) {
1991
+ const VAL : u64 = 0x12345678 ;
1992
+ #[ cfg( target_endian = "big" ) ]
1993
+ const VAL_BYTES : [ u8 ; 8 ] = VAL . to_be_bytes ( ) ;
1994
+ #[ cfg( target_endian = "little" ) ]
1995
+ const VAL_BYTES : [ u8 ; 8 ] = VAL . to_le_bytes ( ) ;
1996
+
1997
+ // Test FromBytes::{read_from, read_from_prefix, read_from_suffix}
1998
+
1999
+ assert_eq ! ( u64 :: read_from( & VAL_BYTES [ ..] ) , Some ( VAL ) ) ;
2000
+ // The first 8 bytes are from `VAL_BYTES` and the second 8 bytes are all
2001
+ // zeroes.
2002
+ let bytes_with_prefix: [ u8 ; 16 ] = transmute ! ( [ VAL_BYTES , [ 0 ; 8 ] ] ) ;
2003
+ assert_eq ! ( u64 :: read_from_prefix( & bytes_with_prefix[ ..] ) , Some ( VAL ) ) ;
2004
+ assert_eq ! ( u64 :: read_from_suffix( & bytes_with_prefix[ ..] ) , Some ( 0 ) ) ;
2005
+ // The first 8 bytes are all zeroes and the second 8 bytes are from
2006
+ // `VAL_BYTES`
2007
+ let bytes_with_suffix: [ u8 ; 16 ] = transmute ! ( [ [ 0 ; 8 ] , VAL_BYTES ] ) ;
2008
+ assert_eq ! ( u64 :: read_from_prefix( & bytes_with_suffix[ ..] ) , Some ( 0 ) ) ;
2009
+ assert_eq ! ( u64 :: read_from_suffix( & bytes_with_suffix[ ..] ) , Some ( VAL ) ) ;
2010
+
2011
+ // Test AsBytes::{write_to, write_to_prefix, write_to_suffix}
2012
+
2013
+ let mut bytes = [ 0u8 ; 8 ] ;
2014
+ assert_eq ! ( VAL . write_to( & mut bytes[ ..] ) , Some ( ( ) ) ) ;
2015
+ assert_eq ! ( bytes, VAL_BYTES ) ;
2016
+ let mut bytes = [ 0u8 ; 16 ] ;
2017
+ assert_eq ! ( VAL . write_to_prefix( & mut bytes[ ..] ) , Some ( ( ) ) ) ;
2018
+ let want: [ u8 ; 16 ] = transmute ! ( [ VAL_BYTES , [ 0 ; 8 ] ] ) ;
2019
+ assert_eq ! ( bytes, want) ;
2020
+ let mut bytes = [ 0u8 ; 16 ] ;
2021
+ assert_eq ! ( VAL . write_to_suffix( & mut bytes[ ..] ) , Some ( ( ) ) ) ;
2022
+ let want: [ u8 ; 16 ] = transmute ! ( [ [ 0 ; 8 ] , VAL_BYTES ] ) ;
2023
+ assert_eq ! ( bytes, want) ;
2024
+ }
2025
+
1786
2026
#[ test]
1787
2027
fn test_transmute ( ) {
1788
2028
// Test that memory is transmuted as expected.
@@ -1825,22 +2065,29 @@ mod tests {
1825
2065
}
1826
2066
1827
2067
// verify that values written to a LayoutVerified are properly shared
1828
- // between the typed and untyped representations
2068
+ // between the typed and untyped representations, that reads via `deref` and
2069
+ // `read` behave the same, and that writes via `deref_mut` and `write`
2070
+ // behave the same
1829
2071
fn test_new_helper < ' a > ( mut lv : LayoutVerified < & ' a mut [ u8 ] , u64 > ) {
1830
2072
// assert that the value starts at 0
1831
2073
assert_eq ! ( * lv, 0 ) ;
2074
+ assert_eq ! ( lv. read( ) , 0 ) ;
1832
2075
1833
2076
// assert that values written to the typed value are reflected in the
1834
2077
// byte slice
1835
2078
const VAL1 : u64 = 0xFF00FF00FF00FF00 ;
1836
2079
* lv = VAL1 ;
1837
2080
assert_eq ! ( lv. bytes( ) , & u64_to_bytes( VAL1 ) ) ;
2081
+ * lv = 0 ;
2082
+ lv. write ( VAL1 ) ;
2083
+ assert_eq ! ( lv. bytes( ) , & u64_to_bytes( VAL1 ) ) ;
1838
2084
1839
2085
// assert that values written to the byte slice are reflected in the
1840
2086
// typed value
1841
2087
const VAL2 : u64 = !VAL1 ; // different from VAL1
1842
2088
lv. bytes_mut ( ) . copy_from_slice ( & u64_to_bytes ( VAL2 ) [ ..] ) ;
1843
2089
assert_eq ! ( * lv, VAL2 ) ;
2090
+ assert_eq ! ( lv. read( ) , VAL2 ) ;
1844
2091
}
1845
2092
1846
2093
// verify that values written to a LayoutVerified are properly shared
@@ -1871,22 +2118,29 @@ mod tests {
1871
2118
}
1872
2119
1873
2120
// verify that values written to a LayoutVerified are properly shared
1874
- // between the typed and untyped representations
2121
+ // between the typed and untyped representations, that reads via `deref` and
2122
+ // `read` behave the same, and that writes via `deref_mut` and `write`
2123
+ // behave the same
1875
2124
fn test_new_helper_unaligned < ' a > ( mut lv : LayoutVerified < & ' a mut [ u8 ] , [ u8 ; 8 ] > ) {
1876
2125
// assert that the value starts at 0
1877
2126
assert_eq ! ( * lv, [ 0 ; 8 ] ) ;
2127
+ assert_eq ! ( lv. read( ) , [ 0 ; 8 ] ) ;
1878
2128
1879
2129
// assert that values written to the typed value are reflected in the
1880
2130
// byte slice
1881
2131
const VAL1 : [ u8 ; 8 ] = [ 0xFF , 0x00 , 0xFF , 0x00 , 0xFF , 0x00 , 0xFF , 0x00 ] ;
1882
2132
* lv = VAL1 ;
1883
2133
assert_eq ! ( lv. bytes( ) , & VAL1 ) ;
2134
+ * lv = [ 0 ; 8 ] ;
2135
+ lv. write ( VAL1 ) ;
2136
+ assert_eq ! ( lv. bytes( ) , & VAL1 ) ;
1884
2137
1885
2138
// assert that values written to the byte slice are reflected in the
1886
2139
// typed value
1887
2140
const VAL2 : [ u8 ; 8 ] = [ 0x00 , 0xFF , 0x00 , 0xFF , 0x00 , 0xFF , 0x00 , 0xFF ] ; // different from VAL1
1888
2141
lv. bytes_mut ( ) . copy_from_slice ( & VAL2 [ ..] ) ;
1889
2142
assert_eq ! ( * lv, VAL2 ) ;
2143
+ assert_eq ! ( lv. read( ) , VAL2 ) ;
1890
2144
}
1891
2145
1892
2146
// verify that values written to a LayoutVerified are properly shared
0 commit comments