]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/tmutfmt.cpp
ICU-57166.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / tmutfmt.cpp
index 57f3463d1e102d2651afcd9561cd5bc8fa8e816f..fa31d7b3c1815cc50375dea3ac6f81a551c67d06 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *******************************************************************************
- * 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 +10,7 @@
 #if !UCONFIG_NO_FORMATTING
 
 #include "unicode/decimfmt.h"
+#include "unicode/localpointer.h"
 #include "plurrule_impl.h"
 #include "uvector.h"
 #include "charstr.h"
@@ -17,6 +18,7 @@
 #include "cstring.h"
 #include "hash.h"
 #include "uresimp.h"
+#include "ureslocs.h"
 #include "unicode/msgfmt.h"
 #include "uassert.h"
 
@@ -118,7 +120,7 @@ TimeUnitFormat::TimeUnitFormat(const TimeUnitFormat& other)
             delete fTimeUnitToCountToPatterns[i];
             fTimeUnitToCountToPatterns[i] = NULL;
         }
-    } 
+    }
 }
 
 
@@ -132,13 +134,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;
@@ -161,16 +163,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();
@@ -180,7 +182,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.
@@ -188,14 +190,14 @@ TimeUnitFormat::parseObject(const UnicodeString& source,
          i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
          i = (TimeUnit::UTimeUnitFields)(i+1)) {
         Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i];
-        int32_t elemPos = -1;
+        int32_t elemPos = UHASH_FIRST;
         const UHashElement* elem = NULL;
         while ((elem = countToPatterns->nextElement(elemPos)) != NULL){
             const UHashTok keyTok = elem->key;
             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*
@@ -270,9 +272,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 {
@@ -308,16 +310,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;
     }
@@ -329,7 +331,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;
 }
 
 
@@ -357,123 +358,109 @@ TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* ke
     // 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(NULL, getLocaleID(status), &status);
-    unitsRes = ures_getByKey(rb, key, NULL, &status);
-    unitsRes = ures_getByKey(unitsRes, "duration", unitsRes, &status);
+    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)) {
-        ures_close(unitsRes);
-        ures_close(rb);
         return;
     }
-    int32_t size = ures_getSize(unitsRes);
+    int32_t size = ures_getSize(unitsRes.getAlias());
     for ( int32_t index = 0; index < size; ++index) {
+        status = U_ZERO_ERROR;
         // resource of one time unit
-        UResourceBundle* oneTimeUnit = ures_getByIndex(unitsRes, index,
-                                                       NULL, &status);
-        if (U_SUCCESS(status)) {
-            const char* timeUnitName = ures_getKey(oneTimeUnit);
-            if (timeUnitName == NULL) {
-                ures_close(oneTimeUnit);
-                continue;
+        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<Hashtable> localCountToPatterns;
+        Hashtable *countToPatterns = fTimeUnitToCountToPatterns[timeUnitField];
+        if (countToPatterns == NULL) {
+            localCountToPatterns.adoptInsteadAndCheckErrorCode(initHash(err), err);
+            countToPatterns = localCountToPatterns.getAlias();
+            if (U_FAILURE(err)) {
+                return;
             }
-            UResourceBundle* countsToPatternRB = ures_getByKey(unitsRes, 
-                                                             timeUnitName, 
-                                                             NULL, &status);
-            if (countsToPatternRB == NULL || U_FAILURE(status)) {
-                ures_close(countsToPatternRB);
-                ures_close(oneTimeUnit);
+        }
+        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;
             }
-            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 {
-                ures_close(countsToPatternRB);
-                ures_close(oneTimeUnit);
+            UnicodeString pluralCountUniStr(pluralCount, -1, US_INV);
+            if (!pluralCounts.contains(&pluralCountUniStr)) {
                 continue;
             }
-            Hashtable* countToPatterns = fTimeUnitToCountToPatterns[timeUnitField];
-            if (countToPatterns == NULL) {
-                countToPatterns = initHash(err);
-                if (U_FAILURE(err)) {
-                    ures_close(countsToPatternRB);
-                    ures_close(oneTimeUnit);
-                    delete countToPatterns;
-                    break;
-                }
+            LocalPointer<MessageFormat> messageFormat(new MessageFormat(pattern, getLocale(err), err), err);
+            if (U_FAILURE(err)) {
+                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)) {
-                    continue;
-                }
-                UnicodeString pluralCountUniStr(pluralCount, -1, US_INV);
-                if (!pluralCounts.contains(&pluralCountUniStr)) {
-                  continue;
+            MessageFormat** formatters = (MessageFormat**)countToPatterns->get(pluralCountUniStr);
+            if (formatters == NULL) {
+                LocalMemory<MessageFormat *> localFormatters(
+                        (MessageFormat **)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*)));
+                if (localFormatters.isNull()) {
+                    err = U_MEMORY_ALLOCATION_ERROR;
+                    return;
                 }
-                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;
-                  }
-                } 
+                localFormatters[UTMUTFMT_FULL_STYLE] = NULL;
+                localFormatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL;
+                countToPatterns->put(pluralCountUniStr, localFormatters.getAlias(), err);
                 if (U_FAILURE(err)) {
-                    ures_close(countsToPatternRB);
-                    ures_close(oneTimeUnit);
-                    ures_close(unitsRes);
-                    ures_close(rb);
-                    delete messageFormat;
-                    delete countToPatterns;
                     return;
                 }
+                formatters = localFormatters.orphan();
             }
-            if (fTimeUnitToCountToPatterns[timeUnitField] == NULL) {
-                fTimeUnitToCountToPatterns[timeUnitField] = countToPatterns;
-            }
-            ures_close(countsToPatternRB);
+            //delete formatters[style];
+            formatters[style] = messageFormat.orphan();
+        }
+        if (fTimeUnitToCountToPatterns[timeUnitField] == NULL) {
+            fTimeUnitToCountToPatterns[timeUnitField] = localCountToPatterns.orphan();
         }
