示例#1
0
        /// <summary>
        /// This method produces a buffer which contains the collation
        /// elements for the two characters, with colFirst's values preceding
        /// another character's.  Presumably, the other character precedes colFirst
        /// in logical order (otherwise you wouldn't need this method would you?).
        /// The assumption is that the other char's value(s) have already been
        /// computed.  If this char has a single element it is passed to this
        /// method as lastValue, and lastExpansion is null.  If it has an
        /// expansion it is passed in lastExpansion, and colLastValue is ignored.
        /// </summary>
        private int[] MakeReorderedBuffer(int colFirst, int lastValue, int[] lastExpansion, bool forward)
        {
            int[] result;

            int firstValue = Ordering.GetUnicodeOrder(colFirst);

            if (firstValue >= RuleBasedCollator.CONTRACTCHARINDEX)
            {
                firstValue = forward? NextContractChar(colFirst) : PrevContractChar(colFirst);
            }

            int[] firstExpansion = null;
            if (firstValue >= RuleBasedCollator.EXPANDCHARINDEX)
            {
                firstExpansion = Ordering.GetExpandValueList(firstValue);
            }

            if (!forward)
            {
                int temp1 = firstValue;
                firstValue = lastValue;
                lastValue  = temp1;
                int[] temp2 = firstExpansion;
                firstExpansion = lastExpansion;
                lastExpansion  = temp2;
            }

            if (firstExpansion == null && lastExpansion == null)
            {
                result    = new int [2];
                result[0] = firstValue;
                result[1] = lastValue;
            }
            else
            {
                int firstLength = firstExpansion == null? 1 : firstExpansion.Length;
                int lastLength  = lastExpansion == null? 1 : lastExpansion.Length;
                result = new int[firstLength + lastLength];

                if (firstExpansion == null)
                {
                    result[0] = firstValue;
                }
                else
                {
                    System.Array.Copy(firstExpansion, 0, result, 0, firstLength);
                }

                if (lastExpansion == null)
                {
                    result[firstLength] = lastValue;
                }
                else
                {
                    System.Array.Copy(lastExpansion, 0, result, firstLength, lastLength);
                }
            }

            return(result);
        }
示例#2
0
        /// <summary>
        /// Get the previous collation element in the string.  <para>This iterator iterates
        /// over a sequence of collation elements that were built from the string.
        /// Because there isn't necessarily a one-to-one mapping from characters to
        /// collation elements, this doesn't mean the same thing as "return the
        /// collation element [or ordering priority] of the previous character in the
        /// string".</p>
        /// </para>
        /// <para>This function updates the iterator's internal pointer to point to the
        /// collation element preceding the one it's currently pointing to and then
        /// returns that element, while next() returns the current element and then
        /// updates the pointer.  This means that when you change direction while
        /// iterating (i.e., call next() and then call previous(), or call previous()
        /// and then call next()), you'll get back the same element twice.</para>
        /// </summary>
        /// <returns> the previous collation element
        /// @since 1.2 </returns>
        public int Previous()
        {
            if (Text_Renamed == null)
            {
                return(NULLORDER);
            }
            NormalizerBase.Mode textMode = Text_Renamed.Mode;
            // convert the owner's mode to something the Normalizer understands
            NormalizerBase.Mode ownerMode = CollatorUtilities.toNormalizerMode(Owner.Decomposition);
            if (textMode != ownerMode)
            {
                Text_Renamed.Mode = ownerMode;
            }
            if (Buffer != null)
            {
                if (ExpIndex > 0)
                {
                    return(StrengthOrder(Buffer[--ExpIndex]));
                }
                else
                {
                    Buffer   = null;
                    ExpIndex = 0;
                }
            }
            else if (SwapOrder != 0)
            {
                if (Character.IsSupplementaryCodePoint(SwapOrder))
                {
                    char[] chars = Character.ToChars(SwapOrder);
                    SwapOrder = chars[1];
                    return(chars[0] << 16);
                }
                int order = SwapOrder << 16;
                SwapOrder = 0;
                return(order);
            }
            int ch = Text_Renamed.previous();

            if (ch == NormalizerBase.DONE)
            {
                return(NULLORDER);
            }

            int value = Ordering.GetUnicodeOrder(ch);

            if (value == RuleBasedCollator.UNMAPPED)
            {
                SwapOrder = UNMAPPEDCHARVALUE;
                return(ch);
            }
            else if (value >= RuleBasedCollator.CONTRACTCHARINDEX)
            {
                value = PrevContractChar(ch);
            }
            if (value >= RuleBasedCollator.EXPANDCHARINDEX)
            {
                Buffer   = Ordering.GetExpandValueList(value);
                ExpIndex = Buffer.Length;
                value    = Buffer[--ExpIndex];
            }

            if (Ordering.SEAsianSwapping)
            {
                int vowel;
                if (IsThaiBaseConsonant(ch))
                {
                    vowel = Text_Renamed.previous();
                    if (IsThaiPreVowel(vowel))
                    {
                        Buffer   = MakeReorderedBuffer(vowel, value, Buffer, false);
                        ExpIndex = Buffer.Length - 1;
                        value    = Buffer[ExpIndex];
                    }
                    else
                    {
                        Text_Renamed.next();
                    }
                }
                if (IsLaoBaseConsonant(ch))
                {
                    vowel = Text_Renamed.previous();
                    if (IsLaoPreVowel(vowel))
                    {
                        Buffer   = MakeReorderedBuffer(vowel, value, Buffer, false);
                        ExpIndex = Buffer.Length - 1;
                        value    = Buffer[ExpIndex];
                    }
                    else
                    {
                        Text_Renamed.next();
                    }
                }
            }

            return(StrengthOrder(value));
        }
