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