From: kazède king Date: Fri, 24 Jun 2016 00:51:49 +0000 (+0000) Subject: ICU-12605 convert data enumeration to resource sink for TimeUnitFormat, C++ X-Git-Tag: milestone-59-0-1~362 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b9250c1a6e0314461d2df7795272a069e4f92427;p=icu ICU-12605 convert data enumeration to resource sink for TimeUnitFormat, C++ X-SVN-Rev: 38878 --- diff --git a/icu4c/source/i18n/tmutfmt.cpp b/icu4c/source/i18n/tmutfmt.cpp index 629e85616ff..1669546f767 100644 --- a/icu4c/source/i18n/tmutfmt.cpp +++ b/icu4c/source/i18n/tmutfmt.cpp @@ -349,6 +349,115 @@ TimeUnitFormat::initDataMembers(UErrorCode& err){ } } +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) { + continue; + } + + TimeUnit::UTimeUnitFields timeUnitField = TimeUnit::UTIMEUNIT_FIELD_COUNT; + if ( uprv_strcmp(timeUnitName, gTimeUnitYear) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_YEAR; + } else if ( uprv_strcmp(timeUnitName, gTimeUnitMonth) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_MONTH; + } else if ( uprv_strcmp(timeUnitName, gTimeUnitDay) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_DAY; + } else if ( uprv_strcmp(timeUnitName, gTimeUnitHour) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_HOUR; + } else if ( uprv_strcmp(timeUnitName, gTimeUnitMinute) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_MINUTE; + } else if ( uprv_strcmp(timeUnitName, gTimeUnitSecond) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_SECOND; + } else if ( uprv_strcmp(timeUnitName, gTimeUnitWeek) == 0 ) { + timeUnitField = TimeUnit::UTIMEUNIT_WEEK; + } else { + continue; + } + LocalPointer localCountToPatterns; + Hashtable *countToPatterns = + timeUnitFormatObj->fTimeUnitToCountToPatterns[timeUnitField]; + if (countToPatterns == NULL) { + localCountToPatterns.adoptInsteadAndCheckErrorCode( + timeUnitFormatObj->initHash(errorCode), errorCode); + countToPatterns = localCountToPatterns.getAlias(); + if (U_FAILURE(errorCode)) { + return; + } + } + + 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(key, -1, US_INV); + if (!pluralCounts.contains(&pluralCountUniStr)) { + continue; + } + LocalPointer messageFormat(new MessageFormat( + pattern, timeUnitFormatObj->getLocale(errorCode), errorCode), errorCode); + if (U_FAILURE(errorCode)) { + return; + } + MessageFormat** formatters = + (MessageFormat**)countToPatterns->get(pluralCountUniStr); + if (formatters == NULL) { + LocalMemory 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 (timeUnitFormatObj->fTimeUnitToCountToPatterns[timeUnitField] == NULL) { + timeUnitFormatObj->fTimeUnitToCountToPatterns[timeUnitField] = localCountToPatterns.orphan(); + } + } + } + +}; + +TimeUnitFormatReadSink::~TimeUnitFormatReadSink() {} + void TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* key, const UVector& pluralCounts, UErrorCode& err) { @@ -367,94 +476,10 @@ TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* ke if (U_FAILURE(status)) { return; } - int32_t size = ures_getSize(unitsRes.getAlias()); - for ( int32_t index = 0; index < size; ++index) { - status = U_ZERO_ERROR; - // resource of one time unit - LocalUResourceBundlePointer oneTimeUnit( - ures_getByIndex(unitsRes.getAlias(), index, NULL, &status)); - if (U_FAILURE(status)) { - continue; - } - const char* timeUnitName = ures_getKey(oneTimeUnit.getAlias()); - if (timeUnitName == NULL) { - continue; - } - LocalUResourceBundlePointer countsToPatternRB( - ures_getByKey(unitsRes.getAlias(), timeUnitName, NULL, &status)); - if (countsToPatternRB.isNull() || U_FAILURE(status)) { - continue; - } - TimeUnit::UTimeUnitFields timeUnitField = TimeUnit::UTIMEUNIT_FIELD_COUNT; - if ( uprv_strcmp(timeUnitName, gTimeUnitYear) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_YEAR; - } else if ( uprv_strcmp(timeUnitName, gTimeUnitMonth) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_MONTH; - } else if ( uprv_strcmp(timeUnitName, gTimeUnitDay) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_DAY; - } else if ( uprv_strcmp(timeUnitName, gTimeUnitHour) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_HOUR; - } else if ( uprv_strcmp(timeUnitName, gTimeUnitMinute) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_MINUTE; - } else if ( uprv_strcmp(timeUnitName, gTimeUnitSecond) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_SECOND; - } else if ( uprv_strcmp(timeUnitName, gTimeUnitWeek) == 0 ) { - timeUnitField = TimeUnit::UTIMEUNIT_WEEK; - } else { - continue; - } - LocalPointer localCountToPatterns; - Hashtable *countToPatterns = fTimeUnitToCountToPatterns[timeUnitField]; - if (countToPatterns == NULL) { - localCountToPatterns.adoptInsteadAndCheckErrorCode(initHash(err), err); - countToPatterns = localCountToPatterns.getAlias(); - if (U_FAILURE(err)) { - return; - } - } - int32_t count = ures_getSize(countsToPatternRB.getAlias()); - const char* pluralCount; - for ( int32_t pluralIndex = 0; pluralIndex < count; ++pluralIndex) { - // resource of count to pattern - status = U_ZERO_ERROR; - UnicodeString pattern = - ures_getNextUnicodeString(countsToPatternRB.getAlias(), &pluralCount, &status); - if (U_FAILURE(status)) { - continue; - } - UnicodeString pluralCountUniStr(pluralCount, -1, US_INV); - if (!pluralCounts.contains(&pluralCountUniStr)) { - continue; - } - LocalPointer messageFormat(new MessageFormat(pattern, getLocale(err), err), err); - if (U_FAILURE(err)) { - return; - } - MessageFormat** formatters = (MessageFormat**)countToPatterns->get(pluralCountUniStr); - if (formatters == NULL) { - LocalMemory localFormatters( - (MessageFormat **)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*))); - if (localFormatters.isNull()) { - err = U_MEMORY_ALLOCATION_ERROR; - return; - } - localFormatters[UTMUTFMT_FULL_STYLE] = NULL; - localFormatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL; - countToPatterns->put(pluralCountUniStr, localFormatters.getAlias(), err); - if (U_FAILURE(err)) { - return; - } - formatters = localFormatters.orphan(); - } - //delete formatters[style]; - formatters[style] = messageFormat.orphan(); - } - if (fTimeUnitToCountToPatterns[timeUnitField] == NULL) { - fTimeUnitToCountToPatterns[timeUnitField] = localCountToPatterns.orphan(); - } - } -} + TimeUnitFormatReadSink sink(this, pluralCounts, style); + ures_getAllItemsWithFallback(unitsRes.getAlias(), "", sink, status); +} void TimeUnitFormat::checkConsistency(UTimeUnitFormatStyle style, const char* key, UErrorCode& err) { diff --git a/icu4c/source/i18n/unicode/tmutfmt.h b/icu4c/source/i18n/unicode/tmutfmt.h index eb4cd785b81..a3049a7835d 100644 --- a/icu4c/source/i18n/unicode/tmutfmt.h +++ b/icu4c/source/i18n/unicode/tmutfmt.h @@ -52,6 +52,8 @@ U_NAMESPACE_BEGIN class Hashtable; class UVector; +struct TimeUnitFormatReadSink; + /** * Format or parse a TimeUnitAmount, using plural rules for the units where available. * @@ -229,6 +231,7 @@ private: // UTIMEUNIT_YEAR. static const char* getTimeUnitName(TimeUnit::UTimeUnitFields field, UErrorCode& status); + friend TimeUnitFormatReadSink; }; inline UBool