示例#1
0
        /// <summary>
        /// Transliterate the given text with the given UTransPosition
        /// indices.  Return TRUE if the transliteration should continue
        /// or FALSE if it should halt (because of a U_PARTIAL_MATCH match).
        /// Note that FALSE is only ever returned if isIncremental is TRUE.
        /// </summary>
        /// <param name="text">The text to be transliterated.</param>
        /// <param name="pos">The position indices, which will be updated.</param>
        /// <param name="incremental">If TRUE, assume new text may be inserted
        /// at index.Limit, and return FALSE if thre is a partial match.</param>
        /// <returns>TRUE unless a U_PARTIAL_MATCH has been obtained,
        /// indicating that transliteration should stop until more text
        /// arrives.</returns>
        public virtual bool Transliterate(IReplaceable text,
                                          TransliterationPosition pos,
                                          bool incremental)
        {
            int indexByte = text.Char32At(pos.Start) & 0xFF;

            for (int i = index[indexByte]; i < index[indexByte + 1]; ++i)
            {
                MatchDegree m = rules[i].MatchAndReplace(text, pos, incremental);
                switch (m)
                {
                case MatchDegree.Match:
                    if (Transliterator.DEBUG)
                    {
                        Console.Out.WriteLine((incremental ? "Rule.i: match " : "Rule: match ") +
                                              rules[i].ToRule(true) + " => " +
                                              UtilityExtensions.FormatInput(text, pos));
                    }
                    return(true);

                case MatchDegree.PartialMatch:
                    if (Transliterator.DEBUG)
                    {
                        Console.Out.WriteLine((incremental ? "Rule.i: partial match " : "Rule: partial match ") +
                                              rules[i].ToRule(true) + " => " +
                                              UtilityExtensions.FormatInput(text, pos));
                    }
                    return(false);

                default:
                    if (Transliterator.DEBUG)
                    {
                        Console.Out.WriteLine("Rule: no match " + rules[i]);
                    }
                    break;
                }
            }
            // No match or partial match from any rule
            pos.Start += UTF16.GetCharCount(text.Char32At(pos.Start));
            if (Transliterator.DEBUG)
            {
                Console.Out.WriteLine((incremental ? "Rule.i: no match => " : "Rule: no match => ") +
                                      UtilityExtensions.FormatInput(text, pos));
            }
            return(true);
        }
示例#2
0
        /// <summary>
        /// Implement <see cref="IUnicodeMatcher"/> API.
        /// </summary>
        public virtual MatchDegree Matches(IReplaceable text,
                                           int[] offset,
                                           int limit,
                                           bool incremental)
        {
            int start = offset[0];
            int count = 0;

            while (count < maxCount)
            {
                int         pos = offset[0];
                MatchDegree m   = matcher.Matches(text, offset, limit, incremental);
                if (m == MatchDegree.Match)
                {
                    ++count;
                    if (pos == offset[0])
                    {
                        // If offset has not moved we have a zero-width match.
                        // Don't keep matching it infinitely.
                        break;
                    }
                }
                else if (incremental && m == MatchDegree.PartialMatch)
                {
                    return(MatchDegree.PartialMatch);
                }
                else
                {
                    break;
                }
            }
            if (incremental && offset[0] == limit)
            {
                return(MatchDegree.PartialMatch);
            }
            if (count >= minCount)
            {
                return(MatchDegree.Match);
            }
            offset[0] = start;
            return(MatchDegree.Mismatch);
        }
示例#3
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);
        }