public void ReplaceMarks(TextOccurences occurences, int start, int end, int tailOffset) { if (occurences == null) { throw new ArgumentNullException("occurences"); } lock (_marksSyncRoot) { if (_positions == null) { ReplaceMarks(occurences); return; } Treap markThatContainsStart = FindMarkThatContainsPosition(_positions, start); if (markThatContainsStart != null) { start = markThatContainsStart.x; } Treap right = null; Treap garbage = null; _positions.Split(start - 1, out _positions, out right); if (right != null) { right.Split(end, out garbage, out right); } if (garbage != null) { garbage.ForEachInOrder(IncludeTextToScreenUpdate); } if (occurences != TextOccurences.Empty && occurences.Count > 0) { _markLength = occurences.TextLength; occurences.Positions.ForEachInOrder(IncludeTextToScreenUpdate); _positions = Treap.Merge(_positions, occurences.Positions); } if (right != null) { TreapBuilder shiftedMarks = new TreapBuilder(); right.ForEachInOrder((x) => { shiftedMarks.Add(x + tailOffset); }); _positions = Treap.Merge(_positions, shiftedMarks.ToTreap()); } } }
public TextOccurences SearchOccurrencesInText(string text, int searchStart, int searchEnd) { int textLength = text.Length; int sampleLength = _sample.Length; //Make sure, that the search range is not out of the text searchStart = Math.Max(0, searchStart); searchEnd = Math.Min(searchEnd, textLength); var positions = new TreapBuilder(); /* Searching */ var comparsion = (_caseSensitiveSearch ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase); int searchLoopEnd = Math.Min(searchEnd, text.Length) - (sampleLength - 1); for (int i = searchStart; i < searchLoopEnd;) { if (text.Substring(i, sampleLength).StartsWith(_sample, comparsion)) { bool occurrenceFound = true; if (_searchWholeWordsOnly) { int previousCharIndex = i - 1; int nextCharIndex = i + sampleLength; bool isPreviousCharPartOfWord = previousCharIndex >= 0 && IsWordCharacter(text[previousCharIndex]); bool isNextCharPartOfWord = nextCharIndex < textLength && IsWordCharacter(text[nextCharIndex]); occurrenceFound = !isPreviousCharPartOfWord && !isNextCharPartOfWord; } if (occurrenceFound) { positions.Add(i); } //Don't search inside a found substring (no crossed search marks). i += sampleLength; continue; } if (i + sampleLength >= searchEnd) { break; } int key = text[i + sampleLength]; if (_badChars.ContainsKey(key)) { i += _badChars[key]; } else { i += sampleLength + 1; } } return(new TextOccurences(_sample, positions)); }
public void ReplaceMarks(TextOccurences occurences, int start, int end, int tailOffset) { if (occurences == null) throw new ArgumentNullException("occurences"); lock (_marksSyncRoot) { if (_positions == null) { ReplaceMarks(occurences); return; } Treap markThatContainsStart = FindMarkThatContainsPosition(_positions, start); if (markThatContainsStart != null) { start = markThatContainsStart.x; } Treap right = null; Treap garbage = null; _positions.Split(start - 1, out _positions, out right); if (right != null) { right.Split(end, out garbage, out right); } if (garbage != null) { garbage.ForEachInOrder(IncludeTextToScreenUpdate); } if (occurences != TextOccurences.Empty && occurences.Count > 0) { _markLength = occurences.TextLength; occurences.Positions.ForEachInOrder(IncludeTextToScreenUpdate); _positions = Treap.Merge(_positions, occurences.Positions); } if (right != null) { TreapBuilder shiftedMarks = new TreapBuilder(); right.ForEachInOrder((x) => { shiftedMarks.Add(x + tailOffset); }); _positions = Treap.Merge(_positions, shiftedMarks.ToTreap()); } } }