1111//! Define the `ByteValued` trait to mark that it is safe to instantiate the struct with random
1212//! data.
1313
14+ use std:: io:: { Read , Write } ;
1415use std:: mem:: { size_of, MaybeUninit } ;
1516use std:: result:: Result ;
1617use std:: slice:: { from_raw_parts, from_raw_parts_mut} ;
@@ -116,6 +117,20 @@ pub unsafe trait ByteValued: Copy + Send + Sync {
116117 fn as_bytes ( & mut self ) -> VolatileSlice {
117118 VolatileSlice :: from ( self . as_mut_slice ( ) )
118119 }
120+
121+ /// Writes this [`ByteValued`]'s byte representation to the given [`Write`] impl.
122+ fn write_all_to < W : Write > ( & self , mut writer : W ) -> Result < ( ) , std:: io:: Error > {
123+ writer. write_all ( self . as_slice ( ) )
124+ }
125+
126+ /// Constructs an instance of this [`ByteValued`] by reading from the given [`Read`] impl.
127+ fn read_exact_from < R : Read > ( mut reader : R ) -> Result < Self , std:: io:: Error > {
128+ // SAFETY: ByteValued objects must be assignable from arbitrary byte
129+ // sequences and are mandated to be packed.
130+ // Hence, zeroed memory is a fine initialization.
131+ let mut result: Self = unsafe { MaybeUninit :: < Self > :: zeroed ( ) . assume_init ( ) } ;
132+ reader. read_exact ( result. as_mut_slice ( ) ) . map ( |_| result)
133+ }
119134}
120135
121136macro_rules! byte_valued_array {
@@ -407,6 +422,7 @@ pub(crate) mod tests {
407422
408423 use std:: cell:: RefCell ;
409424 use std:: fmt:: Debug ;
425+ use std:: io:: ErrorKind ;
410426 use std:: mem:: align_of;
411427
412428 // Helper method to test atomic accesses for a given `b: Bytes` that's supposed to be
@@ -607,7 +623,7 @@ pub(crate) mod tests {
607623 }
608624
609625 #[ repr( C ) ]
610- #[ derive( Copy , Clone , Default ) ]
626+ #[ derive( Copy , Clone , Default , Debug ) ]
611627 struct S {
612628 a : u32 ,
613629 b : u32 ,
@@ -623,4 +639,24 @@ pub(crate) mod tests {
623639 assert_eq ! ( s. a, 0 ) ;
624640 assert_eq ! ( s. b, 0x0101_0101 ) ;
625641 }
642+
643+ #[ test]
644+ fn test_byte_valued_io ( ) {
645+ let a: [ u8 ; 8 ] = [ 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 ] ;
646+
647+ let result = S :: read_exact_from ( & a[ 1 ..] ) ;
648+ assert_eq ! ( result. unwrap_err( ) . kind( ) , ErrorKind :: UnexpectedEof ) ;
649+
650+ let s = S :: read_exact_from ( & a[ ..] ) . unwrap ( ) ;
651+ assert_eq ! ( s. a, 0 ) ;
652+ assert_eq ! ( s. b, 0x0101_0101 ) ;
653+
654+ let mut b = Vec :: new ( ) ;
655+ s. write_all_to ( & mut b) . unwrap ( ) ;
656+ assert_eq ! ( a. as_ref( ) , b. as_slice( ) ) ;
657+
658+ let mut b = [ 0 ; 7 ] ;
659+ let result = s. write_all_to ( b. as_mut_slice ( ) ) ;
660+ assert_eq ! ( result. unwrap_err( ) . kind( ) , ErrorKind :: WriteZero ) ;
661+ }
626662}
0 commit comments