ICU-9042 in time unit format, ignore those plural counts that are not defined in the locale's plural rules

X-SVN-Rev: 31924
This commit is contained in:
Xiaomei Ji 2012-06-08 19:02:03 +00:00
parent 3c69969daa
commit a9ea9b2a82
4 changed files with 59 additions and 11 deletions

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2008-2011, Google, International Business Machines Corporation
* Copyright (C) 2008-2012, Google, International Business Machines Corporation
* and others. All Rights Reserved.
*******************************************************************************
*/
@ -386,9 +386,19 @@ TimeUnitFormat::create(const Locale& locale, UTimeUnitFormatStyle style, UErrorC
void
TimeUnitFormat::setup(UErrorCode& err) {
initDataMembers(err);
readFromCurrentLocale(UTMUTFMT_FULL_STYLE, gUnitsTag, err);
UVector pluralCounts(0, uhash_compareUnicodeString, 6, err);
StringEnumeration* keywords = fPluralRules->getKeywords(err);
if (U_FAILURE(err)) {
return;
}
UnicodeString* pluralCount;
while ((pluralCount = const_cast<UnicodeString*>(keywords->snext(err))) != NULL) {
pluralCounts.addElement(pluralCount, err);
}
readFromCurrentLocale(UTMUTFMT_FULL_STYLE, gUnitsTag, pluralCounts, err);
checkConsistency(UTMUTFMT_FULL_STYLE, gUnitsTag, err);
readFromCurrentLocale(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, err);
readFromCurrentLocale(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, pluralCounts, err);
checkConsistency(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, err);
}
@ -415,7 +425,8 @@ TimeUnitFormat::initDataMembers(UErrorCode& err){
void
TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* key, UErrorCode& err) {
TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* key,
const UVector& pluralCounts, UErrorCode& err) {
if (U_FAILURE(err)) {
return;
}
@ -490,12 +501,15 @@ TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* ke
if (U_FAILURE(status)) {
continue;
}
UnicodeString pluralCountUniStr(pluralCount, -1, US_INV);
if (!pluralCounts.contains(&pluralCountUniStr)) {
continue;
}
MessageFormat* messageFormat = new MessageFormat(pattern, fLocale, err);
if ( U_SUCCESS(err) ) {
if (fNumberFormat != NULL) {
messageFormat->setFormat(0, *fNumberFormat);
}
UnicodeString pluralCountUniStr(pluralCount, -1, US_INV);
MessageFormat** formatters = (MessageFormat**)countToPatterns->get(pluralCountUniStr);
if (formatters == NULL) {
formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*));
@ -763,6 +777,7 @@ TimeUnitFormat::setNumberFormat(const NumberFormat& format, UErrorCode& status){
while ((elem = fTimeUnitToCountToPatterns[i]->nextElement(pos)) != NULL){
const UHashTok keyTok = elem->value;
MessageFormat** pattern = (MessageFormat**)keyTok.pointer;
pattern[UTMUTFMT_FULL_STYLE]->setFormat(0, format);
pattern[UTMUTFMT_ABBREVIATED_STYLE]->setFormat(0, format);
}

View File

@ -24,6 +24,7 @@
#include "unicode/measfmt.h"
#include "unicode/numfmt.h"
#include "unicode/plurrule.h"
#include "uvector.h"
/**
* Constants for various styles.
@ -229,7 +230,8 @@ private:
void initDataMembers(UErrorCode& status);
// initialize fTimeUnitToCountToPatterns from current locale's resource.
void readFromCurrentLocale(UTimeUnitFormatStyle style, const char* key, UErrorCode& status);
void readFromCurrentLocale(UTimeUnitFormatStyle style, const char* key, const UVector& pluralCounts,
UErrorCode& status);
// check completeness of fTimeUnitToCountToPatterns against all time units,
// and all plural rules, fill in fallback as necessary.

View File

@ -1,5 +1,5 @@
/********************************************************************
* Copyright (c) 2008-2011, International Business Machines Corporation and
* Copyright (c) 2008-2012, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
@ -25,7 +25,8 @@ void TimeUnitTest::runIndexedTest( int32_t index, UBool exec, const char* &name,
switch (index) {
TESTCASE(0, testBasic);
TESTCASE(1, testAPI);
TESTCASE(2, testGreek);
TESTCASE(2, testGreekWithFallback);
TESTCASE(3, testGreekWithSanitization);
default: name = ""; break;
}
}
@ -208,7 +209,7 @@ void TimeUnitTest::testAPI() {
* to long unit names for a locale where the locale data does not
* provide short unit names. As of CLDR 1.9, Greek is one such language.
*/
void TimeUnitTest::testGreek() {
void TimeUnitTest::testGreekWithFallback() {
UErrorCode status = U_ZERO_ERROR;
const char* locales[] = {"el-GR", "el"};
@ -323,4 +324,23 @@ void TimeUnitTest::testGreek() {
}
}
// Test bug9042
void TimeUnitTest::testGreekWithSanitization() {
UErrorCode status = U_ZERO_ERROR;
Locale elLoc("el");
NumberFormat* numberFmt = NumberFormat::createInstance(Locale("el"), status);
if (!assertSuccess("NumberFormat::createInstance for el locale", status)) return;
numberFmt->setMaximumFractionDigits(1);
TimeUnitFormat* timeUnitFormat = new TimeUnitFormat(elLoc, status);
if (!assertSuccess("TimeUnitFormat::TimeUnitFormat for el locale", status)) return;
timeUnitFormat->setNumberFormat(*numberFmt, status);
delete numberFmt;
delete timeUnitFormat;
}
#endif

View File

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 2008-2010, International Business Machines Corporation
* Copyright (c) 2008-2012, International Business Machines Corporation
* and others. All Rights Reserved.
********************************************************************/
@ -37,7 +37,18 @@ public:
* to long unit names for a locale where the locale data does not
* provide short unit names. As of CLDR 1.9, Greek is one such language.
**/
void testGreek();
void testGreekWithFallback();
/**
* Performs tests for Greek
* This tests that if the plural count listed in time unit format does not
* match those in the plural rules for the locale, those plural count in
* time unit format will be ingored and subsequently, fall back will kick in
* which is tested above.
* Without data sanitization, setNumberFormat() would crash.
* As of CLDR shiped in ICU4.8, Greek is one such language.
*/
void testGreekWithSanitization();
};
#endif /* #if !UCONFIG_NO_FORMATTING */