Ejemplo n.º 1
0
        // 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);
        }
Ejemplo n.º 2
0
        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;
        }