HexPosition?FindCoreReverse(SearchState state, HexPosition start, HexPosition lowerBounds) { var patternLocal = pattern; var maskLocal = mask; var pos = start; state.SetPreviousPosition(pos); var patternLocal0 = patternLocal[patternLocal.Length - 1]; var maskLocal0 = maskLocal[maskLocal.Length - 1]; var patternLocal1 = patternLocal.Length <= 1 ? 0 : patternLocal[patternLocal.Length - 2]; var maskLocal1 = maskLocal.Length <= 1 ? 0 : maskLocal[maskLocal.Length - 2]; 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 < lowerBounds) { return(null); } int skip; HexPosition?beforePos; if (maskLocalLengthIsAtLeast2) { skip = 2; beforePos = maskLocal0 == 0xFF ? state.PositionBefore2(patternLocal0, patternLocal1, maskLocal1, lowerBounds) : state.PositionBeforeWithMask2(patternLocal0, patternLocal1, maskLocal0, maskLocal1, lowerBounds); } else if (maskLocal0 == 0xFF) { skip = 1; beforePos = state.PositionBefore1(patternLocal0, lowerBounds); } else { skip = 1; beforePos = state.PositionBeforeWithMask1(patternLocal0, maskLocal0, lowerBounds); } if (beforePos == null) { return(null); } pos = beforePos.Value; for (int i = patternLocal.Length - 1 - skip; i >= 0; i--) { var b = state.GetPreviousByte(); var m = maskLocal[i]; if ((b & m) != patternLocal[i]) { pos = pos + (skip - 1); state.SetPreviousPosition(pos); goto loop; } } return(pos - (patternLocal.LongLength - skip - 1)); }
HexPosition?FindCoreReverse(SearchState state, HexPosition start, HexPosition lowerBounds) { var charLengthsLocal = charLengths; var lowerBytesLocal = lowerBytes; var upperBytesLocal = upperBytes; var pos = start; state.SetPreviousPosition(pos); var lowerBytesLocal0 = lowerBytesLocal[lowerBytesLocal.Length - 1]; var upperBytesLocal0 = upperBytesLocal[upperBytesLocal.Length - 1]; var lowerBytesLocal1 = lowerBytesLocal.Length <= 1 ? 0 : lowerBytesLocal[lowerBytesLocal.Length - 2]; var upperBytesLocal1 = upperBytesLocal.Length <= 1 ? 0 : upperBytesLocal[upperBytesLocal.Length - 2]; 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 < lowerBounds) { return(null); } int skip; HexPosition?beforePos; if (lowerBytesLocalLengthIsAtLeast2) { skip = 2; beforePos = state.PositionBefore2(lowerBytesLocal0, upperBytesLocal0, lowerBytesLocal1, upperBytesLocal1, lowerBounds); } else { skip = 1; beforePos = state.PositionBefore1(lowerBytesLocal0, upperBytesLocal0, lowerBounds); } if (beforePos == null) { return(null); } pos = beforePos.Value + skip; state.SetPreviousPosition(pos); for (int i = charLengthsLocal.Length - 1, bi = lowerBytesLocal.Length - 1; i >= 0; i--) { int charByteLen = charLengthsLocal[i]; bool upperMatch = true; bool lowerMatch = true; for (int j = 0; j < charByteLen; j++, bi--) { var b = state.GetPreviousByte(); upperMatch &= b == upperBytesLocal[bi]; lowerMatch &= b == lowerBytesLocal[bi]; } if (!upperMatch && !lowerMatch) { // pos can't be 0 here since skip != 0, see above pos = pos - 1; state.SetPreviousPosition(pos); goto loop; } } return(pos - (lowerBytesLocal.LongLength - 1)); }