示例#3
0
        /// <summary>
        /// Get the next collation element in the string.  <para>This iterator iterates
        /// over a sequence of collation elements that were built from the string.
        /// Because there isn't necessarily a one-to-one mapping from characters to
        /// collation elements, this doesn't mean the same thing as "return the
        /// collation element [or ordering priority] of the next character in the
        /// string".</p>
        /// </para>
        /// <para>This function returns the collation element that the iterator is currently
        /// pointing to and then updates the internal pointer to point to the next element.
        /// previous() updates the pointer first and then returns the element.  This
        /// means that when you change direction while iterating (i.e., call next() and
        /// then call previous(), or call previous() and then call next()), you'll get
        /// back the same element twice.</para>
        /// </summary>
        /// <returns> the next collation element </returns>
        public int Next()
        {
            if (Text_Renamed == null)
            {
                return(NULLORDER);
            }
            NormalizerBase.Mode textMode = Text_Renamed.Mode;
            // convert the owner's mode to something the Normalizer understands
            NormalizerBase.Mode ownerMode = CollatorUtilities.toNormalizerMode(Owner.Decomposition);
            if (textMode != ownerMode)
            {
                Text_Renamed.Mode = ownerMode;
            }

            // if buffer contains any decomposed char values
            // return their strength orders before continuing in
            // the Normalizer's CharacterIterator.
            if (Buffer != null)
            {
                if (ExpIndex < Buffer.Length)
                {
                    return(StrengthOrder(Buffer[ExpIndex++]));
                }
                else
                {
                    Buffer   = null;
                    ExpIndex = 0;
                }
            }
            else if (SwapOrder != 0)
            {
                if (Character.IsSupplementaryCodePoint(SwapOrder))
                {
                    char[] chars = Character.ToChars(SwapOrder);
                    SwapOrder = chars[1];
                    return(chars[0] << 16);
                }
                int order = SwapOrder << 16;
                SwapOrder = 0;
                return(order);
            }
            int ch = Text_Renamed.next();

            // are we at the end of Normalizer's text?
            if (ch == NormalizerBase.DONE)
            {
                return(NULLORDER);
            }

            int value = Ordering.GetUnicodeOrder(ch);

            if (value == RuleBasedCollator.UNMAPPED)
            {
                SwapOrder = ch;
                return(UNMAPPEDCHARVALUE);
            }
            else if (value >= RuleBasedCollator.CONTRACTCHARINDEX)
            {
                value = NextContractChar(ch);
            }
            if (value >= RuleBasedCollator.EXPANDCHARINDEX)
            {
                Buffer   = Ordering.GetExpandValueList(value);
                ExpIndex = 0;
                value    = Buffer[ExpIndex++];
            }

            if (Ordering.SEAsianSwapping)
            {
                int consonant;
                if (IsThaiPreVowel(ch))
                {
                    consonant = Text_Renamed.next();
                    if (IsThaiBaseConsonant(consonant))
                    {
                        Buffer   = MakeReorderedBuffer(consonant, value, Buffer, true);
                        value    = Buffer[0];
                        ExpIndex = 1;
                    }
                    else if (consonant != NormalizerBase.DONE)
                    {
                        Text_Renamed.previous();
                    }
                }
                if (IsLaoPreVowel(ch))
                {
                    consonant = Text_Renamed.next();
                    if (IsLaoBaseConsonant(consonant))
                    {
                        Buffer   = MakeReorderedBuffer(consonant, value, Buffer, true);
                        value    = Buffer[0];
                        ExpIndex = 1;
                    }
                    else if (consonant != NormalizerBase.DONE)
                    {
                        Text_Renamed.previous();
                    }
                }
            }

            return(StrengthOrder(value));
        }