Example #1
0
        // private methods ------------------------------------------------

        /// <summary>
        /// Set the result values.
        /// </summary>
        /// <param name="element">Return result object.</param>
        /// <param name="start">Start codepoint of range.</param>
        /// <param name="limit">(end + 1) codepoint of range.</param>
        /// <param name="value">Common value of range.</param>
        private void SetResult(Element element, int start, int limit,
                               int value)
        {
            element.Start = start;
            element.Limit = limit;
            element.Value = value;
        }
Example #2
0
        /// <summary>
        /// Returns true if we are not at the end of the iteration, false
        /// otherwise.
        /// The next set of codepoints with the same value type will be
        /// calculated during this call and set to <see cref="Current"/>.
        /// </summary>
        /// <returns>true if we are not at the end of the iteration, false otherwise.</returns>
        /// <seealso cref="Element"/>
        public bool MoveNext()
        {
            var temp    = new Element();
            var hasNext = Next(temp);

            if (hasNext)
            {
                current = temp;
            }
            return(hasNext);
        }
Example #3
0
        // public methods -------------------------------------------------

        /// <summary>
        /// Returns true if we are not at the end of the iteration, false
        /// otherwise.
        /// The next set of codepoints with the same value type will be
        /// calculated during this call and returned in the arguement element.
        /// </summary>
        /// <param name="element">Return result.</param>
        /// <returns>true if we are not at the end of the iteration, false otherwise.</returns>
        /// <seealso cref="Element"/>
        private bool Next(Element element)
        {
            if (m_nextCodepoint_ > UCharacter.MAX_VALUE)
            {
                return(false);
            }
            if (m_nextCodepoint_ < UCharacter.SUPPLEMENTARY_MIN_VALUE &&
                CalculateNextBMPElement(element))
            {
                return(true);
            }
            CalculateNextSupplementaryElement(element);
            return(true);
        }
Example #4
0
        // public methods -------------------------------------------------

        /// <summary>
        /// Returns true if we are not at the end of the iteration, false
        /// otherwise.
        /// The next set of codepoints with the same value type will be
        /// calculated during this call and returned in the arguement element.
        /// </summary>
        /// <param name="element">Return result.</param>
        /// <returns>true if we are not at the end of the iteration, false otherwise.</returns>
        /// <seealso cref="Element"/>
        private bool Next(Element element)
        {
            if (m_nextCodepoint_ > UChar.MaxValue)
            {
                return(false);
            }
            if (m_nextCodepoint_ < UChar.SupplementaryMinValue &&
                CalculateNextBMPElement(element))
            {
                return(true);
            }
            CalculateNextSupplementaryElement(element);
            return(true);
        }
Example #5
0
        /// <summary>
        /// Finding the next element.
        /// This method is called just before returning the result of
        /// <see cref="Next(Element)"/>.
        /// We always store the next element before it is requested.
        /// In the case that we have to continue calculations into the
        /// supplementary planes, a false will be returned.
        /// </summary>
        /// <param name="element">Return result object.</param>
        /// <returns>true if the next range is found, false if we have to proceed to
        /// the supplementary range.</returns>
        private bool CalculateNextBMPElement(Element element)
        {
            int currentValue = m_nextValue_;

            m_currentCodepoint_ = m_nextCodepoint_;
            m_nextCodepoint_++;
            m_nextBlockIndex_++;
            if (!CheckBlockDetail(currentValue))
            {
                SetResult(element, m_currentCodepoint_, m_nextCodepoint_,
                          currentValue);
                return(true);
            }
            // synwee check that next block index == 0 here
            // enumerate BMP - the main loop enumerates data blocks
            while (m_nextCodepoint_ < UCharacter.SUPPLEMENTARY_MIN_VALUE)
            {
                // because of the way the character is split to form the index
                // the lead surrogate and trail surrogate can not be in the
                // mid of a block
                if (m_nextCodepoint_ == LEAD_SURROGATE_MIN_VALUE_)
                {
                    // skip lead surrogate code units,
                    // go to lead surrogate codepoints
                    m_nextIndex_ = BMP_INDEX_LENGTH_;
                }
                else if (m_nextCodepoint_ == TRAIL_SURROGATE_MIN_VALUE_)
                {
                    // go back to regular BMP code points
                    m_nextIndex_ = m_nextCodepoint_ >> Trie.INDEX_STAGE_1_SHIFT_;
                }
                else
                {
                    m_nextIndex_++;
                }

                m_nextBlockIndex_ = 0;
                if (!CheckBlock(currentValue))
                {
                    SetResult(element, m_currentCodepoint_, m_nextCodepoint_,
                              currentValue);
                    return(true);
                }
            }
            m_nextCodepoint_--;   // step one back since this value has not been
            m_nextBlockIndex_--;  // retrieved yet.
            return(false);
        }
