ICU-8624 Fixed a collation key compression problem. A tertiary key value was incorrect with a long string when case first option is set.

X-SVN-Rev: 30220
This commit is contained in:
Yoshito Umaoka 2011-06-20 17:18:46 +00:00
parent 53aae67b42
commit 0f29677f6a
3 changed files with 78 additions and 8 deletions

View 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);

View 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 {

View 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 */