@@ -86,11 +86,47 @@ library LibBit {
8686 function countZeroBytes (uint256 x ) internal pure returns (uint256 c ) {
8787 /// @solidity memory-safe-assembly
8888 assembly {
89- c := 0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f
90- c := not (or (or (add (and (x, c), c), x), c)) // `.each(b => b == 0x00 ? 0x80 : 0x00)`.
91- c := shr (7 , c)
92- c := mul (0x0101010101010101010101010101010101010101010101010101010101010101 , c)
93- c := byte (0 , c)
89+ let m := 0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f
90+ c := byte (0 , mul (shr (7 , not (m)), shr (7 , not (or (or (add (and (x, m), m), x), m)))))
91+ }
92+ }
93+
94+ /// @dev Returns the number of zero bytes in `s`.
95+ /// To get the number of non-zero bytes, simply do `s.length - countZeroBytes(s)`.
96+ function countZeroBytes (bytes memory s ) internal pure returns (uint256 c ) {
97+ /// @solidity memory-safe-assembly
98+ assembly {
99+ function czb (x_) -> _c {
100+ let _m := 0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f
101+ _c := shr (7 , not (or (or (add (and (x_, _m), _m), x_), _m)))
102+ _c := byte (0 , mul (shr (7 , not (_m)), _c))
103+ }
104+ let n := mload (s)
105+ let l := shl (5 , shr (5 , n))
106+ s := add (s, 0x20 )
107+ for { let i } xor (i, l) { i := add (i, 0x20 ) } { c := add (czb (mload (add (s, i))), c) }
108+ if lt (l, n) { c := add (czb (or (shr (shl (3 , sub (n, l)), not (0 )), mload (add (s, l)))), c) }
109+ }
110+ }
111+
112+ /// @dev Returns the number of zero bytes in `s`.
113+ /// To get the number of non-zero bytes, simply do `s.length - countZeroBytes(s)`.
114+ function countZeroBytesCalldata (bytes calldata s ) internal pure returns (uint256 c ) {
115+ /// @solidity memory-safe-assembly
116+ assembly {
117+ function czb (x_) -> _c {
118+ let _m := 0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f
119+ _c := shr (7 , not (or (or (add (and (x_, _m), _m), x_), _m)))
120+ _c := byte (0 , mul (shr (7 , not (_m)), _c))
121+ }
122+ let l := shl (5 , shr (5 , s.length ))
123+ for { let i } xor (i, l) { i := add (i, 0x20 ) } {
124+ c := add (czb (calldataload (add (s.offset, i))), c)
125+ }
126+ if lt (l, s.length ) {
127+ let m := shr (shl (3 , sub (s.length , l)), not (0 ))
128+ c := add (czb (or (m, calldataload (add (s.offset, l)))), c)
129+ }
94130 }
95131 }
96132
0 commit comments