Example #6
0
        /// <summary>
        /// Finds the next supplementary element.
        /// For each entry in the trie, the value to be delivered is passed through
        /// <see cref="Extract(int)"/>.
        /// We always store the next element before it is requested.
        /// Called after <see cref="CalculateNextBMPElement(Element)"/> completes its round of BMP characters.
        /// There is a slight difference in the usage of <see cref="m_currentCodepoint_"/>.
        /// here as compared to <see cref="CalculateNextBMPElement(Element)"/>. Though both represents the
        /// lower bound of the next element, in <see cref="CalculateNextBMPElement(Element)"/> it gets set
        /// at the start of any loop, where-else, in <see cref="CalculateNextSupplementaryElement(Element)"/>
        /// since <see cref="m_currentCodepoint_"/> already contains the lower bound of the
        /// next element (passed down from <see cref="CalculateNextBMPElement(Element)"/>), we keep it till
        /// the end before resetting it to the new value.
        /// Note, if there are no more iterations, it will never get to here.
        /// Blocked out by <see cref="Next(Element)"/>.
        /// </summary>
        /// <param name="element">Return result object.</param>
        private void CalculateNextSupplementaryElement(Element element)
        {
            int currentValue = m_nextValue_;

            m_nextCodepoint_++;
            m_nextBlockIndex_++;

            if (UTF16.GetTrailSurrogate(m_nextCodepoint_)
                != UTF16.TRAIL_SURROGATE_MIN_VALUE)
            {
                // this piece is only called when we are in the middle of a lead
                // surrogate block
                if (!CheckNullNextTrailIndex() && !CheckBlockDetail(currentValue))
                {
                    SetResult(element, m_currentCodepoint_, m_nextCodepoint_,
                              currentValue);
                    m_currentCodepoint_ = m_nextCodepoint_;
                    return;
                }
                // we have cleared one block
                m_nextIndex_++;
                m_nextTrailIndexOffset_++;
                if (!CheckTrailBlock(currentValue))
                {
                    SetResult(element, m_currentCodepoint_, m_nextCodepoint_,
                              currentValue);
                    m_currentCodepoint_ = m_nextCodepoint_;
                    return;
                }
            }
            int nextLead = UTF16.GetLeadSurrogate(m_nextCodepoint_);

            // enumerate supplementary code points
            while (nextLead < TRAIL_SURROGATE_MIN_VALUE_)
            {
                // lead surrogate access
                int leadBlock =
                    m_trie_.m_index_[nextLead >> Trie.INDEX_STAGE_1_SHIFT_] <<
                        Trie.INDEX_STAGE_2_SHIFT_;
                if (leadBlock == m_trie_.m_dataOffset_)
                {
                    // no entries for a whole block of lead surrogates
                    if (currentValue != m_initialValue_)
                    {
                        m_nextValue_      = m_initialValue_;
                        m_nextBlock_      = leadBlock; // == m_trie_.m_dataOffset_
                        m_nextBlockIndex_ = 0;
                        SetResult(element, m_currentCodepoint_, m_nextCodepoint_,
                                  currentValue);
                        m_currentCodepoint_ = m_nextCodepoint_;
                        return;
                    }

                    nextLead += DATA_BLOCK_LENGTH_;
                    // number of total affected supplementary codepoints in one
                    // block
                    // this is not a simple addition of
                    // DATA_BLOCK_SUPPLEMENTARY_LENGTH since we need to consider
                    // that we might have moved some of the codepoints
                    m_nextCodepoint_ = Character.ToCodePoint((char)nextLead, (char)UTF16.TRAIL_SURROGATE_MIN_VALUE);
                    continue;
                }
                if (m_trie_.m_dataManipulate_ == null)
                {
                    throw new InvalidOperationException(
                              "The field DataManipulate in this Trie is null");   // ICU4N: This was originally NullPointerException
                }
                // enumerate trail surrogates for this lead surrogate
                m_nextIndex_ = m_trie_.m_dataManipulate_.GetFoldingOffset(
                    m_trie_[leadBlock +
                            (nextLead & Trie.INDEX_STAGE_3_MASK_)]);
                if (m_nextIndex_ <= 0)
                {
                    // no data for this lead surrogate
                    if (currentValue != m_initialValue_)
                    {
                        m_nextValue_      = m_initialValue_;
                        m_nextBlock_      = m_trie_.m_dataOffset_;
                        m_nextBlockIndex_ = 0;
                        SetResult(element, m_currentCodepoint_, m_nextCodepoint_,
                                  currentValue);
                        m_currentCodepoint_ = m_nextCodepoint_;
                        return;
                    }
                    m_nextCodepoint_ += TRAIL_SURROGATE_COUNT_;
                }
                else
                {
                    m_nextTrailIndexOffset_ = 0;
                    if (!CheckTrailBlock(currentValue))
                    {
                        SetResult(element, m_currentCodepoint_, m_nextCodepoint_,
                                  currentValue);
                        m_currentCodepoint_ = m_nextCodepoint_;
                        return;
                    }
                }
                nextLead++;
            }

            // deliver last range
            SetResult(element, m_currentCodepoint_, UCharacter.MAX_VALUE + 1,
                      currentValue);
        }