@@ -5,13 +5,9 @@ macro_rules! generate_read_fn {
55 ( $fn_name: ident, $data_type: ty, $byte_type: ty, $type_size: expr, $endian_type: ident) => {
66 /// Read bytes from the slice
77 pub fn $fn_name( input: & [ $byte_type] ) -> $data_type {
8- assert!( $type_size == std:: mem:: size_of:: <$data_type>( ) ) ;
9- let mut array = [ 0u8 ; $type_size] ;
10- #[ allow( clippy:: cast_sign_loss) ]
11- #[ allow( clippy:: cast_possible_wrap) ]
12- for ( byte, read) in array. iter_mut( ) . zip( input. iter( ) . cloned( ) ) {
13- * byte = read as u8 ;
14- }
8+ let mut array = [ 0u8 ; std:: mem:: size_of:: <$data_type>( ) ] ;
9+ let how_many = input. len( ) . min( std:: mem:: size_of:: <$data_type>( ) ) ;
10+ array[ ..how_many] . copy_from_slice( & input[ ..how_many] ) ;
1511 <$data_type>:: $endian_type( array)
1612 }
1713 } ;
@@ -21,36 +17,46 @@ macro_rules! generate_write_fn {
2117 ( $fn_name: ident, $data_type: ty, $byte_type: ty, $endian_type: ident) => {
2218 /// Write bytes to the slice
2319 pub fn $fn_name( buf: & mut [ $byte_type] , n: $data_type) {
24- #[ allow( clippy:: cast_sign_loss) ]
25- #[ allow( clippy:: cast_possible_wrap) ]
26- for ( byte, read) in buf
27- . iter_mut( )
28- . zip( <$data_type>:: $endian_type( n) . iter( ) . cloned( ) )
29- {
30- * byte = read as $byte_type;
31- }
20+ let bytes = n. $endian_type( ) ;
21+ let how_much = buf. len( ) . min( bytes. len( ) ) ;
22+ buf[ ..how_much] . copy_from_slice( & bytes[ ..how_much] ) ;
3223 }
3324 } ;
3425}
3526
36- generate_read_fn ! ( read_le_u16, u16 , u8 , 2 , from_le_bytes) ;
3727generate_read_fn ! ( read_le_u32, u32 , u8 , 4 , from_le_bytes) ;
38- generate_read_fn ! ( read_le_u32_from_i8, u32 , i8 , 4 , from_le_bytes) ;
3928generate_read_fn ! ( read_le_u64, u64 , u8 , 8 , from_le_bytes) ;
40- generate_read_fn ! ( read_le_i32, i32 , i8 , 4 , from_le_bytes) ;
4129
4230generate_read_fn ! ( read_be_u16, u16 , u8 , 2 , from_be_bytes) ;
4331generate_read_fn ! ( read_be_u32, u32 , u8 , 4 , from_be_bytes) ;
4432
45- generate_write_fn ! ( write_le_u16, u16 , u8 , to_le_bytes) ;
4633generate_write_fn ! ( write_le_u32, u32 , u8 , to_le_bytes) ;
47- generate_write_fn ! ( write_le_u32_to_i8, u32 , i8 , to_le_bytes) ;
4834generate_write_fn ! ( write_le_u64, u64 , u8 , to_le_bytes) ;
49- generate_write_fn ! ( write_le_i32, i32 , i8 , to_le_bytes) ;
5035
5136generate_write_fn ! ( write_be_u16, u16 , u8 , to_be_bytes) ;
5237generate_write_fn ! ( write_be_u32, u32 , u8 , to_be_bytes) ;
5338
39+ /// Reads a `u32` from a stream of `i8` by casting the input to `u8`s. If `input`
40+ /// is too small for reading an entire u32, the function pads it with zeros.
41+ pub fn read_le_u32_from_i8 ( input : & [ i8 ] ) -> u32 {
42+ let mut tmp = [ 0u8 ; std:: mem:: size_of :: < u32 > ( ) ] ;
43+ #[ allow( clippy:: cast_sign_loss) ]
44+ tmp. iter_mut ( )
45+ . zip ( input)
46+ . for_each ( |( b_tmp, & b) | * b_tmp = b as u8 ) ;
47+ u32:: from_le_bytes ( tmp)
48+ }
49+
50+ /// Writes the given `u32` into the given buffer, casting the individual bytes to i8. If
51+ /// the buffer is too small to contain an entire u32, the function truncates and does
52+ /// a partial write.
53+ pub fn write_le_u32_to_i8 ( buf : & mut [ i8 ] , n : u32 ) {
54+ #[ allow( clippy:: cast_possible_wrap) ]
55+ buf. iter_mut ( )
56+ . zip ( n. to_le_bytes ( ) )
57+ . for_each ( |( b_buf, b) | * b_buf = b as i8 ) ;
58+ }
59+
5460#[ cfg( test) ]
5561mod tests {
5662 use super :: * ;
@@ -110,10 +116,8 @@ mod tests {
110116 } ;
111117 }
112118
113- byte_order_test_read_write ! ( test_le_u16, write_le_u16, read_le_u16, false , u16 ) ;
114119 byte_order_test_read_write ! ( test_le_u32, write_le_u32, read_le_u32, false , u32 ) ;
115120 byte_order_test_read_write ! ( test_le_u64, write_le_u64, read_le_u64, false , u64 ) ;
116- byte_order_test_read_write ! ( test_le_i32, write_le_i32, read_le_i32, false , i32 ) ;
117121 byte_order_test_read_write ! ( test_be_u16, write_be_u16, read_be_u16, true , u16 ) ;
118122 byte_order_test_read_write ! ( test_be_u32, write_be_u32, read_be_u32, true , u32 ) ;
119123}
0 commit comments