Beispiel #1
0
    /// <summary>
    /// Find all instances of the search pattern stored in <paramref
    /// name="compiledTextSearchData"/> within the passed in <paramref
    /// name="textRange"/>
    /// </summary>
    public IList<TextRange> FindAll(
      CompiledTextSearchData compiledTextSearchData,
      TextRange textRange,
      IOperationProgressTracker progressTracker) {

      var textFragment = CreateFragmentFromRange(textRange);
      var providerForMainEntry = compiledTextSearchData
        .GetSearchContainer(compiledTextSearchData.ParsedSearchString.MainEntry);
      var textSearch = GetCompiledTextSearch(providerForMainEntry);
      var postProcessSearchHit = CreateFilterForOtherEntries(compiledTextSearchData);
      var result = textSearch.FindAll(textFragment, postProcessSearchHit, progressTracker);
      return result;
    }
    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? FilterSearchHit(TextRange match) {
      var lineExtentStart = _getLineExtentCache.GetLineExtent(match.Position);
      var lineExtentEnd = _getLineExtentCache.GetLineExtent(match.EndPosition);
      var lineExtent = new TextRange(
        lineExtentStart.Position,
        lineExtentEnd.EndPosition - lineExtentStart.Position);
      if (_previousMatch.HasValue) {
        // If match overlaps with previous one, fail
        if (match.Position < _previousMatch.Value.EndPosition) {
          return null;
        }
        // If line extent overlaps with previous match, shrink it.
        if (lineExtent.Position < _previousMatch.Value.EndPosition) {
          lineExtent = new TextRange(
            _previousMatch.Value.EndPosition,
            lineExtent.EndPosition - _previousMatch.Value.EndPosition);
        }
      }
      // We got the line extent, the offset at which we found the MainEntry.
      // Now we need to check that "OtherEntries" are present (in order) and
      // in appropriate intervals.
      var range1 = new TextRange(
        lineExtent.Position,
        match.Position - lineExtent.Position);
      var entriesInterval1 = _parsedSearchString.EntriesBeforeMainEntry;
      var foundRange1 = entriesInterval1.Any()
        ? CheckEntriesInRange(range1, entriesInterval1)
        : match;

      var range2 = new TextRange(
        match.EndPosition,
        lineExtent.EndPosition - match.EndPosition);
      var entriesInterval2 = _parsedSearchString.EntriesAfterMainEntry;
      var foundRange2 = entriesInterval2.Any()
        ? CheckEntriesInRange(range2, entriesInterval2)
        : match;

      if (foundRange1.HasValue && foundRange2.HasValue) {
        var newMatch = new TextRange(
          foundRange1.Value.Position,
          foundRange2.Value.EndPosition - foundRange1.Value.Position);
        // Save the this match for next iteration
        _previousMatch = newMatch;
        return newMatch;
      }
      return null;
    }
Beispiel #4
0
 public FileContentsPiece CreatePiece(FileName fileName, int fileId, TextRange range) {
   return new FileContentsPiece(fileName, this, fileId, range);
 }
Beispiel #5
0
 private TextFragment CreateFragmentFromRange(TextRange textRange) {
   return TextFragment.Sub(textRange.Position, textRange.Length);
 }
 public FileContentsPiece(FileName fileName, FileContents fileContents, int fileId, TextRange textRange) {
   _fileName = fileName;
   _fileContents = fileContents;
   _fileId = fileId;
   _textRange = textRange;
 }
        /// <summary>
        ///  Create chunks of 100KB for files larger than 100KB.
        /// </summary>
        private static IEnumerable<FileContentsPiece> SplitFileContents(FileData fileData, int fileId)
        {
            var range = fileData.Contents.TextRange;
              while (range.Length > 0) {
            // TODO(rpaquay): Be smarter and split around new lines characters.
            var chunkLength = Math.Min(range.Length, ChunkSize);
            var chunk = new TextRange(range.Position, chunkLength);
            yield return fileData.Contents.CreatePiece(fileData.FileName, fileId, chunk);

            range = new TextRange(chunk.EndPosition, range.EndPosition - chunk.EndPosition);
              }
        }
    private TextRange? CheckEntriesInRange(
      TextRange textRange,
      IEnumerable<ParsedSearchString.Entry> entries) {
      TextRange? result = null;
      foreach (var entry in entries) {
        var entryRange = _findEntry(textRange, entry);
        if (entryRange == null) {
          return null;
        }

        var newOffset = entryRange.Value.EndPosition;
        textRange = new TextRange(newOffset, textRange.EndPosition - newOffset);

        if (result == null) {
          result = entryRange;
        } else {
          result = new TextRange(result.Value.Position, newOffset - result.Value.Position);
        }
      }
      return result;
    }