]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/collationfastlatin.cpp
ICU-551.51.4.tar.gz
[apple/icu.git] / icuSources / i18n / collationfastlatin.cpp
index 0b26d1d9f973551c8d8da126fb7d0a7d11b83fd9..4ae24e72265583d30938c2cb3f2dc897b9473a25 100644 (file)
@@ -1,6 +1,6 @@
 /*
 *******************************************************************************
-* Copyright (C) 2013-2014, International Business Machines
+* Copyright (C) 2013-2015, International Business Machines
 * Corporation and others.  All Rights Reserved.
 *******************************************************************************
 * collationfastlatin.cpp
@@ -36,33 +36,50 @@ CollationFastLatin::getOptions(const CollationData *data, const CollationSetting
         // lowest long mini primary.
         miniVarTop = MIN_LONG - 1;
     } else {
-        uint32_t v1 = settings.variableTop >> 24;
         int32_t headerLength = *table & 0xff;
-        int32_t i = headerLength - 1;
-        if(i <= 0 || v1 > (table[i] & 0x7f)) {
+        int32_t i = 1 + settings.getMaxVariable();
+        if(i >= headerLength) {
             return -1;  // variableTop >= digits, should not occur
         }
-        while(i > 1 && v1 <= (table[i - 1] & 0x7f)) { --i; }
-        // In the table header, the miniVarTop is in bits 15..7, with 4 zero bits 19..16 implied.
-        // Shift right to make it comparable with long mini primaries in bits 15..3.
-        miniVarTop = (table[i] & 0xff80) >> 4;
+        miniVarTop = table[i];
     }
 
-    const uint8_t *reorderTable = settings.reorderTable;
-    if(reorderTable != NULL) {
-        const uint16_t *scripts = data->scripts;
-        int32_t length = data->scriptsLength;
-        uint32_t prevLastByte = 0;
-        for(int32_t i = 0; i < length;) {
-            // reordered last byte of the group
-            uint32_t lastByte = reorderTable[scripts[i] & 0xff];
-            if(lastByte < prevLastByte) {
-                // The permutation affects the groups up to Latin.
-                return -1;
+    UBool digitsAreReordered = FALSE;
+    if(settings.hasReordering()) {
+        uint32_t prevStart = 0;
+        uint32_t beforeDigitStart = 0;
+        uint32_t digitStart = 0;
+        uint32_t afterDigitStart = 0;
+        for(int32_t group = UCOL_REORDER_CODE_FIRST;
+                group < UCOL_REORDER_CODE_FIRST + CollationData::MAX_NUM_SPECIAL_REORDER_CODES;
+                ++group) {
+            uint32_t start = data->getFirstPrimaryForGroup(group);
+            start = settings.reorder(start);
+            if(group == UCOL_REORDER_CODE_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;
             }
-            if(scripts[i + 2] == USCRIPT_LATIN) { break; }
-            i = i + 2 + scripts[i + 1];
-            prevLastByte = lastByte;
+        }
+        uint32_t 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;
         }
     }
 
@@ -78,7 +95,7 @@ CollationFastLatin::getOptions(const CollationData *data, const CollationSetting
         }
         primaries[c] = (uint16_t)p;
     }
-    if((settings.options & CollationSettings::NUMERIC) != 0) {
+    if(digitsAreReordered || (settings.options & CollationSettings::NUMERIC) != 0) {
         // Bail out for digits.
         for(UChar32 c = 0x30; c <= 0x39; ++c) { primaries[c] = 0; }
     }