1b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 2b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho******************************************************************************* 3b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* Copyright (C) 2011, International Business Machines Corporation and * 4b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* others. All Rights Reserved. * 5b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho******************************************************************************* 6b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho*/ 7b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 8b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/utypes.h" 9b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 10b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#if !UCONFIG_NO_FORMATTING 11b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 12b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "tznames.h" 13b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "tznames_impl.h" 14b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 15b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/locid.h" 16b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/uenum.h" 17b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "cmemory.h" 18b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "cstring.h" 19b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "putilimp.h" 20b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uassert.h" 21b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "ucln_in.h" 22b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uhash.h" 23b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "umutex.h" 24b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 25b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 26b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_NAMESPACE_BEGIN 27b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 28b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar gEtcPrefix[] = { 0x45, 0x74, 0x63, 0x2F }; // "Etc/" 29b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const int32_t gEtcPrefixLen = 4; 30b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar gSystemVPrefix[] = { 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x56, 0x2F }; // "SystemV/ 31b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const int32_t gSystemVPrefixLen = 8; 32b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar gRiyadh8[] = { 0x52, 0x69, 0x79, 0x61, 0x64, 0x68, 0x38 }; // "Riyadh8" 33b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const int32_t gRiyadh8Len = 7; 34b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 35b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TimeZoneNames object cache handling 36b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic UMTX gTimeZoneNamesLock = NULL; 37b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic UHashtable *gTimeZoneNamesCache = NULL; 38b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic UBool gTimeZoneNamesCacheInitialized = FALSE; 39b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 40b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Access count - incremented every time up to SWEEP_INTERVAL, 41b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// then reset to 0 42b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic int32_t gAccessCount = 0; 43b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 44b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Interval for calling the cache sweep function - every 100 times 45b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define SWEEP_INTERVAL 100 46b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 47b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Cache expiration in millisecond. When a cached entry is no 48b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// longer referenced and exceeding this threshold since last 49b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// access time, then the cache entry will be deleted by the sweep 50b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// function. For now, 3 minutes. 51b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define CACHE_EXPIRATION 180000.0 52b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 53b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehotypedef struct TimeZoneNamesCacheEntry { 54b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNames* names; 55b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t refCount; 56b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho double lastAccess; 57b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} TimeZoneNamesCacheEntry; 58b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 59b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_BEGIN 60b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 61b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Cleanup callback func 62b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 63b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic UBool U_CALLCONV timeZoneNames_cleanup(void) 64b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho{ 65b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_destroy(&gTimeZoneNamesLock); 66b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 67b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (gTimeZoneNamesCache != NULL) { 68b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(gTimeZoneNamesCache); 69b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho gTimeZoneNamesCache = NULL; 70b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 71b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho gTimeZoneNamesCacheInitialized = FALSE; 72b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 73b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 74b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 75b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 76b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Deleter for TimeZoneNamesCacheEntry 77b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 78b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void U_CALLCONV 79b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehodeleteTimeZoneNamesCacheEntry(void *obj) { 80b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho icu::TimeZoneNamesCacheEntry *entry = (icu::TimeZoneNamesCacheEntry*)obj; 81b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete (icu::TimeZoneNamesImpl*) entry->names; 82b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(entry); 83b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 84b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_END 85b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 86b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 87b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Function used for removing unreferrenced cache entries exceeding 88b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * the expiration time. This function must be called with in the mutex 89b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * block. 90b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 91b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void sweepCache() { 92b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t pos = -1; 93b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UHashElement* elem; 94b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho double now = (double)uprv_getUTCtime(); 95b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 96b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while ((elem = uhash_nextElement(gTimeZoneNamesCache, &pos))) { 97b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNamesCacheEntry *entry = (TimeZoneNamesCacheEntry *)elem->value.pointer; 98b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (entry->refCount <= 0 && (now - entry->lastAccess) > CACHE_EXPIRATION) { 99b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // delete this entry 100b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_removeElement(gTimeZoneNamesCache, elem); 101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 103b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass TimeZoneNamesDelegate : public TimeZoneNames { 106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehopublic: 107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNamesDelegate(const Locale& locale, UErrorCode& status); 108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual ~TimeZoneNamesDelegate(); 109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho StringEnumeration* getAvailableMetaZoneIDs(UErrorCode& status) const; 111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho StringEnumeration* getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const; 112b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString& getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const; 113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString& getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const; 114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString& getMetaZoneDisplayName(const UnicodeString& mzID, UTimeZoneNameType type, UnicodeString& name) const; 116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString& getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, UnicodeString& name) const; 117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString& getExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) const; 119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNameMatchInfo* find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const; 121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprivate: 122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNamesCacheEntry* fTZnamesCacheEntry; 123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesDelegate::TimeZoneNamesDelegate(const Locale& locale, UErrorCode& status) { 126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool initialized; 127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UMTX_CHECK(&gTimeZoneNamesLock, gTimeZoneNamesCacheInitialized, initialized); 128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!initialized) { 129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Create empty hashtable 130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_lock(&gTimeZoneNamesLock); 131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!gTimeZoneNamesCacheInitialized) { 133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho gTimeZoneNamesCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status); 134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_setKeyDeleter(gTimeZoneNamesCache, uprv_free); 136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_setValueDeleter(gTimeZoneNamesCache, deleteTimeZoneNamesCacheEntry); 137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho gTimeZoneNamesCacheInitialized = TRUE; 138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONENAMES, timeZoneNames_cleanup); 139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_unlock(&gTimeZoneNamesLock); 143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Check the cache, if not available, create new one and cache 150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNamesCacheEntry *cacheEntry = NULL; 151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_lock(&gTimeZoneNamesLock); 152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const char *key = locale.getName(); 154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheEntry = (TimeZoneNamesCacheEntry *)uhash_get(gTimeZoneNamesCache, key); 155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cacheEntry == NULL) { 156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNames *tznames = NULL; 157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho char *newKey = NULL; 158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tznames = new TimeZoneNamesImpl(locale, status); 160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tznames == NULL) { 161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 162b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 163b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho newKey = (char *)uprv_malloc(uprv_strlen(key) + 1); 165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newKey == NULL) { 166b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_strcpy(newKey, key); 169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheEntry = (TimeZoneNamesCacheEntry *)uprv_malloc(sizeof(TimeZoneNamesCacheEntry)); 173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cacheEntry == NULL) { 174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheEntry->names = tznames; 177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheEntry->refCount = 1; 178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheEntry->lastAccess = (double)uprv_getUTCtime(); 179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_put(gTimeZoneNamesCache, newKey, cacheEntry, &status); 181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tznames != NULL) { 185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tznames; 186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newKey != NULL) { 188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(newKey); 189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cacheEntry != NULL) { 191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(cacheEntry); 192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheEntry = NULL; 194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Update the reference count 197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheEntry->refCount++; 198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheEntry->lastAccess = (double)uprv_getUTCtime(); 199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho gAccessCount++; 201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (gAccessCount >= SWEEP_INTERVAL) { 202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // sweep 203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho sweepCache(); 204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho gAccessCount = 0; 205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_unlock(&gTimeZoneNamesLock); 208b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTZnamesCacheEntry = cacheEntry; 210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesDelegate::~TimeZoneNamesDelegate() { 213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_lock(&gTimeZoneNamesLock); 214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 215b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(fTZnamesCacheEntry->refCount > 0); 216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Just decrement the reference count 217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTZnamesCacheEntry->refCount--; 218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 219b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_unlock(&gTimeZoneNamesLock); 220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoStringEnumeration* 223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesDelegate::getAvailableMetaZoneIDs(UErrorCode& status) const { 224b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fTZnamesCacheEntry->names->getAvailableMetaZoneIDs(status); 225b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 226b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoStringEnumeration* 228b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesDelegate::getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const { 229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fTZnamesCacheEntry->names->getAvailableMetaZoneIDs(tzID, status); 230b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 232b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 233b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesDelegate::getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const { 234b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fTZnamesCacheEntry->names->getMetaZoneID(tzID, date, mzID); 235b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 237b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 238b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesDelegate::getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const { 239b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fTZnamesCacheEntry->names->getReferenceZoneID(mzID, region, tzID); 240b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 241b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 242b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesDelegate::getMetaZoneDisplayName(const UnicodeString& mzID, UTimeZoneNameType type, UnicodeString& name) const { 244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fTZnamesCacheEntry->names->getMetaZoneDisplayName(mzID, type, name); 245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 246b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesDelegate::getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, UnicodeString& name) const { 249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fTZnamesCacheEntry->names->getTimeZoneDisplayName(tzID, type, name); 250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 251b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 252b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesDelegate::getExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) const { 254b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fTZnamesCacheEntry->names->getExemplarLocationName(tzID, name); 255b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 256b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 257b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNameMatchInfo* 258b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesDelegate::find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const { 259b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fTZnamesCacheEntry->names->find(text, start, types, status); 260b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 261b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 262b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 263b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNames* 265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNames::createInstance(const Locale& locale, UErrorCode& status) { 266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return new TimeZoneNamesDelegate(locale, status); 267b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 268b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 269b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNames::getExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) const { 271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzID.isEmpty() || tzID.startsWith(gEtcPrefix, gEtcPrefixLen) 272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho || tzID.startsWith(gSystemVPrefix, gSystemVPrefixLen) || tzID.indexOf(gRiyadh8, gRiyadh8Len, 0) > 0) { 273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setToBogus(); 274b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t sep = tzID.lastIndexOf((UChar)0x2F /* '/' */); 278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (sep > 0 && sep + 1 < tzID.length()) { 279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setTo(tzID, sep + 1); 280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.findAndReplace(UnicodeString((UChar)0x5f /* _ */), 281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString((UChar)0x20 /* space */)); 282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setToBogus(); 284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 287b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNames::getDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, UDate date, UnicodeString& name) const { 290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho getTimeZoneDisplayName(tzID, type, name); 291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (name.isEmpty()) { 292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString mzID; 293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho getMetaZoneID(tzID, date, mzID); 294b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho getMetaZoneDisplayName(mzID, type, name); 295b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_NAMESPACE_END 300b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#endif 301