private unsafe List<TextRange> FindWorker( TextFragment textFragment, Func<TextRange, TextRange?> postProcess, IOperationProgressTracker progressTracker, int maxResultSize) { List<TextRange> result = null; // Note: From C# spec: If E is zero, then no allocation is made, and // the pointer returned is implementation-defined. byte* searchBuffer = stackalloc byte[this.SearchBufferSize]; var searchParams = new NativeMethods.SearchParams { TextStart = textFragment.StartPtr, TextLength = textFragment.Length, SearchBuffer = new IntPtr(searchBuffer), }; while (true) { // Perform next search Search(ref searchParams); if (searchParams.MatchStart == IntPtr.Zero) break; // Convert match from *byte* pointers to a *text* range var matchFragment = textFragment.Sub(searchParams.MatchStart, searchParams.MatchLength); var matchRange = new TextRange(matchFragment.Position, matchFragment.Length); // Post process match, maybe skipping it var postMatchRange = postProcess(matchRange); if (postMatchRange == null) continue; matchRange = postMatchRange.Value; // Add to result collection if (result == null) result = new List<TextRange>(); result.Add(matchRange); // Check it is time to end processing early. maxResultSize--; progressTracker.AddResults(1); if (maxResultSize <= 0 || progressTracker.ShouldEndProcessing) { CancelSearch(ref searchParams); break; } } return result ?? NoResult; }
public TextRange? FindFirst(TextFragment textFragment, IOperationProgressTracker progressTracker) { return null; }
public IList<TextRange> FindAll( TextFragment textFragment, Func<TextRange, TextRange?> postProcess, IOperationProgressTracker progressTracker) { return NoResult; }
public TextRange? FindFirst(TextFragment textFragment, IOperationProgressTracker progressTracker) { var result = FindWorker(textFragment, x => x, progressTracker, 1); if (result.Count == 0) return null; return result.First(); }
public IList<TextRange> FindAll(TextFragment textFragment, Func<TextRange, TextRange?> postProcess, IOperationProgressTracker progressTracker) { if (progressTracker.ShouldEndProcessing) return NoResult; return FindWorker(textFragment, postProcess, progressTracker, int.MaxValue); }