IEnumerable <HexBufferSpan> FindAllCore(SearchState state, HexSpan span, HexFindOptions options) { var pos = span.Start; if (pos + pattern.LongLength > span.End) { yield break; } var endPos = span.End - pattern.LongLength + 1; while (pos < endPos) { state.CancellationToken.ThrowIfCancellationRequested(); var result = FindCore(state, pos, span.End); if (result == null) { break; } yield return(new HexBufferSpan(state.Buffer, new HexSpan(result.Value, (ulong)pattern.LongLength))); if ((options & HexFindOptions.NoOverlaps) != 0) { pos = result.Value + (ulong)pattern.LongLength; } else { // We must return all possible matches. If we search for 1111 and data is // 11111111, we must return positions 0, 1, 2, and not 0, 2. pos = result.Value + 1; } } }
public FindAllCoreEnumerable(ByteHexSearchService owner, HexBufferSpan searchRange, HexBufferPoint startingPosition, HexFindOptions options, CancellationToken cancellationToken) { this.owner = owner; this.searchRange = searchRange; this.startingPosition = startingPosition; this.options = options; this.cancellationToken = cancellationToken; }
/// <summary> /// Finds the pattern /// </summary> /// <param name="startingPosition">Starting position</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public HexBufferSpan?Find(HexBufferPoint startingPosition, HexFindOptions options, CancellationToken cancellationToken) { if (startingPosition.IsDefault) { throw new ArgumentException(); } var buffer = startingPosition.Buffer; return(Find(new HexBufferSpan(buffer, buffer.Span), startingPosition, options, cancellationToken)); }
IEnumerable <HexBufferSpan> FindAllCoreReverse(SearchState state, HexSpan span, HexFindOptions options) { if (span.Length < pattern.LongLength) { yield break; } var lowerBounds = span.Start + pattern.LongLength - 1; var pos = span.End - 1; while (pos >= lowerBounds) { state.CancellationToken.ThrowIfCancellationRequested(); var result = FindCoreReverse(state, pos, lowerBounds); if (result == null) { break; } yield return(new HexBufferSpan(state.Buffer, new HexSpan(result.Value, (ulong)pattern.LongLength))); if ((options & HexFindOptions.NoOverlaps) != 0) { if (result.Value == HexPosition.Zero) { break; } pos = result.Value - 1; } else { // We must return all possible matches. If we search for 1111 and data is // 11111111, we must return positions 3, 2, 1, and not 3, 1 pos = result.Value + (pattern.LongLength - 1); if (pos == HexPosition.Zero) { break; } pos = pos - 1; } } }
IEnumerable <HexBufferSpan> FindAllCoreReverse(SearchState state, HexBufferSpan searchRange, HexBufferPoint startingPosition, HexFindOptions options, CancellationToken cancellationToken) { HexBufferSpan?firstBlockResult = null; foreach (var span in GetValidSpansReverse(startingPosition.Buffer, startingPosition, searchRange.Start)) { cancellationToken.ThrowIfCancellationRequested(); foreach (var span2 in FindAllCoreReverse(state, span, options)) { if (firstBlockResult == null) { firstBlockResult = span2; } yield return(span2); } } if ((options & HexFindOptions.Wrap) != 0) { var lowerBounds = startingPosition.Position >= pattern.LongLength - 1 ? startingPosition.Position - (pattern.LongLength - 1) : HexPosition.Zero; if (lowerBounds < searchRange.Span.Start) { lowerBounds = searchRange.Span.Start; } if ((options & HexFindOptions.NoOverlaps) != 0 && firstBlockResult != null && lowerBounds < firstBlockResult.Value.End) { lowerBounds = firstBlockResult.Value.End; } foreach (var span in GetValidSpansReverse(startingPosition.Buffer, searchRange.End - 1, lowerBounds)) { cancellationToken.ThrowIfCancellationRequested(); foreach (var span2 in FindAllCoreReverse(state, span, options)) { yield return(span2); } } } }
public override IEnumerable <HexBufferSpan> FindAll(HexBufferSpan searchRange, HexBufferPoint startingPosition, HexFindOptions options, CancellationToken cancellationToken) { if (searchRange.IsDefault) { throw new ArgumentException(); } if (searchRange.Buffer != startingPosition.Buffer) { throw new ArgumentException(); } if (startingPosition < searchRange.Start || startingPosition > searchRange.End) { throw new ArgumentException(); } if (searchRange.IsEmpty) { return(Array.Empty <HexBufferSpan>()); } return(new FindAllCoreEnumerable(this, searchRange, startingPosition, options, cancellationToken)); }
IEnumerable <HexBufferSpan> FindAllCore(SearchState state, HexBufferSpan searchRange, HexBufferPoint startingPosition, HexFindOptions options, CancellationToken cancellationToken) { HexBufferSpan?firstBlockResult = null; foreach (var span in GetValidSpans(startingPosition.Buffer, startingPosition, searchRange.End)) { cancellationToken.ThrowIfCancellationRequested(); foreach (var span2 in FindAllCore(state, span, options)) { if (firstBlockResult == null) { firstBlockResult = span2; } yield return(span2); } } if ((options & HexFindOptions.Wrap) != 0) { var upperBounds = HexPosition.Min(searchRange.Span.End, startingPosition.Position + pattern.LongLength - 1); if ((options & HexFindOptions.NoOverlaps) != 0 && firstBlockResult != null && upperBounds > firstBlockResult.Value.Start) { upperBounds = firstBlockResult.Value.Start; } foreach (var span in GetValidSpans(startingPosition.Buffer, searchRange.Start, upperBounds)) { cancellationToken.ThrowIfCancellationRequested(); foreach (var span2 in FindAllCore(state, span, options)) { yield return(span2); } } } }
/// <summary> /// Finds all matches /// </summary> /// <param name="searchRange">Search range</param> /// <param name="startingPosition">Starting position</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public abstract IEnumerable <HexBufferSpan> FindAll(HexBufferSpan searchRange, HexBufferPoint startingPosition, HexFindOptions options, CancellationToken cancellationToken);
/// <summary> /// Finds all matches /// </summary> /// <param name="searchRange">Search range</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public IEnumerable <HexBufferSpan> FindAll(HexBufferSpan searchRange, HexFindOptions options, CancellationToken cancellationToken) => FindAll(searchRange, searchRange.Start, options, cancellationToken);
/// <summary> /// Finds the pattern /// </summary> /// <param name="searchRange">Search range</param> /// <param name="startingPosition">Starting position</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public HexBufferSpan?Find(HexBufferSpan searchRange, HexBufferPoint startingPosition, HexFindOptions options, CancellationToken cancellationToken) { foreach (var span in FindAll(searchRange, startingPosition, options, cancellationToken)) { return(span); } return(null); }
/// <summary> /// Finds all matches /// </summary> /// <param name="searchRange">Search range</param> /// <param name="startingPosition">Starting position</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public abstract IEnumerable<HexBufferSpan> FindAll(HexBufferSpan searchRange, HexBufferPoint startingPosition, HexFindOptions options, CancellationToken cancellationToken);
/// <summary> /// Finds all matches /// </summary> /// <param name="searchRange">Search range</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public IEnumerable<HexBufferSpan> FindAll(HexBufferSpan searchRange, HexFindOptions options, CancellationToken cancellationToken) => FindAll(searchRange, searchRange.Start, options, cancellationToken);
/// <summary> /// Finds the pattern /// </summary> /// <param name="searchRange">Search range</param> /// <param name="startingPosition">Starting position</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public HexBufferSpan? Find(HexBufferSpan searchRange, HexBufferPoint startingPosition, HexFindOptions options, CancellationToken cancellationToken) { foreach (var span in FindAll(searchRange, startingPosition, options, cancellationToken)) return span; return null; }
/// <summary> /// Finds the pattern /// </summary> /// <param name="startingPosition">Starting position</param> /// <param name="options">Options</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns></returns> public HexBufferSpan? Find(HexBufferPoint startingPosition, HexFindOptions options, CancellationToken cancellationToken) { if (startingPosition.IsDefault) throw new ArgumentException(); var buffer = startingPosition.Buffer; return Find(new HexBufferSpan(buffer, buffer.Span), startingPosition, options, cancellationToken); }