// TODO https://github.com/dotnet/runtime/issues/62573: Obsolete this. /// <summary> /// This method's body is only kept since it is a protected member that could be called by someone outside /// the assembly. /// </summary> protected internal Match?Scan(Regex regex, string text, int textbeg, int textend, int textstart, int prevlen, bool quick, TimeSpan timeout) { InitializeTimeout(timeout); RegexRunnerMode mode = quick ? RegexRunnerMode.ExistenceRequired : RegexRunnerMode.FullMatchRequired; // We set runtext before calling InitializeForScan so that runmatch object is initialized with the text runtext = text; InitializeForScan(regex, text, textstart, mode); // InitializeForScan will default runtextstart and runtextend to 0 and length of string // since it is configured to work over a sliced portion of text so we adjust those values. runtextstart = textstart; runtextend = textend; // Configure the additional value to "bump" the position along each time we loop around // to call FindFirstChar again, as well as the stopping position for the loop. We generally // bump by 1 and stop at textend, but if we're examining right-to-left, we instead bump // by -1 and stop at textbeg. int bump = 1, stoppos = textend; if (regex.RightToLeft) { bump = -1; stoppos = textbeg; } // If previous match was empty or failed, advance by one before matching. if (prevlen == 0) { if (textstart == stoppos) { return(Match.Empty); } runtextpos += bump; } Match match = InternalScan(regex, textbeg, textend); runtext = null; //drop reference if (match.FoundMatch) { if (quick) { return(null); } runmatch = null; match.Tidy(runtextpos, 0, mode); } else { runmatch !.Text = null; } return(match); }
internal void InitializeForScan(Regex regex, ReadOnlySpan <char> text, int textstart, RegexRunnerMode mode) { // Store remaining arguments into fields now that we're going to start the scan. // These are referenced by the derived runner. _mode = mode; runregex = regex; runtextstart = textstart; runtextbeg = 0; runtextend = text.Length; runtextpos = textstart; Match?m = runmatch; if (m is null) { // Use a hashtabled Match object if the capture numbers are sparse runmatch = runregex !.caps is null ? new Match(runregex, runregex.capsize, runtext, text.Length) : new MatchSparse(runregex, runregex.caps, runregex.capsize, runtext, text.Length); } else { m.Reset(runtext, text.Length); } // Note we test runcrawl, because it is the last one to be allocated // If there is an alloc failure in the middle of the three allocations, // we may still return to reuse this instance, and we want to behave // as if the allocations didn't occur. if (runcrawl != null) { runtrackpos = runtrack !.Length; runstackpos = runstack !.Length; runcrawlpos = runcrawl.Length; return; } // Everything above runs once per match. // Everything below runs once per runner. InitTrackCount(); int stacksize; int tracksize = stacksize = runtrackcount * 8; if (tracksize < 32) { tracksize = 32; } if (stacksize < 16) { stacksize = 16; } runtrack = new int[tracksize]; runtrackpos = tracksize; runstack = new int[stacksize]; runstackpos = stacksize; runcrawl = new int[32]; runcrawlpos = 32; }