Ejemplo n.º 1
0
        /// <summary>
        /// Returns the single CE that c maps to.
        /// Throws <see cref="NotSupportedException"/> if <paramref name="c"/> does not map to a single CE.
        /// </summary>
        internal long GetSingleCE(int c)
        {
            CollationData d;
            int           ce32 = GetCE32(c);

            if (ce32 == Collation.FALLBACK_CE32)
            {
                d    = base_;
                ce32 = base_.GetCE32(c);
            }
            else
            {
                d = this;
            }
            while (Collation.IsSpecialCE32(ce32))
            {
                switch (Collation.TagFromCE32(ce32))
                {
                case Collation.LATIN_EXPANSION_TAG:
                case Collation.BUILDER_DATA_TAG:
                case Collation.PREFIX_TAG:
                case Collation.CONTRACTION_TAG:
                case Collation.HANGUL_TAG:
                case Collation.LEAD_SURROGATE_TAG:
                    throw new NotSupportedException(string.Format(
                                                        "there is not exactly one collation element for U+{0:X4} (CE32 0x{1:x8})",
                                                        c, ce32));

                case Collation.FALLBACK_TAG:
                case Collation.RESERVED_TAG_3:
                    throw new InvalidOperationException(string.Format(
                                                            "unexpected CE32 tag for U+{0:X4} (CE32 0x{1:x8})", c, ce32));

                case Collation.LONG_PRIMARY_TAG:
                    return(Collation.CeFromLongPrimaryCE32(ce32));

                case Collation.LONG_SECONDARY_TAG:
                    return(Collation.CeFromLongSecondaryCE32(ce32));

                case Collation.EXPANSION32_TAG:
                    if (Collation.LengthFromCE32(ce32) == 1)
                    {
                        ce32 = d.ce32s[Collation.IndexFromCE32(ce32)];
                        break;
                    }
                    else
                    {
                        throw new NotSupportedException(string.Format(
                                                            "there is not exactly one collation element for U+{0:X4} (CE32 0x{1:x8})",
                                                            c, ce32));
                    }

                case Collation.EXPANSION_TAG:
                {
                    if (Collation.LengthFromCE32(ce32) == 1)
                    {
                        return(d.ces[Collation.IndexFromCE32(ce32)]);
                    }
                    else
                    {
                        throw new NotSupportedException(string.Format(
                                                            "there is not exactly one collation element for U+{0:X4} (CE32 0x{1:x8})",
                                                            c, ce32));
                    }
                }

                case Collation.DIGIT_TAG:
                    // Fetch the non-numeric-collation CE32 and continue.
                    ce32 = d.ce32s[Collation.IndexFromCE32(ce32)];
                    break;

                case Collation.U0000_TAG:
                    Debug.Assert(c == 0);
                    // Fetch the normal ce32 for U+0000 and continue.
                    ce32 = d.ce32s[0];
                    break;

                case Collation.OFFSET_TAG:
                    return(d.GetCEFromOffsetCE32(c, ce32));

                case Collation.IMPLICIT_TAG:
                    return(Collation.UnassignedCEFromCodePoint(c));
                }
            }
            return(Collation.CeFromSimpleCE32(ce32));
        }
