+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
-* Copyright (C) 2011-2013, International Business Machines Corporation and
+* Copyright (C) 2011-2016, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
#include "unicode/basictz.h"
#include "unicode/locdspnm.h"
-#include "unicode/msgfmt.h"
#include "unicode/rbtz.h"
+#include "unicode/simpleformatter.h"
#include "unicode/simpletz.h"
+#include "unicode/strenum.h"
#include "unicode/vtzone.h"
#include "cmemory.h"
return results;
}
-static UMutex gLock = U_MUTEX_INITIALIZER;
+static UMutex *gLock() {
+ static UMutex *m = STATIC_NEW(UMutex);
+ return m;
+}
class TZGNCore : public UMemory {
public:
UHashtable* fLocationNamesMap;
UHashtable* fPartialLocationNamesMap;
- MessageFormat* fRegionFormat;
- MessageFormat* fFallbackFormat;
+ SimpleFormatter fRegionFormat;
+ SimpleFormatter fFallbackFormat;
LocaleDisplayNames* fLocaleDisplayNames;
ZNStringPool fStringPool;
fTimeZoneNames(NULL),
fLocationNamesMap(NULL),
fPartialLocationNamesMap(NULL),
- fRegionFormat(NULL),
- fFallbackFormat(NULL),
fLocaleDisplayNames(NULL),
fStringPool(status),
fGNamesTrie(TRUE, deleteGNameInfo),
}
ures_close(zoneStrings);
- fRegionFormat = new MessageFormat(rpat, status);
- if (fRegionFormat == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- }
- fFallbackFormat = new MessageFormat(fpat, status);
- if (fFallbackFormat == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- }
+ fRegionFormat.applyPatternMinMaxArguments(rpat, 1, 1, status);
+ fFallbackFormat.applyPatternMinMaxArguments(fpat, 2, 2, status);
if (U_FAILURE(status)) {
cleanup();
return;
// target region
const char* region = fLocale.getCountry();
- int32_t regionLen = uprv_strlen(region);
+ int32_t regionLen = static_cast<int32_t>(uprv_strlen(region));
if (regionLen == 0) {
char loc[ULOC_FULLNAME_CAPACITY];
uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status);
TimeZone *tz = TimeZone::createDefault();
const UChar *tzID = ZoneMeta::getCanonicalCLDRID(*tz);
if (tzID != NULL) {
- loadStrings(UnicodeString(tzID));
+ loadStrings(UnicodeString(TRUE, tzID, -1));
}
delete tz;
}
void
TZGNCore::cleanup() {
- if (fRegionFormat != NULL) {
- delete fRegionFormat;
- }
- if (fFallbackFormat != NULL) {
- delete fFallbackFormat;
- }
if (fLocaleDisplayNames != NULL) {
delete fLocaleDisplayNames;
}
{
const UChar* tzCanonicalID = ZoneMeta::getCanonicalCLDRID(tz);
if (tzCanonicalID != NULL) {
- getGenericLocationName(UnicodeString(tzCanonicalID), name);
+ getGenericLocationName(UnicodeString(TRUE, tzCanonicalID, -1), name);
}
}
break;
if (name.isEmpty()) {
const UChar* tzCanonicalID = ZoneMeta::getCanonicalCLDRID(tz);
if (tzCanonicalID != NULL) {
- getGenericLocationName(UnicodeString(tzCanonicalID), name);
+ getGenericLocationName(UnicodeString(TRUE, tzCanonicalID, -1), name);
}
}
break;
const UChar *locname = NULL;
TZGNCore *nonConstThis = const_cast<TZGNCore *>(this);
- umtx_lock(&gLock);
+ umtx_lock(gLock());
{
locname = nonConstThis->getGenericLocationName(tzCanonicalID);
}
- umtx_unlock(&gLock);
+ umtx_unlock(gLock());
if (locname == NULL) {
name.setToBogus();
ZoneMeta::getCanonicalCountry(tzCanonicalID, usCountryCode, &isPrimary);
if (!usCountryCode.isEmpty()) {
- FieldPosition fpos;
-
if (isPrimary) {
// If this is the primary zone in the country, use the country name.
char countryCode[ULOC_COUNTRY_CAPACITY];
UnicodeString country;
fLocaleDisplayNames->regionDisplayName(countryCode, country);
-
- Formattable param[] = {
- Formattable(country)
- };
-
- fRegionFormat->format(param, 1, name, fpos, status);
+ fRegionFormat.format(country, name, status);
} else {
// If this is not the primary zone in the country,
// use the exemplar city name.
UnicodeString city;
fTimeZoneNames->getExemplarLocationName(tzCanonicalID, city);
-
- Formattable param[] = {
- Formattable(city),
- };
-
- fRegionFormat->format(param, 1, name, fpos, status);
+ fRegionFormat.format(city, name, status);
}
if (U_FAILURE(status)) {
return NULL;
return name;
}
- UnicodeString tzID(uID);
+ UnicodeString tzID(TRUE, uID, -1);
// Try to get a name from time zone first
UTimeZoneNameType nameType = (type == UTZGNM_LONG) ? UTZNM_LONG_GENERIC : UTZNM_SHORT_GENERIC;
}
// Try meta zone
- UnicodeString mzID;
+ UChar mzIDBuf[32];
+ UnicodeString mzID(mzIDBuf, 0, UPRV_LENGTHOF(mzIDBuf));
fTimeZoneNames->getMetaZoneID(tzID, date, mzID);
if (!mzID.isEmpty()) {
UErrorCode status = U_ZERO_ERROR;
UBool useStandard = FALSE;
int32_t raw, sav;
+ UChar tmpNameBuf[ZONE_NAME_U16_MAX];
tz.getOffset(date, FALSE, raw, sav, status);
if (U_FAILURE(status)) {
if (useStandard) {
UTimeZoneNameType stdNameType = (nameType == UTZNM_LONG_GENERIC)
? UTZNM_LONG_STANDARD : UTZNM_SHORT_STANDARD;
- UnicodeString stdName;
+ UnicodeString stdName(tmpNameBuf, 0, UPRV_LENGTHOF(tmpNameBuf));
fTimeZoneNames->getDisplayName(tzID, stdNameType, date, stdName);
if (!stdName.isEmpty()) {
name.setTo(stdName);
// for some meta zones in some locales. This looks like a data bugs.
// For now, we check if the standard name is different from its generic
// name below.
- UnicodeString mzGenericName;
+ UChar genNameBuf[ZONE_NAME_U16_MAX];
+ UnicodeString mzGenericName(genNameBuf, 0, UPRV_LENGTHOF(genNameBuf));
fTimeZoneNames->getMetaZoneDisplayName(mzID, nameType, mzGenericName);
if (stdName.caseCompare(mzGenericName, 0) == 0) {
name.setToBogus();
}
if (name.isEmpty()) {
// Get a name from meta zone
- UnicodeString mzName;
+ UnicodeString mzName(tmpNameBuf, 0, UPRV_LENGTHOF(tmpNameBuf));
fTimeZoneNames->getMetaZoneDisplayName(mzID, nameType, mzName);
if (!mzName.isEmpty()) {
// Check if we need to use a partial location format.
// This check is done by comparing offset with the meta zone's
// golden zone at the given date.
- UnicodeString goldenID;
+ UChar idBuf[32];
+ UnicodeString goldenID(idBuf, 0, UPRV_LENGTHOF(idBuf));
fTimeZoneNames->getReferenceZoneID(mzID, fTargetRegion, goldenID);
if (!goldenID.isEmpty() && goldenID != tzID) {
TimeZone *goldenZone = TimeZone::createTimeZone(goldenID);
const UChar *uplname = NULL;
TZGNCore *nonConstThis = const_cast<TZGNCore *>(this);
- umtx_lock(&gLock);
+ umtx_lock(gLock());
{
uplname = nonConstThis->getPartialLocationName(tzCanonicalID, mzID, isLong, mzDisplayName);
}
- umtx_unlock(&gLock);
+ umtx_unlock(gLock());
if (uplname == NULL) {
name.setToBogus();
UErrorCode status = U_ZERO_ERROR;
UnicodeString name;
-
- FieldPosition fpos;
- Formattable param[] = {
- Formattable(location),
- Formattable(mzDisplayName)
- };
- fFallbackFormat->format(param, 2, name, fpos, status);
+ fFallbackFormat.format(location, mzDisplayName, name, status);
if (U_FAILURE(status)) {
return NULL;
}
};
StringEnumeration *mzIDs = fTimeZoneNames->getAvailableMetaZoneIDs(tzCanonicalID, status);
- while ((mzID = mzIDs->snext(status))) {
+ while ((mzID = mzIDs->snext(status)) != NULL) {
if (U_FAILURE(status)) {
break;
}
TZGNCore *nonConstThis = const_cast<TZGNCore *>(this);
- umtx_lock(&gLock);
+ umtx_lock(gLock());
{
fGNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status);
}
- umtx_unlock(&gLock);
+ umtx_unlock(gLock());
if (U_FAILURE(status)) {
return NULL;
// All names are not yet loaded into the local trie.
// Load all available names into the trie. This could be very heavy.
- umtx_lock(&gLock);
+ umtx_lock(gLock());
{
if (!fGNamesTrieFullyLoaded) {
StringEnumeration *tzIDs = TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status);
if (U_SUCCESS(status)) {
const UnicodeString *tzID;
- while ((tzID = tzIDs->snext(status))) {
+ while ((tzID = tzIDs->snext(status)) != NULL) {
if (U_FAILURE(status)) {
break;
}
}
}
}
- umtx_unlock(&gLock);
+ umtx_unlock(gLock());
if (U_FAILURE(status)) {
return NULL;
}
- umtx_lock(&gLock);
+ umtx_lock(gLock());
{
// now try it again
fGNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status);
}
- umtx_unlock(&gLock);
+ umtx_unlock(gLock());
results = handler.getMatches(maxLen);
if (results != NULL && maxLen > 0) {
} TZGNCoreRef;
// TZGNCore object cache handling
-static UMutex gTZGNLock = U_MUTEX_INITIALIZER;
+static UMutex *gTZGNLock() {
+ static UMutex *m = STATIC_NEW(UMutex);
+ return m;
+}
static UHashtable *gTZGNCoreCache = NULL;
static UBool gTZGNCoreCacheInitialized = FALSE;
* block.
*/
static void sweepCache() {
- int32_t pos = -1;
+ int32_t pos = UHASH_FIRST;
const UHashElement* elem;
double now = (double)uprv_getUTCtime();
- while ((elem = uhash_nextElement(gTZGNCoreCache, &pos))) {
+ while ((elem = uhash_nextElement(gTZGNCoreCache, &pos)) != NULL) {
TZGNCoreRef *entry = (TZGNCoreRef *)elem->value.pointer;
if (entry->refCount <= 0 && (now - entry->lastAccess) > CACHE_EXPIRATION) {
// delete this entry
}
TimeZoneGenericNames::~TimeZoneGenericNames() {
- umtx_lock(&gTZGNLock);
+ umtx_lock(gTZGNLock());
{
U_ASSERT(fRef->refCount > 0);
// Just decrement the reference count
fRef->refCount--;
}
- umtx_unlock(&gTZGNLock);
+ umtx_unlock(gTZGNLock());
}
TimeZoneGenericNames*
TZGNCoreRef *cacheEntry = NULL;
{
- Mutex lock(&gTZGNLock);
+ Mutex lock(gTZGNLock());
if (!gTZGNCoreCacheInitialized) {
// Create empty hashtable
TimeZoneGenericNames::clone() const {
TimeZoneGenericNames* other = new TimeZoneGenericNames();
if (other) {
- umtx_lock(&gTZGNLock);
+ umtx_lock(gTZGNLock());
{
// Just increments the reference count
fRef->refCount++;
other->fRef = fRef;
}
- umtx_unlock(&gTZGNLock);
+ umtx_unlock(gTZGNLock());
}
return other;
}