11/// <summary>
2- /// Helper for matching patterns in StringBuilder that may span across chunk boundaries.
2+ /// Helper for matching and replacing patterns in StringBuilder that may span across chunk boundaries.
33/// </summary>
44static class CrossChunkMatcher
55{
66 /// <summary>
7- /// Iterates through StringBuilder chunks, invoking callbacks for potential matches
8- /// both within chunks and spanning chunk boundaries.
7+ /// Finds all matches in a StringBuilder (handling patterns spanning chunk boundaries) and applies replacements.
98 /// </summary>
10- /// <param name="builder">The StringBuilder to search</param>
9+ /// <param name="builder">The StringBuilder to search and modify </param>
1110 /// <param name="carryoverSize">Size of carryover buffer (typically maxPatternLength - 1)</param>
1211 /// <param name="context">User context passed to callbacks</param>
1312 /// <param name="onCrossChunk">Called for each potential cross-chunk match position</param>
1413 /// <param name="onWithinChunk">Called for each position within a chunk</param>
15- public static void ProcessChunks < TContext > (
14+ /// <param name="getMatches">Retrieves the list of matches from the context</param>
15+ /// <param name="getIndex">Gets the start index from a match</param>
16+ /// <param name="getLength">Gets the original length from a match</param>
17+ /// <param name="getValue">Gets the replacement value from a match</param>
18+ public static void ReplaceAll < TContext , TMatch > (
1619 StringBuilder builder ,
1720 int carryoverSize ,
1821 TContext context ,
1922 CrossChunkHandler < TContext > onCrossChunk ,
20- WithinChunkHandler < TContext > onWithinChunk )
23+ WithinChunkHandler < TContext > onWithinChunk ,
24+ Func < TContext , List < TMatch > > getMatches ,
25+ Func < TMatch , int > getIndex ,
26+ Func < TMatch , int > getLength ,
27+ Func < TMatch , string > getValue )
2128 {
2229 Span < char > carryoverBuffer = stackalloc char [ carryoverSize ] ;
2330 var carryoverLength = 0 ;
@@ -63,18 +70,9 @@ public static void ProcessChunks<TContext>(
6370 previousChunkAbsoluteEnd = absolutePosition + chunk . Length ;
6471 absolutePosition += chunk . Length ;
6572 }
66- }
6773
68- /// <summary>
69- /// Applies matches to a StringBuilder in descending position order.
70- /// </summary>
71- public static void ApplyMatches < TMatch > (
72- StringBuilder builder ,
73- List < TMatch > matches ,
74- Func < TMatch , int > getIndex ,
75- Func < TMatch , int > getLength ,
76- Func < TMatch , string > getValue )
77- {
74+ // Apply matches in descending position order
75+ var matches = getMatches ( context ) ;
7876 foreach ( var match in matches . OrderByDescending ( getIndex ) )
7977 {
8078 builder . Overwrite ( getValue ( match ) , getIndex ( match ) , getLength ( match ) ) ;
@@ -84,13 +82,6 @@ public static void ApplyMatches<TMatch>(
8482 /// <summary>
8583 /// Callback for processing potential cross-chunk matches.
8684 /// </summary>
87- /// <param name="builder">The StringBuilder being processed</param>
88- /// <param name="carryoverBuffer">Buffer containing end of previous chunk</param>
89- /// <param name="carryoverIndex">Starting index within carryover buffer</param>
90- /// <param name="remainingInCarryover">Characters remaining from carryoverIndex to end</param>
91- /// <param name="currentChunkSpan">Span of the current chunk</param>
92- /// <param name="absoluteStartPosition">Absolute position in StringBuilder where potential match starts</param>
93- /// <param name="context">User context</param>
9485 public delegate void CrossChunkHandler < TContext > (
9586 StringBuilder builder ,
9687 Span < char > carryoverBuffer ,
@@ -103,11 +94,6 @@ public delegate void CrossChunkHandler<TContext>(
10394 /// <summary>
10495 /// Callback for processing positions within a chunk.
10596 /// </summary>
106- /// <param name="chunk">The current chunk memory</param>
107- /// <param name="chunkSpan">Span of the current chunk</param>
108- /// <param name="chunkIndex">Current index within the chunk</param>
109- /// <param name="absoluteIndex">Absolute position in StringBuilder</param>
110- /// <param name="context">User context</param>
11197 /// <returns>Number of positions to skip ahead (0 or 1 for normal iteration, more to skip past a match)</returns>
11298 public delegate int WithinChunkHandler < TContext > (
11399 ReadOnlyMemory < char > chunk ,
0 commit comments