mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 23:10:40 +00:00
ICU-11912 Adding more efficient implementation of getDisplayNames(), which was already present in Java
X-SVN-Rev: 39041
This commit is contained in:
parent
e271d8a317
commit
d88a4109a5
5 changed files with 106 additions and 44 deletions
|
@ -1323,7 +1323,7 @@ DateFormatSymbols::initZoneStringsArray(void) {
|
|||
}
|
||||
|
||||
zarray[i][0].setTo(*tzid);
|
||||
tzNames->getDisplayNames(*tzid, TYPES, NUM_TYPES, now, zarray[i]+1);
|
||||
tzNames->getDisplayNames(*tzid, TYPES, NUM_TYPES, now, zarray[i]+1, status);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
@ -1337,6 +1337,7 @@ DateFormatSymbols::initZoneStringsArray(void) {
|
|||
}
|
||||
}
|
||||
uprv_free(zarray);
|
||||
zarray = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ public:
|
|||
UnicodeString& getExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) const;
|
||||
|
||||
void loadAllDisplayNames(UErrorCode& status);
|
||||
void getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[], UErrorCode& status) const;
|
||||
|
||||
MatchInfoCollection* find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const;
|
||||
private:
|
||||
|
@ -287,6 +288,11 @@ TimeZoneNamesDelegate::loadAllDisplayNames(UErrorCode& status) {
|
|||
fTZnamesCacheEntry->names->loadAllDisplayNames(status);
|
||||
}
|
||||
|
||||
void
|
||||
TimeZoneNamesDelegate::getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[], UErrorCode& status) const {
|
||||
fTZnamesCacheEntry->names->getDisplayNames(tzID, types, numTypes, date, dest, status);
|
||||
}
|
||||
|
||||
TimeZoneNames::MatchInfoCollection*
|
||||
TimeZoneNamesDelegate::find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const {
|
||||
return fTZnamesCacheEntry->names->find(text, start, types, status);
|
||||
|
@ -339,26 +345,26 @@ TimeZoneNames::getDisplayName(const UnicodeString& tzID, UTimeZoneNameType type,
|
|||
return name;
|
||||
}
|
||||
|
||||
// Empty default implementation, to be overriden in tznames_impl.cpp.
|
||||
void
|
||||
TimeZoneNames::loadAllDisplayNames(UErrorCode& status) {
|
||||
return loadAllDisplayNames(status);
|
||||
TimeZoneNames::loadAllDisplayNames(UErrorCode& /*status*/) {
|
||||
}
|
||||
|
||||
// A default, lightweight implementation of getDisplayNames.
|
||||
// Overridden in tznames_impl.cpp.
|
||||
void
|
||||
TimeZoneNames::getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[]) const {
|
||||
TimeZoneNames::getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[], UErrorCode& status) const {
|
||||
if (U_FAILURE(status)) { return; }
|
||||
if (tzID.isEmpty()) { return; }
|
||||
UnicodeString mzID;
|
||||
for (int i = 0; i < numTypes; i++) {
|
||||
UnicodeString name;
|
||||
UTimeZoneNameType type = types[i];
|
||||
getTimeZoneDisplayName(tzID, type, name);
|
||||
if (name.isEmpty()) {
|
||||
getTimeZoneDisplayName(tzID, types[i], dest[i]);
|
||||
if (dest[i].isEmpty()) {
|
||||
if (mzID.isEmpty()) {
|
||||
getMetaZoneID(tzID, date, mzID);
|
||||
}
|
||||
getMetaZoneDisplayName(mzID, type, name);
|
||||
getMetaZoneDisplayName(mzID, types[i], dest[i]);
|
||||
}
|
||||
dest[i].setTo(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1050,7 +1050,7 @@ TimeZoneNamesImpl::initialize(const Locale& locale, UErrorCode& status) {
|
|||
TimeZone *tz = TimeZone::createDefault();
|
||||
const UChar *tzID = ZoneMeta::getCanonicalCLDRID(*tz);
|
||||
if (tzID != NULL) {
|
||||
loadStrings(UnicodeString(tzID));
|
||||
loadStrings(UnicodeString(tzID), status);
|
||||
}
|
||||
delete tz;
|
||||
|
||||
|
@ -1062,20 +1062,15 @@ TimeZoneNamesImpl::initialize(const Locale& locale, UErrorCode& status) {
|
|||
* except initializer.
|
||||
*/
|
||||
void
|
||||
TimeZoneNamesImpl::loadStrings(const UnicodeString& tzCanonicalID) {
|
||||
loadTimeZoneNames(tzCanonicalID);
|
||||
TimeZoneNamesImpl::loadStrings(const UnicodeString& tzCanonicalID, UErrorCode& status) {
|
||||
loadTimeZoneNames(tzCanonicalID, status);
|
||||
LocalPointer<StringEnumeration> mzIDs(getAvailableMetaZoneIDs(tzCanonicalID, status));
|
||||
if (U_FAILURE(status)) { return; }
|
||||
U_ASSERT(!mzIDs.isNull());
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
StringEnumeration *mzIDs = getAvailableMetaZoneIDs(tzCanonicalID, status);
|
||||
if (U_SUCCESS(status) && mzIDs != NULL) {
|
||||
const UnicodeString *mzID;
|
||||
while ((mzID = mzIDs->snext(status))) {
|
||||
if (U_FAILURE(status)) {
|
||||
break;
|
||||
}
|
||||
loadMetaZoneNames(*mzID);
|
||||
}
|
||||
delete mzIDs;
|
||||
const UnicodeString *mzID;
|
||||
while ((mzID = mzIDs->snext(status)) && U_SUCCESS(status)) {
|
||||
loadMetaZoneNames(*mzID, status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1196,7 +1191,6 @@ TimeZoneNamesImpl::_getReferenceZoneID(const UnicodeString& mzID, const char* re
|
|||
return tzID;
|
||||
}
|
||||
|
||||
|
||||
UnicodeString&
|
||||
TimeZoneNamesImpl::getMetaZoneDisplayName(const UnicodeString& mzID,
|
||||
UTimeZoneNameType type,
|
||||
|
@ -1211,7 +1205,9 @@ TimeZoneNamesImpl::getMetaZoneDisplayName(const UnicodeString& mzID,
|
|||
|
||||
{
|
||||
Mutex lock(&gDataMutex);
|
||||
znames = nonConstThis->loadMetaZoneNames(mzID);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
znames = nonConstThis->loadMetaZoneNames(mzID, status);
|
||||
if (U_FAILURE(status)) { return name; }
|
||||
}
|
||||
|
||||
if (znames != NULL) {
|
||||
|
@ -1235,7 +1231,9 @@ TimeZoneNamesImpl::getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNa
|
|||
|
||||
{
|
||||
Mutex lock(&gDataMutex);
|
||||
tznames = nonConstThis->loadTimeZoneNames(tzID);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
tznames = nonConstThis->loadTimeZoneNames(tzID, status);
|
||||
if (U_FAILURE(status)) { return name; }
|
||||
}
|
||||
|
||||
if (tznames != NULL) {
|
||||
|
@ -1256,7 +1254,9 @@ TimeZoneNamesImpl::getExemplarLocationName(const UnicodeString& tzID, UnicodeStr
|
|||
|
||||
{
|
||||
Mutex lock(&gDataMutex);
|
||||
tznames = nonConstThis->loadTimeZoneNames(tzID);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
tznames = nonConstThis->loadTimeZoneNames(tzID, status);
|
||||
if (U_FAILURE(status)) { return name; }
|
||||
}
|
||||
|
||||
if (tznames != NULL) {
|
||||
|
@ -1290,14 +1290,13 @@ static void mergeTimeZoneKey(const UnicodeString& mzID, char* result) {
|
|||
* This method updates the cache and must be called with a lock
|
||||
*/
|
||||
ZNames*
|
||||
TimeZoneNamesImpl::loadMetaZoneNames(const UnicodeString& mzID) {
|
||||
TimeZoneNamesImpl::loadMetaZoneNames(const UnicodeString& mzID, UErrorCode& status) {
|
||||
if (U_FAILURE(status)) { return NULL; }
|
||||
U_ASSERT(mzID.length() <= ZID_KEY_MAX - MZ_PREFIX_LEN);
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
UChar mzIDKey[ZID_KEY_MAX + 1];
|
||||
mzID.extract(mzIDKey, ZID_KEY_MAX + 1, status);
|
||||
U_ASSERT(status == U_ZERO_ERROR); // already checked length above
|
||||
U_ASSERT(U_SUCCESS(status)); // already checked length above
|
||||
mzIDKey[mzID.length()] = 0;
|
||||
|
||||
void* mznames = uhash_get(fMZNamesMap, mzIDKey);
|
||||
|
@ -1319,14 +1318,13 @@ TimeZoneNamesImpl::loadMetaZoneNames(const UnicodeString& mzID) {
|
|||
* This method updates the cache and must be called with a lock
|
||||
*/
|
||||
ZNames*
|
||||
TimeZoneNamesImpl::loadTimeZoneNames(const UnicodeString& tzID) {
|
||||
TimeZoneNamesImpl::loadTimeZoneNames(const UnicodeString& tzID, UErrorCode& status) {
|
||||
if (U_FAILURE(status)) { return NULL; }
|
||||
U_ASSERT(tzID.length() <= ZID_KEY_MAX);
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
UChar tzIDKey[ZID_KEY_MAX + 1];
|
||||
int32_t tzIDKeyLen = tzID.extract(tzIDKey, ZID_KEY_MAX + 1, status);
|
||||
U_ASSERT(status == U_ZERO_ERROR); // already checked length above
|
||||
U_ASSERT(U_SUCCESS(status)); // already checked length above
|
||||
tzIDKey[tzIDKeyLen] = 0;
|
||||
|
||||
void *tznames = uhash_get(fTZNamesMap, tzIDKey);
|
||||
|
@ -1582,6 +1580,61 @@ void TimeZoneNamesImpl::loadAllDisplayNames(UErrorCode& status) {
|
|||
}
|
||||
}
|
||||
|
||||
void TimeZoneNamesImpl::getDisplayNames(const UnicodeString& tzID,
|
||||
const UTimeZoneNameType types[], int32_t numTypes,
|
||||
UDate date, UnicodeString dest[], UErrorCode& status) const {
|
||||
if (U_FAILURE(status)) return;
|
||||
|
||||
if (tzID.isEmpty()) { return; }
|
||||
void* tznames = NULL;
|
||||
void* mznames = NULL;
|
||||
TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl*>(this);
|
||||
|
||||
// Load the time zone strings
|
||||
{
|
||||
Mutex lock(&gDataMutex);
|
||||
tznames = (void*) nonConstThis->loadTimeZoneNames(tzID, status);
|
||||
if (U_FAILURE(status)) { return; }
|
||||
}
|
||||
U_ASSERT(tznames != NULL);
|
||||
|
||||
// Load the values into the dest array
|
||||
for (int i = 0; i < numTypes; i++) {
|
||||
UTimeZoneNameType type = types[i];
|
||||
const UChar* name = ((ZNames*)tznames)->getName(type);
|
||||
if (name == NULL) {
|
||||
if (mznames == NULL) {
|
||||
// Load the meta zone name
|
||||
UnicodeString mzID;
|
||||
getMetaZoneID(tzID, date, mzID);
|
||||
if (mzID.isEmpty()) {
|
||||
mznames = (void*) EMPTY;
|
||||
} else {
|
||||
// Load the meta zone strings
|
||||
// Mutex is scoped to the "else" statement
|
||||
Mutex lock(&gDataMutex);
|
||||
mznames = (void*) nonConstThis->loadMetaZoneNames(mzID, status);
|
||||
if (U_FAILURE(status)) { return; }
|
||||
// Note: when the metazone doesn't exist, in Java, loadMetaZoneNames returns
|
||||
// a dummy object instead of NULL.
|
||||
if (mznames == NULL) {
|
||||
mznames = (void*) EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
U_ASSERT(mznames != NULL);
|
||||
if (mznames != EMPTY) {
|
||||
name = ((ZNames*)mznames)->getName(type);
|
||||
}
|
||||
}
|
||||
if (name != NULL) {
|
||||
dest[i].setTo(TRUE, name, -1);
|
||||
} else {
|
||||
dest[i].setToBogus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Caller must synchronize.
|
||||
void TimeZoneNamesImpl::internalLoadAllDisplayNames(UErrorCode& status) {
|
||||
if (!fNamesFullyLoaded) {
|
||||
|
@ -1604,8 +1657,8 @@ void TimeZoneNamesImpl::internalLoadAllDisplayNames(UErrorCode& status) {
|
|||
UnicodeString copy(*id);
|
||||
void* value = uhash_get(fTZNamesMap, copy.getTerminatedBuffer());
|
||||
if (value == NULL) {
|
||||
// loadStrings also load related metazone strings
|
||||
loadStrings(*id);
|
||||
// loadStrings also loads related metazone strings
|
||||
loadStrings(*id, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,8 +186,8 @@ public:
|
|||
|
||||
TimeZoneNames::MatchInfoCollection* find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const;
|
||||
|
||||
void loadAllDisplayNames(UErrorCode& errorCode);
|
||||
void internalLoadAllDisplayNames(UErrorCode& errorCode);
|
||||
void loadAllDisplayNames(UErrorCode& status);
|
||||
void getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[], UErrorCode& status) const;
|
||||
|
||||
static UnicodeString& getDefaultExemplarLocationName(const UnicodeString& tzID, UnicodeString& name);
|
||||
|
||||
|
@ -212,14 +212,16 @@ private:
|
|||
void initialize(const Locale& locale, UErrorCode& status);
|
||||
void cleanup();
|
||||
|
||||
void loadStrings(const UnicodeString& tzCanonicalID);
|
||||
void loadStrings(const UnicodeString& tzCanonicalID, UErrorCode& status);
|
||||
|
||||
ZNames* loadMetaZoneNames(const UnicodeString& mzId);
|
||||
ZNames* loadTimeZoneNames(const UnicodeString& mzId);
|
||||
ZNames* loadMetaZoneNames(const UnicodeString& mzId, UErrorCode& status);
|
||||
ZNames* loadTimeZoneNames(const UnicodeString& mzId, UErrorCode& status);
|
||||
TimeZoneNames::MatchInfoCollection* doFind(ZNameSearchHandler& handler,
|
||||
const UnicodeString& text, int32_t start, UErrorCode& status) const;
|
||||
void addAllNamesIntoTrie(UErrorCode& errorCode);
|
||||
|
||||
void internalLoadAllDisplayNames(UErrorCode& status);
|
||||
|
||||
struct ZoneStringsLoader;
|
||||
};
|
||||
|
||||
|
|
|
@ -300,7 +300,7 @@ public:
|
|||
* @internal For specific users only until proposed publicly.
|
||||
* @deprecated This API is ICU internal only.
|
||||
*/
|
||||
virtual void getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[]) const;
|
||||
virtual void getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[], UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* <code>MatchInfoCollection</code> represents a collection of time zone name matches used by
|
||||
|
|
Loading…
Add table
Reference in a new issue