Index: source/i18n/tmutfmt.cpp |
diff --git a/source/i18n/tmutfmt.cpp b/source/i18n/tmutfmt.cpp |
index b7c16e513bceb828c9ae7abcacb040bafa47eb28..1669546f7675354bbfc3538435e641dc9f174bd6 100644 |
--- a/source/i18n/tmutfmt.cpp |
+++ b/source/i18n/tmutfmt.cpp |
@@ -1,6 +1,8 @@ |
+// Copyright (C) 2016 and later: Unicode, Inc. and others. |
+// License & terms of use: http://www.unicode.org/copyright.html |
/* |
******************************************************************************* |
- * Copyright (C) 2008-2014, Google, International Business Machines Corporation |
+ * Copyright (C) 2008-2015, Google, International Business Machines Corporation |
* and others. All Rights Reserved. |
******************************************************************************* |
*/ |
@@ -10,6 +12,7 @@ |
#if !UCONFIG_NO_FORMATTING |
#include "unicode/decimfmt.h" |
+#include "unicode/localpointer.h" |
#include "plurrule_impl.h" |
#include "uvector.h" |
#include "charstr.h" |
@@ -119,7 +122,7 @@ TimeUnitFormat::TimeUnitFormat(const TimeUnitFormat& other) |
delete fTimeUnitToCountToPatterns[i]; |
fTimeUnitToCountToPatterns[i] = NULL; |
} |
- } |
+ } |
} |
@@ -133,13 +136,13 @@ TimeUnitFormat::~TimeUnitFormat() { |
} |
-Format* |
+Format* |
TimeUnitFormat::clone(void) const { |
return new TimeUnitFormat(*this); |
} |
-TimeUnitFormat& |
+TimeUnitFormat& |
TimeUnitFormat::operator=(const TimeUnitFormat& other) { |
if (this == &other) { |
return *this; |
@@ -162,16 +165,16 @@ TimeUnitFormat::operator=(const TimeUnitFormat& other) { |
delete fTimeUnitToCountToPatterns[i]; |
fTimeUnitToCountToPatterns[i] = NULL; |
} |
- } |
+ } |
fStyle = other.fStyle; |
return *this; |
} |
-void |
-TimeUnitFormat::parseObject(const UnicodeString& source, |
+void |
+TimeUnitFormat::parseObject(const UnicodeString& source, |
Formattable& result, |
ParsePosition& pos) const { |
- Formattable resultNumber(0.0); |
+ Formattable resultNumber(0.0); |
UBool withNumberFormat = false; |
TimeUnit::UTimeUnitFields resultTimeUnit = TimeUnit::UTIMEUNIT_FIELD_COUNT; |
int32_t oldPos = pos.getIndex(); |
@@ -181,7 +184,7 @@ TimeUnitFormat::parseObject(const UnicodeString& source, |
#ifdef TMUTFMT_DEBUG |
char res[1000]; |
source.extract(0, source.length(), res, "UTF-8"); |
- std::cout << "parse source: " << res << "\n"; |
+ std::cout << "parse source: " << res << "\n"; |
#endif |
// parse by iterating through all available patterns |
// and looking for the longest match. |
@@ -196,7 +199,7 @@ TimeUnitFormat::parseObject(const UnicodeString& source, |
UnicodeString* count = (UnicodeString*)keyTok.pointer; |
#ifdef TMUTFMT_DEBUG |
count->extract(0, count->length(), res, "UTF-8"); |
- std::cout << "parse plural count: " << res << "\n"; |
+ std::cout << "parse plural count: " << res << "\n"; |
#endif |
const UHashTok valueTok = elem->value; |
// the value is a pair of MessageFormat* |
@@ -271,9 +274,9 @@ TimeUnitFormat::parseObject(const UnicodeString& source, |
pos.setErrorIndex(0); |
} else { |
UErrorCode status = U_ZERO_ERROR; |
- TimeUnitAmount* tmutamt = new TimeUnitAmount(resultNumber, resultTimeUnit, status); |
+ LocalPointer<TimeUnitAmount> tmutamt(new TimeUnitAmount(resultNumber, resultTimeUnit, status), status); |
if (U_SUCCESS(status)) { |
- result.adoptObject(tmutamt); |
+ result.adoptObject(tmutamt.orphan()); |
pos.setIndex(newPos); |
pos.setErrorIndex(-1); |
} else { |
@@ -309,16 +312,16 @@ TimeUnitFormat::create(UTimeUnitFormatStyle style, UErrorCode& status) { |
//In Java, create an empty instance does not setup locale as |
//default locale. If it followed by setNumberFormat(), |
//in format(), the locale will set up as the locale in fNumberFormat. |
- //But in C++, this sets the locale as the default locale. |
+ //But in C++, this sets the locale as the default locale. |
setup(status); |
} |
-void |
+void |
TimeUnitFormat::setup(UErrorCode& err) { |
initDataMembers(err); |
UVector pluralCounts(0, uhash_compareUnicodeString, 6, err); |
- StringEnumeration* keywords = getPluralRules().getKeywords(err); |
+ LocalPointer<StringEnumeration> keywords(getPluralRules().getKeywords(err), err); |
if (U_FAILURE(err)) { |
return; |
} |
@@ -330,7 +333,6 @@ TimeUnitFormat::setup(UErrorCode& err) { |
checkConsistency(UTMUTFMT_FULL_STYLE, gUnitsTag, err); |
readFromCurrentLocale(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, pluralCounts, err); |
checkConsistency(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, err); |
- delete keywords; |
} |
@@ -347,45 +349,36 @@ TimeUnitFormat::initDataMembers(UErrorCode& err){ |
} |
} |
-void |
-TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* key, |
- const UVector& pluralCounts, UErrorCode& err) { |
- if (U_FAILURE(err)) { |
- return; |
- } |
- // fill timeUnitToCountToPatterns from resource file |
- // err is used to indicate wrong status except missing resource. |
- // status is an error code used in resource lookup. |
- // status does not affect "err". |
- UErrorCode status = U_ZERO_ERROR; |
- UResourceBundle *rb, *unitsRes; |
- rb = ures_open(U_ICUDATA_UNIT, getLocaleID(status), &status); |
- unitsRes = ures_getByKey(rb, key, NULL, &status); |
- unitsRes = ures_getByKey(unitsRes, "duration", unitsRes, &status); |
- if (U_FAILURE(status)) { |
- ures_close(unitsRes); |
- ures_close(rb); |
- return; |
- } |
- int32_t size = ures_getSize(unitsRes); |
- for ( int32_t index = 0; index < size; ++index) { |
- // resource of one time unit |
- UResourceBundle* oneTimeUnit = ures_getByIndex(unitsRes, index, |
- NULL, &status); |
- if (U_SUCCESS(status)) { |
- const char* timeUnitName = ures_getKey(oneTimeUnit); |
+struct TimeUnitFormatReadSink : public ResourceSink { |
+ TimeUnitFormat *timeUnitFormatObj; |
+ const UVector &pluralCounts; |
+ UTimeUnitFormatStyle style; |
+ UBool beenHere; |
+ |
+ TimeUnitFormatReadSink(TimeUnitFormat *timeUnitFormatObj, |
+ const UVector &pluralCounts, UTimeUnitFormatStyle style) : |
+ timeUnitFormatObj(timeUnitFormatObj), pluralCounts(pluralCounts), |
+ style(style), beenHere(FALSE){} |
+ |
+ virtual ~TimeUnitFormatReadSink(); |
+ |
+ virtual void put(const char *key, ResourceValue &value, UBool, UErrorCode &errorCode) { |
+ // Skip all put() calls except the first one -- discard all fallback data. |
+ if (beenHere) { |
+ return; |
+ } else { |
+ beenHere = TRUE; |
+ } |
+ |
+ ResourceTable units = value.getTable(errorCode); |
+ if (U_FAILURE(errorCode)) { return; } |
+ |
+ for (int32_t i = 0; units.getKeyAndValue(i, key, value); ++i) { |
+ const char* timeUnitName = key; |
if (timeUnitName == NULL) { |
- ures_close(oneTimeUnit); |
- continue; |
- } |
- UResourceBundle* countsToPatternRB = ures_getByKey(unitsRes, |
- timeUnitName, |
- NULL, &status); |
- if (countsToPatternRB == NULL || U_FAILURE(status)) { |
- ures_close(countsToPatternRB); |
- ures_close(oneTimeUnit); |
continue; |
} |
+ |
TimeUnit::UTimeUnitFields timeUnitField = TimeUnit::UTIMEUNIT_FIELD_COUNT; |
if ( uprv_strcmp(timeUnitName, gTimeUnitYear) == 0 ) { |
timeUnitField = TimeUnit::UTIMEUNIT_YEAR; |
@@ -402,79 +395,99 @@ TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* ke |
} else if ( uprv_strcmp(timeUnitName, gTimeUnitWeek) == 0 ) { |
timeUnitField = TimeUnit::UTIMEUNIT_WEEK; |
} else { |
- ures_close(countsToPatternRB); |
- ures_close(oneTimeUnit); |
continue; |
} |
- Hashtable* countToPatterns = fTimeUnitToCountToPatterns[timeUnitField]; |
+ LocalPointer<Hashtable> localCountToPatterns; |
+ Hashtable *countToPatterns = |
+ timeUnitFormatObj->fTimeUnitToCountToPatterns[timeUnitField]; |
if (countToPatterns == NULL) { |
- countToPatterns = initHash(err); |
- if (U_FAILURE(err)) { |
- ures_close(countsToPatternRB); |
- ures_close(oneTimeUnit); |
- delete countToPatterns; |
- break; |
+ localCountToPatterns.adoptInsteadAndCheckErrorCode( |
+ timeUnitFormatObj->initHash(errorCode), errorCode); |
+ countToPatterns = localCountToPatterns.getAlias(); |
+ if (U_FAILURE(errorCode)) { |
+ return; |
} |
} |
- int32_t count = ures_getSize(countsToPatternRB); |
- const char* pluralCount; |
- for ( int32_t pluralIndex = 0; pluralIndex < count; ++pluralIndex) { |
- // resource of count to pattern |
- UnicodeString pattern = |
- ures_getNextUnicodeString(countsToPatternRB, &pluralCount, &status); |
- if (U_FAILURE(status)) { |
+ |
+ ResourceTable countsToPatternTable = value.getTable(errorCode); |
+ if (U_FAILURE(errorCode)) { |
+ continue; |
+ } |
+ for (int32_t j = 0; countsToPatternTable.getKeyAndValue(j, key, value); ++j) { |
+ errorCode = U_ZERO_ERROR; |
+ UnicodeString pattern = value.getUnicodeString(errorCode); |
+ if (U_FAILURE(errorCode)) { |
continue; |
} |
- UnicodeString pluralCountUniStr(pluralCount, -1, US_INV); |
+ UnicodeString pluralCountUniStr(key, -1, US_INV); |
if (!pluralCounts.contains(&pluralCountUniStr)) { |
- continue; |
+ continue; |
} |
- MessageFormat* messageFormat = new MessageFormat(pattern, getLocale(err), err); |
- if ( U_SUCCESS(err) ) { |
- MessageFormat** formatters = (MessageFormat**)countToPatterns->get(pluralCountUniStr); |
- if (formatters == NULL) { |
- formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*)); |
- formatters[UTMUTFMT_FULL_STYLE] = NULL; |
- formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL; |
- countToPatterns->put(pluralCountUniStr, formatters, err); |
- if (U_FAILURE(err)) { |
- uprv_free(formatters); |
- } |
- } |
- if (U_SUCCESS(err)) { |
- //delete formatters[style]; |
- formatters[style] = messageFormat; |
- } |
- } |
- if (U_FAILURE(err)) { |
- ures_close(countsToPatternRB); |
- ures_close(oneTimeUnit); |
- ures_close(unitsRes); |
- ures_close(rb); |
- delete messageFormat; |
- delete countToPatterns; |
+ LocalPointer<MessageFormat> messageFormat(new MessageFormat( |
+ pattern, timeUnitFormatObj->getLocale(errorCode), errorCode), errorCode); |
+ if (U_FAILURE(errorCode)) { |
return; |
} |
+ MessageFormat** formatters = |
+ (MessageFormat**)countToPatterns->get(pluralCountUniStr); |
+ if (formatters == NULL) { |
+ LocalMemory<MessageFormat *> localFormatters( |
+ (MessageFormat **)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*))); |
+ if (localFormatters.isNull()) { |
+ errorCode = U_MEMORY_ALLOCATION_ERROR; |
+ return; |
+ } |
+ localFormatters[UTMUTFMT_FULL_STYLE] = NULL; |
+ localFormatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL; |
+ countToPatterns->put(pluralCountUniStr, localFormatters.getAlias(), errorCode); |
+ if (U_FAILURE(errorCode)) { |
+ return; |
+ } |
+ formatters = localFormatters.orphan(); |
+ } |
+ formatters[style] = messageFormat.orphan(); |
} |
- if (fTimeUnitToCountToPatterns[timeUnitField] == NULL) { |
- fTimeUnitToCountToPatterns[timeUnitField] = countToPatterns; |
+ |
+ if (timeUnitFormatObj->fTimeUnitToCountToPatterns[timeUnitField] == NULL) { |
+ timeUnitFormatObj->fTimeUnitToCountToPatterns[timeUnitField] = localCountToPatterns.orphan(); |
} |
- ures_close(countsToPatternRB); |
} |
- ures_close(oneTimeUnit); |
} |
- ures_close(unitsRes); |
- ures_close(rb); |
-} |
+}; |
+ |
+TimeUnitFormatReadSink::~TimeUnitFormatReadSink() {} |
-void |
+void |
+TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* key, |
+ const UVector& pluralCounts, UErrorCode& err) { |
+ if (U_FAILURE(err)) { |
+ return; |
+ } |
+ // fill timeUnitToCountToPatterns from resource file |
+ // err is used to indicate wrong status except missing resource. |
+ // status is an error code used in resource lookup. |
+ // status does not affect "err". |
+ UErrorCode status = U_ZERO_ERROR; |
+ LocalUResourceBundlePointer rb(ures_open(U_ICUDATA_UNIT, getLocaleID(status), &status)); |
+ |
+ LocalUResourceBundlePointer unitsRes(ures_getByKey(rb.getAlias(), key, NULL, &status)); |
+ ures_getByKey(unitsRes.getAlias(), "duration", unitsRes.getAlias(), &status); |
+ if (U_FAILURE(status)) { |
+ return; |
+ } |
+ |
+ TimeUnitFormatReadSink sink(this, pluralCounts, style); |
+ ures_getAllItemsWithFallback(unitsRes.getAlias(), "", sink, status); |
+} |
+ |
+void |
TimeUnitFormat::checkConsistency(UTimeUnitFormatStyle style, const char* key, UErrorCode& err) { |
if (U_FAILURE(err)) { |
return; |
} |
// there should be patterns for each plural rule in each time unit. |
- // For each time unit, |
+ // For each time unit, |
// for each plural rule, following is unit pattern fall-back rule: |
// ( for example: "one" hour ) |
// look for its unit pattern in its locale tree. |
@@ -485,45 +498,41 @@ TimeUnitFormat::checkConsistency(UTimeUnitFormatStyle style, const char* key, UE |
// fallback to plural count "other", |
// look for the pattern of "other" in the locale tree: |
// "de_DE" to "de" to "root". |
- // If not found, fall back to value of |
- // static variable DEFAULT_PATTERN_FOR_xxx, such as "{0} h". |
+ // If not found, fall back to value of |
+ // static variable DEFAULT_PATTERN_FOR_xxx, such as "{0} h". |
// |
// Following is consistency check to create pattern for each |
// plural rule in each time unit using above fall-back rule. |
// |
- StringEnumeration* keywords = getPluralRules().getKeywords(err); |
- if (U_SUCCESS(err)) { |
- const UnicodeString* pluralCount; |
- while ((pluralCount = keywords->snext(err)) != NULL) { |
- if ( U_SUCCESS(err) ) { |
- for (int32_t i = 0; i < TimeUnit::UTIMEUNIT_FIELD_COUNT; ++i) { |
- // for each time unit, |
- // get all the patterns for each plural rule in this locale. |
- Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i]; |
- if ( countToPatterns == NULL ) { |
- countToPatterns = initHash(err); |
- if (U_FAILURE(err)) { |
- delete countToPatterns; |
- return; |
- } |
- fTimeUnitToCountToPatterns[i] = countToPatterns; |
- } |
- MessageFormat** formatters = (MessageFormat**)countToPatterns->get(*pluralCount); |
- if( formatters == NULL || formatters[style] == NULL ) { |
- // look through parents |
- const char* localeName = getLocaleID(err); |
- CharString pluralCountChars; |
- pluralCountChars.appendInvariantChars(*pluralCount, err); |
- searchInLocaleChain(style, key, localeName, |
- (TimeUnit::UTimeUnitFields)i, |
- *pluralCount, pluralCountChars.data(), |
- countToPatterns, err); |
- } |
+ LocalPointer<StringEnumeration> keywords( |
+ getPluralRules().getKeywords(err), err); |
+ const UnicodeString* pluralCount; |
+ while (U_SUCCESS(err) && (pluralCount = keywords->snext(err)) != NULL) { |
+ for (int32_t i = 0; i < TimeUnit::UTIMEUNIT_FIELD_COUNT; ++i) { |
+ // for each time unit, |
+ // get all the patterns for each plural rule in this locale. |
+ Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i]; |
+ if ( countToPatterns == NULL ) { |
+ fTimeUnitToCountToPatterns[i] = countToPatterns = initHash(err); |
+ if (U_FAILURE(err)) { |
+ return; |
} |
} |
+ MessageFormat** formatters = (MessageFormat**)countToPatterns->get(*pluralCount); |
+ if( formatters == NULL || formatters[style] == NULL ) { |
+ // look through parents |
+ const char* localeName = getLocaleID(err); |
+ CharString pluralCountChars; |
+ pluralCountChars.appendInvariantChars(*pluralCount, err); |
+ searchInLocaleChain(style, key, localeName, |
+ (TimeUnit::UTimeUnitFields)i, |
+ *pluralCount, pluralCountChars.data(), |
+ countToPatterns, err); |
+ } |
+ // TODO: what to do with U_FAILURE(err) at this point. |
+ // As is, the outer loop continues to run, but does nothing. |
} |
} |
- delete keywords; |
} |
@@ -533,14 +542,14 @@ TimeUnitFormat::checkConsistency(UTimeUnitFormatStyle style, const char* key, UE |
// searchPluralCount is the fallback plural count. |
// For example, to search for pattern for ""one" hour", |
// "one" is the srcPluralCount, |
-// if the pattern is not found even in root, fallback to |
-// using patterns of plural count "other", |
+// if the pattern is not found even in root, fallback to |
+// using patterns of plural count "other", |
// then, "other" is the searchPluralCount. |
-void |
+void |
TimeUnitFormat::searchInLocaleChain(UTimeUnitFormatStyle style, const char* key, const char* localeName, |
TimeUnit::UTimeUnitFields srcTimeUnitField, |
const UnicodeString& srcPluralCount, |
- const char* searchPluralCount, |
+ const char* searchPluralCount, |
Hashtable* countToPatterns, |
UErrorCode& err) { |
if (U_FAILURE(err)) { |
@@ -554,46 +563,38 @@ TimeUnitFormat::searchInLocaleChain(UTimeUnitFormatStyle style, const char* key, |
while ((locNameLen = uloc_getParent(parentLocale, parentLocale, |
ULOC_FULLNAME_CAPACITY, &status)) >= 0){ |
// look for pattern for srcPluralCount in locale tree |
- UResourceBundle *rb, *unitsRes, *countsToPatternRB; |
- rb = ures_open(U_ICUDATA_UNIT, parentLocale, &status); |
- unitsRes = ures_getByKey(rb, key, NULL, &status); |
+ LocalUResourceBundlePointer rb(ures_open(U_ICUDATA_UNIT, parentLocale, &status)); |
+ LocalUResourceBundlePointer unitsRes(ures_getByKey(rb.getAlias(), key, NULL, &status)); |
const char* timeUnitName = getTimeUnitName(srcTimeUnitField, status); |
- countsToPatternRB = ures_getByKey(unitsRes, timeUnitName, NULL, &status); |
+ LocalUResourceBundlePointer countsToPatternRB(ures_getByKey(unitsRes.getAlias(), timeUnitName, NULL, &status)); |
const UChar* pattern; |
int32_t ptLength; |
- pattern = ures_getStringByKeyWithFallback(countsToPatternRB, searchPluralCount, &ptLength, &status); |
+ pattern = ures_getStringByKeyWithFallback(countsToPatternRB.getAlias(), searchPluralCount, &ptLength, &status); |
if (U_SUCCESS(status)) { |
//found |
- MessageFormat* messageFormat = new MessageFormat(UnicodeString(TRUE, pattern, ptLength), getLocale(err), err); |
- if (U_SUCCESS(err)) { |
- MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount); |
- if (formatters == NULL) { |
- formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*)); |
- formatters[UTMUTFMT_FULL_STYLE] = NULL; |
- formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL; |
- countToPatterns->put(srcPluralCount, formatters, err); |
- if (U_FAILURE(err)) { |
- uprv_free(formatters); |
- delete messageFormat; |
- } |
- } |
- if (U_SUCCESS(err)) { |
- //delete formatters[style]; |
- formatters[style] = messageFormat; |
+ LocalPointer<MessageFormat> messageFormat( |
+ new MessageFormat(UnicodeString(TRUE, pattern, ptLength), getLocale(err), err), err); |
+ if (U_FAILURE(err)) { |
+ return; |
+ } |
+ MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount); |
+ if (formatters == NULL) { |
+ LocalMemory<MessageFormat *> localFormatters( |
+ (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*))); |
+ formatters = localFormatters.getAlias(); |
+ localFormatters[UTMUTFMT_FULL_STYLE] = NULL; |
+ localFormatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL; |
+ countToPatterns->put(srcPluralCount, localFormatters.orphan(), err); |
+ if (U_FAILURE(err)) { |
+ return; |
} |
- } else { |
- delete messageFormat; |
} |
- ures_close(countsToPatternRB); |
- ures_close(unitsRes); |
- ures_close(rb); |
+ //delete formatters[style]; |
+ formatters[style] = messageFormat.orphan(); |
return; |
} |
- ures_close(countsToPatternRB); |
- ures_close(unitsRes); |
- ures_close(rb); |
status = U_ZERO_ERROR; |
- if ( locNameLen ==0 ) { |
+ if (locNameLen == 0) { |
break; |
} |
} |
@@ -604,13 +605,15 @@ TimeUnitFormat::searchInLocaleChain(UTimeUnitFormatStyle style, const char* key, |
#ifdef TMUTFMT_DEBUG |
std::cout << "loop into searchInLocaleChain since Short-Long-Alternative \n"; |
#endif |
- char pLocale[ULOC_FULLNAME_CAPACITY]; |
- uprv_strcpy(pLocale, localeName); |
+ CharString pLocale(localeName, -1, err); |
// Add an underscore at the tail of locale name, |
// so that searchInLocaleChain will check the current locale before falling back |
- uprv_strcat(pLocale, "_"); |
- searchInLocaleChain(style, gUnitsTag, pLocale, srcTimeUnitField, srcPluralCount, |
+ pLocale.append('_', err); |
+ searchInLocaleChain(style, gUnitsTag, pLocale.data(), srcTimeUnitField, srcPluralCount, |
searchPluralCount, countToPatterns, err); |
+ if (U_FAILURE(err)) { |
+ return; |
+ } |
MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount); |
if (formatters != NULL && formatters[style] != NULL) { |
return; |
@@ -621,7 +624,7 @@ TimeUnitFormat::searchInLocaleChain(UTimeUnitFormatStyle style, const char* key, |
// fall-back to plural count "other" |
if ( uprv_strcmp(searchPluralCount, gPluralCountOther) == 0 ) { |
// set default fall back the same as the resource in root |
- MessageFormat* messageFormat = NULL; |
+ LocalPointer<MessageFormat> messageFormat; |
const UChar *pattern = NULL; |
if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_SECOND ) { |
pattern = DEFAULT_PATTERN_FOR_SECOND; |
@@ -639,35 +642,37 @@ TimeUnitFormat::searchInLocaleChain(UTimeUnitFormatStyle style, const char* key, |
pattern = DEFAULT_PATTERN_FOR_YEAR; |
} |
if (pattern != NULL) { |
- messageFormat = new MessageFormat(UnicodeString(TRUE, pattern, -1), getLocale(err), err); |
+ messageFormat.adoptInsteadAndCheckErrorCode( |
+ new MessageFormat(UnicodeString(TRUE, pattern, -1), getLocale(err), err), err); |
} |
- if (U_SUCCESS(err)) { |
- MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount); |
- if (formatters == NULL) { |
- formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*)); |
- formatters[UTMUTFMT_FULL_STYLE] = NULL; |
- formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL; |
- countToPatterns->put(srcPluralCount, formatters, err); |
- if (U_FAILURE(err)) { |
- uprv_free(formatters); |
- delete messageFormat; |
- } |
- } |
- if (U_SUCCESS(err)) { |
- //delete formatters[style]; |
- formatters[style] = messageFormat; |
+ if (U_FAILURE(err)) { |
+ return; |
+ } |
+ MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount); |
+ if (formatters == NULL) { |
+ LocalMemory<MessageFormat *> localFormatters ( |
+ (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*))); |
+ if (localFormatters.isNull()) { |
+ err = U_MEMORY_ALLOCATION_ERROR; |
+ return; |
} |
- } else { |
- delete messageFormat; |
+ formatters = localFormatters.getAlias(); |
+ formatters[UTMUTFMT_FULL_STYLE] = NULL; |
+ formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL; |
+ countToPatterns->put(srcPluralCount, localFormatters.orphan(), err); |
+ } |
+ if (U_SUCCESS(err)) { |
+ //delete formatters[style]; |
+ formatters[style] = messageFormat.orphan(); |
} |
} else { |
// fall back to rule "other", and search in parents |
- searchInLocaleChain(style, key, localeName, srcTimeUnitField, srcPluralCount, |
+ searchInLocaleChain(style, key, localeName, srcTimeUnitField, srcPluralCount, |
gPluralCountOther, countToPatterns, err); |
} |
} |
-void |
+void |
TimeUnitFormat::setLocale(const Locale& locale, UErrorCode& status) { |
if (setMeasureFormatLocale(locale, status)) { |
setup(status); |
@@ -675,7 +680,7 @@ TimeUnitFormat::setLocale(const Locale& locale, UErrorCode& status) { |
} |
-void |
+void |
TimeUnitFormat::setNumberFormat(const NumberFormat& format, UErrorCode& status){ |
if (U_FAILURE(status)) { |
return; |
@@ -730,7 +735,7 @@ TimeUnitFormat::copyHash(const Hashtable* source, Hashtable* target, UErrorCode& |
} |
-U_CDECL_BEGIN |
+U_CDECL_BEGIN |
/** |
* set hash table value comparator |
@@ -761,7 +766,7 @@ TimeUnitFormat::initHash(UErrorCode& status) { |
return NULL; |
} |
if ( U_FAILURE(status) ) { |
- delete hTable; |
+ delete hTable; |
return NULL; |
} |
hTable->setValueComparator(tmutfmtHashTableValueComparator); |
@@ -770,7 +775,7 @@ TimeUnitFormat::initHash(UErrorCode& status) { |
const char* |
-TimeUnitFormat::getTimeUnitName(TimeUnit::UTimeUnitFields unitField, |
+TimeUnitFormat::getTimeUnitName(TimeUnit::UTimeUnitFields unitField, |
UErrorCode& status) { |
if (U_FAILURE(status)) { |
return NULL; |