Example #1
0
        /// <summary>
        /// Implement <see cref="IUnicodeMatcher"/>
        /// </summary>
        public virtual MatchDegree Matches(IReplaceable text,
                                           int[] offset,
                                           int limit,
                                           bool incremental)
        {
            // Note (1): We process text in 16-bit code units, rather than
            // 32-bit code points.  This works because stand-ins are
            // always in the BMP and because we are doing a literal match
            // operation, which can be done 16-bits at a time.
            int i;

            int[] cursor = new int[] { offset[0] };
            if (limit < cursor[0])
            {
                // Match in the reverse direction
                for (i = pattern.Length - 1; i >= 0; --i)
                {
                    char            keyChar = pattern[i]; // OK; see note (1) above
                    IUnicodeMatcher subm    = data.LookupMatcher(keyChar);
                    if (subm == null)
                    {
                        if (cursor[0] > limit &&
                            keyChar == text[cursor[0]])
                        { // OK; see note (1) above
                            --cursor[0];
                        }
                        else
                        {
                            return(MatchDegree.Mismatch);
                        }
                    }
                    else
                    {
                        MatchDegree m =
                            subm.Matches(text, cursor, limit, incremental);
                        if (m != MatchDegree.Match)
                        {
                            return(m);
                        }
                    }
                }
                // Record the match position, but adjust for a normal
                // forward start, limit, and only if a prior match does not
                // exist -- we want the rightmost match.
                if (matchStart < 0)
                {
                    matchStart = cursor[0] + 1;
                    matchLimit = offset[0] + 1;
                }
            }
            else
            {
                for (i = 0; i < pattern.Length; ++i)
                {
                    if (incremental && cursor[0] == limit)
                    {
                        // We've reached the context limit without a mismatch and
                        // without completing our match.
                        return(MatchDegree.PartialMatch);
                    }
                    char            keyChar = pattern[i]; // OK; see note (1) above
                    IUnicodeMatcher subm    = data.LookupMatcher(keyChar);
                    if (subm == null)
                    {
                        // Don't need the cursor < limit check if
                        // incremental is true (because it's done above); do need
                        // it otherwise.
                        if (cursor[0] < limit &&
                            keyChar == text[cursor[0]])
                        { // OK; see note (1) above
                            ++cursor[0];
                        }
                        else
                        {
                            return(MatchDegree.Mismatch);
                        }
                    }
                    else
                    {
                        MatchDegree m =
                            subm.Matches(text, cursor, limit, incremental);
                        if (m != MatchDegree.Match)
                        {
                            return(m);
                        }
                    }
                }
                // Record the match position
                matchStart = offset[0];
                matchLimit = cursor[0];
            }

            offset[0] = cursor[0];
            return(MatchDegree.Match);
        }