bool BitTestMatchExpression::performBitTest(const char* eBinary, uint32_t eBinaryLen) const { const MatchType mt = matchType(); // Test each bit position. for (auto bitPosition : _bitPositions) { bool isBitSet; if (bitPosition >= eBinaryLen * 8) { // If position to test is longer than the data to test against, zero-extend. isBitSet = false; } else { // Map to byte position and bit position within that byte. Note that byte positions // start at position 0 in the char array, and bit positions start at the least // significant bit. int bytePosition = bitPosition / 8; int bit = bitPosition % 8; char byte = eBinary[bytePosition]; isBitSet = byte & (1 << bit); } if (!needFurtherBitTests(isBitSet)) { // If we can skip the rest fo the tests, that means we succeeded with _ANY_ or failed // with _ALL_. return mt == BITS_ANY_SET || mt == BITS_ANY_CLEAR; } } // If we finished all the tests, that means we succeeded with _ALL_ or failed with _ANY_. return mt == BITS_ALL_SET || mt == BITS_ALL_CLEAR; }
bool BitTestMatchExpression::performBitTest(long long eValue) const { const MatchType mt = matchType(); // Test each bit position. for (auto bitPosition : _bitPositions) { bool isBitSet; if (bitPosition >= 63) { // If position to test is longer than 64 bits, sign-extend. isBitSet = eValue < 0; } else { isBitSet = eValue & (1LL << bitPosition); } if (!needFurtherBitTests(isBitSet)) { // If we can skip the rest of the tests, that means we succeeded with _ANY_ or failed // with _ALL_. return mt == BITS_ANY_SET || mt == BITS_ANY_CLEAR; } } // If we finished all the tests, that means we succeeded with _ALL_ or failed with _ANY_. return mt == BITS_ALL_SET || mt == BITS_ALL_CLEAR; }