HexPosition?FindCore(SearchState state, HexPosition start, HexPosition upperBounds) { var patternLocal = pattern; var maskLocal = mask; var pos = start; if (pos + patternLocal.LongLength > upperBounds) { return(null); } var endPos = upperBounds - patternLocal.LongLength + 1; state.SetPosition(pos); var patternLocal0 = patternLocal[0]; var maskLocal0 = maskLocal[0]; var patternLocal1 = patternLocal.Length <= 1 ? 0 : patternLocal[1]; var maskLocal1 = maskLocal.Length <= 1 ? 0 : maskLocal[1]; var maskLocalLengthIsAtLeast2 = maskLocal.Length >= 2; loop: // This loop doesn't check the cancellation token because SearchState does that // every time it reads new memory from the buffer. if (pos >= endPos) { return(null); } int skip; HexPosition?afterPos; if (maskLocalLengthIsAtLeast2) { skip = 2; afterPos = maskLocal0 == 0xFF ? state.PositionAfter2(patternLocal0, patternLocal1, maskLocal1, endPos) : state.PositionAfterWithMask2(patternLocal0, patternLocal1, maskLocal0, maskLocal1, endPos); } else if (maskLocal0 == 0xFF) { skip = 1; afterPos = state.PositionAfter1(patternLocal0, endPos); } else { skip = 1; afterPos = state.PositionAfterWithMask1(patternLocal0, maskLocal0, endPos); } if (afterPos == null) { return(null); } pos = afterPos.Value; for (int i = skip; i < patternLocal.Length; i++) { var b = state.GetNextByte(); var m = maskLocal[i]; if ((b & m) != patternLocal[i]) { pos = pos - (skip - 1); state.SetPosition(pos); goto loop; } } return(pos - skip); }
HexPosition?FindCore(SearchState state, HexPosition start, HexPosition upperBounds) { var charLengthsLocal = charLengths; var lowerBytesLocal = lowerBytes; var upperBytesLocal = upperBytes; var pos = start; if (pos + lowerBytesLocal.LongLength > upperBounds) { return(null); } var endPos = upperBounds - lowerBytesLocal.LongLength + 1; state.SetPosition(pos); var lowerBytesLocal0 = lowerBytesLocal[0]; var upperBytesLocal0 = upperBytesLocal[0]; var lowerBytesLocal1 = lowerBytesLocal.Length <= 1 ? 0 : lowerBytesLocal[1]; var upperBytesLocal1 = upperBytesLocal.Length <= 1 ? 0 : upperBytesLocal[1]; var lowerBytesLocalLengthIsAtLeast2 = lowerBytesLocal.Length >= 2; loop: // This loop doesn't check the cancellation token because SearchState does that // every time it reads new memory from the buffer. if (pos >= endPos) { return(null); } int skip; HexPosition?afterPos; if (lowerBytesLocalLengthIsAtLeast2) { skip = 2; afterPos = state.PositionAfter2(lowerBytesLocal0, upperBytesLocal0, lowerBytesLocal1, upperBytesLocal1, endPos); } else { skip = 1; afterPos = state.PositionAfter1(lowerBytesLocal0, upperBytesLocal0, endPos); } if (afterPos == null) { return(null); } pos = afterPos.Value - skip; state.SetPosition(pos); for (int i = 0, bi = 0; i < charLengthsLocal.Length; i++) { int charByteLen = charLengthsLocal[i]; bool upperMatch = true; bool lowerMatch = true; for (int j = 0; j < charByteLen; j++, bi++) { var b = state.GetNextByte(); upperMatch &= b == upperBytesLocal[bi]; lowerMatch &= b == lowerBytesLocal[bi]; } if (!upperMatch && !lowerMatch) { pos = pos + 1; state.SetPosition(pos); goto loop; } } return(pos); }