11
11
//! Define the `ByteValued` trait to mark that it is safe to instantiate the struct with random
12
12
//! data.
13
13
14
+ use std:: io:: { Read , Write } ;
14
15
use std:: mem:: { size_of, MaybeUninit } ;
15
16
use std:: result:: Result ;
16
17
use std:: slice:: { from_raw_parts, from_raw_parts_mut} ;
@@ -116,6 +117,20 @@ pub unsafe trait ByteValued: Copy + Send + Sync {
116
117
fn as_bytes ( & mut self ) -> VolatileSlice {
117
118
VolatileSlice :: from ( self . as_mut_slice ( ) )
118
119
}
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
+ }
119
134
}
120
135
121
136
macro_rules! byte_valued_array {
@@ -407,6 +422,7 @@ pub(crate) mod tests {
407
422
408
423
use std:: cell:: RefCell ;
409
424
use std:: fmt:: Debug ;
425
+ use std:: io:: ErrorKind ;
410
426
use std:: mem:: align_of;
411
427
412
428
// Helper method to test atomic accesses for a given `b: Bytes` that's supposed to be
@@ -607,7 +623,7 @@ pub(crate) mod tests {
607
623
}
608
624
609
625
#[ repr( C ) ]
610
- #[ derive( Copy , Clone , Default ) ]
626
+ #[ derive( Copy , Clone , Default , Debug ) ]
611
627
struct S {
612
628
a : u32 ,
613
629
b : u32 ,
@@ -623,4 +639,24 @@ pub(crate) mod tests {
623
639
assert_eq ! ( s. a, 0 ) ;
624
640
assert_eq ! ( s. b, 0x0101_0101 ) ;
625
641
}
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
+ }
626
662
}
0 commit comments