-        ures_close(oneTimeUnit);
     }
-    ures_close(unitsRes);
-    ures_close(rb);
 }
 
 
-void 
+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.
@@ -484,45 +471,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;
 }
 
 
@@ -532,14 +515,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)) {
@@ -553,46 +536,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(NULL, 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;
         }
     }
@@ -603,13 +578,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;
@@ -620,7 +597,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;
@@ -638,35 +615,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);
@@ -674,7 +653,7 @@ TimeUnitFormat::setLocale(const Locale& locale, UErrorCode& status) {
 }
 
 
-void 
+void
 TimeUnitFormat::setNumberFormat(const NumberFormat& format, UErrorCode& status){
     if (U_FAILURE(status)) {
         return;
@@ -685,7 +664,7 @@ TimeUnitFormat::setNumberFormat(const NumberFormat& format, UErrorCode& status){
 
 void
 TimeUnitFormat::deleteHash(Hashtable* htable) {
-    int32_t pos = -1;
+    int32_t pos = UHASH_FIRST;
     const UHashElement* element = NULL;
     if ( htable ) {
         while ( (element = htable->nextElement(pos)) != NULL ) {
@@ -706,7 +685,7 @@ TimeUnitFormat::copyHash(const Hashtable* source, Hashtable* target, UErrorCode&
     if ( U_FAILURE(status) ) {
         return;
     }
-    int32_t pos = -1;
+    int32_t pos = UHASH_FIRST;
     const UHashElement* element = NULL;
     if ( source ) {
         while ( (element = source->nextElement(pos)) != NULL ) {
@@ -729,7 +708,7 @@ TimeUnitFormat::copyHash(const Hashtable* source, Hashtable* target, UErrorCode&
 }
 
 
-U_CDECL_BEGIN 
+U_CDECL_BEGIN
 
 /**
  * set hash table value comparator
@@ -760,7 +739,7 @@ TimeUnitFormat::initHash(UErrorCode& status) {
         return NULL;
     }
     if ( U_FAILURE(status) ) {
-        delete hTable; 
+        delete hTable;
         return NULL;
     }
     hTable->setValueComparator(tmutfmtHashTableValueComparator);
@@ -769,7 +748,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;