protected override void Search(ref NativeMethods.SearchParams searchParams) { var start = searchParams.TextStart; if (searchParams.MatchStart != IntPtr.Zero) { start = searchParams.MatchStart + searchParams.MatchLength * sizeof(char); } var end = searchParams.TextStart + searchParams.TextLength * sizeof(char); var count = Pointers.Offset64(start, end) / sizeof(char); var searchHitPtr = NativeMethods.Utf16_Search( start, count, _patternPtr.Pointer, _patternLength, _searchOptions); if (searchHitPtr == IntPtr.Zero) { searchParams.MatchStart = IntPtr.Zero; searchParams.MatchLength = 0; } else { searchParams.MatchStart = searchHitPtr; searchParams.MatchLength = _patternLength; } }
/// <summary> /// Return a new fragment starting at <paramref name="startPtr"/> /// and containing <paramref name="count"/> characters. /// </summary> public TextFragment Sub(IntPtr startPtr, int count) { var byteOffset = Pointers.Offset32(_textPtr, startPtr); if (byteOffset < 0 || (byteOffset % _characterSize) != 0) { ThrowArgumentException(); } return(Sub(byteOffset / _characterSize, count)); }
/// <summary> /// Find all occurrences of the pattern in the text block starting at /// |<paramref name="textPtr"/>| and containing |<paramref name="textLen"/>| /// characters. /// </summary> public IEnumerable <FilePositionSpan> SearchAll(IntPtr textPtr, int textLen) { var currentPtr = textPtr; var remainingLength = textLen; while (true) { currentPtr = Search(currentPtr, remainingLength); if (currentPtr == IntPtr.Zero) { break; } // TODO(rpaquay): We are limited to 2GB for now. var offset = Pointers.Offset32(textPtr, currentPtr); yield return(new FilePositionSpan { Position = offset, Length = PatternLength }); currentPtr += PatternLength; remainingLength = textLen - offset - PatternLength; } }