1616// under the License.
1717
1818use super :: { Buffer , MutableBuffer } ;
19+ use crate :: bit_util:: bitwise_binary_op;
1920use crate :: util:: bit_util:: ceil;
2021
2122/// Apply a bitwise operation `op` to four inputs and return the result as a Buffer.
@@ -66,33 +67,31 @@ pub fn bitwise_bin_op_helper<F>(
6667 right : & Buffer ,
6768 right_offset_in_bits : usize ,
6869 len_in_bits : usize ,
69- mut op : F ,
70+ op : F ,
7071) -> Buffer
7172where
7273 F : FnMut ( u64 , u64 ) -> u64 ,
7374{
74- let left_chunks = left. bit_chunks ( left_offset_in_bits, len_in_bits) ;
75- let right_chunks = right. bit_chunks ( right_offset_in_bits, len_in_bits) ;
76-
77- let chunks = left_chunks
78- . iter ( )
79- . zip ( right_chunks. iter ( ) )
80- . map ( |( left, right) | op ( left, right) ) ;
81- // Soundness: `BitChunks` is a `BitChunks` iterator which
82- // correctly reports its upper bound
83- let mut buffer = unsafe { MutableBuffer :: from_trusted_len_iter ( chunks) } ;
84-
85- let remainder_bytes = ceil ( left_chunks. remainder_len ( ) , 8 ) ;
86- let rem = op ( left_chunks. remainder_bits ( ) , right_chunks. remainder_bits ( ) ) ;
87- // we are counting its starting from the least significant bit, to to_le_bytes should be correct
88- let rem = & rem. to_le_bytes ( ) [ 0 ..remainder_bytes] ;
89- buffer. extend_from_slice ( rem) ;
75+ let len_bytes = ceil ( len_in_bits + left_offset_in_bits, 8 ) ;
76+ let mut result = left[ 0 ..len_bytes] . to_vec ( ) ;
77+ bitwise_binary_op (
78+ & mut result,
79+ left_offset_in_bits,
80+ right,
81+ right_offset_in_bits,
82+ len_in_bits,
83+ op,
84+ ) ;
9085
91- buffer . into ( )
86+ result . into ( )
9287}
9388
9489/// Apply a bitwise operation `op` to one input and return the result as a Buffer.
9590/// The input is treated as a bitmap, meaning that offset and length are specified in number of bits.
91+ ///
92+ /// The output is guaranteed to have
93+ /// 1. all bits outside the specified range set to zero
94+ /// 2. start at offset zero
9695pub fn bitwise_unary_op_helper < F > (
9796 left : & Buffer ,
9897 offset_in_bits : usize ,
@@ -102,26 +101,14 @@ pub fn bitwise_unary_op_helper<F>(
102101where
103102 F : FnMut ( u64 ) -> u64 ,
104103{
105- // reserve capacity and set length so we can get a typed view of u64 chunks
106- let mut result =
107- MutableBuffer :: new ( ceil ( len_in_bits, 8 ) ) . with_bitset ( len_in_bits / 64 * 8 , false ) ;
108-
109- let left_chunks = left. bit_chunks ( offset_in_bits, len_in_bits) ;
110-
111- let result_chunks = result. typed_data_mut :: < u64 > ( ) . iter_mut ( ) ;
112-
113- result_chunks
114- . zip ( left_chunks. iter ( ) )
115- . for_each ( |( res, left) | {
116- * res = op ( left) ;
117- } ) ;
118-
119- let remainder_bytes = ceil ( left_chunks. remainder_len ( ) , 8 ) ;
120- let rem = op ( left_chunks. remainder_bits ( ) ) ;
121- // we are counting its starting from the least significant bit, to to_le_bytes should be correct
122- let rem = & rem. to_le_bytes ( ) [ 0 ..remainder_bytes] ;
123- result. extend_from_slice ( rem) ;
124-
104+ if len_in_bits == 0 {
105+ return Buffer :: default ( ) ;
106+ }
107+ let len_in_bytes = ceil ( len_in_bits, 8 ) ;
108+ let mut result = vec ! [ 0u8 ; len_in_bytes] ;
109+ bitwise_binary_op ( & mut result, 0 , left, offset_in_bits, len_in_bits, |_, b| {
110+ op ( b)
111+ } ) ;
125112 result. into ( )
126113}
127114
0 commit comments