]> granicus.if.org Git - icu/commitdiff
ICU-8624 Fixed a collation key compression problem. A tertiary key value was incorrec...
authorYoshito Umaoka <y.umaoka@gmail.com>
Mon, 20 Jun 2011 17:18:46 +0000 (17:18 +0000)
committerYoshito Umaoka <y.umaoka@gmail.com>
Mon, 20 Jun 2011 17:18:46 +0000 (17:18 +0000)
X-SVN-Rev: 30220

icu4c/source/i18n/ucol.cpp
icu4c/source/test/intltest/regcoll.cpp
icu4c/source/test/intltest/regcoll.h

index 32c6a74f0f6aa383bbe518793f4c89347b56e831..162388cdf712dbb20edc9b8107d42d51d3280c7c 100644 (file)
@@ -6417,7 +6417,7 @@ void ucol_updateInternalState(UCollator *coll, UErrorCode *status) {
         }
 
         /* Set the compression values */
-        uint8_t tertiaryTotal = (uint8_t)(coll->tertiaryTop - UCOL_COMMON_BOT3-1);
+        uint8_t tertiaryTotal = (uint8_t)(coll->tertiaryTop - coll->tertiaryBottom - 1);
         coll->tertiaryTopCount = (uint8_t)(UCOL_PROPORTION3*tertiaryTotal); /* we multilply double with int, but need only int */
         coll->tertiaryBottomCount = (uint8_t)(tertiaryTotal - coll->tertiaryTopCount);
 
index 874ca8783c428ddbc64c9021b7fcd76c77340e5f..4028f43602dad29cd22676907278ea3926d7dbe6 100644 (file)
@@ -1,6 +1,6 @@
 /********************************************************************
  * COPYRIGHT:
- * Copyright (c) 1997-2010, International Business Machines Corporation and
+ * Copyright (c) 1997-2011, International Business Machines Corporation and
  * others. All Rights Reserved.
  ********************************************************************/
 
@@ -1157,6 +1157,67 @@ void CollationRegressionTest::TestT7189() {
     ucol_close(coll);
 }
 
+void CollationRegressionTest::TestCaseFirstCompression() {
+    RuleBasedCollator *col = (RuleBasedCollator *) en_us->clone();
+    UErrorCode status = U_ZERO_ERROR;
+
+    // default
+    caseFirstCompressionSub(col, "default");
+
+    // Upper first
+    col->setAttribute(UCOL_CASE_FIRST, UCOL_UPPER_FIRST, status);
+    if (U_FAILURE(status)) {
+        errln("Failed to set UCOL_UPPER_FIRST");
+        return;
+    }
+    caseFirstCompressionSub(col, "upper first");
+
+    // Lower first
+    col->setAttribute(UCOL_CASE_FIRST, UCOL_LOWER_FIRST, status);
+    if (U_FAILURE(status)) {
+        errln("Failed to set UCOL_LOWER_FIRST");
+        return;
+    }
+    caseFirstCompressionSub(col, "lower first");
+
+    delete col;
+}
+
+void CollationRegressionTest::caseFirstCompressionSub(Collator *col, UnicodeString opt) {
+    const int32_t maxLength = 50;
+
+    UChar str1[maxLength];
+    UChar str2[maxLength];
+
+    CollationKey key1, key2;
+
+    for (int32_t len = 1; len <= maxLength; len++) {
+        int32_t i = 0;
+        for (; i < len - 1; i++) {
+            str1[i] = str2[i] = (UChar)0x61; // 'a'
+        }
+        str1[i] = (UChar)0x41; // 'A'
+        str2[i] = (UChar)0x61; // 'a'
+
+        UErrorCode status = U_ZERO_ERROR;
+        col->getCollationKey(str1, len, key1, status);
+        col->getCollationKey(str2, len, key2, status);
+
+        UCollationResult cmpKey = key1.compareTo(key2, status);
+        UCollationResult cmpCol = col->compare(str1, len, str2, len, status);
+
+        if (U_FAILURE(status)) {
+            errln("Error in caseFirstCompressionSub");
+        } else if (cmpKey != cmpCol) {
+            errln((UnicodeString)"Inconsistent comparison(" + opt
+                + "): str1=" + UnicodeString(str1, len) + ", str2=" + UnicodeString(str2, len)
+                + ", cmpKey=" + cmpKey + ", cmpCol=" + cmpCol);
+        }
+    }
+}
+
+
+
 void CollationRegressionTest::compareArray(Collator &c,
                                            const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN],
                                            int32_t testCount)
@@ -1288,7 +1349,8 @@ void CollationRegressionTest::runIndexedTest(int32_t index, UBool exec, const ch
           case 28: name = "Test4139572"; if (exec) Test4139572(/* par */); break;
           case 29: name = "Test4141640"; if (exec) Test4141640(/* par */); break;
           case 30: name = "Test4146160"; if (exec) Test4146160(/* par */); break;
-                 case 31: name = "TestT7189";   if (exec) TestT7189(); break;
+          case 31: name = "TestT7189";   if (exec) TestT7189(); break;
+          case 32: name = "TestCaseFirstCompression"; if (exec) TestCaseFirstCompression(); break;
           default: name = ""; break;
       }
     } else {
index 07f5a7e18f09014a97f5554ec38254fb7930ba7e..54fb280553f6e8f291f674aedc02e09c398c6e8f 100644 (file)
@@ -1,6 +1,6 @@
 /********************************************************************
  * COPYRIGHT: 
- * Copyright (c) 1997-2009, International Business Machines Corporation and
+ * Copyright (c) 1997-2011, International Business Machines Corporation and
  * others. All Rights Reserved.
  ********************************************************************/
 
@@ -224,10 +224,17 @@ public:
     //
     void Test4146160(/* char* par */);
 
-       // Ticket 7189
-       //
-       // nextSortKeyPart incorrect for EO_S1 collation
-       void TestT7189();
+    // Ticket 7189
+    //
+    // nextSortKeyPart incorrect for EO_S1 collation
+    //
+    void TestT7189();
+
+    // Ticket 8624
+    //
+    // Tertiary value compression problem with case first option enabled
+    //
+    void TestCaseFirstCompression();
 
 private:
     //------------------------------------------------------------------------
@@ -242,6 +249,7 @@ private:
 
     RuleBasedCollator *en_us;
 
+    void caseFirstCompressionSub(Collator *col, UnicodeString opt);
 };
 
 #endif /* #if !UCONFIG_NO_COLLATION */