]> granicus.if.org Git - icu/commitdiff
ICU-8627 Lazily instantiate TimeZoneGenericNames instance in TimeZoneFormat, so forma...
authorYoshito Umaoka <y.umaoka@gmail.com>
Wed, 8 Jun 2011 20:23:20 +0000 (20:23 +0000)
committerYoshito Umaoka <y.umaoka@gmail.com>
Wed, 8 Jun 2011 20:23:20 +0000 (20:23 +0000)
X-SVN-Rev: 30196

icu4c/source/i18n/tzfmt.cpp

index 571d609a7f54e2d39ac97884e2548b56fd0fff7e..5347f92e56d7beef947875e74331df24a8ceb2c3 100644 (file)
@@ -39,6 +39,7 @@ public:
         UnicodeString& tzID, UTimeZoneTimeType* timeType = NULL) const;
 
 private:
+    UMTX fLock;
     Locale fLocale;
     char fTargetRegion[ULOC_COUNTRY_CAPACITY];
     TimeZoneNames* fTimeZoneNames;
@@ -48,10 +49,12 @@ private:
 
     UnicodeString& formatSpecific(const TimeZone& tz, UTimeZoneNameType stdType, UTimeZoneNameType dstType,
         UDate date, UnicodeString& name, UTimeZoneTimeType *timeType) const;
+
+    const TimeZoneGenericNames* getTimeZoneGenericNames(UErrorCode& status) const;
 };
 
 TimeZoneFormatImpl::TimeZoneFormatImpl(const Locale& locale, UErrorCode& status)
-: fLocale(locale), fTimeZoneNames(NULL), fTimeZoneGenericNames(NULL) {
+: fLocale(locale), fTimeZoneNames(NULL), fTimeZoneGenericNames(NULL), fLock(NULL) {
 
     const char* region = fLocale.getCountry();
     int32_t regionLen = uprv_strlen(region);
@@ -72,10 +75,7 @@ TimeZoneFormatImpl::TimeZoneFormatImpl(const Locale& locale, UErrorCode& status)
     }
 
     fTimeZoneNames = TimeZoneNames::createInstance(locale, status);
-    fTimeZoneGenericNames = new TimeZoneGenericNames(locale, status);
-    if (U_SUCCESS(status) && fTimeZoneGenericNames == NULL) {
-        status = U_MEMORY_ALLOCATION_ERROR;
-    }
+    // fTimeZoneGenericNames is lazily instantiated
 }
 
 TimeZoneFormatImpl::~TimeZoneFormatImpl() {
@@ -85,6 +85,7 @@ TimeZoneFormatImpl::~TimeZoneFormatImpl() {
     if (fTimeZoneGenericNames != NULL) {
         delete fTimeZoneGenericNames;
     }
+    umtx_destroy(&fLock);
 }
 
 const TimeZoneNames*
@@ -92,6 +93,31 @@ TimeZoneFormatImpl::getTimeZoneNames() const {
     return fTimeZoneNames;
 }
 
+const TimeZoneGenericNames*
+TimeZoneFormatImpl::getTimeZoneGenericNames(UErrorCode& status) const {
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+
+    UBool create;
+    UMTX_CHECK(&gZoneMetaLock, (fTimeZoneGenericNames == NULL), create);
+    if (create) {
+        TimeZoneFormatImpl *nonConstThis = const_cast<TimeZoneFormatImpl *>(this);
+        umtx_lock(&nonConstThis->fLock);
+        {
+            if (fTimeZoneGenericNames == NULL) {
+                nonConstThis->fTimeZoneGenericNames = new TimeZoneGenericNames(fLocale, status);
+                if (U_SUCCESS(status) && fTimeZoneGenericNames == NULL) {
+                    status = U_MEMORY_ALLOCATION_ERROR;
+                }
+            }
+        }
+        umtx_unlock(&nonConstThis->fLock);
+    }
+
+    return fTimeZoneGenericNames;
+}
+
 UnicodeString&
 TimeZoneFormatImpl::format(UTimeZoneFormatStyle style, const TimeZone& tz, UDate date,
         UnicodeString& name, UTimeZoneTimeType* timeType /* = NULL */) const {
@@ -163,7 +189,11 @@ TimeZoneFormatImpl::parse(UTimeZoneFormatStyle style, const UnicodeString& text,
     UErrorCode status = U_ZERO_ERROR;
 
     if (isGeneric) {
-        int32_t len = fTimeZoneGenericNames->findBestMatch(text, startIdx, types, parsedTzID, parsedTimeType, status);
+        int32_t len = 0;
+        const TimeZoneGenericNames *gnames = getTimeZoneGenericNames(status);
+        if (U_SUCCESS(status)) {
+            len = gnames->findBestMatch(text, startIdx, types, parsedTzID, parsedTimeType, status);
+        }
         if (U_FAILURE(status) || len == 0) {
             pos.setErrorIndex(startIdx);
             return tzID;
@@ -221,7 +251,9 @@ TimeZoneFormatImpl::parse(UTimeZoneFormatStyle style, const UnicodeString& text,
 
 UnicodeString&
 TimeZoneFormatImpl::formatGeneric(const TimeZone& tz, UTimeZoneGenericNameType genType, UDate date, UnicodeString& name) const {
-    if (fTimeZoneGenericNames == NULL) {
+    UErrorCode status = U_ZERO_ERROR;
+    const TimeZoneGenericNames* gnames = getTimeZoneGenericNames(status);
+    if (U_FAILURE(status)) {
         name.setToBogus();
         return name;
     }
@@ -232,9 +264,9 @@ TimeZoneFormatImpl::formatGeneric(const TimeZone& tz, UTimeZoneGenericNameType g
             name.setToBogus();
             return name;
         }
-        return fTimeZoneGenericNames->getGenericLocationName(UnicodeString(canonicalID), name);
+        return gnames->getGenericLocationName(UnicodeString(canonicalID), name);
     }
-    return fTimeZoneGenericNames->getDisplayName(tz, genType, date, name);
+    return gnames->getDisplayName(tz, genType, date, name);
 }
 
 UnicodeString&