コード例 #1
0
ファイル: CharsTrie.cs プロジェクト: introfog/ICU4N
        private int BranchNext(int pos, int length)
        {
            while (length > CharsTrie.kMaxBranchLinearSubNodeLength)
            {
                ++pos;  // ignore the comparison unit
                        // Push state for the greater-or-equal edge.
                        // ICU4N: Sign extended operand here is desirable, as that is what was happening in Java
                stack_.Add(((long)CharsTrie.SkipDelta(chars_, pos) << 32) | (uint)((length - (length >> 1)) << 16) | (uint)str_.Length);
                // Follow the less-than edge.
                length >>= 1;
                pos      = CharsTrie.JumpByDelta(chars_, pos);
            }
            // List of key-value pairs where values are either final values or jump deltas.
            // Read the first (key, value) pair.
            char trieUnit = chars_[pos++];
            int  node     = chars_[pos++];
            bool isFinal  = (node & CharsTrie.kValueIsFinal) != 0;
            int  value    = CharsTrie.ReadValue(chars_, pos, node &= 0x7fff);

            pos = CharsTrie.SkipValue(pos, node);
            // ICU4N: Sign extended operand here is desirable, as that is what was happening in Java
            stack_.Add(((long)pos << 32) | (uint)((length - 1) << 16) | (uint)str_.Length);
            str_.Append(trieUnit);
            if (isFinal)
            {
                pos_         = -1;
                entry_.Chars = str_.AsCharSequence();
                entry_.Value = value;
                return(-1);
            }
            else
            {
                return(pos + value);
            }
        }
コード例 #2
0
ファイル: CharsTrie.cs プロジェクト: introfog/ICU4N
        /// <summary>
        /// Finds the next (string, value) pair if there is one.
        /// </summary>
        /// <remarks>
        /// If the string is truncated to the maximum length and does not
        /// have a real value, then the value is set to -1.
        /// In this case, this "not a real value" is indistinguishable from
        /// a real value of -1.
        /// </remarks>
        /// <returns>An <see cref="CharsTrieEntry"/> with the string and value of the next element.</returns>
        /// <stable>ICU 4.8</stable>
        private CharsTrieEntry Next()
        {
            int pos = pos_;

            if (pos < 0)
            {
                //if (stack_.isEmpty())
                //{
                //    throw new NoSuchElementException();
                //}
                // Pop the state off the stack and continue with the next outbound edge of
                // the branch node.
                long top = stack_[stack_.Count - 1];
                stack_.Remove(top);
                int length = (int)top;
                pos         = (int)(top >> 32);
                str_.Length = (length & 0xffff);
                length      = length.TripleShift(16);
                if (length > 1)
                {
                    pos = BranchNext(pos, length);
                    if (pos < 0)
                    {
                        return(entry_);  // Reached a final value.
                    }
                }
                else
                {
                    str_.Append(chars_[pos++]);
                }
            }
            if (remainingMatchLength_ >= 0)
            {
                // We only get here if we started in a pending linear-match node
                // with more than maxLength remaining units.
                return(TruncateAndStop());
            }
            for (; ;)
            {
                int node = chars_[pos++];
                if (node >= CharsTrie.kMinValueLead)
                {
                    if (skipValue_)
                    {
                        pos        = CharsTrie.SkipNodeValue(pos, node);
                        node      &= CharsTrie.kNodeTypeMask;
                        skipValue_ = false;
                    }
                    else
                    {
                        // Deliver value for the string so far.
                        bool isFinal = (node & CharsTrie.kValueIsFinal) != 0;
                        if (isFinal)
                        {
                            entry_.Value = CharsTrie.ReadValue(chars_, pos, node & 0x7fff);
                        }
                        else
                        {
                            entry_.Value = CharsTrie.ReadNodeValue(chars_, pos, node);
                        }
                        if (isFinal || (maxLength_ > 0 && str_.Length == maxLength_))
                        {
                            pos_ = -1;
                        }
                        else
                        {
                            // We cannot skip the value right here because it shares its
                            // lead unit with a match node which we have to evaluate
                            // next time.
                            // Instead, keep pos_ on the node lead unit itself.
                            pos_       = pos - 1;
                            skipValue_ = true;
                        }
                        entry_.Chars = str_.AsCharSequence();
                        return(entry_);
                    }
                }
                if (maxLength_ > 0 && str_.Length == maxLength_)
                {
                    return(TruncateAndStop());
                }
                if (node < CharsTrie.kMinLinearMatch)
                {
                    if (node == 0)
                    {
                        node = chars_[pos++];
                    }
                    pos = BranchNext(pos, node + 1);
                    if (pos < 0)
                    {
                        return(entry_);  // Reached a final value.
                    }
                }
                else
                {
                    // Linear-match node, append length units to str_.
                    int length = node - CharsTrie.kMinLinearMatch + 1;
                    if (maxLength_ > 0 && str_.Length + length > maxLength_)
                    {
                        str_.Append(chars_, pos, maxLength_ - str_.Length); // ICU4N: (pos + maxLength_ - str_.Length) - pos == (maxLength_ - str_.Length)
                        return(TruncateAndStop());
                    }
                    str_.Append(chars_, pos, length); // ICU4N: (pos + length) - pos == length
                    pos += length;
                }
            }
        }