@@ -58,28 +58,21 @@ macro_rules! fill_via_chunks {
58
58
let chunk_size_u8 = min( $src. len( ) * SIZE , $dst. len( ) ) ;
59
59
let chunk_size = ( chunk_size_u8 + SIZE - 1 ) / SIZE ;
60
60
61
- if cfg!( target_endian = "little" ) {
62
- // On LE we can do a simple copy, which is 25-50% faster:
63
- unsafe {
64
- core:: ptr:: copy_nonoverlapping(
65
- $src. as_ptr( ) as * const u8 ,
66
- $dst. as_mut_ptr( ) ,
67
- chunk_size_u8) ;
68
- }
69
- } else {
70
- // This code is valid on all arches, but slower than the above:
71
- let mut i = 0 ;
72
- let mut iter = $dst[ ..chunk_size_u8] . chunks_exact_mut( SIZE ) ;
73
- while let Some ( chunk) = iter. next( ) {
74
- chunk. copy_from_slice( & $src[ i] . to_le_bytes( ) ) ;
75
- i += 1 ;
76
- }
77
- let chunk = iter. into_remainder( ) ;
78
- if !chunk. is_empty( ) {
79
- chunk. copy_from_slice( & $src[ i] . to_le_bytes( ) [ ..chunk. len( ) ] ) ;
61
+ // Byte-swap for portability of results:
62
+ if cfg!( target_endian = "big" ) {
63
+ for x in & mut $src[ ..chunk_size] {
64
+ * x = x. to_le( ) ;
80
65
}
81
66
}
82
67
68
+ // We do a simple copy, which is 25-50% faster:
69
+ unsafe {
70
+ core:: ptr:: copy_nonoverlapping(
71
+ $src. as_ptr( ) as * const u8 ,
72
+ $dst. as_mut_ptr( ) ,
73
+ chunk_size_u8) ;
74
+ }
75
+
83
76
( chunk_size, chunk_size_u8)
84
77
} } ;
85
78
}
@@ -89,6 +82,9 @@ macro_rules! fill_via_chunks {
89
82
///
90
83
/// The return values are `(consumed_u32, filled_u8)`.
91
84
///
85
+ /// On big-endian systems, endianness of `src[..consumed_u32]` values is
86
+ /// swapped. No other adjustments to `src` are made.
87
+ ///
92
88
/// `filled_u8` is the number of filled bytes in `dest`, which may be less than
93
89
/// the length of `dest`.
94
90
/// `consumed_u32` is the number of words consumed from `src`, which is the same
@@ -114,21 +110,25 @@ macro_rules! fill_via_chunks {
114
110
/// }
115
111
/// }
116
112
/// ```
117
- pub fn fill_via_u32_chunks ( src : & [ u32 ] , dest : & mut [ u8 ] ) -> ( usize , usize ) {
113
+ pub fn fill_via_u32_chunks ( src : & mut [ u32 ] , dest : & mut [ u8 ] ) -> ( usize , usize ) {
118
114
fill_via_chunks ! ( src, dest, u32 )
119
115
}
120
116
121
117
/// Implement `fill_bytes` by reading chunks from the output buffer of a block
122
118
/// based RNG.
123
119
///
124
120
/// The return values are `(consumed_u64, filled_u8)`.
121
+ ///
122
+ /// On big-endian systems, endianness of `src[..consumed_u64]` values is
123
+ /// swapped. No other adjustments to `src` are made.
124
+ ///
125
125
/// `filled_u8` is the number of filled bytes in `dest`, which may be less than
126
126
/// the length of `dest`.
127
127
/// `consumed_u64` is the number of words consumed from `src`, which is the same
128
128
/// as `filled_u8 / 8` rounded up.
129
129
///
130
130
/// See `fill_via_u32_chunks` for an example.
131
- pub fn fill_via_u64_chunks ( src : & [ u64 ] , dest : & mut [ u8 ] ) -> ( usize , usize ) {
131
+ pub fn fill_via_u64_chunks ( src : & mut [ u64 ] , dest : & mut [ u8 ] ) -> ( usize , usize ) {
132
132
fill_via_chunks ! ( src, dest, u64 )
133
133
}
134
134
@@ -152,33 +152,41 @@ mod test {
152
152
153
153
#[ test]
154
154
fn test_fill_via_u32_chunks ( ) {
155
- let src = [ 1 , 2 , 3 ] ;
155
+ let src_orig = [ 1 , 2 , 3 ] ;
156
+
157
+ let mut src = src_orig;
156
158
let mut dst = [ 0u8 ; 11 ] ;
157
- assert_eq ! ( fill_via_u32_chunks( & src, & mut dst) , ( 3 , 11 ) ) ;
159
+ assert_eq ! ( fill_via_u32_chunks( & mut src, & mut dst) , ( 3 , 11 ) ) ;
158
160
assert_eq ! ( dst, [ 1 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 3 , 0 , 0 ] ) ;
159
161
162
+ let mut src = src_orig;
160
163
let mut dst = [ 0u8 ; 13 ] ;
161
- assert_eq ! ( fill_via_u32_chunks( & src, & mut dst) , ( 3 , 12 ) ) ;
164
+ assert_eq ! ( fill_via_u32_chunks( & mut src, & mut dst) , ( 3 , 12 ) ) ;
162
165
assert_eq ! ( dst, [ 1 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 3 , 0 , 0 , 0 , 0 ] ) ;
163
166
167
+ let mut src = src_orig;
164
168
let mut dst = [ 0u8 ; 5 ] ;
165
- assert_eq ! ( fill_via_u32_chunks( & src, & mut dst) , ( 2 , 5 ) ) ;
169
+ assert_eq ! ( fill_via_u32_chunks( & mut src, & mut dst) , ( 2 , 5 ) ) ;
166
170
assert_eq ! ( dst, [ 1 , 0 , 0 , 0 , 2 ] ) ;
167
171
}
168
172
169
173
#[ test]
170
174
fn test_fill_via_u64_chunks ( ) {
171
- let src = [ 1 , 2 ] ;
175
+ let src_orig = [ 1 , 2 ] ;
176
+
177
+ let mut src = src_orig;
172
178
let mut dst = [ 0u8 ; 11 ] ;
173
- assert_eq ! ( fill_via_u64_chunks( & src, & mut dst) , ( 2 , 11 ) ) ;
179
+ assert_eq ! ( fill_via_u64_chunks( & mut src, & mut dst) , ( 2 , 11 ) ) ;
174
180
assert_eq ! ( dst, [ 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 , 0 , 0 ] ) ;
175
181
182
+ let mut src = src_orig;
176
183
let mut dst = [ 0u8 ; 17 ] ;
177
- assert_eq ! ( fill_via_u64_chunks( & src, & mut dst) , ( 2 , 16 ) ) ;
184
+ assert_eq ! ( fill_via_u64_chunks( & mut src, & mut dst) , ( 2 , 16 ) ) ;
178
185
assert_eq ! ( dst, [ 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ) ;
179
186
187
+ let mut src = src_orig;
180
188
let mut dst = [ 0u8 ; 5 ] ;
181
- assert_eq ! ( fill_via_u64_chunks( & src, & mut dst) , ( 1 , 5 ) ) ;
189
+ assert_eq ! ( fill_via_u64_chunks( & mut src, & mut dst) , ( 1 , 5 ) ) ;
182
190
assert_eq ! ( dst, [ 1 , 0 , 0 , 0 , 0 ] ) ;
183
191
}
184
192
}
0 commit comments