// private methods -------------------------------------------------- /// <summary> /// Group name iteration, iterate all the names in the current 32-group and /// returns the first codepoint that has a valid name. /// </summary> /// /// <param name="result">stores the result codepoint and name</param> /// <param name="limit">last codepoint + 1 in range to search</param> /// <returns>false if a codepoint with a name is found in group and we can /// bail from further iteration, true to continue on with the /// iteration</returns> private bool IterateSingleGroup(ValueIterator_Constants.Element result, int limit) { lock (GROUP_OFFSETS_) { lock (GROUP_LENGTHS_) { int index = m_name_.GetGroupLengths(m_groupIndex_, GROUP_OFFSETS_, GROUP_LENGTHS_); while (m_current_ < limit) { int offset = IBM.ICU.Impl.UCharacterName.GetGroupOffset(m_current_); String name = m_name_.GetGroupName(index + GROUP_OFFSETS_[offset], GROUP_LENGTHS_[offset], m_choice_); if ((name == null || name.Length == 0) && m_choice_ == IBM.ICU.Impl.UCharacterNameChoice_Constants.EXTENDED_CHAR_NAME) { name = m_name_.GetExtendedName(m_current_); } if (name != null && name.Length > 0) { result.integer = m_current_; result.value_ren = name; return(false); } ++m_current_; } } } return(true); }
/// <summary> /// Group name iteration, iterate all the names in the current 32-group and /// returns the first codepoint that has a valid name. /// </summary> /// /// <param name="result">stores the result codepoint and name</param> /// <param name="limit">last codepoint + 1 in range to search</param> /// <returns>false if a codepoint with a name is found in group and we can /// bail from further iteration, true to continue on with the /// iteration</returns> private bool IterateGroup(ValueIterator_Constants.Element result, int limit) { if (m_groupIndex_ < 0) { m_groupIndex_ = m_name_.GetGroup(m_current_); } while (m_groupIndex_ < m_name_.m_groupcount_ && m_current_ < limit) { // iterate till the last group or the last codepoint int startMSB = IBM.ICU.Impl.UCharacterName.GetCodepointMSB(m_current_); int gMSB = m_name_.GetGroupMSB(m_groupIndex_); // can be -1 if (startMSB == gMSB) { if (startMSB == IBM.ICU.Impl.UCharacterName.GetCodepointMSB(limit - 1)) { // if start and limit - 1 are in the same group, then // enumerate // only in that one return(IterateSingleGroup(result, limit)); } // enumerate characters in the partial start group // if (m_name_.getGroupOffset(m_current_) != 0) { if (!IterateSingleGroup(result, IBM.ICU.Impl.UCharacterName.GetGroupLimit(gMSB))) { return(false); } ++m_groupIndex_; // continue with the next group } else if (startMSB > gMSB) { // make sure that we start enumerating with the first group // after start m_groupIndex_++; } else { int gMIN = IBM.ICU.Impl.UCharacterName.GetGroupMin(gMSB); if (gMIN > limit) { gMIN = limit; } if (m_choice_ == IBM.ICU.Impl.UCharacterNameChoice_Constants.EXTENDED_CHAR_NAME) { if (!IterateExtended(result, gMIN)) { return(false); } } m_current_ = gMIN; } } return(true); }
/// <summary> /// Iterate extended names. /// </summary> /// /// <param name="result">stores the result codepoint and name</param> /// <param name="limit">last codepoint + 1 in range to search</param> /// <returns>false if a codepoint with a name is found and we can bail from /// further iteration, true to continue on with the iteration (this /// will always be false for valid codepoints)</returns> private bool IterateExtended(ValueIterator_Constants.Element result, int limit) { while (m_current_ < limit) { String name = m_name_.GetExtendedOr10Name(m_current_); if (name != null && name.Length > 0) { result.integer = m_current_; result.value_ren = name; return(false); } ++m_current_; } return(true); }
// public methods ---------------------------------------------------- /// <summary> /// <p> /// Gets the next result for this iteration and returns true if we are not at /// the end of the iteration, false otherwise. /// </p> /// <p> /// If the return boolean is a false, the contents of elements will not be /// updated. /// </p> /// </summary> /// /// <param name="element">for storing the result codepoint and name</param> /// <returns>true if we are not at the end of the iteration, false otherwise.</returns> /// <seealso cref="null"/> /// @draft 2.1 public virtual bool Next(ValueIterator_Constants.Element element) { if (m_current_ >= m_limit_) { return(false); } if (m_choice_ != IBM.ICU.Impl.UCharacterNameChoice_Constants.UNICODE_10_CHAR_NAME) { int length = m_name_.GetAlgorithmLength(); if (m_algorithmIndex_ < length) { while (m_algorithmIndex_ < length) { // find the algorithm range that could contain m_current_ if (m_algorithmIndex_ < 0 || m_name_.GetAlgorithmEnd(m_algorithmIndex_) < m_current_) { m_algorithmIndex_++; } else { break; } } if (m_algorithmIndex_ < length) { // interleave the data-driven ones with the algorithmic ones // iterate over all algorithmic ranges; assume that they are // in ascending order int start = m_name_.GetAlgorithmStart(m_algorithmIndex_); if (m_current_ < start) { // this should get rid of those codepoints that are not // in the algorithmic range int end = start; if (m_limit_ <= start) { end = m_limit_; } if (!IterateGroup(element, end)) { m_current_++; return(true); } } if (m_current_ >= m_limit_) { // after iterateGroup fails, current codepoint may be // greater than limit return(false); } element.integer = m_current_; element.value_ren = m_name_.GetAlgorithmName(m_algorithmIndex_, m_current_); // reset the group index if we are in the algorithmic names m_groupIndex_ = -1; m_current_++; return(true); } } } // enumerate the character names after the last algorithmic range if (!IterateGroup(element, m_limit_)) { m_current_++; return(true); } else if (m_choice_ == IBM.ICU.Impl.UCharacterNameChoice_Constants.EXTENDED_CHAR_NAME) { if (!IterateExtended(element, m_limit_)) { m_current_++; return(true); } } return(false); }