1b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 2b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho******************************************************************************* 3f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius* Copyright (C) 2011-2014, International Business Machines Corporation and 4b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* others. All Rights Reserved. 5b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho******************************************************************************* 6b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* 7b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* File TZNAMES_IMPL.CPP 8b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* 9b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho******************************************************************************* 10b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho*/ 11b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 12b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/utypes.h" 13b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 14b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#if !UCONFIG_NO_FORMATTING 15b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 16b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/ustring.h" 17b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/timezone.h" 18b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 19b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "tznames_impl.h" 20b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "cmemory.h" 21b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "cstring.h" 22b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uassert.h" 2359d709d503bab6e2b61931737e662dd293b40578ccornelius#include "mutex.h" 24b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uresimp.h" 25b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "ureslocs.h" 26b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "zonemeta.h" 27b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "ucln_in.h" 28b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uvector.h" 29b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "olsontz.h" 30b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 31b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 32b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_NAMESPACE_BEGIN 33b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 34b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define ZID_KEY_MAX 128 35b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define MZ_PREFIX_LEN 5 36b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 37b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char gZoneStrings[] = "zoneStrings"; 38b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char gMZPrefix[] = "meta:"; 39b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 40b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char* KEYS[] = {"lg", "ls", "ld", "sg", "ss", "sd"}; 41b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const int32_t KEYS_SIZE = (sizeof KEYS / sizeof KEYS[0]); 42b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 43b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char gEcTag[] = "ec"; 44b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 45b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char EMPTY[] = "<empty>"; // place holder for empty ZNames/TZNames 46b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 47b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UTimeZoneNameType ALL_NAME_TYPES[] = { 48b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTZNM_LONG_GENERIC, UTZNM_LONG_STANDARD, UTZNM_LONG_DAYLIGHT, 49b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTZNM_SHORT_GENERIC, UTZNM_SHORT_STANDARD, UTZNM_SHORT_DAYLIGHT, 508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UTZNM_EXEMPLAR_LOCATION, 51b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTZNM_UNKNOWN // unknown as the last one 52b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 53b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 54f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// stuff for TZDBTimeZoneNames 55f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic const char* TZDBNAMES_KEYS[] = {"ss", "sd"}; 56f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic const int32_t TZDBNAMES_KEYS_SIZE = (sizeof TZDBNAMES_KEYS / sizeof TZDBNAMES_KEYS[0]); 57f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 58f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic UMutex gTZDBNamesMapLock = U_MUTEX_INITIALIZER; 59f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 60f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic UHashtable* gTZDBNamesMap = NULL; 61f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic icu::UInitOnce gTZDBNamesMapInitOnce = U_INITONCE_INITIALIZER; 62f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 63f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic TextTrieMap* gTZDBNamesTrie = NULL; 64f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic icu::UInitOnce gTZDBNamesTrieInitOnce = U_INITONCE_INITIALIZER; 65f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 66f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CDECL_BEGIN 67f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic UBool U_CALLCONV tzdbTimeZoneNames_cleanup(void) { 68f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (gTZDBNamesMap != NULL) { 69f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uhash_close(gTZDBNamesMap); 70f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gTZDBNamesMap = NULL; 71f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 72f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gTZDBNamesMapInitOnce.reset(); 73f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 74f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (gTZDBNamesTrie != NULL) { 75f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius delete gTZDBNamesTrie; 76f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gTZDBNamesTrie = NULL; 77f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 78f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gTZDBNamesTrieInitOnce.reset(); 79f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 80f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TRUE; 81f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 82f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CDECL_END 83f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 84b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define DEFAULT_CHARACTERNODE_CAPACITY 1 85b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 86b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 87103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// CharacterNode class implementation 88b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 89b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid CharacterNode::clear() { 90b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_memset(this, 0, sizeof(*this)); 91b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 92b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 93b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid CharacterNode::deleteValues(UObjectDeleter *valueDeleter) { 94b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fValues == NULL) { 95b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Do nothing. 96b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (!fHasValuesVector) { 97b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (valueDeleter) { 98b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho valueDeleter(fValues); 99b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 100b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete (UVector *)fValues; 102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 103b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoCharacterNode::addValue(void *value, UObjectDeleter *valueDeleter, UErrorCode &status) { 107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (valueDeleter) { 109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho valueDeleter(value); 110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 112b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fValues == NULL) { 114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fValues = value; 115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // At least one value already. 117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!fHasValuesVector) { 118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // There is only one value so far, and not in a vector yet. 119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Create a vector and add the old value. 120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UVector *values = new UVector(valueDeleter, NULL, DEFAULT_CHARACTERNODE_CAPACITY, status); 121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (valueDeleter) { 123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho valueDeleter(value); 124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho values->addElement(fValues, status); 128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fValues = values; 129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fHasValuesVector = TRUE; 130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Add the new value. 132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ((UVector *)fValues)->addElement(value, status); 133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TextTrieMapSearchResultHandler class implementation 138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMapSearchResultHandler::~TextTrieMapSearchResultHandler(){ 140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TextTrieMap class implementation 144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::TextTrieMap(UBool ignoreCase, UObjectDeleter *valueDeleter) 146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: fIgnoreCase(ignoreCase), fNodes(NULL), fNodesCapacity(0), fNodesCount(0), 147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLazyContents(NULL), fIsEmpty(TRUE), fValueDeleter(valueDeleter) { 148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::~TextTrieMap() { 151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t index; 152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (index = 0; index < fNodesCount; ++index) { 153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodes[index].deleteValues(fValueDeleter); 154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(fNodes); 156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fLazyContents != NULL) { 157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i=0; i<fLazyContents->size(); i+=2) { 158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fValueDeleter) { 159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fValueDeleter(fLazyContents->elementAt(i+1)); 160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 162b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fLazyContents; 163b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 166b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t TextTrieMap::isEmpty() const { 167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Use a separate field for fIsEmpty because it will remain unchanged once the 168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Trie is built, while fNodes and fLazyContents change with the lazy init 169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // of the nodes structure. Trying to test the changing fields has 170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // thread safety complications. 171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fIsEmpty; 172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// We defer actually building the TextTrieMap node structure until the first time a 176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// search is performed. put() simply saves the parameters in case we do 177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// eventually need to build it. 178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// 179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::put(const UnicodeString &key, void *value, ZNStringPool &sp, UErrorCode &status) { 181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *s = sp.get(key, status); 182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho put(s, value, status); 183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// This method is for designed for a persistent key, such as string key stored in 186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// resource bundle. 187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::put(const UChar *key, void *value, UErrorCode &status) { 189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fIsEmpty = FALSE; 190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fLazyContents == NULL) { 191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLazyContents = new UVector(status); 192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fLazyContents == NULL) { 193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 199103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(fLazyContents != NULL); 200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar *s = const_cast<UChar *>(key); 201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLazyContents->addElement(s, status); 202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLazyContents->addElement(value, status); 203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::putImpl(const UnicodeString &key, void *value, UErrorCode &status) { 207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fNodes == NULL) { 208b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodesCapacity = 512; 209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodes = (CharacterNode *)uprv_malloc(fNodesCapacity * sizeof(CharacterNode)); 210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodes[0].clear(); // Init root node. 211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodesCount = 1; 212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString foldedKey; 215b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *keyBuffer; 216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t keyLength; 217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fIgnoreCase) { 218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Ok to use fastCopyFrom() because we discard the copy when we return. 219b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho foldedKey.fastCopyFrom(key).foldCase(); 220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho keyBuffer = foldedKey.getBuffer(); 221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho keyLength = foldedKey.length(); 222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho keyBuffer = key.getBuffer(); 224b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho keyLength = key.length(); 225b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 226b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho CharacterNode *node = fNodes; 228b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t index; 229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (index = 0; index < keyLength; ++index) { 230b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node = addChildNode(node, keyBuffer[index], status); 231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 232b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node->addValue(value, fValueDeleter, status); 233b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 234b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 235b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::growNodes() { 237b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fNodesCapacity == 0xffff) { 238b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; // We use 16-bit node indexes. 239b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 240b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t newCapacity = fNodesCapacity + 1000; 241b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newCapacity > 0xffff) { 242b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho newCapacity = 0xffff; 243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho CharacterNode *newNodes = (CharacterNode *)uprv_malloc(newCapacity * sizeof(CharacterNode)); 245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newNodes == NULL) { 246b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_memcpy(newNodes, fNodes, fNodesCount * sizeof(CharacterNode)); 249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(fNodes); 250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodes = newNodes; 251b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodesCapacity = newCapacity; 252b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 254b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 255b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoCharacterNode* 256b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::addChildNode(CharacterNode *parent, UChar c, UErrorCode &status) { 257b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 258b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 259b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 260b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Linear search of the sorted list of children. 261b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t prevIndex = 0; 262b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t nodeIndex = parent->fFirstChild; 263b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while (nodeIndex > 0) { 264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho CharacterNode *current = fNodes + nodeIndex; 265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar childCharacter = current->fCharacter; 266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (childCharacter == c) { 267b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return current; 268b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (childCharacter > c) { 269b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho prevIndex = nodeIndex; 272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nodeIndex = current->fNextSibling; 273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 274b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Ensure capacity. Grow fNodes[] if needed. 276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fNodesCount == fNodesCapacity) { 277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t parentIndex = (int32_t)(parent - fNodes); 278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!growNodes()) { 279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho parent = fNodes + parentIndex; 283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Insert a new child node with c in sorted order. 286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho CharacterNode *node = fNodes + fNodesCount; 287b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node->clear(); 288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node->fCharacter = c; 289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node->fNextSibling = nodeIndex; 290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (prevIndex == 0) { 291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho parent->fFirstChild = (uint16_t)fNodesCount; 292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodes[prevIndex].fNextSibling = (uint16_t)fNodesCount; 294b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 295b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ++fNodesCount; 296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return node; 297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoCharacterNode* 300b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::getChildNode(CharacterNode *parent, UChar c) const { 301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Linear search of the sorted list of children. 302b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t nodeIndex = parent->fFirstChild; 303b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while (nodeIndex > 0) { 304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho CharacterNode *current = fNodes + nodeIndex; 305b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar childCharacter = current->fCharacter; 306b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (childCharacter == c) { 307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return current; 308b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (childCharacter > c) { 309b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 310b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 311b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nodeIndex = current->fNextSibling; 312b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 314b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 315b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 316b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Mutex for protecting the lazy creation of the Trie node structure on the first call to search(). 31754dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex TextTrieMutex = U_MUTEX_INITIALIZER; 318b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 319b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// buildTrie() - The Trie node structure is needed. Create it from the data that was 320b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// saved at the time the ZoneStringFormatter was created. The Trie is only 321b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// needed for parsing operations, which are less common than formatting, 322b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// and the Trie is big, which is why its creation is deferred until first use. 323b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid TextTrieMap::buildTrie(UErrorCode &status) { 324b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fLazyContents != NULL) { 325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i=0; i<fLazyContents->size(); i+=2) { 326b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *key = (UChar *)fLazyContents->elementAt(i); 327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void *val = fLazyContents->elementAt(i+1); 328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString keyString(TRUE, key, -1); // Aliasing UnicodeString constructor. 329b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho putImpl(keyString, val, status); 330b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fLazyContents; 332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLazyContents = NULL; 333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 334b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 336b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 337b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::search(const UnicodeString &text, int32_t start, 338b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TextTrieMapSearchResultHandler *handler, UErrorCode &status) const { 33959d709d503bab6e2b61931737e662dd293b40578ccornelius { 34059d709d503bab6e2b61931737e662dd293b40578ccornelius // TODO: if locking the mutex for each check proves to be a performance problem, 34159d709d503bab6e2b61931737e662dd293b40578ccornelius // add a flag of type atomic_int32_t to class TextTrieMap, and use only 34259d709d503bab6e2b61931737e662dd293b40578ccornelius // the ICU atomic safe functions for assigning and testing. 34359d709d503bab6e2b61931737e662dd293b40578ccornelius // Don't test the pointer fLazyContents. 34459d709d503bab6e2b61931737e662dd293b40578ccornelius // Don't do unless it's really required. 34559d709d503bab6e2b61931737e662dd293b40578ccornelius Mutex lock(&TextTrieMutex); 34659d709d503bab6e2b61931737e662dd293b40578ccornelius if (fLazyContents != NULL) { 34759d709d503bab6e2b61931737e662dd293b40578ccornelius TextTrieMap *nonConstThis = const_cast<TextTrieMap *>(this); 34859d709d503bab6e2b61931737e662dd293b40578ccornelius nonConstThis->buildTrie(status); 34959d709d503bab6e2b61931737e662dd293b40578ccornelius } 350b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 351b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fNodes == NULL) { 352b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 353b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 354b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho search(fNodes, text, start, start, handler, status); 355b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 356b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 357b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 358b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::search(CharacterNode *node, const UnicodeString &text, int32_t start, 359b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t index, TextTrieMapSearchResultHandler *handler, UErrorCode &status) const { 360b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 361b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 362b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (node->hasValues()) { 364b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!handler->handleMatch(index - start, node, status)) { 365b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 366b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 367b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 368b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 369b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 370b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar32 c = text.char32At(index); 372b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fIgnoreCase) { 373b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // size of character may grow after fold operation 374b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString tmp(c); 375b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tmp.foldCase(); 376b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t tmpidx = 0; 377b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while (tmpidx < tmp.length()) { 378b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho c = tmp.char32At(tmpidx); 379b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node = getChildNode(node, c); 380b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (node == NULL) { 381b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 382b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 383b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tmpidx = tmp.moveIndex32(tmpidx, 1); 384b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 385b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 386b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node = getChildNode(node, c); 387b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 388b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (node != NULL) { 389b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho search(node, text, start, index+1, handler, status); 390b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 391b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 392b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 393b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 394b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// ZNStringPool class implementation 395b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 396b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const int32_t POOL_CHUNK_SIZE = 2000; 397b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostruct ZNStringPoolChunk: public UMemory { 398b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNStringPoolChunk *fNext; // Ptr to next pool chunk 399b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t fLimit; // Index to start of unused area at end of fStrings 400b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar fStrings[POOL_CHUNK_SIZE]; // Strings array 401b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNStringPoolChunk(); 402b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 403b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 404b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNStringPoolChunk::ZNStringPoolChunk() { 405b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNext = NULL; 406b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLimit = 0; 407b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 408b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 409b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNStringPool::ZNStringPool(UErrorCode &status) { 410b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fChunks = NULL; 411b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fHash = NULL; 412b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 413b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 414b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 415b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fChunks = new ZNStringPoolChunk; 416b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fChunks == NULL) { 417b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 418b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 419b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 420b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 421b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fHash = uhash_open(uhash_hashUChars /* keyHash */, 422b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_compareUChars /* keyComp */, 423b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_compareUChars /* valueComp */, 424b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho &status); 425b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 426b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 427b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 428b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 429b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 430b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNStringPool::~ZNStringPool() { 431b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fHash != NULL) { 432b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(fHash); 433b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fHash = NULL; 434b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 435b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 436b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while (fChunks != NULL) { 437b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNStringPoolChunk *nextChunk = fChunks->fNext; 438b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fChunks; 439b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fChunks = nextChunk; 440b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 441b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 442b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 443b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar EmptyString = 0; 444b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 445b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar *ZNStringPool::get(const UChar *s, UErrorCode &status) { 446b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *pooledString; 447b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 448b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return &EmptyString; 449b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 450b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 451b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pooledString = static_cast<UChar *>(uhash_get(fHash, s)); 452b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (pooledString != NULL) { 453b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return pooledString; 454b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 455b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 456b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t length = u_strlen(s); 457b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t remainingLength = POOL_CHUNK_SIZE - fChunks->fLimit; 458b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (remainingLength <= length) { 459b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(length < POOL_CHUNK_SIZE); 460b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (length >= POOL_CHUNK_SIZE) { 461b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_INTERNAL_PROGRAM_ERROR; 462b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return &EmptyString; 463b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 464b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNStringPoolChunk *oldChunk = fChunks; 465b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fChunks = new ZNStringPoolChunk; 466b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fChunks == NULL) { 467b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 468b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return &EmptyString; 469b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 470b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fChunks->fNext = oldChunk; 471b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 472b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 473b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar *destString = &fChunks->fStrings[fChunks->fLimit]; 474b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho u_strcpy(destString, s); 475b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fChunks->fLimit += (length + 1); 476b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_put(fHash, destString, destString, &status); 477b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return destString; 478b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 479b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 480b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 481b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// 482b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// ZNStringPool::adopt() Put a string into the hash, but do not copy the string data 483b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// into the pool's storage. Used for strings from resource bundles, 484b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// which will perisist for the life of the zone string formatter, and 485b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// therefore can be used directly without copying. 486b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar *ZNStringPool::adopt(const UChar * s, UErrorCode &status) { 487b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *pooledString; 488b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 489b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return &EmptyString; 490b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 491b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (s != NULL) { 492b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pooledString = static_cast<UChar *>(uhash_get(fHash, s)); 493b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (pooledString == NULL) { 494b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar *ncs = const_cast<UChar *>(s); 495b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_put(fHash, ncs, ncs, &status); 496b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 497b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 498b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return s; 499b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 500b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 501b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 502b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar *ZNStringPool::get(const UnicodeString &s, UErrorCode &status) { 503b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString &nonConstStr = const_cast<UnicodeString &>(s); 504b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return this->get(nonConstStr.getTerminatedBuffer(), status); 505b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 506b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 507b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 508b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * freeze(). Close the hash table that maps to the pooled strings. 509b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * After freezing, the pool can not be searched or added to, 510b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * but all existing references to pooled strings remain valid. 511b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * 512b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * The main purpose is to recover the storage used for the hash. 513b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 514b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid ZNStringPool::freeze() { 515b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(fHash); 516b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fHash = NULL; 517b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 518b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 519b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 520b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 521b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// ZNames - names common for time zone and meta zone 522b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 523b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass ZNames : public UMemory { 524b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehopublic: 525b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual ~ZNames(); 526b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 527b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static ZNames* createInstance(UResourceBundle* rb, const char* key); 5288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius virtual const UChar* getName(UTimeZoneNameType type); 529b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 530b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprotected: 531103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ZNames(const UChar** names); 532103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius static const UChar** loadData(UResourceBundle* rb, const char* key); 533b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 534b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprivate: 535b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar** fNames; 536b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 537b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 538103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusZNames::ZNames(const UChar** names) 539103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius: fNames(names) { 540b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 541b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 542b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNames::~ZNames() { 543b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fNames != NULL) { 544b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(fNames); 545b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 546b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 547b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 548b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNames* 549b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNames::createInstance(UResourceBundle* rb, const char* key) { 550103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar** names = loadData(rb, key); 551b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (names == NULL) { 552b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // No names data available 553b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 554b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 555103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return new ZNames(names); 556b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 557b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 558b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar* 559b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNames::getName(UTimeZoneNameType type) { 560b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fNames == NULL) { 561b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 562b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 563b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *name = NULL; 564b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho switch(type) { 565b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_LONG_GENERIC: 566b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name = fNames[0]; 567b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 568b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_LONG_STANDARD: 569b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name = fNames[1]; 570b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 571b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_LONG_DAYLIGHT: 572b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name = fNames[2]; 573b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 574b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_SHORT_GENERIC: 575103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius name = fNames[3]; 576b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 577b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_SHORT_STANDARD: 578b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name = fNames[4]; 579b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 580b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_SHORT_DAYLIGHT: 581b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name = fNames[5]; 582b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 5838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZNM_EXEMPLAR_LOCATION: // implemeted by subclass 584b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho default: 585b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name = NULL; 586b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 587b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 588b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 589b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 590b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar** 591103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusZNames::loadData(UResourceBundle* rb, const char* key) { 592b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (rb == NULL || key == NULL || *key == 0) { 593b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 594b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 595b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 596b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 597b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar **names = NULL; 598b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 599b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UResourceBundle* rbTable = NULL; 600b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho rbTable = ures_getByKeyWithFallback(rb, key, rbTable, &status); 601b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 602b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho names = (const UChar **)uprv_malloc(sizeof(const UChar*) * KEYS_SIZE); 603b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (names != NULL) { 604b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool isEmpty = TRUE; 605b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; i < KEYS_SIZE; i++) { 606b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_ZERO_ERROR; 607b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t len = 0; 608b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *value = ures_getStringByKeyWithFallback(rbTable, KEYS[i], &len, &status); 609b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status) || len == 0) { 610b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho names[i] = NULL; 611b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 612b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho names[i] = value; 613b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho isEmpty = FALSE; 614b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 615b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 616b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (isEmpty) { 617b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // No need to keep the names array 618b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(names); 619b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho names = NULL; 620b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 621b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 622b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 623b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ures_close(rbTable); 624b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return names; 625b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 626b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 627b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 628b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TZNames - names for a time zone 629b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 630b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass TZNames : public ZNames { 631b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehopublic: 632b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual ~TZNames(); 633b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 6348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius static TZNames* createInstance(UResourceBundle* rb, const char* key, const UnicodeString& tzID); 6358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius virtual const UChar* getName(UTimeZoneNameType type); 636b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 637b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprivate: 6388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius TZNames(const UChar** names); 639b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* fLocationName; 6408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UChar* fLocationNameOwned; 641b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 642b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 6438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTZNames::TZNames(const UChar** names) 6448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius: ZNames(names), fLocationName(NULL), fLocationNameOwned(NULL) { 645b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 646b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 647b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTZNames::~TZNames() { 6488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (fLocationNameOwned) { 6498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius uprv_free(fLocationNameOwned); 6508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 651b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 652b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 653b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar* 6548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTZNames::getName(UTimeZoneNameType type) { 6558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (type == UTZNM_EXEMPLAR_LOCATION) { 6568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return fLocationName; 6578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 6588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return ZNames::getName(type); 659b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 660b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 661b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTZNames* 6628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTZNames::createInstance(UResourceBundle* rb, const char* key, const UnicodeString& tzID) { 663b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (rb == NULL || key == NULL || *key == 0) { 664b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 665b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 6668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 6678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius const UChar** names = loadData(rb, key); 6688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius const UChar* locationName = NULL; 6698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UChar* locationNameOwned = NULL; 6708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 671b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 6728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t len = 0; 6738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 6748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UResourceBundle* table = ures_getByKeyWithFallback(rb, key, NULL, &status); 6758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius locationName = ures_getStringByKeyWithFallback(table, gEcTag, &len, &status); 6768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // ignore missing resource here 6778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius status = U_ZERO_ERROR; 6788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 6798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ures_close(table); 6808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 6818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (locationName == NULL) { 6828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UnicodeString tmpName; 6838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t tmpNameLen = 0; 6848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius TimeZoneNamesImpl::getDefaultExemplarLocationName(tzID, tmpName); 6858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpNameLen = tmpName.length(); 6868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 6878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tmpNameLen > 0) { 6888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius locationNameOwned = (UChar*) uprv_malloc(sizeof(UChar) * (tmpNameLen + 1)); 6898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (locationNameOwned) { 6908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpName.extract(locationNameOwned, tmpNameLen + 1, status); 6918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius locationName = locationNameOwned; 6928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 693b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 6948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 695b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 6968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius TZNames* tznames = NULL; 6978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (locationName != NULL || names != NULL) { 6988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tznames = new TZNames(names); 6998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tznames == NULL) { 7008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (locationNameOwned) { 7018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius uprv_free(locationNameOwned); 7028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 703b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 7048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tznames->fLocationName = locationName; 7058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tznames->fLocationNameOwned = locationNameOwned; 706b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 7078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 708b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return tznames; 709b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 710b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 711b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 712b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// The meta zone ID enumeration class 713b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 714b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass MetaZoneIDsEnumeration : public StringEnumeration { 715b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehopublic: 716b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MetaZoneIDsEnumeration(); 717b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MetaZoneIDsEnumeration(const UVector& mzIDs); 718b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MetaZoneIDsEnumeration(UVector* mzIDs); 719b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual ~MetaZoneIDsEnumeration(); 720b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static UClassID U_EXPORT2 getStaticClassID(void); 721b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual UClassID getDynamicClassID(void) const; 722b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual const UnicodeString* snext(UErrorCode& status); 723b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual void reset(UErrorCode& status); 724b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual int32_t count(UErrorCode& status) const; 725b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprivate: 726b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t fLen; 727b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t fPos; 728b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UVector* fMetaZoneIDs; 729b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UVector *fLocalVector; 730b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 731b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 732b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUOBJECT_DEFINE_RTTI_IMPLEMENTATION(MetaZoneIDsEnumeration) 733b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 734b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::MetaZoneIDsEnumeration() 735b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: fLen(0), fPos(0), fMetaZoneIDs(NULL), fLocalVector(NULL) { 736b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 737b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 738b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::MetaZoneIDsEnumeration(const UVector& mzIDs) 739b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: fPos(0), fMetaZoneIDs(&mzIDs), fLocalVector(NULL) { 740b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLen = fMetaZoneIDs->size(); 741b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 742b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 743b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::MetaZoneIDsEnumeration(UVector *mzIDs) 744b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: fLen(0), fPos(0), fMetaZoneIDs(mzIDs), fLocalVector(mzIDs) { 745b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fMetaZoneIDs) { 746b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLen = fMetaZoneIDs->size(); 747b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 748b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 749b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 750b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UnicodeString* 751b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::snext(UErrorCode& status) { 752b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status) && fMetaZoneIDs != NULL && fPos < fLen) { 753b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho unistr.setTo((const UChar*)fMetaZoneIDs->elementAt(fPos++), -1); 754b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return &unistr; 755b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 756b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 757b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 758b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 759b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 760b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::reset(UErrorCode& /*status*/) { 761b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fPos = 0; 762b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 763b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 764b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t 765b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::count(UErrorCode& /*status*/) const { 766b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fLen; 767b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 768b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 769b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::~MetaZoneIDsEnumeration() { 770b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fLocalVector) { 771b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fLocalVector; 772b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 773b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 774b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 775b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_BEGIN 776b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 777b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * ZNameInfo stores zone name information in the trie 778b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 779b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehotypedef struct ZNameInfo { 780b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTimeZoneNameType type; 781b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* tzID; 782b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* mzID; 783b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} ZNameInfo; 784b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 785b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 786b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * ZMatchInfo stores zone name match information used by find method 787b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 788b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehotypedef struct ZMatchInfo { 789b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const ZNameInfo* znameInfo; 790b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t matchLength; 791b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} ZMatchInfo; 792b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_END 793b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 794b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 795b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 796b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// ZNameSearchHandler 797b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 798b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass ZNameSearchHandler : public TextTrieMapSearchResultHandler { 799b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehopublic: 800b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNameSearchHandler(uint32_t types); 801b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual ~ZNameSearchHandler(); 802b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 803b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status); 804103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius TimeZoneNames::MatchInfoCollection* getMatches(int32_t& maxMatchLen); 805b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 806b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprivate: 807b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint32_t fTypes; 808b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t fMaxMatchLen; 809103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius TimeZoneNames::MatchInfoCollection* fResults; 810b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 811b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 812b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNameSearchHandler::ZNameSearchHandler(uint32_t types) 813103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius: fTypes(types), fMaxMatchLen(0), fResults(NULL) { 814b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 815b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 816b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNameSearchHandler::~ZNameSearchHandler() { 817b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fResults != NULL) { 818b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fResults; 819b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 820b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 821b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 822b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 823b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNameSearchHandler::handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status) { 824b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 825b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 826b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 827b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (node->hasValues()) { 828b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t valuesCount = node->countValues(); 829b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; i < valuesCount; i++) { 830b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNameInfo *nameinfo = (ZNameInfo *)node->getValue(i); 831b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (nameinfo == NULL) { 832f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius continue; 833b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 834b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if ((nameinfo->type & fTypes) != 0) { 835b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // matches a requested type 836b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fResults == NULL) { 837103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fResults = new TimeZoneNames::MatchInfoCollection(); 838b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fResults == NULL) { 839b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 840b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 841b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 842b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 843103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(fResults != NULL); 844103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (nameinfo->tzID) { 845103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fResults->addZone(nameinfo->type, matchLength, UnicodeString(nameinfo->tzID, -1), status); 846b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 847103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(nameinfo->mzID); 848103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fResults->addMetaZone(nameinfo->type, matchLength, UnicodeString(nameinfo->mzID, -1), status); 849103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 850103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status) && matchLength > fMaxMatchLen) { 851103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fMaxMatchLen = matchLength; 852b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 853b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 854b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 855b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 856b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 857b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 858b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 859b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 860103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneNames::MatchInfoCollection* 861b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNameSearchHandler::getMatches(int32_t& maxMatchLen) { 862b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // give the ownership to the caller 863103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius TimeZoneNames::MatchInfoCollection* results = fResults; 864b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho maxMatchLen = fMaxMatchLen; 865b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 866b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // reset 867b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fResults = NULL; 868b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fMaxMatchLen = 0; 869b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return results; 870b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 871b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 872b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 873b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TimeZoneNamesImpl 874b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// 875b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TimeZoneNames implementation class. This is the main 876b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// part of this module. 877b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 878b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 879b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_BEGIN 880b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 881b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Deleter for ZNames 882b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 883b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void U_CALLCONV 884b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehodeleteZNames(void *obj) { 885b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (obj != EMPTY) { 886b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete (ZNames *)obj; 887b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 888b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 889b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 890b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Deleter for TZNames 891b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 892b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void U_CALLCONV 893b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehodeleteTZNames(void *obj) { 894b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (obj != EMPTY) { 895b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete (TZNames *)obj; 896b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 897b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 898b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 899b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 900b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Deleter for ZNameInfo 901b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 902b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void U_CALLCONV 903b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehodeleteZNameInfo(void *obj) { 904b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(obj); 905b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 906b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 907b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_END 908b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 90954dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex gLock = U_MUTEX_INITIALIZER; 91054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 911b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::TimeZoneNamesImpl(const Locale& locale, UErrorCode& status) 912b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: fLocale(locale), 913b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fZoneStrings(NULL), 914b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTZNamesMap(NULL), 915b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fMZNamesMap(NULL), 916b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNamesTrieFullyLoaded(FALSE), 917b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNamesTrie(TRUE, deleteZNameInfo) { 918b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho initialize(locale, status); 919b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 920b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 921b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 922b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::initialize(const Locale& locale, UErrorCode& status) { 923b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 924b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 925b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 926b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 927b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Load zoneStrings bundle 928b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode tmpsts = U_ZERO_ERROR; // OK with fallback warning.. 929b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fZoneStrings = ures_open(U_ICUDATA_ZONE, locale.getName(), &tmpsts); 930b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fZoneStrings = ures_getByKeyWithFallback(fZoneStrings, gZoneStrings, fZoneStrings, &tmpsts); 931b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(tmpsts)) { 932b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = tmpsts; 933b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cleanup(); 934b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 935b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 936b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 937b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Initialize hashtables holding time zone/meta zone names 938b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fMZNamesMap = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status); 939b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTZNamesMap = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status); 940b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 941b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cleanup(); 942b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 943b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 944b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 945b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_setValueDeleter(fMZNamesMap, deleteZNames); 946b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_setValueDeleter(fTZNamesMap, deleteTZNames); 947b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // no key deleters for name maps 948b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 949b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // preload zone strings for the default zone 950b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZone *tz = TimeZone::createDefault(); 951b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *tzID = ZoneMeta::getCanonicalCLDRID(*tz); 952b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzID != NULL) { 953b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho loadStrings(UnicodeString(tzID)); 954b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 955b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tz; 956b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 957b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 958b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 959b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 960b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 961b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * This method updates the cache and must be called with a lock, 962b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * except initializer. 963b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 964b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 965b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::loadStrings(const UnicodeString& tzCanonicalID) { 966b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho loadTimeZoneNames(tzCanonicalID); 967b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 968b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 969b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho StringEnumeration *mzIDs = getAvailableMetaZoneIDs(tzCanonicalID, status); 970b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status) && mzIDs != NULL) { 971b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString *mzID; 972b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while ((mzID = mzIDs->snext(status))) { 973b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 974b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 975b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 976b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho loadMetaZoneNames(*mzID); 977b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 978b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete mzIDs; 979b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 980b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 981b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 982b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::~TimeZoneNamesImpl() { 983b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cleanup(); 984b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 985b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 986b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 987b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::cleanup() { 988b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fZoneStrings != NULL) { 989b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ures_close(fZoneStrings); 990b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fZoneStrings = NULL; 991b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 992b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fMZNamesMap != NULL) { 993b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(fMZNamesMap); 994b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fMZNamesMap = NULL; 995b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 996b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fTZNamesMap != NULL) { 997b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(fTZNamesMap); 998b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTZNamesMap = NULL; 999b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1000b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1001b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1002103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUBool 1003103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneNamesImpl::operator==(const TimeZoneNames& other) const { 1004103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (this == &other) { 1005103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return TRUE; 1006103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1007103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // No implementation for now 1008103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return FALSE; 1009103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1010103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1011103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneNames* 1012103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneNamesImpl::clone() const { 1013103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode status = U_ZERO_ERROR; 1014103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return new TimeZoneNamesImpl(fLocale, status); 1015103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1016103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1017b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoStringEnumeration* 1018b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getAvailableMetaZoneIDs(UErrorCode& status) const { 1019f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TimeZoneNamesImpl::_getAvailableMetaZoneIDs(status); 1020f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1021f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1022f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// static implementation of getAvailableMetaZoneIDs(UErrorCode&) 1023f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusStringEnumeration* 1024f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTimeZoneNamesImpl::_getAvailableMetaZoneIDs(UErrorCode& status) { 1025b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1026b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1027b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1028b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UVector* mzIDs = ZoneMeta::getAvailableMetazoneIDs(); 1029b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (mzIDs == NULL) { 1030b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return new MetaZoneIDsEnumeration(); 1031b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1032b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return new MetaZoneIDsEnumeration(*mzIDs); 1033b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1034b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1035b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoStringEnumeration* 1036b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const { 1037f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TimeZoneNamesImpl::_getAvailableMetaZoneIDs(tzID, status); 1038f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1039f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1040f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// static implementation of getAvailableMetaZoneIDs(const UnicodeString&, UErrorCode&) 1041f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusStringEnumeration* 1042f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTimeZoneNamesImpl::_getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) { 1043b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1044b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1045b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1046b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UVector* mappings = ZoneMeta::getMetazoneMappings(tzID); 1047b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (mappings == NULL) { 1048b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return new MetaZoneIDsEnumeration(); 1049b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1050b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1051b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MetaZoneIDsEnumeration *senum = NULL; 1052b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UVector* mzIDs = new UVector(NULL, uhash_compareUChars, status); 1053b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (mzIDs == NULL) { 1054b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 1055b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1056b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 1057103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(mzIDs != NULL); 1058b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; U_SUCCESS(status) && i < mappings->size(); i++) { 1059b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1060b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho OlsonToMetaMappingEntry *map = (OlsonToMetaMappingEntry *)mappings->elementAt(i); 1061b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *mzID = map->mzid; 1062b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!mzIDs->contains((void *)mzID)) { 1063b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho mzIDs->addElement((void *)mzID, status); 1064b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1065b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1066b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 1067b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho senum = new MetaZoneIDsEnumeration(mzIDs); 1068b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1069b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete mzIDs; 1070b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1071b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1072b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return senum; 1073b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1074b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1075b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 1076b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const { 1077f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TimeZoneNamesImpl::_getMetaZoneID(tzID, date, mzID); 1078f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1079f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1080f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// static implementation of getMetaZoneID 1081f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusUnicodeString& 1082f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTimeZoneNamesImpl::_getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) { 1083b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZoneMeta::getMetazoneID(tzID, date, mzID); 1084b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return mzID; 1085b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1086b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1087b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 1088b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const { 1089f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TimeZoneNamesImpl::_getReferenceZoneID(mzID, region, tzID); 1090f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1091f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1092f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// static implementaion of getReferenceZoneID 1093f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusUnicodeString& 1094f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTimeZoneNamesImpl::_getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) { 1095b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZoneMeta::getZoneIdByMetazone(mzID, UnicodeString(region, -1, US_INV), tzID); 1096b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return tzID; 1097b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1098b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1099f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1100b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 1101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getMetaZoneDisplayName(const UnicodeString& mzID, 1102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTimeZoneNameType type, 1103b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString& name) const { 1104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setToBogus(); // cleanup result. 1105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (mzID.isEmpty()) { 1106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 1107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNames *znames = NULL; 1110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); 1111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 111254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_lock(&gLock); 1113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 1114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho znames = nonConstThis->loadMetaZoneNames(mzID); 1115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 111654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_unlock(&gLock); 1117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (znames != NULL) { 1119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* s = znames->getName(type); 1120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (s != NULL) { 1121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setTo(TRUE, s, -1); 1122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 1125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 1128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, UnicodeString& name) const { 1129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setToBogus(); // cleanup result. 1130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzID.isEmpty()) { 1131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 1132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TZNames *tznames = NULL; 1135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); 1136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 113754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_lock(&gLock); 1138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 1139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tznames = nonConstThis->loadTimeZoneNames(tzID); 1140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 114154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_unlock(&gLock); 1142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tznames != NULL) { 1144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *s = tznames->getName(type); 1145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (s != NULL) { 1146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setTo(TRUE, s, -1); 1147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 1150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 1153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) const { 11548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius name.setToBogus(); // cleanup result. 1155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* locName = NULL; 1156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TZNames *tznames = NULL; 1157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); 1158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 115954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_lock(&gLock); 1160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 1161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tznames = nonConstThis->loadTimeZoneNames(tzID); 1162b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 116354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_unlock(&gLock); 1164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tznames != NULL) { 11668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius locName = tznames->getName(UTZNM_EXEMPLAR_LOCATION); 1167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (locName != NULL) { 1169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setTo(TRUE, locName, -1); 1170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 11728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return name; 1173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Merge the MZ_PREFIX and mzId 1177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void mergeTimeZoneKey(const UnicodeString& mzID, char* result) { 1178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (mzID.isEmpty()) { 1179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result[0] = '\0'; 1180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho char mzIdChar[ZID_KEY_MAX + 1]; 1184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t keyLen; 1185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t prefixLen = uprv_strlen(gMZPrefix); 1186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho keyLen = mzID.extract(0, mzID.length(), mzIdChar, ZID_KEY_MAX + 1, US_INV); 1187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_memcpy((void *)result, (void *)gMZPrefix, prefixLen); 1188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_memcpy((void *)(result + prefixLen), (void *)mzIdChar, keyLen); 1189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result[keyLen + prefixLen] = '\0'; 1190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 1193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * This method updates the cache and must be called with a lock 1194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 1195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNames* 1196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::loadMetaZoneNames(const UnicodeString& mzID) { 1197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (mzID.length() > (ZID_KEY_MAX - MZ_PREFIX_LEN)) { 1198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNames *znames = NULL; 1202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 1204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar mzIDKey[ZID_KEY_MAX + 1]; 1205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho mzID.extract(mzIDKey, ZID_KEY_MAX + 1, status); 1206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(status == U_ZERO_ERROR); // already checked length above 1207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho mzIDKey[mzID.length()] = 0; 1208b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void *cacheVal = uhash_get(fMZNamesMap, mzIDKey); 1210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cacheVal == NULL) { 1211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho char key[ZID_KEY_MAX + 1]; 1212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho mergeTimeZoneKey(mzID, key); 1213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho znames = ZNames::createInstance(fZoneStrings, key); 1214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1215b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (znames == NULL) { 1216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheVal = (void *)EMPTY; 1217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheVal = znames; 1219b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Use the persistent ID as the resource key, so we can 1221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // avoid duplications. 1222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* newKey = ZoneMeta::findMetaZoneID(mzID); 1223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newKey != NULL) { 1224b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_put(fMZNamesMap, (void *)newKey, cacheVal, &status); 1225b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1226b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (znames != NULL) { 1227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete znames; 1228f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius znames = NULL; 1229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1230b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (znames != NULL) { 1231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // put the name info into the trie 1232b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; ALL_NAME_TYPES[i] != UTZNM_UNKNOWN; i++) { 1233b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* name = znames->getName(ALL_NAME_TYPES[i]); 1234b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (name != NULL) { 1235b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(ZNameInfo)); 1236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (nameinfo != NULL) { 1237b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->type = ALL_NAME_TYPES[i]; 1238b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->tzID = NULL; 1239b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->mzID = newKey; 1240b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNamesTrie.put(name, nameinfo, status); 1241b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1242b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1246b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Should never happen with a valid input 1248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (znames != NULL) { 1249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // It's not possible that we get a valid ZNames with unknown ID. 1250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // But just in case.. 1251b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete znames; 1252b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho znames = NULL; 1253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1254b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1255b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (cacheVal != EMPTY) { 1256b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho znames = (ZNames *)cacheVal; 1257b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1258b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1259b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return znames; 1260b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1261b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1262b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 1263b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * This method updates the cache and must be called with a lock 1264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 1265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTZNames* 1266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::loadTimeZoneNames(const UnicodeString& tzID) { 1267b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzID.length() > ZID_KEY_MAX) { 1268b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1269b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TZNames *tznames = NULL; 1272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 1274b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar tzIDKey[ZID_KEY_MAX + 1]; 1275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t tzIDKeyLen = tzID.extract(tzIDKey, ZID_KEY_MAX + 1, status); 1276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(status == U_ZERO_ERROR); // already checked length above 1277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tzIDKey[tzIDKeyLen] = 0; 1278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void *cacheVal = uhash_get(fTZNamesMap, tzIDKey); 1280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cacheVal == NULL) { 1281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho char key[ZID_KEY_MAX + 1]; 1282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 1283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Replace "/" with ":". 1284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString uKey(tzID); 1285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; i < uKey.length(); i++) { 1286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (uKey.charAt(i) == (UChar)0x2F) { 1287b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uKey.setCharAt(i, (UChar)0x3A); 1288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uKey.extract(0, uKey.length(), key, sizeof(key), US_INV); 12918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tznames = TZNames::createInstance(fZoneStrings, key, tzID); 1292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tznames == NULL) { 1294b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheVal = (void *)EMPTY; 1295b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheVal = tznames; 1297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Use the persistent ID as the resource key, so we can 1299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // avoid duplications. 1300b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* newKey = ZoneMeta::findTimeZoneID(tzID); 1301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newKey != NULL) { 1302b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_put(fTZNamesMap, (void *)newKey, cacheVal, &status); 1303b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tznames != NULL) { 1305b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tznames; 1306f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius tznames = NULL; 1307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1308b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (tznames != NULL) { 1309b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // put the name info into the trie 1310b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; ALL_NAME_TYPES[i] != UTZNM_UNKNOWN; i++) { 1311b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* name = tznames->getName(ALL_NAME_TYPES[i]); 1312b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (name != NULL) { 1313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(ZNameInfo)); 1314b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (nameinfo != NULL) { 1315b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->type = ALL_NAME_TYPES[i]; 1316b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->tzID = newKey; 1317b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->mzID = NULL; 1318b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNamesTrie.put(name, nameinfo, status); 1319b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1320b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1321b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1322b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1323b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1324b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Should never happen with a valid input 1325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tznames != NULL) { 1326b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // It's not possible that we get a valid TZNames with unknown ID. 1327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // But just in case.. 1328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tznames; 1329b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tznames = NULL; 1330b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (cacheVal != EMPTY) { 1333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tznames = (TZNames *)cacheVal; 1334b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1336b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return tznames; 1337b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1338b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1339103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneNames::MatchInfoCollection* 1340b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const { 1341b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNameSearchHandler handler(types); 1342b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1343b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); 1344b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 134554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_lock(&gLock); 1346b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 1347b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); 1348b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 134954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_unlock(&gLock); 1350b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1351b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1352b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1353b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1354b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1355b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t maxLen = 0; 1356103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius TimeZoneNames::MatchInfoCollection* matches = handler.getMatches(maxLen); 1357103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (matches != NULL && ((maxLen == (text.length() - start)) || fNamesTrieFullyLoaded)) { 1358b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // perfect match 1359103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return matches; 1360b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1361b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1362103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete matches; 1363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1364b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // All names are not yet loaded into the trie 136554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_lock(&gLock); 1366b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 1367b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!fNamesTrieFullyLoaded) { 1368b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString *id; 1369b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1370b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // load strings for all zones 1371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho StringEnumeration *tzIDs = TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status); 1372b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 1373b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while ((id = tzIDs->snext(status))) { 1374b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1375b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 1376b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1377b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // loadStrings also load related metazone strings 1378b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nonConstThis->loadStrings(*id); 1379b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1380b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1381b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzIDs != NULL) { 1382b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tzIDs; 1383b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1384b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 1385b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nonConstThis->fNamesTrieFullyLoaded = TRUE; 1386b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1387b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1388b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 138954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_unlock(&gLock); 1390b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1391b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1392b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1393b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1394b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 139554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_lock(&gLock); 1396b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 1397b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // now try it again 1398b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); 1399b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 140054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_unlock(&gLock); 1401b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1402103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return handler.getMatches(maxLen); 1403b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1404b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 14058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar gEtcPrefix[] = { 0x45, 0x74, 0x63, 0x2F }; // "Etc/" 14068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const int32_t gEtcPrefixLen = 4; 14078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar gSystemVPrefix[] = { 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x56, 0x2F }; // "SystemV/ 14088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const int32_t gSystemVPrefixLen = 8; 14098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar gRiyadh8[] = { 0x52, 0x69, 0x79, 0x61, 0x64, 0x68, 0x38 }; // "Riyadh8" 14108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const int32_t gRiyadh8Len = 7; 14118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 14128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUnicodeString& U_EXPORT2 14138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneNamesImpl::getDefaultExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) { 14148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tzID.isEmpty() || tzID.startsWith(gEtcPrefix, gEtcPrefixLen) 14158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius || tzID.startsWith(gSystemVPrefix, gSystemVPrefixLen) || tzID.indexOf(gRiyadh8, gRiyadh8Len, 0) > 0) { 14168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius name.setToBogus(); 14178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return name; 14188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 14198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 14208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t sep = tzID.lastIndexOf((UChar)0x2F /* '/' */); 14218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (sep > 0 && sep + 1 < tzID.length()) { 14228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius name.setTo(tzID, sep + 1); 14238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius name.findAndReplace(UnicodeString((UChar)0x5f /* _ */), 14248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UnicodeString((UChar)0x20 /* space */)); 14258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else { 14268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius name.setToBogus(); 14278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 14288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return name; 14298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 14308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1431f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// --------------------------------------------------- 1432f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// TZDBTimeZoneNames and its supporting classes 1433f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// 1434f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// TZDBTimeZoneNames is an implementation class of 1435f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// TimeZoneNames holding the IANA tz database abbreviations. 1436f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// --------------------------------------------------- 1437f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1438f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusclass TZDBNames : public UMemory { 1439f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliuspublic: 1440f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius virtual ~TZDBNames(); 1441f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1442f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius static TZDBNames* createInstance(UResourceBundle* rb, const char* key); 1443f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UChar* getName(UTimeZoneNameType type) const; 1444f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char** getParseRegions(int32_t& numRegions) const; 1445f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1446f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusprotected: 1447f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TZDBNames(const UChar** names, char** regions, int32_t numRegions); 1448f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1449f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusprivate: 1450f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UChar** fNames; 1451f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius char** fRegions; 1452f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t fNumRegions; 1453f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius}; 1454f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1455f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBNames::TZDBNames(const UChar** names, char** regions, int32_t numRegions) 1456f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius : fNames(names), 1457f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius fRegions(regions), 1458f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius fNumRegions(numRegions) { 1459f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1460f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1461f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBNames::~TZDBNames() { 1462f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (fNames != NULL) { 1463f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uprv_free(fNames); 1464f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1465f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (fRegions != NULL) { 1466f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius char **p = fRegions; 1467f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius for (int32_t i = 0; i < fNumRegions; p++, i++) { 1468f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uprv_free(*p); 1469f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1470f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uprv_free(fRegions); 1471f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1472f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1473f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1474f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBNames* 1475f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBNames::createInstance(UResourceBundle* rb, const char* key) { 1476f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (rb == NULL || key == NULL || *key == 0) { 1477f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 1478f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1479f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1480f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UErrorCode status = U_ZERO_ERROR; 1481f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1482f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UChar **names = NULL; 1483f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius char** regions = NULL; 1484f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t numRegions = 0; 1485f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1486f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t len = 0; 1487f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1488f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UResourceBundle* rbTable = NULL; 1489f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius rbTable = ures_getByKey(rb, key, rbTable, &status); 1490f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_FAILURE(status)) { 1491f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 1492f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1493f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1494f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius names = (const UChar **)uprv_malloc(sizeof(const UChar*) * TZDBNAMES_KEYS_SIZE); 1495f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UBool isEmpty = TRUE; 1496f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (names != NULL) { 1497f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius for (int32_t i = 0; i < TZDBNAMES_KEYS_SIZE; i++) { 1498f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius status = U_ZERO_ERROR; 1499f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UChar *value = ures_getStringByKey(rbTable, TZDBNAMES_KEYS[i], &len, &status); 1500f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_FAILURE(status) || len == 0) { 1501f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius names[i] = NULL; 1502f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else { 1503f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius names[i] = value; 1504f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius isEmpty = FALSE; 1505f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1506f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1507f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1508f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1509f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (isEmpty) { 1510f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (names != NULL) { 1511f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uprv_free(names); 1512f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1513f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 1514f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1515f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1516f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UResourceBundle *regionsRes = ures_getByKey(rbTable, "parseRegions", NULL, &status); 1517f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UBool regionError = FALSE; 1518f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_SUCCESS(status)) { 1519f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius numRegions = ures_getSize(regionsRes); 1520f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (numRegions > 0) { 1521f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius regions = (char**)uprv_malloc(sizeof(char*) * numRegions); 1522f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (regions != NULL) { 1523f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius char **pRegion = regions; 1524f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius for (int32_t i = 0; i < numRegions; i++, pRegion++) { 1525f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius *pRegion = NULL; 1526f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1527f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // filling regions 1528f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius pRegion = regions; 1529f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius for (int32_t i = 0; i < numRegions; i++, pRegion++) { 1530f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius status = U_ZERO_ERROR; 1531f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UChar *uregion = ures_getStringByIndex(regionsRes, i, &len, &status); 1532f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_FAILURE(status)) { 1533f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius regionError = TRUE; 1534f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius break; 1535f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1536f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius *pRegion = (char*)uprv_malloc(sizeof(char) * (len + 1)); 1537f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (*pRegion == NULL) { 1538f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius regionError = TRUE; 1539f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius break; 1540f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1541f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius u_UCharsToChars(uregion, *pRegion, len); 1542f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius (*pRegion)[len] = 0; 1543f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1544f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1545f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1546f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1547f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius ures_close(regionsRes); 1548f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius ures_close(rbTable); 1549f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1550f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (regionError) { 1551f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (names != NULL) { 1552f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uprv_free(names); 1553f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1554f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (regions != NULL) { 1555f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius char **p = regions; 1556f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius for (int32_t i = 0; i < numRegions; p++, i++) { 1557f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uprv_free(p); 1558f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1559f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uprv_free(regions); 1560f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1561f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 1562f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1563f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1564f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return new TZDBNames(names, regions, numRegions); 1565f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1566f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1567f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst UChar* 1568f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBNames::getName(UTimeZoneNameType type) const { 1569f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (fNames == NULL) { 1570f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 1571f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1572f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UChar *name = NULL; 1573f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius switch(type) { 1574f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius case UTZNM_SHORT_STANDARD: 1575f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius name = fNames[0]; 1576f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius break; 1577f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius case UTZNM_SHORT_DAYLIGHT: 1578f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius name = fNames[1]; 1579f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius break; 1580f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius default: 1581f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius name = NULL; 1582f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1583f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return name; 1584f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1585f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1586f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst char** 1587f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBNames::getParseRegions(int32_t& numRegions) const { 1588f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (fRegions == NULL) { 1589f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius numRegions = 0; 1590f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else { 1591f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius numRegions = fNumRegions; 1592f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1593f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return (const char**)fRegions; 1594f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1595f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1596f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CDECL_BEGIN 1597f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius/** 1598f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius * TZDBNameInfo stores metazone name information for the IANA abbreviations 1599f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius * in the trie 1600f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius */ 1601f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliustypedef struct TZDBNameInfo { 1602f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UChar* mzID; 1603f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UTimeZoneNameType type; 1604f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UBool ambiguousType; 1605f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char** parseRegions; 1606f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t nRegions; 1607f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} TZDBNameInfo; 1608f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CDECL_END 1609f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1610f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1611f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusclass TZDBNameSearchHandler : public TextTrieMapSearchResultHandler { 1612f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliuspublic: 1613f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TZDBNameSearchHandler(uint32_t types, const char* region); 1614f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius virtual ~TZDBNameSearchHandler(); 1615f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1616f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UBool handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status); 1617f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TimeZoneNames::MatchInfoCollection* getMatches(int32_t& maxMatchLen); 1618f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1619f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusprivate: 1620f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uint32_t fTypes; 1621f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t fMaxMatchLen; 1622f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TimeZoneNames::MatchInfoCollection* fResults; 1623f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char* fRegion; 1624f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius}; 1625f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1626f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBNameSearchHandler::TZDBNameSearchHandler(uint32_t types, const char* region) 1627f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius: fTypes(types), fMaxMatchLen(0), fResults(NULL), fRegion(region) { 1628f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1629f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1630f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBNameSearchHandler::~TZDBNameSearchHandler() { 1631f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (fResults != NULL) { 1632f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius delete fResults; 1633f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1634f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1635f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1636f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusUBool 1637f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBNameSearchHandler::handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status) { 1638f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_FAILURE(status)) { 1639f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return FALSE; 1640f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1641f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1642f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TZDBNameInfo *match = NULL; 1643f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TZDBNameInfo *defaultRegionMatch = NULL; 1644f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1645f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (node->hasValues()) { 1646f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t valuesCount = node->countValues(); 1647f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius for (int32_t i = 0; i < valuesCount; i++) { 1648f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TZDBNameInfo *ninfo = (TZDBNameInfo *)node->getValue(i); 1649f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (ninfo == NULL) { 1650f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius continue; 1651f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1652f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if ((ninfo->type & fTypes) != 0) { 1653f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Some tz database abbreviations are ambiguous. For example, 1654f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // CST means either Central Standard Time or China Standard Time. 1655f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Unlike CLDR time zone display names, this implementation 1656f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // does not use unique names. And TimeZoneFormat does not expect 1657f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // multiple results returned for the same time zone type. 1658f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // For this reason, this implementation resolve one among same 1659f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // zone type with a same name at this level. 1660f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (ninfo->parseRegions == NULL) { 1661f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // parseRegions == null means this is the default metazone 1662f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // mapping for the abbreviation. 1663f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (defaultRegionMatch == NULL) { 1664f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius match = defaultRegionMatch = ninfo; 1665f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1666f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else { 1667f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UBool matchRegion = FALSE; 1668f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // non-default metazone mapping for an abbreviation 1669f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // comes with applicable regions. For example, the default 1670f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // metazone mapping for "CST" is America_Central, 1671f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // but if region is one of CN/MO/TW, "CST" is parsed 1672f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // as metazone China (China Standard Time). 1673f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius for (int32_t i = 0; i < ninfo->nRegions; i++) { 1674f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char *region = ninfo->parseRegions[i]; 1675f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (uprv_strcmp(fRegion, region) == 0) { 1676f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius match = ninfo; 1677f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius matchRegion = TRUE; 1678f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius break; 1679f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1680f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1681f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (matchRegion) { 1682f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius break; 1683f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1684f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (match == NULL) { 1685f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius match = ninfo; 1686f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1687f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1688f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1689f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1690f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1691f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (match != NULL) { 1692f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UTimeZoneNameType ntype = match->type; 1693f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Note: Workaround for duplicated standard/daylight names 1694f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // The tz database contains a few zones sharing a 1695f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // same name for both standard time and daylight saving 1696f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // time. For example, Australia/Sydney observes DST, 1697f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // but "EST" is used for both standard and daylight. 1698f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // When both SHORT_STANDARD and SHORT_DAYLIGHT are included 1699f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // in the find operation, we cannot tell which one was 1700f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // actually matched. 1701f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // TimeZoneFormat#parse returns a matched name type (standard 1702f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // or daylight) and DateFormat implementation uses the info to 1703f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // to adjust actual time. To avoid false type information, 1704f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // this implementation replaces the name type with SHORT_GENERIC. 1705f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (match->ambiguousType 1706f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius && (ntype == UTZNM_SHORT_STANDARD || ntype == UTZNM_SHORT_DAYLIGHT) 1707f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius && (fTypes & UTZNM_SHORT_STANDARD) != 0 1708f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius && (fTypes & UTZNM_SHORT_DAYLIGHT) != 0) { 1709f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius ntype = UTZNM_SHORT_GENERIC; 1710f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1711f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1712f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (fResults == NULL) { 1713f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius fResults = new TimeZoneNames::MatchInfoCollection(); 1714f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (fResults == NULL) { 1715f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius status = U_MEMORY_ALLOCATION_ERROR; 1716f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1717f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1718f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_SUCCESS(status)) { 1719f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius U_ASSERT(fResults != NULL); 1720f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius U_ASSERT(match->mzID != NULL); 1721f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius fResults->addMetaZone(ntype, matchLength, UnicodeString(match->mzID, -1), status); 1722f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_SUCCESS(status) && matchLength > fMaxMatchLen) { 1723f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius fMaxMatchLen = matchLength; 1724f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1725f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1726f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1727f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1728f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TRUE; 1729f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1730f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1731f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTimeZoneNames::MatchInfoCollection* 1732f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBNameSearchHandler::getMatches(int32_t& maxMatchLen) { 1733f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // give the ownership to the caller 1734f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TimeZoneNames::MatchInfoCollection* results = fResults; 1735f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius maxMatchLen = fMaxMatchLen; 1736f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1737f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // reset 1738f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius fResults = NULL; 1739f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius fMaxMatchLen = 0; 1740f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return results; 1741f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1742f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1743f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CDECL_BEGIN 1744f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius/** 1745f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius * Deleter for TZDBNames 1746f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius */ 1747f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic void U_CALLCONV 1748f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusdeleteTZDBNames(void *obj) { 1749f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (obj != EMPTY) { 1750f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius delete (TZDBNames *)obj; 1751f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1752f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1753f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1754f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic void U_CALLCONV initTZDBNamesMap(UErrorCode &status) { 1755f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gTZDBNamesMap = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status); 1756f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_FAILURE(status)) { 1757f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gTZDBNamesMap = NULL; 1758f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return; 1759f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1760f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // no key deleters for tzdb name maps 1761f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uhash_setValueDeleter(gTZDBNamesMap, deleteTZDBNames); 1762f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius ucln_i18n_registerCleanup(UCLN_I18N_TZDBTIMEZONENAMES, tzdbTimeZoneNames_cleanup); 1763f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1764f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1765f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius/** 1766f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius * Deleter for TZDBNameInfo 1767f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius */ 1768f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic void U_CALLCONV 1769f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusdeleteTZDBNameInfo(void *obj) { 1770f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (obj != NULL) { 1771f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uprv_free(obj); 1772f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1773f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1774f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1775f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic void U_CALLCONV prepareFind(UErrorCode &status) { 1776f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_FAILURE(status)) { 1777f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return; 1778f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1779f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gTZDBNamesTrie = new TextTrieMap(TRUE, deleteTZDBNameInfo); 1780f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (gTZDBNamesTrie == NULL) { 1781f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius status = U_MEMORY_ALLOCATION_ERROR; 1782f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return; 1783f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1784f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1785f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UnicodeString *mzID; 1786f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius StringEnumeration *mzIDs = TimeZoneNamesImpl::_getAvailableMetaZoneIDs(status); 1787f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_SUCCESS(status)) { 1788f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius while ((mzID = mzIDs->snext(status)) && U_SUCCESS(status)) { 1789f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const TZDBNames *names = TZDBTimeZoneNames::getMetaZoneNames(*mzID, status); 1790f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (names == NULL) { 1791f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius continue; 1792f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1793f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UChar *std = names->getName(UTZNM_SHORT_STANDARD); 1794f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UChar *dst = names->getName(UTZNM_SHORT_DAYLIGHT); 1795f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (std == NULL && dst == NULL) { 1796f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius continue; 1797f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1798f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t numRegions = 0; 1799f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char **parseRegions = names->getParseRegions(numRegions); 1800f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1801f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // The tz database contains a few zones sharing a 1802f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // same name for both standard time and daylight saving 1803f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // time. For example, Australia/Sydney observes DST, 1804f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // but "EST" is used for both standard and daylight. 1805f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // we need to store the information for later processing. 1806f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UBool ambiguousType = (std != NULL && dst != NULL && u_strcmp(std, dst) == 0); 1807f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1808f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UChar *uMzID = ZoneMeta::findMetaZoneID(*mzID); 1809f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (std != NULL) { 1810f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TZDBNameInfo *stdInf = (TZDBNameInfo *)uprv_malloc(sizeof(TZDBNameInfo)); 1811f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (stdInf == NULL) { 1812f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius status = U_MEMORY_ALLOCATION_ERROR; 1813f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius break; 1814f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1815f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius stdInf->mzID = uMzID; 1816f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius stdInf->type = UTZNM_SHORT_STANDARD; 1817f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius stdInf->ambiguousType = ambiguousType; 1818f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius stdInf->parseRegions = parseRegions; 1819f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius stdInf->nRegions = numRegions; 1820f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gTZDBNamesTrie->put(std, stdInf, status); 1821f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1822f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_SUCCESS(status) && dst != NULL) { 1823f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TZDBNameInfo *dstInf = (TZDBNameInfo *)uprv_malloc(sizeof(TZDBNameInfo)); 1824f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (dstInf == NULL) { 1825f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius status = U_MEMORY_ALLOCATION_ERROR; 1826f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius break; 1827f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1828f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius dstInf->mzID = uMzID; 1829f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius dstInf->type = UTZNM_SHORT_DAYLIGHT; 1830f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius dstInf->ambiguousType = ambiguousType; 1831f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius dstInf->parseRegions = parseRegions; 1832f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius dstInf->nRegions = numRegions; 1833f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gTZDBNamesTrie->put(dst, dstInf, status); 1834f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1835f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1836f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1837f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius delete mzIDs; 1838f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1839f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_FAILURE(status)) { 1840f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius delete gTZDBNamesTrie; 1841f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gTZDBNamesTrie = NULL; 1842f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return; 1843f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1844f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1845f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius ucln_i18n_registerCleanup(UCLN_I18N_TZDBTIMEZONENAMES, tzdbTimeZoneNames_cleanup); 1846f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1847f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1848f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_CDECL_END 1849f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1850f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBTimeZoneNames::TZDBTimeZoneNames(const Locale& locale) 1851f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius: fLocale(locale) { 1852f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UBool useWorld = TRUE; 1853f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char* region = fLocale.getCountry(); 1854f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t regionLen = uprv_strlen(region); 1855f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (regionLen == 0) { 1856f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UErrorCode status = U_ZERO_ERROR; 1857f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius char loc[ULOC_FULLNAME_CAPACITY]; 1858f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status); 1859f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius regionLen = uloc_getCountry(loc, fRegion, sizeof(fRegion), &status); 1860f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_SUCCESS(status) && regionLen < (int32_t)sizeof(fRegion)) { 1861f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius useWorld = FALSE; 1862f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1863f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else if (regionLen < (int32_t)sizeof(fRegion)) { 1864f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uprv_strcpy(fRegion, region); 1865f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius useWorld = FALSE; 1866f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1867f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (useWorld) { 1868f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uprv_strcpy(fRegion, "001"); 1869f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1870f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1871f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1872f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBTimeZoneNames::~TZDBTimeZoneNames() { 1873f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1874f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1875f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusUBool 1876f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBTimeZoneNames::operator==(const TimeZoneNames& other) const { 1877f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (this == &other) { 1878f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TRUE; 1879f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1880f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // No implementation for now 1881f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return FALSE; 1882f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1883f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1884f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTimeZoneNames* 1885f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBTimeZoneNames::clone() const { 1886f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return new TZDBTimeZoneNames(fLocale); 1887f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1888f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1889f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusStringEnumeration* 1890f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBTimeZoneNames::getAvailableMetaZoneIDs(UErrorCode& status) const { 1891f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TimeZoneNamesImpl::_getAvailableMetaZoneIDs(status); 1892f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1893f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1894f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusStringEnumeration* 1895f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBTimeZoneNames::getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const { 1896f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TimeZoneNamesImpl::_getAvailableMetaZoneIDs(tzID, status); 1897f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1898f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1899f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusUnicodeString& 1900f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBTimeZoneNames::getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const { 1901f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TimeZoneNamesImpl::_getMetaZoneID(tzID, date, mzID); 1902f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1903f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1904f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusUnicodeString& 1905f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBTimeZoneNames::getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const { 1906f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TimeZoneNamesImpl::_getReferenceZoneID(mzID, region, tzID); 1907f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1908f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1909f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusUnicodeString& 1910f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBTimeZoneNames::getMetaZoneDisplayName(const UnicodeString& mzID, 1911f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UTimeZoneNameType type, 1912f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UnicodeString& name) const { 1913f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius name.setToBogus(); 1914f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (mzID.isEmpty()) { 1915f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return name; 1916f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1917f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1918f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UErrorCode status = U_ZERO_ERROR; 1919f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const TZDBNames *tzdbNames = TZDBTimeZoneNames::getMetaZoneNames(mzID, status); 1920f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_SUCCESS(status)) { 1921f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UChar *s = tzdbNames->getName(type); 1922f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (s != NULL) { 1923f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius name.setTo(TRUE, s, -1); 1924f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1925f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1926f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1927f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return name; 1928f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1929f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1930f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusUnicodeString& 1931f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBTimeZoneNames::getTimeZoneDisplayName(const UnicodeString& /* tzID */, UTimeZoneNameType /* type */, UnicodeString& name) const { 1932f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // No abbreviations associated a zone directly for now. 1933f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius name.setToBogus(); 1934f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return name; 1935f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1936f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1937f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBTimeZoneNames::MatchInfoCollection* 1938f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBTimeZoneNames::find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const { 1939f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_initOnce(gTZDBNamesTrieInitOnce, &prepareFind, status); 1940f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_FAILURE(status)) { 1941f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 1942f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1943f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1944f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TZDBNameSearchHandler handler(types, fRegion); 1945f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gTZDBNamesTrie->search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); 1946f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_FAILURE(status)) { 1947f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 1948f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1949f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int32_t maxLen = 0; 1950f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return handler.getMatches(maxLen); 1951f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1952f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1953f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst TZDBNames* 1954f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusTZDBTimeZoneNames::getMetaZoneNames(const UnicodeString& mzID, UErrorCode& status) { 1955f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_initOnce(gTZDBNamesMapInitOnce, &initTZDBNamesMap, status); 1956f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_FAILURE(status)) { 1957f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return NULL; 1958f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1959f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1960f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TZDBNames* tzdbNames = NULL; 1961f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1962f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UChar mzIDKey[ZID_KEY_MAX + 1]; 1963f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius mzID.extract(mzIDKey, ZID_KEY_MAX + 1, status); 1964f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius U_ASSERT(status == U_ZERO_ERROR); // already checked length above 1965f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius mzIDKey[mzID.length()] = 0; 1966f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1967f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_lock(&gTZDBNamesMapLock); 1968f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius { 1969f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius void *cacheVal = uhash_get(gTZDBNamesMap, mzIDKey); 1970f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (cacheVal == NULL) { 1971f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UResourceBundle *zoneStringsRes = ures_openDirect(U_ICUDATA_ZONE, "tzdbNames", &status); 1972f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius zoneStringsRes = ures_getByKey(zoneStringsRes, gZoneStrings, zoneStringsRes, &status); 1973f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_SUCCESS(status)) { 1974f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius char key[ZID_KEY_MAX + 1]; 1975f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius mergeTimeZoneKey(mzID, key); 1976f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius tzdbNames = TZDBNames::createInstance(zoneStringsRes, key); 1977f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1978f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (tzdbNames == NULL) { 1979f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius cacheVal = (void *)EMPTY; 1980f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else { 1981f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius cacheVal = tzdbNames; 1982f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1983f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Use the persistent ID as the resource key, so we can 1984f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // avoid duplications. 1985f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UChar* newKey = ZoneMeta::findMetaZoneID(mzID); 1986f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (newKey != NULL) { 1987f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uhash_put(gTZDBNamesMap, (void *)newKey, cacheVal, &status); 1988f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_FAILURE(status)) { 1989f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (tzdbNames != NULL) { 1990f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius delete tzdbNames; 1991f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius tzdbNames = NULL; 1992f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1993f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1994f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else { 1995f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Should never happen with a valid input 1996f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (tzdbNames != NULL) { 1997f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // It's not possible that we get a valid tzdbNames with unknown ID. 1998f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // But just in case.. 1999f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius delete tzdbNames; 2000f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius tzdbNames = NULL; 2001f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2002f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2003f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2004f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius ures_close(zoneStringsRes); 2005f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else if (cacheVal != EMPTY) { 2006f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius tzdbNames = (TZDBNames *)cacheVal; 2007f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2008f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 2009f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_unlock(&gTZDBNamesMapLock); 2010f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 2011f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return tzdbNames; 2012f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 2013f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 2014b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_NAMESPACE_END 2015b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2016b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2017b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#endif /* #if !UCONFIG_NO_FORMATTING */ 2018b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2019b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//eof 2020