Ejemplo n.º 2
0
        private void HandleCE32(int start, int end, int ce32)
        {
            for (; ;)
            {
                if ((ce32 & 0xff) < Collation.SPECIAL_CE32_LOW_BYTE)
                {
                    // !isSpecialCE32()
                    if (sink != null)
                    {
                        sink.HandleCE(Collation.CeFromSimpleCE32(ce32));
                    }
                    return;
                }
                switch (Collation.TagFromCE32(ce32))
                {
                case Collation.FALLBACK_TAG:
                    return;

                case Collation.RESERVED_TAG_3:
                case Collation.BUILDER_DATA_TAG:
                case Collation.LEAD_SURROGATE_TAG:
                    // Java porting note: U_INTERNAL_PROGRAM_ERROR is set to errorCode in ICU4C.
                    throw new InvalidOperationException(
                              string.Format("Unexpected CE32 tag type {0} for ce32=0x{1:x8}",
                                            Collation.TagFromCE32(ce32), ce32));

                case Collation.LONG_PRIMARY_TAG:
                    if (sink != null)
                    {
                        sink.HandleCE(Collation.CeFromLongPrimaryCE32(ce32));
                    }
                    return;

                case Collation.LONG_SECONDARY_TAG:
                    if (sink != null)
                    {
                        sink.HandleCE(Collation.CeFromLongSecondaryCE32(ce32));
                    }
                    return;

                case Collation.LATIN_EXPANSION_TAG:
                    if (sink != null)
                    {
                        ces[0] = Collation.LatinCE0FromCE32(ce32);
                        ces[1] = Collation.LatinCE1FromCE32(ce32);
                        sink.HandleExpansion(ces, 0, 2);
                    }
                    // Optimization: If we have a prefix,
                    // then the relevant strings have been added already.
                    if (unreversedPrefix.Length == 0)
                    {
                        AddExpansions(start, end);
                    }
                    return;

                case Collation.EXPANSION32_TAG:
                    if (sink != null)
                    {
                        int idx    = Collation.IndexFromCE32(ce32);
                        int length = Collation.LengthFromCE32(ce32);
                        for (int i = 0; i < length; ++i)
                        {
                            ces[i] = Collation.CeFromCE32(data.ce32s[idx + i]);
                        }
                        sink.HandleExpansion(ces, 0, length);
                    }
                    // Optimization: If we have a prefix,
                    // then the relevant strings have been added already.
                    if (unreversedPrefix.Length == 0)
                    {
                        AddExpansions(start, end);
                    }
                    return;

                case Collation.EXPANSION_TAG:
                    if (sink != null)
                    {
                        int idx    = Collation.IndexFromCE32(ce32);
                        int length = Collation.LengthFromCE32(ce32);
                        sink.HandleExpansion(data.ces, idx, length);
                    }
                    // Optimization: If we have a prefix,
                    // then the relevant strings have been added already.
                    if (unreversedPrefix.Length == 0)
                    {
                        AddExpansions(start, end);
                    }
                    return;

                case Collation.PREFIX_TAG:
                    HandlePrefixes(start, end, ce32);
                    return;

                case Collation.CONTRACTION_TAG:
                    HandleContractions(start, end, ce32);
                    return;

                case Collation.DIGIT_TAG:
                    // Fetch the non-numeric-collation CE32 and continue.
                    ce32 = data.ce32s[Collation.IndexFromCE32(ce32)];
                    break;

                case Collation.U0000_TAG:
                    Debug.Assert(start == 0 && end == 0);
                    // Fetch the normal ce32 for U+0000 and continue.
                    ce32 = data.ce32s[0];
                    break;

                case Collation.HANGUL_TAG:
                    if (sink != null)
                    {
                        // TODO: This should be optimized,
                        // especially if [start..end] is the complete Hangul range. (assert that)
                        UTF16CollationIterator    iter   = new UTF16CollationIterator(data);
                        StringBuilderCharSequence hangul = new StringBuilderCharSequence(new StringBuilder(1));
                        for (int c = start; c <= end; ++c)
                        {
                            hangul.StringBuilder.Length = 0;
                            hangul.StringBuilder.AppendCodePoint(c);
                            iter.SetText(false, hangul, 0);
                            int length = iter.FetchCEs();
                            // Ignore the terminating non-CE.
                            Debug.Assert(length >= 2 && iter.GetCE(length - 1) == Collation.NO_CE);
                            sink.HandleExpansion(iter.GetCEs(), 0, length - 1);
                        }
                    }
                    // Optimization: If we have a prefix,
                    // then the relevant strings have been added already.
                    if (unreversedPrefix.Length == 0)
                    {
                        AddExpansions(start, end);
                    }
                    return;

                case Collation.OFFSET_TAG:
                    // Currently no need to send offset CEs to the sink.
                    return;

                case Collation.IMPLICIT_TAG:
                    // Currently no need to send implicit CEs to the sink.
                    return;
                }
            }
        }