예제 #1
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));
        }
예제 #2
0
        /// <summary>
        /// Get the ordering priority of the next contracting character in the
        /// string. </summary>
        /// <param name="ch"> the starting character of a contracting character token </param>
        /// <returns> the next contracting character's ordering.  Returns NULLORDER
        /// if the end of string is reached. </returns>
        private int NextContractChar(int ch)
        {
            // First get the ordering of this single character,
            // which is always the first element in the list
            List <EntryPair> list = Ordering.GetContractValues(ch);
            EntryPair        pair = list[0];
            int order             = pair.Value;

            // find out the length of the longest contracting character sequence in the list.
            // There's logic in the builder code to make sure the longest sequence is always
            // the last.
            pair = list[list.Count - 1];
            int maxLength = pair.EntryName.Length();

            // (the Normalizer is cloned here so that the seeking we do in the next loop
            // won't affect our real position in the text)
            NormalizerBase tempText = (NormalizerBase)Text_Renamed.clone();

            // extract the next maxLength characters in the string (we have to do this using the
            // Normalizer to ensure that our offsets correspond to those the rest of the
            // iterator is using) and store it in "fragment".
            tempText.previous();
            Key.Length = 0;
            int c = tempText.next();

            while (maxLength > 0 && c != NormalizerBase.DONE)
            {
                if (Character.IsSupplementaryCodePoint(c))
                {
                    Key.Append(Character.ToChars(c));
                    maxLength -= 2;
                }
                else
                {
                    Key.Append((char)c);
                    --maxLength;
                }
                c = tempText.next();
            }
            String fragment = Key.ToString();

            // now that we have that fragment, iterate through this list looking for the
            // longest sequence that matches the characters in the actual text.  (maxLength
            // is used here to keep track of the length of the longest sequence)
            // Upon exit from this loop, maxLength will contain the length of the matching
            // sequence and order will contain the collation-element value corresponding
            // to this sequence
            maxLength = 1;
            for (int i = list.Count - 1; i > 0; i--)
            {
                pair = list[i];
                if (!pair.Fwd)
                {
                    continue;
                }

                if (fragment.StartsWith(pair.EntryName) && pair.EntryName.Length() > maxLength)
                {
                    maxLength = pair.EntryName.Length();
                    order     = pair.Value;
                }
            }

            // seek our current iteration position to the end of the matching sequence
            // and return the appropriate collation-element value (if there was no matching
            // sequence, we're already seeked to the right position and order already contains
            // the correct collation-element value for the single character)
            while (maxLength > 1)
            {
                c          = Text_Renamed.next();
                maxLength -= Character.CharCount(c);
            }
            return(order);
        }
예제 #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));
        }