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 "tzgnames.h" 13b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 14b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/basictz.h" 15b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/locdspnm.h" 16b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/msgfmt.h" 17b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/rbtz.h" 18b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/simpletz.h" 19b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/vtzone.h" 20b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 21b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "cmemory.h" 22b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "cstring.h" 23b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uhash.h" 24b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uassert.h" 25b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "umutex.h" 26b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uresimp.h" 27b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "ureslocs.h" 28b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "zonemeta.h" 29b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "tznames_impl.h" 30b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "olsontz.h" 31b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 32b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_NAMESPACE_BEGIN 33b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 34b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define ZID_KEY_MAX 128 35b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 36b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char gZoneStrings[] = "zoneStrings"; 37b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 38b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char gRegionFormatTag[] = "regionFormat"; 39b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char gFallbackRegionFormatTag[] = "fallbackRegionFormat"; 40b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char gFallbackFormatTag[] = "fallbackFormat"; 41b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 42b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar gEmpty[] = {0x00}; 43b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 44b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar gDefRegionPattern[] = {0x7B, 0x30, 0x7D, 0x00}; // "{0}" 45b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar gDefFallbackRegionPattern[] = {0x7B, 0x31, 0x7D, 0x20, 0x28, 0x7B, 0x30, 0x7D, 0x29, 0x00}; // "{1} ({0})" 46b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar gDefFallbackPattern[] = {0x7B, 0x31, 0x7D, 0x20, 0x28, 0x7B, 0x30, 0x7D, 0x29, 0x00}; // "{1} ({0})" 47b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 48b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const double kDstCheckRange = (double)184*U_MILLIS_PER_DAY; 49b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 50b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 51b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 52b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_BEGIN 53b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 54b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehotypedef struct PartialLocationKey { 55b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* tzID; 56b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* mzID; 57b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool isLong; 58b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} PartialLocationKey; 59b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 60b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 61b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Hash function for partial location name hash key 62b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 63b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic int32_t U_CALLCONV 64b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehohashPartialLocationKey(const UHashTok key) { 65b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // <tzID>&<mzID>#[L|S] 66b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho PartialLocationKey *p = (PartialLocationKey *)key.pointer; 67b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString str(p->tzID); 68b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho str.append((UChar)0x26) 69b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho .append(p->mzID) 70b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho .append((UChar)0x23) 71b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho .append((UChar)(p->isLong ? 0x4C : 0x53)); 72b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return uhash_hashUCharsN(str.getBuffer(), str.length()); 73b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 74b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 75b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 76b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Comparer for partial location name hash key 77b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 78b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic UBool U_CALLCONV 79b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehocomparePartialLocationKey(const UHashTok key1, const UHashTok key2) { 80b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho PartialLocationKey *p1 = (PartialLocationKey *)key1.pointer; 81b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho PartialLocationKey *p2 = (PartialLocationKey *)key2.pointer; 82b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 83b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (p1 == p2) { 84b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 85b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 86b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (p1 == NULL || p2 == NULL) { 87b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 88b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 89b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We just check identity of tzID/mzID 90b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return (p1->tzID == p2->tzID && p1->mzID == p2->mzID && p1->isLong == p2->isLong); 91b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 92b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 93b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 94b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Deleter for GNameInfo 95b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 96b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void U_CALLCONV 97b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehodeleteGNameInfo(void *obj) { 98b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(obj); 99b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 100b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * GNameInfo stores zone name information in the local trie 103b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehotypedef struct GNameInfo { 105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTimeZoneGenericNameType type; 106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* tzID; 107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} ZNameInfo; 108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * GMatchInfo stores zone name match information used by find method 111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 112b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehotypedef struct GMatchInfo { 113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const GNameInfo* gnameInfo; 114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t matchLength; 115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTimeZoneTimeType timeType; 116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} ZMatchInfo; 117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_END 119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// The class stores time zone generic name match information 122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNameMatchInfo::TimeZoneGenericNameMatchInfo(UVector* matches) 124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: fMatches(matches) { 125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNameMatchInfo::~TimeZoneGenericNameMatchInfo() { 128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fMatches != NULL) { 129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fMatches; 130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t 134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNameMatchInfo::size() const { 135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fMatches == NULL) { 136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return 0; 137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fMatches->size(); 139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUTimeZoneGenericNameType 142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNameMatchInfo::getGenericNameType(int32_t index) const { 143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho GMatchInfo *minfo = (GMatchInfo *)fMatches->elementAt(index); 144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (minfo != NULL) { 145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return static_cast<UTimeZoneGenericNameType>(minfo->gnameInfo->type); 146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return UTZGNM_UNKNOWN; 148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t 151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNameMatchInfo::getMatchLength(int32_t index) const { 152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZMatchInfo *minfo = (ZMatchInfo *)fMatches->elementAt(index); 153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (minfo != NULL) { 154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return minfo->matchLength; 155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return -1; 157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNameMatchInfo::getTimeZoneID(int32_t index, UnicodeString& tzID) const { 161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho GMatchInfo *minfo = (GMatchInfo *)fMatches->elementAt(index); 162b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (minfo != NULL && minfo->gnameInfo->tzID != NULL) { 163b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tzID.setTo(TRUE, minfo->gnameInfo->tzID, -1); 164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tzID.setToBogus(); 166b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return tzID; 168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// GNameSearchHandler 172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass GNameSearchHandler : public TextTrieMapSearchResultHandler { 174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehopublic: 175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho GNameSearchHandler(uint32_t types); 176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual ~GNameSearchHandler(); 177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status); 179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UVector* getMatches(int32_t& maxMatchLen); 180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprivate: 182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint32_t fTypes; 183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UVector* fResults; 184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t fMaxMatchLen; 185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoGNameSearchHandler::GNameSearchHandler(uint32_t types) 188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: fTypes(types), fResults(NULL), fMaxMatchLen(0) { 189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoGNameSearchHandler::~GNameSearchHandler() { 192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fResults != NULL) { 193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fResults; 194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoGNameSearchHandler::handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status) { 199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (node->hasValues()) { 203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t valuesCount = node->countValues(); 204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; i < valuesCount; i++) { 205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho GNameInfo *nameinfo = (ZNameInfo *)node->getValue(i); 206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (nameinfo == NULL) { 207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 208b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if ((nameinfo->type & fTypes) != 0) { 210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // matches a requested type 211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fResults == NULL) { 212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fResults = new UVector(uhash_freeBlock, NULL, status); 213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fResults == NULL) { 214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 215b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho GMatchInfo *gmatch = (GMatchInfo *)uprv_malloc(sizeof(GMatchInfo)); 219b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (gmatch == NULL) { 220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // add the match to the vector 223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho gmatch->gnameInfo = nameinfo; 224b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho gmatch->matchLength = matchLength; 225b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho gmatch->timeType = UTZFMT_TIME_TYPE_UNKNOWN; 226b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fResults->addElement(gmatch, status); 227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 228b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(gmatch); 229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 230b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (matchLength > fMaxMatchLen) { 231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fMaxMatchLen = matchLength; 232b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 233b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 234b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 235b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 237b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 238b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 239b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 240b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 241b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 242b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUVector* 243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoGNameSearchHandler::getMatches(int32_t& maxMatchLen) { 244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // give the ownership to the caller 245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UVector *results = fResults; 246b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho maxMatchLen = fMaxMatchLen; 247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // reset 249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fResults = NULL; 250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fMaxMatchLen = 0; 251b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return results; 252b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 254b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 255b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TimeZoneGenericNames 256b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// 257b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TimeZoneGenericNames is parallel to TimeZoneNames, 258b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// but handles run-time generated time zone names. 259b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// This is the main part of this module. 260b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 261b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::TimeZoneGenericNames(const Locale& locale, UErrorCode& status) 262b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: fLocale(locale), 263b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLock(NULL), 264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames(NULL), 265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLocationNamesMap(NULL), 266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fPartialLocationNamesMap(NULL), 267b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fRegionFormat(NULL), 268b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fFallbackRegionFormat(NULL), 269b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fFallbackFormat(NULL), 270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLocaleDisplayNames(NULL), 271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fStringPool(status), 272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fGNamesTrie(TRUE, deleteGNameInfo), 273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fGNamesTrieFullyLoaded(FALSE) { 274b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho initialize(locale, status); 275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::~TimeZoneGenericNames() { 278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cleanup(); 279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_destroy(&fLock); 280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::initialize(const Locale& locale, UErrorCode& status) { 284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 287b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // TimeZoneNames 289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames = TimeZoneNames::createInstance(locale, status); 290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 294b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Initialize format patterns 295b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString rpat(TRUE, gDefRegionPattern, -1); 296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString frpat(TRUE, gDefFallbackRegionPattern, -1); 297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString fpat(TRUE, gDefFallbackPattern, -1); 298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode tmpsts = U_ZERO_ERROR; // OK with fallback warning.. 300b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UResourceBundle *zoneStrings = ures_open(U_ICUDATA_ZONE, locale.getName(), &tmpsts); 301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho zoneStrings = ures_getByKeyWithFallback(zoneStrings, gZoneStrings, zoneStrings, &tmpsts); 302b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 303b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(tmpsts)) { 304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *regionPattern = ures_getStringByKeyWithFallback(zoneStrings, gRegionFormatTag, NULL, &tmpsts); 305b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(tmpsts) && u_strlen(regionPattern) > 0) { 306b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho rpat.setTo(regionPattern); 307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 308b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tmpsts = U_ZERO_ERROR; 309b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *fallbackRegionPattern = ures_getStringByKeyWithFallback(zoneStrings, gFallbackRegionFormatTag, NULL, &tmpsts); 310b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(tmpsts) && u_strlen(fallbackRegionPattern) > 0) { 311b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho frpat.setTo(fallbackRegionPattern); 312b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tmpsts = U_ZERO_ERROR; 314b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *fallbackPattern = ures_getStringByKeyWithFallback(zoneStrings, gFallbackFormatTag, NULL, &tmpsts); 315b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(tmpsts) && u_strlen(fallbackPattern) > 0) { 316b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fpat.setTo(fallbackPattern); 317b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 318b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 319b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ures_close(zoneStrings); 320b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 321b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fRegionFormat = new MessageFormat(rpat, status); 322b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fRegionFormat == NULL) { 323b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 324b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fFallbackRegionFormat = new MessageFormat(frpat, status); 326b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fFallbackRegionFormat == NULL) { 327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 329b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fFallbackFormat = new MessageFormat(fpat, status); 330b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fFallbackFormat == NULL) { 331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 334b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cleanup(); 335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 336b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 337b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 338b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // locale display names 339b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLocaleDisplayNames = LocaleDisplayNames::createInstance(locale); 340b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 341b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // hash table for names - no key/value deleters 342b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLocationNamesMap = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status); 343b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 344b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cleanup(); 345b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 346b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 347b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 348b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fPartialLocationNamesMap = uhash_open(hashPartialLocationKey, comparePartialLocationKey, NULL, &status); 349b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 350b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cleanup(); 351b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 352b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 353b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_setKeyDeleter(fPartialLocationNamesMap, uhash_freeBlock); 354b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // no value deleter 355b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 356b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // target region 357b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const char* region = fLocale.getCountry(); 358b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t regionLen = uprv_strlen(region); 359b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (regionLen == 0) { 360b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho char loc[ULOC_FULLNAME_CAPACITY]; 361b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status); 362b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho regionLen = uloc_getCountry(loc, fTargetRegion, sizeof(fTargetRegion), &status); 364b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 365b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTargetRegion[regionLen] = 0; 366b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 367b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cleanup(); 368b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 369b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 370b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (regionLen < (int32_t)sizeof(fTargetRegion)) { 371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_strcpy(fTargetRegion, region); 372b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 373b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTargetRegion[0] = 0; 374b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 375b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 376b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // preload generic names for the default zone 377b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZone *tz = TimeZone::createDefault(); 378b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *tzID = ZoneMeta::getCanonicalCLDRID(*tz); 379b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzID != NULL) { 380b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho loadStrings(UnicodeString(tzID)); 381b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 382b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tz; 383b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 384b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 385b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 386b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::cleanup() { 387b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fRegionFormat != NULL) { 388b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fRegionFormat; 389b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 390b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fFallbackRegionFormat != NULL) { 391b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fFallbackRegionFormat; 392b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 393b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fFallbackFormat != NULL) { 394b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fFallbackFormat; 395b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 396b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fLocaleDisplayNames != NULL) { 397b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fLocaleDisplayNames; 398b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 399b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fTimeZoneNames != NULL) { 400b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fTimeZoneNames; 401b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 402b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 403b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(fLocationNamesMap); 404b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(fPartialLocationNamesMap); 405b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 406b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 407b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 408b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::getDisplayName(const TimeZone& tz, UTimeZoneGenericNameType type, UDate date, UnicodeString& name) const { 409b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setToBogus(); 410b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho switch (type) { 411b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZGNM_LOCATION: 412b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 413b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* tzCanonicalID = ZoneMeta::getCanonicalCLDRID(tz); 414b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzCanonicalID != NULL) { 415b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho getGenericLocationName(UnicodeString(tzCanonicalID), name); 416b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 417b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 418b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 419b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZGNM_LONG: 420b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZGNM_SHORT: 421b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formatGenericNonLocationName(tz, type, date, name); 422b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (name.isEmpty()) { 423b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* tzCanonicalID = ZoneMeta::getCanonicalCLDRID(tz); 424b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzCanonicalID != NULL) { 425b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho getGenericLocationName(UnicodeString(tzCanonicalID), name); 426b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 427b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 428b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 429b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho default: 430b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 431b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 432b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 433b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 434b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 435b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 436b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::getGenericLocationName(const UnicodeString& tzCanonicalID, UnicodeString& name) const { 437b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzCanonicalID.isEmpty()) { 438b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setToBogus(); 439b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 440b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 441b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 442b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *locname = NULL; 443b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneGenericNames *nonConstThis = const_cast<TimeZoneGenericNames *>(this); 444b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_lock(&nonConstThis->fLock); 445b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 446b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho locname = nonConstThis->getGenericLocationName(tzCanonicalID); 447b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 448b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_unlock(&nonConstThis->fLock); 449b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 450b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (locname == NULL) { 451b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setToBogus(); 452b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 453b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setTo(TRUE, locname, -1); 454b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 455b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 456b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 457b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 458b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 459b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 460b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * This method updates the cache and must be called with a lock 461b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 462b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar* 463b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::getGenericLocationName(const UnicodeString& tzCanonicalID) { 464b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(!tzCanonicalID.isEmpty()); 465b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzCanonicalID.length() > ZID_KEY_MAX) { 466b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 467b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 468b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 469b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 470b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar tzIDKey[ZID_KEY_MAX + 1]; 471b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t tzIDKeyLen = tzCanonicalID.extract(tzIDKey, ZID_KEY_MAX + 1, status); 472b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(status == U_ZERO_ERROR); // already checked length above 473b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tzIDKey[tzIDKeyLen] = 0; 474b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 475b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *locname = (const UChar *)uhash_get(fLocationNamesMap, tzIDKey); 476b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 477b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (locname != NULL) { 478b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // gEmpty indicate the name is not available 479b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (locname == gEmpty) { 480b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 481b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 482b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return locname; 483b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 484b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 485b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Construct location name 486b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString name; 487b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool isSingleCountry = FALSE; 488b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString usCountryCode; 489b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZoneMeta::getSingleCountry(tzCanonicalID, usCountryCode); 490b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!usCountryCode.isEmpty()) { 491b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho isSingleCountry = TRUE; 492b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 493b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZoneMeta::getCanonicalCountry(tzCanonicalID, usCountryCode); 494b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 495b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 496b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!usCountryCode.isEmpty()) { 497b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho char countryCode[ULOC_COUNTRY_CAPACITY]; 498b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(usCountryCode.length() < ULOC_COUNTRY_CAPACITY); 499b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t ccLen = usCountryCode.extract(0, usCountryCode.length(), countryCode, sizeof(countryCode), US_INV); 500b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho countryCode[ccLen] = 0; 501b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 502b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString country; 503b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLocaleDisplayNames->regionDisplayName(countryCode, country); 504b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 505b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Format 506b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho FieldPosition fpos; 507b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (isSingleCountry) { 508b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // If the zone is only one zone in the country, do not add city 509b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Formattable param[] = { 510b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Formattable(country) 511b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 512b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fRegionFormat->format(param, 1, name, fpos, status); 513b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 514b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // getExemplarLocationName should retur non-empty string 515b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // if the time zone is associated with a region 516b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString city; 517b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames->getExemplarLocationName(tzCanonicalID, city); 518b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 519b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Formattable params[] = { 520b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Formattable(city), 521b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Formattable(country) 522b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 523b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fFallbackRegionFormat->format(params, 2, name, fpos, status); 524b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 525b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 526b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 527b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 528b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 529b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 530b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho locname = name.isEmpty() ? NULL : fStringPool.get(name, status); 531b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 532b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Cache the result 533b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* cacheID = ZoneMeta::findTimeZoneID(tzCanonicalID); 534b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(cacheID != NULL); 535b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (locname == NULL) { 536b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // gEmpty to indicate - no location name available 537b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_put(fLocationNamesMap, (void *)cacheID, (void *)gEmpty, &status); 538b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 539b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_put(fLocationNamesMap, (void *)cacheID, (void *)locname, &status); 540b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 541b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho locname = NULL; 542b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 543b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // put the name info into the trie 544b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho GNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(GNameInfo)); 545b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (nameinfo != NULL) { 546b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->type = UTZGNM_LOCATION; 547b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->tzID = cacheID; 548b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fGNamesTrie.put(locname, nameinfo, status); 549b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 550b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 551b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 552b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 553b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 554b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return locname; 555b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 556b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 557b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 558b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::formatGenericNonLocationName(const TimeZone& tz, UTimeZoneGenericNameType type, UDate date, UnicodeString& name) const { 559b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(type == UTZGNM_LONG || type == UTZGNM_SHORT); 560b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setToBogus(); 561b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 562b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* uID = ZoneMeta::getCanonicalCLDRID(tz); 563b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (uID == NULL) { 564b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 565b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 566b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 567b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString tzID(uID); 568b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 569b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Try to get a name from time zone first 570b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTimeZoneNameType nameType = (type == UTZGNM_LONG) ? UTZNM_LONG_GENERIC : UTZNM_SHORT_GENERIC; 571b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames->getTimeZoneDisplayName(tzID, nameType, name); 572b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 573b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!name.isEmpty()) { 574b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 575b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 576b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 577b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Try meta zone 578b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString mzID; 579b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames->getMetaZoneID(tzID, date, mzID); 580b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!mzID.isEmpty()) { 581b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 582b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool useStandard = FALSE; 583b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t raw, sav; 584b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 585b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tz.getOffset(date, FALSE, raw, sav, status); 586b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 587b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 588b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 589b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 590b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (sav == 0) { 591b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho useStandard = TRUE; 592b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 593b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZone *tmptz = tz.clone(); 594b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Check if the zone actually uses daylight saving time around the time 595b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho BasicTimeZone *btz = NULL; 596b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (dynamic_cast<OlsonTimeZone *>(tmptz) != NULL 597b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho || dynamic_cast<SimpleTimeZone *>(tmptz) != NULL 598b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho || dynamic_cast<RuleBasedTimeZone *>(tmptz) != NULL 599b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho || dynamic_cast<VTimeZone *>(tmptz) != NULL) { 600b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho btz = (BasicTimeZone*)tmptz; 601b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 602b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 603b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (btz != NULL) { 604b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneTransition before; 605b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool beforTrs = btz->getPreviousTransition(date, TRUE, before); 606b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (beforTrs 607b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho && (date - before.getTime() < kDstCheckRange) 608b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho && before.getFrom()->getDSTSavings() != 0) { 609b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho useStandard = FALSE; 610b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 611b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneTransition after; 612b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool afterTrs = btz->getNextTransition(date, FALSE, after); 613b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (afterTrs 614b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho && (after.getTime() - date < kDstCheckRange) 615b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho && after.getTo()->getDSTSavings() != 0) { 616b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho useStandard = FALSE; 617b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 618b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 619b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 620b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // If not BasicTimeZone... only if the instance is not an ICU's implementation. 621b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We may get a wrong answer in edge case, but it should practically work OK. 622b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tmptz->getOffset(date - kDstCheckRange, FALSE, raw, sav, status); 623b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (sav != 0) { 624b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho useStandard = FALSE; 625b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 626b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tmptz->getOffset(date + kDstCheckRange, FALSE, raw, sav, status); 627b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (sav != 0){ 628b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho useStandard = FALSE; 629b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 630b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 631b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 632b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tmptz; 633b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 634b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 635b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 636b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tmptz; 637b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 638b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (useStandard) { 639b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTimeZoneNameType stdNameType = (nameType == UTZNM_LONG_GENERIC) 640b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ? UTZNM_LONG_STANDARD : UTZNM_SHORT_STANDARD_COMMONLY_USED; 641b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString stdName; 642b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames->getDisplayName(tzID, stdNameType, date, stdName); 643b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!stdName.isEmpty()) { 644b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setTo(stdName); 645b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 646b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // TODO: revisit this issue later 647b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // In CLDR, a same display name is used for both generic and standard 648b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // for some meta zones in some locales. This looks like a data bugs. 649b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // For now, we check if the standard name is different from its generic 650b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // name below. 651b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString mzGenericName; 652b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames->getMetaZoneDisplayName(mzID, nameType, mzGenericName); 653b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (stdName.caseCompare(mzGenericName, 0) == 0) { 654b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setToBogus(); 655b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 656b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 657b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 658b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (name.isEmpty()) { 659b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Get a name from meta zone 660b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString mzName; 661b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames->getMetaZoneDisplayName(mzID, nameType, mzName); 662b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!mzName.isEmpty()) { 663b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Check if we need to use a partial location format. 664b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // This check is done by comparing offset with the meta zone's 665b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // golden zone at the given date. 666b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString goldenID; 667b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames->getReferenceZoneID(mzID, fTargetRegion, goldenID); 668b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!goldenID.isEmpty() && goldenID != tzID) { 669b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZone *goldenZone = TimeZone::createTimeZone(goldenID); 670b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t raw1, sav1; 671b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 672b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Check offset in the golden zone with wall time. 673b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // With getOffset(date, false, offsets1), 674b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // you may get incorrect results because of time overlap at DST->STD 675b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // transition. 676b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho goldenZone->getOffset(date + raw + sav, TRUE, raw1, sav1, status); 677b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete goldenZone; 678b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 679b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (raw != raw1 || sav != sav1) { 680b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Now we need to use a partial location format 681b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho getPartialLocationName(tzID, mzID, (nameType == UTZNM_LONG_GENERIC), mzName, name); 682b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 683b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setTo(mzName); 684b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 685b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 686b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 687b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setTo(mzName); 688b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 689b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 690b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 691b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 692b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 693b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 694b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 695b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 696b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::getPartialLocationName(const UnicodeString& tzCanonicalID, 697b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString& mzID, UBool isLong, const UnicodeString& mzDisplayName, 698b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString& name) const { 699b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setToBogus(); 700b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzCanonicalID.isEmpty() || mzID.isEmpty() || mzDisplayName.isEmpty()) { 701b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 702b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 703b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 704b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *uplname = NULL; 705b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneGenericNames *nonConstThis = const_cast<TimeZoneGenericNames *>(this); 706b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_lock(&nonConstThis->fLock); 707b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 708b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uplname = nonConstThis->getPartialLocationName(tzCanonicalID, mzID, isLong, mzDisplayName); 709b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 710b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_unlock(&nonConstThis->fLock); 711b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 712b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (uplname == NULL) { 713b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setToBogus(); 714b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 715b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setTo(TRUE, uplname, -1); 716b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 717b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 718b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 719b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 720b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 721b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * This method updates the cache and must be called with a lock 722b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 723b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar* 724b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::getPartialLocationName(const UnicodeString& tzCanonicalID, 725b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString& mzID, UBool isLong, const UnicodeString& mzDisplayName) { 726b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(!tzCanonicalID.isEmpty()); 727b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(!mzID.isEmpty()); 728b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(!mzDisplayName.isEmpty()); 729b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 730b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho PartialLocationKey key; 731b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho key.tzID = ZoneMeta::findTimeZoneID(tzCanonicalID); 732b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho key.mzID = ZoneMeta::findMetaZoneID(mzID); 733b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho key.isLong = isLong; 734b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(key.tzID != NULL && key.mzID != NULL); 735b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 736b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* uplname = (const UChar*)uhash_get(fPartialLocationNamesMap, (void *)&key); 737b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (uplname != NULL) { 738b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return uplname; 739b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 740b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 741b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString location; 742b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString usCountryCode; 743b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZoneMeta::getCanonicalCountry(tzCanonicalID, usCountryCode); 744b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!usCountryCode.isEmpty()) { 745b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho char countryCode[ULOC_COUNTRY_CAPACITY]; 746b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(usCountryCode.length() < ULOC_COUNTRY_CAPACITY); 747b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t ccLen = usCountryCode.extract(0, usCountryCode.length(), countryCode, sizeof(countryCode), US_INV); 748b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho countryCode[ccLen] = 0; 749b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 750b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString regionalGolden; 751b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames->getReferenceZoneID(mzID, countryCode, regionalGolden); 752b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzCanonicalID == regionalGolden) { 753b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Use country name 754b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLocaleDisplayNames->regionDisplayName(countryCode, location); 755b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 756b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Otherwise, use exemplar city name 757b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames->getExemplarLocationName(tzCanonicalID, location); 758b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 759b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 760b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames->getExemplarLocationName(tzCanonicalID, location); 761b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (location.isEmpty()) { 762b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // This could happen when the time zone is not associated with a country, 763b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // and its ID is not hierarchical, for example, CST6CDT. 764b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We use the canonical ID itself as the location for this case. 765b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho location.setTo(tzCanonicalID); 766b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 767b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 768b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 769b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 770b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString name; 771b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 772b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho FieldPosition fpos; 773b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Formattable param[] = { 774b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Formattable(location), 775b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Formattable(mzDisplayName) 776b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 777b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fFallbackFormat->format(param, 2, name, fpos, status); 778b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 779b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 780b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 781b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 782b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uplname = fStringPool.get(name, status); 783b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 784b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Add the name to cache 785b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho PartialLocationKey* cacheKey = (PartialLocationKey *)uprv_malloc(sizeof(PartialLocationKey)); 786b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cacheKey != NULL) { 787b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheKey->tzID = key.tzID; 788b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheKey->mzID = key.mzID; 789b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheKey->isLong = key.isLong; 790b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_put(fPartialLocationNamesMap, (void *)cacheKey, (void *)uplname, &status); 791b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 792b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(cacheKey); 793b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 794b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // put the name to the local trie as well 795b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho GNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(GNameInfo)); 796b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (nameinfo != NULL) { 797b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->type = isLong ? UTZGNM_LONG : UTZGNM_SHORT; 798b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->tzID = key.tzID; 799b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fGNamesTrie.put(uplname, nameinfo, status); 800b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 801b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 802b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 803b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 804b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return uplname; 805b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 806b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 807b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 808b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * This method updates the cache and must be called with a lock, 809b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * except initializer. 810b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 811b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 812b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::loadStrings(const UnicodeString& tzCanonicalID) { 813b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // load the generic location name 814b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho getGenericLocationName(tzCanonicalID); 815b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 816b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // partial location names 817b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 818b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 819b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString *mzID; 820b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString goldenID; 821b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString mzGenName; 822b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTimeZoneNameType genNonLocTypes[] = { 823b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTZNM_LONG_GENERIC, UTZNM_SHORT_GENERIC, 824b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTZNM_UNKNOWN /*terminator*/ 825b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho }; 826b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 827b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho StringEnumeration *mzIDs = fTimeZoneNames->getAvailableMetaZoneIDs(tzCanonicalID, status); 828b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while ((mzID = mzIDs->snext(status))) { 829b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 830b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 831b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 832b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // if this time zone is not the golden zone of the meta zone, 833b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // partial location name (such as "PT (Los Angeles)") might be 834b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // available. 835b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames->getReferenceZoneID(*mzID, fTargetRegion, goldenID); 836b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzCanonicalID != goldenID) { 837b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; genNonLocTypes[i] != UTZNM_UNKNOWN; i++) { 838b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames->getMetaZoneDisplayName(*mzID, genNonLocTypes[i], mzGenName); 839b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!mzGenName.isEmpty()) { 840b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // getPartialLocationName formats a name and put it into the trie 841b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho getPartialLocationName(tzCanonicalID, *mzID, 842b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (genNonLocTypes[i] == UTZNM_LONG_GENERIC), mzGenName); 843b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 844b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 845b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 846b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 847b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (mzIDs != NULL) { 848b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete mzIDs; 849b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 850b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 851b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 852b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t 853b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::findBestMatch(const UnicodeString& text, int32_t start, uint32_t types, 854b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString& tzID, UTimeZoneTimeType& timeType, UErrorCode& status) const { 855b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho timeType = UTZFMT_TIME_TYPE_UNKNOWN; 856b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tzID.setToBogus(); 857b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 858b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 859b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return 0; 860b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 861b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 862b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Find matches in the TimeZoneNames first 863b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNameMatchInfo *tznamesMatches = findTimeZoneNames(text, start, types, status); 864b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 865b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return 0; 866b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 867b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 868b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t bestMatchLen = 0; 869b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTimeZoneTimeType bestMatchTimeType = UTZFMT_TIME_TYPE_UNKNOWN; 870b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString bestMatchTzID; 871b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool isLongStandard = FALSE; // workaround - see the comments below 872b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 873b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tznamesMatches != NULL) { 874b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString mzID; 875b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; i < tznamesMatches->size(); i++) { 876b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t len = tznamesMatches->getMatchLength(i); 877b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (len > bestMatchLen) { 878b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho bestMatchLen = len; 879b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tznamesMatches->getTimeZoneID(i, bestMatchTzID); 880b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (bestMatchTzID.isEmpty()) { 881b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // name for a meta zone 882b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tznamesMatches->getMetaZoneID(i, mzID); 883b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(mzID.length() > 0); 884b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTimeZoneNames->getReferenceZoneID(mzID, fTargetRegion, bestMatchTzID); 885b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 886b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTimeZoneNameType nameType = tznamesMatches->getNameType(i); 887b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho switch (nameType) { 888b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_LONG_STANDARD: 889b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho isLongStandard = TRUE; 890b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_SHORT_STANDARD_COMMONLY_USED: 891b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_SHORT_STANDARD: // this one is never used for generic, but just in case 892b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho bestMatchTimeType = UTZFMT_TIME_TYPE_STANDARD; 893b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 894b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_LONG_DAYLIGHT: 895b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_SHORT_DAYLIGHT_COMMONLY_USED: 896b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_SHORT_DAYLIGHT: // this one is never used for generic, but just in case 897b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho bestMatchTimeType = UTZFMT_TIME_TYPE_DAYLIGHT; 898b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 899b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho default: 900b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho bestMatchTimeType = UTZFMT_TIME_TYPE_UNKNOWN; 901b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 902b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 903b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 904b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tznamesMatches; 905b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 906b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (bestMatchLen == (text.length() - start)) { 907b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Full match 908b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 909b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho //tzID.setTo(bestMatchTzID); 910b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho //timeType = bestMatchTimeType; 911b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho //return bestMatchLen; 912b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 913b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // TODO Some time zone uses a same name for the long standard name 914b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // and the location name. When the match is a long standard name, 915b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // then we need to check if the name is same with the location name. 916b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // This is probably a data error or a design bug. 917b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!isLongStandard) { 918b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tzID.setTo(bestMatchTzID); 919b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho timeType = bestMatchTimeType; 920b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return bestMatchLen; 921b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 922b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 923b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 924b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 925b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Find matches in the local trie 926b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneGenericNameMatchInfo *localMatches = findLocal(text, start, types, status); 927b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 928b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return 0; 929b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 930b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (localMatches != NULL) { 931b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; i < localMatches->size(); i++) { 932b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t len = localMatches->getMatchLength(i); 933b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 934b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // TODO See the above TODO. We use len >= bestMatchLen 935b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // because of the long standard/location name collision 936b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // problem. If it is also a location name, carrying 937b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // timeType = UTZFMT_TIME_TYPE_STANDARD will cause a 938b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // problem in SimpleDateFormat 939b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (len >= bestMatchLen) { 940b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho bestMatchLen = localMatches->getMatchLength(i); 941b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho bestMatchTimeType = UTZFMT_TIME_TYPE_UNKNOWN; // because generic 942b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho localMatches->getTimeZoneID(i, bestMatchTzID); 943b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 944b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 945b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete localMatches; 946b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 947b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 948b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (bestMatchLen > 0) { 949b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho timeType = bestMatchTimeType; 950b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tzID.setTo(bestMatchTzID); 951b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 952b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return bestMatchLen; 953b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 954b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 955b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNameMatchInfo* 956b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::findLocal(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const { 957b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho GNameSearchHandler handler(types); 958b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 959b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneGenericNames *nonConstThis = const_cast<TimeZoneGenericNames *>(this); 960b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 961b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_lock(&nonConstThis->fLock); 962b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 963b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fGNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); 964b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 965b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_unlock(&nonConstThis->fLock); 966b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 967b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 968b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 969b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 970b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 971b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneGenericNameMatchInfo *gmatchInfo = NULL; 972b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 973b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t maxLen = 0; 974b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UVector *results = handler.getMatches(maxLen); 975b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (results != NULL && ((maxLen == (text.length() - start)) || fGNamesTrieFullyLoaded)) { 976b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // perfect match 977b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho gmatchInfo = new TimeZoneGenericNameMatchInfo(results); 978b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (gmatchInfo == NULL) { 979b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 980b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete results; 981b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 982b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 983b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return gmatchInfo; 984b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 985b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 986b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (results != NULL) { 987b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete results; 988b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 989b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 990b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // All names are not yet loaded into the local trie. 991b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Load all available names into the trie. This could be very heavy. 992b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_lock(&nonConstThis->fLock); 993b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 994b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!fGNamesTrieFullyLoaded) { 995b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho StringEnumeration *tzIDs = TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status); 996b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 997b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString *tzID; 998b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while ((tzID = tzIDs->snext(status))) { 999b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1000b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 1001b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1002b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nonConstThis->loadStrings(*tzID); 1003b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1004b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1005b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzIDs != NULL) { 1006b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tzIDs; 1007b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1008b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1009b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 1010b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nonConstThis->fGNamesTrieFullyLoaded = TRUE; 1011b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1012b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1013b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1014b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_unlock(&nonConstThis->fLock); 1015b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1016b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1017b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1018b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1019b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1020b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_lock(&nonConstThis->fLock); 1021b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 1022b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // now try it again 1023b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fGNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); 1024b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1025b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_unlock(&nonConstThis->fLock); 1026b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1027b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho results = handler.getMatches(maxLen); 1028b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (results != NULL && maxLen > 0) { 1029b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho gmatchInfo = new TimeZoneGenericNameMatchInfo(results); 1030b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (gmatchInfo == NULL) { 1031b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 1032b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete results; 1033b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1034b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1035b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1036b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1037b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return gmatchInfo; 1038b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1039b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1040b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNameMatchInfo* 1041b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneGenericNames::findTimeZoneNames(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const { 1042b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNameMatchInfo *matchInfo = NULL; 1043b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1044b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Check if the target name typs is really in the TimeZoneNames 1045b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint32_t nameTypes = 0; 1046b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (types & UTZGNM_LONG) { 1047b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameTypes |= (UTZNM_LONG_GENERIC | UTZNM_LONG_STANDARD); 1048b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1049b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (types & UTZGNM_SHORT) { 1050b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameTypes |= (UTZNM_SHORT_GENERIC | UTZNM_SHORT_STANDARD_COMMONLY_USED); 1051b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1052b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1053b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (types) { 1054b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Find matches in the TimeZoneNames 1055b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho matchInfo = fTimeZoneNames->find(text, start, nameTypes, status); 1056b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1057b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1058b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return matchInfo; 1059b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1060b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1061b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_NAMESPACE_END 1062b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#endif 1063