コード例 #1
0
        private bool LoadGroups(CollationData data)
        {
            headerLength = 1 + NUM_SPECIAL_GROUPS;
            int r0 = (CollationFastLatin.Version << 8) | headerLength;

            result.Append((char)r0);
            // The first few reordering groups should be special groups
            // (space, punct, ..., digit) followed by Latn, then Grek and other scripts.
            for (int i = 0; i < NUM_SPECIAL_GROUPS; ++i)
            {
                lastSpecialPrimaries[i] = data.GetLastPrimaryForGroup(ReorderCodes.First + i);
                if (lastSpecialPrimaries[i] == 0)
                {
                    // missing data
                    return(false);
                }
                // ICU4N: Use char instead of int to append the value to ensure ambient culture has no effect
                result.Append('0');  // reserve a slot for this group
            }

            firstDigitPrimary = data.GetFirstPrimaryForGroup(ReorderCodes.Digit);
            firstLatinPrimary = data.GetFirstPrimaryForGroup(UScript.Latin);
            lastLatinPrimary  = data.GetLastPrimaryForGroup(UScript.Latin);
            if (firstDigitPrimary == 0 || firstLatinPrimary == 0)
            {
                // missing data
                return(false);
            }
            return(true);
        }
コード例 #2
0
        private bool LoadGroups(CollationData data)
        {
            headerLength = 1 + NUM_SPECIAL_GROUPS;
            int r0 = (CollationFastLatin.VERSION << 8) | headerLength;

            result.Append((char)r0);
            // The first few reordering groups should be special groups
            // (space, punct, ..., digit) followed by Latn, then Grek and other scripts.
            for (int i = 0; i < NUM_SPECIAL_GROUPS; ++i)
            {
                lastSpecialPrimaries[i] = data.GetLastPrimaryForGroup(ReorderCodes.First + i);
                if (lastSpecialPrimaries[i] == 0)
                {
                    // missing data
                    return(false);
                }
                // ICU4N TODO: Check this (not sure about char data type)
                result.Append((char)0);  // reserve a slot for this group
            }

            firstDigitPrimary = data.GetFirstPrimaryForGroup(ReorderCodes.Digit);
            firstLatinPrimary = data.GetFirstPrimaryForGroup(UScript.Latin);
            lastLatinPrimary  = data.GetLastPrimaryForGroup(UScript.Latin);
            if (firstDigitPrimary == 0 || firstLatinPrimary == 0)
            {
                // missing data
                return(false);
            }
            return(true);
        }
コード例 #3
0
        /// <summary>
        /// Computes the options value for the compare functions
        /// and writes the precomputed primary weights.
        /// Returns -1 if the Latin fastpath is not supported for the data and settings.
        /// The capacity must be <see cref="LatinLimit"/>.
        /// </summary>
        public static int GetOptions(CollationData data, CollationSettings settings,
                                     char[] primaries)
        {
            char[] header = data.fastLatinTableHeader;
            if (header == null)
            {
                return(-1);
            }
            Debug.Assert((header[0] >> 8) == Version);
            if (primaries.Length != LatinLimit)
            {
                Debug.Assert(false);
                return(-1);
            }

            int miniVarTop;

            if ((settings.Options & CollationSettings.AlternateMask) == 0)
            {
                // No mini primaries are variable, set a variableTop just below the
                // lowest long mini primary.
                miniVarTop = MIN_LONG - 1;
            }
            else
            {
                int headerLength = header[0] & 0xff;
                int i            = 1 + settings.MaxVariable;
                if (i >= headerLength)
                {
                    return(-1);  // variableTop >= digits, should not occur
                }
                miniVarTop = header[i];
            }

            bool digitsAreReordered = false;

            if (settings.HasReordering)
            {
                long prevStart        = 0;
                long beforeDigitStart = 0;
                long digitStart       = 0;
                long afterDigitStart  = 0;
                for (int group = ReorderCodes.First;
                     group < ReorderCodes.First + CollationData.MAX_NUM_SPECIAL_REORDER_CODES;
                     ++group)
                {
                    long start = data.GetFirstPrimaryForGroup(group);
                    start = settings.Reorder(start);
                    if (group == ReorderCodes.Digit)
                    {
                        beforeDigitStart = prevStart;
                        digitStart       = start;
                    }
                    else if (start != 0)
                    {
                        if (start < prevStart)
                        {
                            // The permutation affects the groups up to Latin.
                            return(-1);
                        }
                        // In the future, there might be a special group between digits & Latin.
                        if (digitStart != 0 && afterDigitStart == 0 && prevStart == beforeDigitStart)
                        {
                            afterDigitStart = start;
                        }
                        prevStart = start;
                    }
                }
                long latinStart = data.GetFirstPrimaryForGroup(UScript.Latin);
                latinStart = settings.Reorder(latinStart);
                if (latinStart < prevStart)
                {
                    return(-1);
                }
                if (afterDigitStart == 0)
                {
                    afterDigitStart = latinStart;
                }
                if (!(beforeDigitStart < digitStart && digitStart < afterDigitStart))
                {
                    digitsAreReordered = true;
                }
            }

            char[] table = data.FastLatinTable;  // skip the header
            for (int c = 0; c < LatinLimit; ++c)
            {
                int p = table[c];
                if (p >= MIN_SHORT)
                {
                    p &= SHORT_PRIMARY_MASK;
                }
                else if (p > miniVarTop)
                {
                    p &= LONG_PRIMARY_MASK;
                }
                else
                {
                    p = 0;
                }
                primaries[c] = (char)p;
            }
            if (digitsAreReordered || (settings.Options & CollationSettings.Numeric) != 0)
            {
                // Bail out for digits.
                for (int c = 0x30; c <= 0x39; ++c)
                {
                    primaries[c] = (char)0;
                }
            }

            // Shift the miniVarTop above other options.
            return((miniVarTop << 16) | settings.Options);
        }