// 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; }
/// <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); }
// 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); }
// 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); }
/// <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); }
/// <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); }