ICU-22457 count() of getUnicodeKeywords is incorrect

The count() is incorrect if the Locale contains extension which is not -u-
for example -x-, -t-.

Currently, this PR only contains tests to show the problem.

ICU-22457 Fix the enum_count
This commit is contained in:
Frank Tang 2023-08-09 17:51:06 -07:00 committed by Frank Yung-Fong Tang
parent 52177cc8c7
commit 667ee72b7c
2 changed files with 30 additions and 1 deletions

View file

@ -2407,8 +2407,9 @@ Locale::getLocaleCache()
}
class KeywordEnumeration : public StringEnumeration {
private:
protected:
char *keywords;
private:
char *current;
int32_t length;
UnicodeString currUSKey;
@ -2515,6 +2516,17 @@ public:
if (resultLength != nullptr) *resultLength = 0;
return nullptr;
}
virtual int32_t count(UErrorCode &/*status*/) const override {
char *kw = keywords;
int32_t result = 0;
while(*kw) {
if (uloc_toUnicodeLocaleKey(kw) != nullptr) {
result++;
}
kw += uprv_strlen(kw)+1;
}
return result;
}
};
// Out-of-line virtual destructor to serve as the "key function".

View file

@ -3989,6 +3989,8 @@ LocaleTest::TestCreateUnicodeKeywords() {
LocalPointer<StringEnumeration> keys(l.createUnicodeKeywords(status));
status.errIfFailureAndReset("\"%s\"", l.getName());
assertEquals("count", 2, keys->count(status));
const char* key;
int32_t resultLength;
@ -4139,6 +4141,11 @@ LocaleTest::TestCreateUnicodeKeywordSet() {
result.find("ca") != result.end());
assertTrue("set::find(\"co\")",
result.find("co") != result.end());
LocalPointer<StringEnumeration> se(l.createUnicodeKeywords(status), status);
status.errIfFailureAndReset("\"%s\" createUnicodeKeywords()", l.getName());
assertEquals("count()", 2, se->count(status));
status.errIfFailureAndReset("\"%s\" count()", l.getName());
}
void
@ -4154,6 +4161,10 @@ LocaleTest::TestCreateUnicodeKeywordSetEmpty() {
status.errIfFailureAndReset("\"%s\"", l.getName());
assertEquals("set::size()", 0, static_cast<int32_t>(result.size()));
LocalPointer<StringEnumeration> se(l.createUnicodeKeywords(status), status);
assertTrue("createUnicodeKeywords", se.isNull());
status.expectErrorAndReset(U_MEMORY_ALLOCATION_ERROR);
}
void
@ -4174,6 +4185,12 @@ LocaleTest::TestCreateUnicodeKeywordSetWithPrivateUse() {
result.find("x") == result.end());
assertTrue("getUnicodeKeywords set::find(\"foo\")",
result.find("foo") == result.end());
assertEquals("set::size()", 1, static_cast<int32_t>(result.size()));
LocalPointer<StringEnumeration> se(l.createUnicodeKeywords(status), status);
status.errIfFailureAndReset("\"%s\" createUnicodeKeywords()", l.getName());
assertEquals("count()", 1, se->count(status));
status.errIfFailureAndReset("\"%s\" count()", l.getName());
}
void