1b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 2b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho******************************************************************************* 38393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius* Copyright (C) 2011-2013, 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" 23b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uresimp.h" 24b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "ureslocs.h" 25b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "zonemeta.h" 26b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "ucln_in.h" 27b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uvector.h" 28b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "olsontz.h" 29b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 30b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 31b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_NAMESPACE_BEGIN 32b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 33b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define ZID_KEY_MAX 128 34b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define MZ_PREFIX_LEN 5 35b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 36b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char gZoneStrings[] = "zoneStrings"; 37b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char gMZPrefix[] = "meta:"; 38b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 39b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char* KEYS[] = {"lg", "ls", "ld", "sg", "ss", "sd"}; 40b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const int32_t KEYS_SIZE = (sizeof KEYS / sizeof KEYS[0]); 41b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 42b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char gEcTag[] = "ec"; 43b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 44b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char EMPTY[] = "<empty>"; // place holder for empty ZNames/TZNames 45b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 46b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UTimeZoneNameType ALL_NAME_TYPES[] = { 47b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTZNM_LONG_GENERIC, UTZNM_LONG_STANDARD, UTZNM_LONG_DAYLIGHT, 48b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTZNM_SHORT_GENERIC, UTZNM_SHORT_STANDARD, UTZNM_SHORT_DAYLIGHT, 498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UTZNM_EXEMPLAR_LOCATION, 50b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTZNM_UNKNOWN // unknown as the last one 51b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 52b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 53b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define DEFAULT_CHARACTERNODE_CAPACITY 1 54b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 55b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 56103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// CharacterNode class implementation 57b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 58b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid CharacterNode::clear() { 59b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_memset(this, 0, sizeof(*this)); 60b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 61b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 62b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid CharacterNode::deleteValues(UObjectDeleter *valueDeleter) { 63b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fValues == NULL) { 64b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Do nothing. 65b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (!fHasValuesVector) { 66b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (valueDeleter) { 67b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho valueDeleter(fValues); 68b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 69b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 70b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete (UVector *)fValues; 71b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 72b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 73b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 74b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 75b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoCharacterNode::addValue(void *value, UObjectDeleter *valueDeleter, UErrorCode &status) { 76b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 77b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (valueDeleter) { 78b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho valueDeleter(value); 79b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 80b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 81b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 82b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fValues == NULL) { 83b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fValues = value; 84b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 85b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // At least one value already. 86b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!fHasValuesVector) { 87b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // There is only one value so far, and not in a vector yet. 88b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Create a vector and add the old value. 89b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UVector *values = new UVector(valueDeleter, NULL, DEFAULT_CHARACTERNODE_CAPACITY, status); 90b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 91b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (valueDeleter) { 92b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho valueDeleter(value); 93b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 94b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 95b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 96b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho values->addElement(fValues, status); 97b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fValues = values; 98b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fHasValuesVector = TRUE; 99b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 100b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Add the new value. 101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ((UVector *)fValues)->addElement(value, status); 102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 103b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TextTrieMapSearchResultHandler class implementation 107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMapSearchResultHandler::~TextTrieMapSearchResultHandler(){ 109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 112b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TextTrieMap class implementation 113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::TextTrieMap(UBool ignoreCase, UObjectDeleter *valueDeleter) 115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: fIgnoreCase(ignoreCase), fNodes(NULL), fNodesCapacity(0), fNodesCount(0), 116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLazyContents(NULL), fIsEmpty(TRUE), fValueDeleter(valueDeleter) { 117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::~TextTrieMap() { 120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t index; 121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (index = 0; index < fNodesCount; ++index) { 122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodes[index].deleteValues(fValueDeleter); 123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(fNodes); 125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fLazyContents != NULL) { 126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i=0; i<fLazyContents->size(); i+=2) { 127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fValueDeleter) { 128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fValueDeleter(fLazyContents->elementAt(i+1)); 129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fLazyContents; 132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t TextTrieMap::isEmpty() const { 136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Use a separate field for fIsEmpty because it will remain unchanged once the 137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Trie is built, while fNodes and fLazyContents change with the lazy init 138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // of the nodes structure. Trying to test the changing fields has 139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // thread safety complications. 140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fIsEmpty; 141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// We defer actually building the TextTrieMap node structure until the first time a 145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// search is performed. put() simply saves the parameters in case we do 146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// eventually need to build it. 147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// 148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::put(const UnicodeString &key, void *value, ZNStringPool &sp, UErrorCode &status) { 150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *s = sp.get(key, status); 151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho put(s, value, status); 152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// This method is for designed for a persistent key, such as string key stored in 155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// resource bundle. 156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::put(const UChar *key, void *value, UErrorCode &status) { 158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fIsEmpty = FALSE; 159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fLazyContents == NULL) { 160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLazyContents = new UVector(status); 161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fLazyContents == NULL) { 162b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 163b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 166b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 168103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(fLazyContents != NULL); 169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar *s = const_cast<UChar *>(key); 170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLazyContents->addElement(s, status); 171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLazyContents->addElement(value, status); 172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::putImpl(const UnicodeString &key, void *value, UErrorCode &status) { 176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fNodes == NULL) { 177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodesCapacity = 512; 178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodes = (CharacterNode *)uprv_malloc(fNodesCapacity * sizeof(CharacterNode)); 179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodes[0].clear(); // Init root node. 180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodesCount = 1; 181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString foldedKey; 184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *keyBuffer; 185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t keyLength; 186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fIgnoreCase) { 187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Ok to use fastCopyFrom() because we discard the copy when we return. 188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho foldedKey.fastCopyFrom(key).foldCase(); 189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho keyBuffer = foldedKey.getBuffer(); 190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho keyLength = foldedKey.length(); 191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho keyBuffer = key.getBuffer(); 193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho keyLength = key.length(); 194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho CharacterNode *node = fNodes; 197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t index; 198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (index = 0; index < keyLength; ++index) { 199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node = addChildNode(node, keyBuffer[index], status); 200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node->addValue(value, fValueDeleter, status); 202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::growNodes() { 206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fNodesCapacity == 0xffff) { 207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; // We use 16-bit node indexes. 208b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t newCapacity = fNodesCapacity + 1000; 210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newCapacity > 0xffff) { 211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho newCapacity = 0xffff; 212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho CharacterNode *newNodes = (CharacterNode *)uprv_malloc(newCapacity * sizeof(CharacterNode)); 214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newNodes == NULL) { 215b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_memcpy(newNodes, fNodes, fNodesCount * sizeof(CharacterNode)); 218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(fNodes); 219b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodes = newNodes; 220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodesCapacity = newCapacity; 221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 224b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoCharacterNode* 225b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::addChildNode(CharacterNode *parent, UChar c, UErrorCode &status) { 226b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 228b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Linear search of the sorted list of children. 230b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t prevIndex = 0; 231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t nodeIndex = parent->fFirstChild; 232b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while (nodeIndex > 0) { 233b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho CharacterNode *current = fNodes + nodeIndex; 234b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar childCharacter = current->fCharacter; 235b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (childCharacter == c) { 236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return current; 237b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (childCharacter > c) { 238b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 239b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 240b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho prevIndex = nodeIndex; 241b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nodeIndex = current->fNextSibling; 242b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Ensure capacity. Grow fNodes[] if needed. 245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fNodesCount == fNodesCapacity) { 246b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t parentIndex = (int32_t)(parent - fNodes); 247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!growNodes()) { 248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 251b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho parent = fNodes + parentIndex; 252b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 254b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Insert a new child node with c in sorted order. 255b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho CharacterNode *node = fNodes + fNodesCount; 256b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node->clear(); 257b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node->fCharacter = c; 258b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node->fNextSibling = nodeIndex; 259b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (prevIndex == 0) { 260b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho parent->fFirstChild = (uint16_t)fNodesCount; 261b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 262b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNodes[prevIndex].fNextSibling = (uint16_t)fNodesCount; 263b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ++fNodesCount; 265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return node; 266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 267b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 268b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoCharacterNode* 269b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::getChildNode(CharacterNode *parent, UChar c) const { 270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Linear search of the sorted list of children. 271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t nodeIndex = parent->fFirstChild; 272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while (nodeIndex > 0) { 273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho CharacterNode *current = fNodes + nodeIndex; 274b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar childCharacter = current->fCharacter; 275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (childCharacter == c) { 276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return current; 277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (childCharacter > c) { 278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nodeIndex = current->fNextSibling; 281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Mutex for protecting the lazy creation of the Trie node structure on the first call to search(). 28654dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex TextTrieMutex = U_MUTEX_INITIALIZER; 287b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// buildTrie() - The Trie node structure is needed. Create it from the data that was 289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// saved at the time the ZoneStringFormatter was created. The Trie is only 290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// needed for parsing operations, which are less common than formatting, 291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// and the Trie is big, which is why its creation is deferred until first use. 292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid TextTrieMap::buildTrie(UErrorCode &status) { 293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_lock(&TextTrieMutex); 294b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fLazyContents != NULL) { 295b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i=0; i<fLazyContents->size(); i+=2) { 296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *key = (UChar *)fLazyContents->elementAt(i); 297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void *val = fLazyContents->elementAt(i+1); 298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString keyString(TRUE, key, -1); // Aliasing UnicodeString constructor. 299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho putImpl(keyString, val, status); 300b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fLazyContents; 302b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLazyContents = NULL; 303b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho umtx_unlock(&TextTrieMutex); 305b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 306b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 308b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::search(const UnicodeString &text, int32_t start, 309b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TextTrieMapSearchResultHandler *handler, UErrorCode &status) const { 310b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool trieNeedsInitialization = FALSE; 311b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UMTX_CHECK(&TextTrieMutex, fLazyContents != NULL, trieNeedsInitialization); 312b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (trieNeedsInitialization) { 313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TextTrieMap *nonConstThis = const_cast<TextTrieMap *>(this); 314b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nonConstThis->buildTrie(status); 315b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 316b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fNodes == NULL) { 317b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 318b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 319b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho search(fNodes, text, start, start, handler, status); 320b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 321b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 322b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 323b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTextTrieMap::search(CharacterNode *node, const UnicodeString &text, int32_t start, 324b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t index, TextTrieMapSearchResultHandler *handler, UErrorCode &status) const { 325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 326b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (node->hasValues()) { 329b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!handler->handleMatch(index - start, node, status)) { 330b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 334b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 336b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar32 c = text.char32At(index); 337b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fIgnoreCase) { 338b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // size of character may grow after fold operation 339b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString tmp(c); 340b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tmp.foldCase(); 341b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t tmpidx = 0; 342b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while (tmpidx < tmp.length()) { 343b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho c = tmp.char32At(tmpidx); 344b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node = getChildNode(node, c); 345b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (node == NULL) { 346b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 347b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 348b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tmpidx = tmp.moveIndex32(tmpidx, 1); 349b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 350b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 351b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho node = getChildNode(node, c); 352b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 353b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (node != NULL) { 354b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho search(node, text, start, index+1, handler, status); 355b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 356b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 357b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 358b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 359b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// ZNStringPool class implementation 360b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 361b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const int32_t POOL_CHUNK_SIZE = 2000; 362b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostruct ZNStringPoolChunk: public UMemory { 363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNStringPoolChunk *fNext; // Ptr to next pool chunk 364b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t fLimit; // Index to start of unused area at end of fStrings 365b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar fStrings[POOL_CHUNK_SIZE]; // Strings array 366b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNStringPoolChunk(); 367b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 368b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 369b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNStringPoolChunk::ZNStringPoolChunk() { 370b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNext = NULL; 371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLimit = 0; 372b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 373b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 374b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNStringPool::ZNStringPool(UErrorCode &status) { 375b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fChunks = NULL; 376b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fHash = NULL; 377b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 378b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 379b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 380b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fChunks = new ZNStringPoolChunk; 381b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fChunks == NULL) { 382b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 383b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 384b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 385b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 386b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fHash = uhash_open(uhash_hashUChars /* keyHash */, 387b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_compareUChars /* keyComp */, 388b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_compareUChars /* valueComp */, 389b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho &status); 390b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 391b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 392b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 393b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 394b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 395b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNStringPool::~ZNStringPool() { 396b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fHash != NULL) { 397b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(fHash); 398b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fHash = NULL; 399b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 400b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 401b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while (fChunks != NULL) { 402b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNStringPoolChunk *nextChunk = fChunks->fNext; 403b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fChunks; 404b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fChunks = nextChunk; 405b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 406b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 407b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 408b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar EmptyString = 0; 409b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 410b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar *ZNStringPool::get(const UChar *s, UErrorCode &status) { 411b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *pooledString; 412b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 413b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return &EmptyString; 414b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 415b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 416b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pooledString = static_cast<UChar *>(uhash_get(fHash, s)); 417b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (pooledString != NULL) { 418b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return pooledString; 419b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 420b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 421b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t length = u_strlen(s); 422b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t remainingLength = POOL_CHUNK_SIZE - fChunks->fLimit; 423b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (remainingLength <= length) { 424b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(length < POOL_CHUNK_SIZE); 425b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (length >= POOL_CHUNK_SIZE) { 426b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_INTERNAL_PROGRAM_ERROR; 427b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return &EmptyString; 428b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 429b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNStringPoolChunk *oldChunk = fChunks; 430b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fChunks = new ZNStringPoolChunk; 431b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fChunks == NULL) { 432b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 433b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return &EmptyString; 434b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 435b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fChunks->fNext = oldChunk; 436b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 437b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 438b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar *destString = &fChunks->fStrings[fChunks->fLimit]; 439b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho u_strcpy(destString, s); 440b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fChunks->fLimit += (length + 1); 441b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_put(fHash, destString, destString, &status); 442b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return destString; 443b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 444b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 445b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 446b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// 447b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// ZNStringPool::adopt() Put a string into the hash, but do not copy the string data 448b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// into the pool's storage. Used for strings from resource bundles, 449b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// which will perisist for the life of the zone string formatter, and 450b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// therefore can be used directly without copying. 451b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar *ZNStringPool::adopt(const UChar * s, UErrorCode &status) { 452b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *pooledString; 453b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 454b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return &EmptyString; 455b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 456b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (s != NULL) { 457b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pooledString = static_cast<UChar *>(uhash_get(fHash, s)); 458b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (pooledString == NULL) { 459b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar *ncs = const_cast<UChar *>(s); 460b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_put(fHash, ncs, ncs, &status); 461b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 462b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 463b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return s; 464b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 465b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 466b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 467b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar *ZNStringPool::get(const UnicodeString &s, UErrorCode &status) { 468b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString &nonConstStr = const_cast<UnicodeString &>(s); 469b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return this->get(nonConstStr.getTerminatedBuffer(), status); 470b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 471b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 472b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 473b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * freeze(). Close the hash table that maps to the pooled strings. 474b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * After freezing, the pool can not be searched or added to, 475b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * but all existing references to pooled strings remain valid. 476b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * 477b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * The main purpose is to recover the storage used for the hash. 478b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 479b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid ZNStringPool::freeze() { 480b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(fHash); 481b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fHash = NULL; 482b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 483b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 484b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 485b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 486b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// ZNames - names common for time zone and meta zone 487b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 488b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass ZNames : public UMemory { 489b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehopublic: 490b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual ~ZNames(); 491b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 492b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static ZNames* createInstance(UResourceBundle* rb, const char* key); 4938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius virtual const UChar* getName(UTimeZoneNameType type); 494b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 495b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprotected: 496103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ZNames(const UChar** names); 497103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius static const UChar** loadData(UResourceBundle* rb, const char* key); 498b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 499b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprivate: 500b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar** fNames; 501b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 502b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 503103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusZNames::ZNames(const UChar** names) 504103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius: fNames(names) { 505b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 506b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 507b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNames::~ZNames() { 508b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fNames != NULL) { 509b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(fNames); 510b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 511b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 512b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 513b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNames* 514b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNames::createInstance(UResourceBundle* rb, const char* key) { 515103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar** names = loadData(rb, key); 516b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (names == NULL) { 517b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // No names data available 518b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 519b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 520103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return new ZNames(names); 521b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 522b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 523b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar* 524b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNames::getName(UTimeZoneNameType type) { 525b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fNames == NULL) { 526b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 527b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 528b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *name = NULL; 529b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho switch(type) { 530b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_LONG_GENERIC: 531b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name = fNames[0]; 532b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 533b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_LONG_STANDARD: 534b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name = fNames[1]; 535b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 536b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_LONG_DAYLIGHT: 537b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name = fNames[2]; 538b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 539b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_SHORT_GENERIC: 540103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius name = fNames[3]; 541b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 542b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_SHORT_STANDARD: 543b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name = fNames[4]; 544b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 545b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UTZNM_SHORT_DAYLIGHT: 546b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name = fNames[5]; 547b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 5488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZNM_EXEMPLAR_LOCATION: // implemeted by subclass 549b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho default: 550b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name = NULL; 551b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 552b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 553b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 554b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 555b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar** 556103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusZNames::loadData(UResourceBundle* rb, const char* key) { 557b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (rb == NULL || key == NULL || *key == 0) { 558b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 559b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 560b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 561b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 562b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar **names = NULL; 563b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 564b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UResourceBundle* rbTable = NULL; 565b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho rbTable = ures_getByKeyWithFallback(rb, key, rbTable, &status); 566b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 567b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho names = (const UChar **)uprv_malloc(sizeof(const UChar*) * KEYS_SIZE); 568b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (names != NULL) { 569b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool isEmpty = TRUE; 570b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; i < KEYS_SIZE; i++) { 571b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_ZERO_ERROR; 572b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t len = 0; 573b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *value = ures_getStringByKeyWithFallback(rbTable, KEYS[i], &len, &status); 574b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status) || len == 0) { 575b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho names[i] = NULL; 576b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 577b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho names[i] = value; 578b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho isEmpty = FALSE; 579b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 580b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 581b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (isEmpty) { 582b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // No need to keep the names array 583b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(names); 584b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho names = NULL; 585b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 586b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 587b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 588b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ures_close(rbTable); 589b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return names; 590b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 591b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 592b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 593b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TZNames - names for a time zone 594b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 595b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass TZNames : public ZNames { 596b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehopublic: 597b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual ~TZNames(); 598b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 5998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius static TZNames* createInstance(UResourceBundle* rb, const char* key, const UnicodeString& tzID); 6008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius virtual const UChar* getName(UTimeZoneNameType type); 601b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 602b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprivate: 6038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius TZNames(const UChar** names); 604b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* fLocationName; 6058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UChar* fLocationNameOwned; 606b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 607b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 6088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTZNames::TZNames(const UChar** names) 6098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius: ZNames(names), fLocationName(NULL), fLocationNameOwned(NULL) { 610b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 611b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 612b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTZNames::~TZNames() { 6138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (fLocationNameOwned) { 6148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius uprv_free(fLocationNameOwned); 6158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 616b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 617b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 618b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UChar* 6198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTZNames::getName(UTimeZoneNameType type) { 6208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (type == UTZNM_EXEMPLAR_LOCATION) { 6218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return fLocationName; 6228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 6238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return ZNames::getName(type); 624b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 625b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 626b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTZNames* 6278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTZNames::createInstance(UResourceBundle* rb, const char* key, const UnicodeString& tzID) { 628b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (rb == NULL || key == NULL || *key == 0) { 629b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 630b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 6318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 6328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius const UChar** names = loadData(rb, key); 6338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius const UChar* locationName = NULL; 6348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UChar* locationNameOwned = NULL; 6358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 636b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 6378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t len = 0; 6388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 6398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UResourceBundle* table = ures_getByKeyWithFallback(rb, key, NULL, &status); 6408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius locationName = ures_getStringByKeyWithFallback(table, gEcTag, &len, &status); 6418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // ignore missing resource here 6428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius status = U_ZERO_ERROR; 6438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 6448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ures_close(table); 6458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 6468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (locationName == NULL) { 6478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UnicodeString tmpName; 6488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t tmpNameLen = 0; 6498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius TimeZoneNamesImpl::getDefaultExemplarLocationName(tzID, tmpName); 6508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpNameLen = tmpName.length(); 6518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 6528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tmpNameLen > 0) { 6538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius locationNameOwned = (UChar*) uprv_malloc(sizeof(UChar) * (tmpNameLen + 1)); 6548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (locationNameOwned) { 6558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpName.extract(locationNameOwned, tmpNameLen + 1, status); 6568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius locationName = locationNameOwned; 6578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 658b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 6598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 660b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 6618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius TZNames* tznames = NULL; 6628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (locationName != NULL || names != NULL) { 6638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tznames = new TZNames(names); 6648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tznames == NULL) { 6658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (locationNameOwned) { 6668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius uprv_free(locationNameOwned); 6678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 668b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 6698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tznames->fLocationName = locationName; 6708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tznames->fLocationNameOwned = locationNameOwned; 671b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 6728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 673b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return tznames; 674b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 675b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 676b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 677b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// The meta zone ID enumeration class 678b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 679b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass MetaZoneIDsEnumeration : public StringEnumeration { 680b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehopublic: 681b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MetaZoneIDsEnumeration(); 682b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MetaZoneIDsEnumeration(const UVector& mzIDs); 683b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MetaZoneIDsEnumeration(UVector* mzIDs); 684b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual ~MetaZoneIDsEnumeration(); 685b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho static UClassID U_EXPORT2 getStaticClassID(void); 686b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual UClassID getDynamicClassID(void) const; 687b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual const UnicodeString* snext(UErrorCode& status); 688b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual void reset(UErrorCode& status); 689b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual int32_t count(UErrorCode& status) const; 690b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprivate: 691b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t fLen; 692b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t fPos; 693b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UVector* fMetaZoneIDs; 694b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UVector *fLocalVector; 695b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 696b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 697b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUOBJECT_DEFINE_RTTI_IMPLEMENTATION(MetaZoneIDsEnumeration) 698b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 699b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::MetaZoneIDsEnumeration() 700b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: fLen(0), fPos(0), fMetaZoneIDs(NULL), fLocalVector(NULL) { 701b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 702b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 703b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::MetaZoneIDsEnumeration(const UVector& mzIDs) 704b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: fPos(0), fMetaZoneIDs(&mzIDs), fLocalVector(NULL) { 705b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLen = fMetaZoneIDs->size(); 706b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 707b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 708b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::MetaZoneIDsEnumeration(UVector *mzIDs) 709b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: fLen(0), fPos(0), fMetaZoneIDs(mzIDs), fLocalVector(mzIDs) { 710b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fMetaZoneIDs) { 711b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLen = fMetaZoneIDs->size(); 712b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 713b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 714b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 715b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst UnicodeString* 716b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::snext(UErrorCode& status) { 717b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status) && fMetaZoneIDs != NULL && fPos < fLen) { 718b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho unistr.setTo((const UChar*)fMetaZoneIDs->elementAt(fPos++), -1); 719b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return &unistr; 720b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 721b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 722b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 723b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 724b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 725b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::reset(UErrorCode& /*status*/) { 726b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fPos = 0; 727b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 728b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 729b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t 730b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::count(UErrorCode& /*status*/) const { 731b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fLen; 732b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 733b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 734b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMetaZoneIDsEnumeration::~MetaZoneIDsEnumeration() { 735b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fLocalVector) { 736b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fLocalVector; 737b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 738b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 739b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 740b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_BEGIN 741b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 742b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * ZNameInfo stores zone name information in the trie 743b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 744b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehotypedef struct ZNameInfo { 745b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTimeZoneNameType type; 746b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* tzID; 747b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* mzID; 748b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} ZNameInfo; 749b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 750b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 751b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * ZMatchInfo stores zone name match information used by find method 752b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 753b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehotypedef struct ZMatchInfo { 754b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const ZNameInfo* znameInfo; 755b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t matchLength; 756b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} ZMatchInfo; 757b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_END 758b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 759b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 760b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 761b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// ZNameSearchHandler 762b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 763b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass ZNameSearchHandler : public TextTrieMapSearchResultHandler { 764b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehopublic: 765b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNameSearchHandler(uint32_t types); 766b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual ~ZNameSearchHandler(); 767b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 768b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status); 769103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius TimeZoneNames::MatchInfoCollection* getMatches(int32_t& maxMatchLen); 770b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 771b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprivate: 772b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint32_t fTypes; 773b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t fMaxMatchLen; 774103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius TimeZoneNames::MatchInfoCollection* fResults; 775b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 776b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 777b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNameSearchHandler::ZNameSearchHandler(uint32_t types) 778103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius: fTypes(types), fMaxMatchLen(0), fResults(NULL) { 779b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 780b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 781b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNameSearchHandler::~ZNameSearchHandler() { 782b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fResults != NULL) { 783b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fResults; 784b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 785b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 786b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 787b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 788b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNameSearchHandler::handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status) { 789b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 790b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 791b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 792b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (node->hasValues()) { 793b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t valuesCount = node->countValues(); 794b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; i < valuesCount; i++) { 795b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNameInfo *nameinfo = (ZNameInfo *)node->getValue(i); 796b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (nameinfo == NULL) { 797b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 798b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 799b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if ((nameinfo->type & fTypes) != 0) { 800b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // matches a requested type 801b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fResults == NULL) { 802103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fResults = new TimeZoneNames::MatchInfoCollection(); 803b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fResults == NULL) { 804b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 805b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 806b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 807b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 808103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(fResults != NULL); 809103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (nameinfo->tzID) { 810103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fResults->addZone(nameinfo->type, matchLength, UnicodeString(nameinfo->tzID, -1), status); 811b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 812103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(nameinfo->mzID); 813103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fResults->addMetaZone(nameinfo->type, matchLength, UnicodeString(nameinfo->mzID, -1), status); 814103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 815103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status) && matchLength > fMaxMatchLen) { 816103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fMaxMatchLen = matchLength; 817b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 818b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 819b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 820b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 821b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 822b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 823b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 824b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 825103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneNames::MatchInfoCollection* 826b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNameSearchHandler::getMatches(int32_t& maxMatchLen) { 827b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // give the ownership to the caller 828103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius TimeZoneNames::MatchInfoCollection* results = fResults; 829b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho maxMatchLen = fMaxMatchLen; 830b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 831b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // reset 832b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fResults = NULL; 833b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fMaxMatchLen = 0; 834b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return results; 835b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 836b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 837b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 838b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TimeZoneNamesImpl 839b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// 840b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TimeZoneNames implementation class. This is the main 841b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// part of this module. 842b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// --------------------------------------------------- 843b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 844b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_BEGIN 845b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 846b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Deleter for ZNames 847b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 848b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void U_CALLCONV 849b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehodeleteZNames(void *obj) { 850b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (obj != EMPTY) { 851b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete (ZNames *)obj; 852b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 853b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 854b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 855b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Deleter for TZNames 856b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 857b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void U_CALLCONV 858b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehodeleteTZNames(void *obj) { 859b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (obj != EMPTY) { 860b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete (TZNames *)obj; 861b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 862b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 863b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 864b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 865b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Deleter for ZNameInfo 866b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 867b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void U_CALLCONV 868b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehodeleteZNameInfo(void *obj) { 869b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(obj); 870b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 871b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 872b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_END 873b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 87454dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex gLock = U_MUTEX_INITIALIZER; 87554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 876b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::TimeZoneNamesImpl(const Locale& locale, UErrorCode& status) 877b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: fLocale(locale), 878b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fZoneStrings(NULL), 879b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTZNamesMap(NULL), 880b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fMZNamesMap(NULL), 881b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNamesTrieFullyLoaded(FALSE), 882b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNamesTrie(TRUE, deleteZNameInfo) { 883b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho initialize(locale, status); 884b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 885b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 886b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 887b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::initialize(const Locale& locale, UErrorCode& status) { 888b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 889b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 890b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 891b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 892b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Load zoneStrings bundle 893b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode tmpsts = U_ZERO_ERROR; // OK with fallback warning.. 894b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fZoneStrings = ures_open(U_ICUDATA_ZONE, locale.getName(), &tmpsts); 895b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fZoneStrings = ures_getByKeyWithFallback(fZoneStrings, gZoneStrings, fZoneStrings, &tmpsts); 896b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(tmpsts)) { 897b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = tmpsts; 898b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cleanup(); 899b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 900b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 901b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 902b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Initialize hashtables holding time zone/meta zone names 903b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fMZNamesMap = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status); 904b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTZNamesMap = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status); 905b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 906b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cleanup(); 907b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 908b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 909b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 910b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_setValueDeleter(fMZNamesMap, deleteZNames); 911b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_setValueDeleter(fTZNamesMap, deleteTZNames); 912b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // no key deleters for name maps 913b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 914b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // preload zone strings for the default zone 915b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZone *tz = TimeZone::createDefault(); 916b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *tzID = ZoneMeta::getCanonicalCLDRID(*tz); 917b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzID != NULL) { 918b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho loadStrings(UnicodeString(tzID)); 919b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 920b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tz; 921b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 922b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 923b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 924b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 925b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 926b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * This method updates the cache and must be called with a lock, 927b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * except initializer. 928b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 929b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 930b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::loadStrings(const UnicodeString& tzCanonicalID) { 931b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho loadTimeZoneNames(tzCanonicalID); 932b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 933b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 934b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho StringEnumeration *mzIDs = getAvailableMetaZoneIDs(tzCanonicalID, status); 935b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status) && mzIDs != NULL) { 936b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString *mzID; 937b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while ((mzID = mzIDs->snext(status))) { 938b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 939b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 940b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 941b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho loadMetaZoneNames(*mzID); 942b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 943b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete mzIDs; 944b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 945b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 946b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 947b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::~TimeZoneNamesImpl() { 948b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cleanup(); 949b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 950b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 951b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 952b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::cleanup() { 953b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fZoneStrings != NULL) { 954b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ures_close(fZoneStrings); 955b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fZoneStrings = NULL; 956b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 957b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fMZNamesMap != NULL) { 958b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(fMZNamesMap); 959b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fMZNamesMap = NULL; 960b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 961b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fTZNamesMap != NULL) { 962b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(fTZNamesMap); 963b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fTZNamesMap = NULL; 964b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 965b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 966b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 967103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUBool 968103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneNamesImpl::operator==(const TimeZoneNames& other) const { 969103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (this == &other) { 970103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return TRUE; 971103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 972103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // No implementation for now 973103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return FALSE; 974103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 975103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 976103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneNames* 977103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneNamesImpl::clone() const { 978103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode status = U_ZERO_ERROR; 979103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return new TimeZoneNamesImpl(fLocale, status); 980103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 981103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 982b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoStringEnumeration* 983b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getAvailableMetaZoneIDs(UErrorCode& status) const { 984b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 985b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 986b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 987b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UVector* mzIDs = ZoneMeta::getAvailableMetazoneIDs(); 988b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (mzIDs == NULL) { 989b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return new MetaZoneIDsEnumeration(); 990b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 991b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return new MetaZoneIDsEnumeration(*mzIDs); 992b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 993b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 994b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoStringEnumeration* 995b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const { 996b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 997b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 998b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 999b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UVector* mappings = ZoneMeta::getMetazoneMappings(tzID); 1000b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (mappings == NULL) { 1001b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return new MetaZoneIDsEnumeration(); 1002b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1003b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1004b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MetaZoneIDsEnumeration *senum = NULL; 1005b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UVector* mzIDs = new UVector(NULL, uhash_compareUChars, status); 1006b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (mzIDs == NULL) { 1007b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 1008b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1009b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 1010103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(mzIDs != NULL); 1011b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; U_SUCCESS(status) && i < mappings->size(); i++) { 1012b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1013b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho OlsonToMetaMappingEntry *map = (OlsonToMetaMappingEntry *)mappings->elementAt(i); 1014b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *mzID = map->mzid; 1015b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!mzIDs->contains((void *)mzID)) { 1016b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho mzIDs->addElement((void *)mzID, status); 1017b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1018b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1019b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 1020b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho senum = new MetaZoneIDsEnumeration(mzIDs); 1021b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1022b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete mzIDs; 1023b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1024b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1025b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return senum; 1026b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1027b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1028b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 1029b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const { 1030b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZoneMeta::getMetazoneID(tzID, date, mzID); 1031b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return mzID; 1032b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1033b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1034b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 1035b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const { 1036b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZoneMeta::getZoneIdByMetazone(mzID, UnicodeString(region, -1, US_INV), tzID); 1037b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return tzID; 1038b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1039b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1040b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 1041b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getMetaZoneDisplayName(const UnicodeString& mzID, 1042b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UTimeZoneNameType type, 1043b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString& name) const { 1044b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setToBogus(); // cleanup result. 1045b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (mzID.isEmpty()) { 1046b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 1047b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1048b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1049b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNames *znames = NULL; 1050b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); 1051b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 105254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_lock(&gLock); 1053b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 1054b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho znames = nonConstThis->loadMetaZoneNames(mzID); 1055b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 105654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_unlock(&gLock); 1057b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1058b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (znames != NULL) { 1059b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* s = znames->getName(type); 1060b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (s != NULL) { 1061b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setTo(TRUE, s, -1); 1062b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1063b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1064b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 1065b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1066b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1067b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 1068b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, UnicodeString& name) const { 1069b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setToBogus(); // cleanup result. 1070b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzID.isEmpty()) { 1071b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 1072b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1073b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1074b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TZNames *tznames = NULL; 1075b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); 1076b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 107754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_lock(&gLock); 1078b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 1079b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tznames = nonConstThis->loadTimeZoneNames(tzID); 1080b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 108154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_unlock(&gLock); 1082b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1083b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tznames != NULL) { 1084b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *s = tznames->getName(type); 1085b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (s != NULL) { 1086b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setTo(TRUE, s, -1); 1087b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1088b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1089b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return name; 1090b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1091b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1092b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& 1093b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::getExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) const { 10948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius name.setToBogus(); // cleanup result. 1095b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* locName = NULL; 1096b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TZNames *tznames = NULL; 1097b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); 1098b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 109954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_lock(&gLock); 1100b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 1101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tznames = nonConstThis->loadTimeZoneNames(tzID); 1102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 110354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_unlock(&gLock); 1104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tznames != NULL) { 11068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius locName = tznames->getName(UTZNM_EXEMPLAR_LOCATION); 1107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (locName != NULL) { 1109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho name.setTo(TRUE, locName, -1); 1110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 11128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return name; 1113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Merge the MZ_PREFIX and mzId 1117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void mergeTimeZoneKey(const UnicodeString& mzID, char* result) { 1118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (mzID.isEmpty()) { 1119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result[0] = '\0'; 1120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho char mzIdChar[ZID_KEY_MAX + 1]; 1124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t keyLen; 1125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t prefixLen = uprv_strlen(gMZPrefix); 1126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho keyLen = mzID.extract(0, mzID.length(), mzIdChar, ZID_KEY_MAX + 1, US_INV); 1127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_memcpy((void *)result, (void *)gMZPrefix, prefixLen); 1128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_memcpy((void *)(result + prefixLen), (void *)mzIdChar, keyLen); 1129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result[keyLen + prefixLen] = '\0'; 1130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 1133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * This method updates the cache and must be called with a lock 1134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 1135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoZNames* 1136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::loadMetaZoneNames(const UnicodeString& mzID) { 1137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (mzID.length() > (ZID_KEY_MAX - MZ_PREFIX_LEN)) { 1138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNames *znames = NULL; 1142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 1144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar mzIDKey[ZID_KEY_MAX + 1]; 1145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho mzID.extract(mzIDKey, ZID_KEY_MAX + 1, status); 1146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(status == U_ZERO_ERROR); // already checked length above 1147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho mzIDKey[mzID.length()] = 0; 1148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void *cacheVal = uhash_get(fMZNamesMap, mzIDKey); 1150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cacheVal == NULL) { 1151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho char key[ZID_KEY_MAX + 1]; 1152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho mergeTimeZoneKey(mzID, key); 1153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho znames = ZNames::createInstance(fZoneStrings, key); 1154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (znames == NULL) { 1156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheVal = (void *)EMPTY; 1157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheVal = znames; 1159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Use the persistent ID as the resource key, so we can 1161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // avoid duplications. 1162b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* newKey = ZoneMeta::findMetaZoneID(mzID); 1163b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newKey != NULL) { 1164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_put(fMZNamesMap, (void *)newKey, cacheVal, &status); 1165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1166b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (znames != NULL) { 1167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete znames; 1168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (znames != NULL) { 1170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // put the name info into the trie 1171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; ALL_NAME_TYPES[i] != UTZNM_UNKNOWN; i++) { 1172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* name = znames->getName(ALL_NAME_TYPES[i]); 1173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (name != NULL) { 1174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(ZNameInfo)); 1175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (nameinfo != NULL) { 1176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->type = ALL_NAME_TYPES[i]; 1177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->tzID = NULL; 1178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->mzID = newKey; 1179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNamesTrie.put(name, nameinfo, status); 1180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Should never happen with a valid input 1187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (znames != NULL) { 1188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // It's not possible that we get a valid ZNames with unknown ID. 1189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // But just in case.. 1190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete znames; 1191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho znames = NULL; 1192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (cacheVal != EMPTY) { 1195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho znames = (ZNames *)cacheVal; 1196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return znames; 1199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 1202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * This method updates the cache and must be called with a lock 1203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 1204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTZNames* 1205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::loadTimeZoneNames(const UnicodeString& tzID) { 1206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzID.length() > ZID_KEY_MAX) { 1207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1208b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TZNames *tznames = NULL; 1211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 1213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar tzIDKey[ZID_KEY_MAX + 1]; 1214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t tzIDKeyLen = tzID.extract(tzIDKey, ZID_KEY_MAX + 1, status); 1215b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(status == U_ZERO_ERROR); // already checked length above 1216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tzIDKey[tzIDKeyLen] = 0; 1217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void *cacheVal = uhash_get(fTZNamesMap, tzIDKey); 1219b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cacheVal == NULL) { 1220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho char key[ZID_KEY_MAX + 1]; 1221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 1222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Replace "/" with ":". 1223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString uKey(tzID); 1224b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; i < uKey.length(); i++) { 1225b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (uKey.charAt(i) == (UChar)0x2F) { 1226b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uKey.setCharAt(i, (UChar)0x3A); 1227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1228b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uKey.extract(0, uKey.length(), key, sizeof(key), US_INV); 12308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tznames = TZNames::createInstance(fZoneStrings, key, tzID); 1231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1232b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tznames == NULL) { 1233b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheVal = (void *)EMPTY; 1234b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1235b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheVal = tznames; 1236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1237b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Use the persistent ID as the resource key, so we can 1238b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // avoid duplications. 1239b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* newKey = ZoneMeta::findTimeZoneID(tzID); 1240b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newKey != NULL) { 1241b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_put(fTZNamesMap, (void *)newKey, cacheVal, &status); 1242b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tznames != NULL) { 1244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tznames; 1245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1246b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (tznames != NULL) { 1247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // put the name info into the trie 1248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; ALL_NAME_TYPES[i] != UTZNM_UNKNOWN; i++) { 1249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* name = tznames->getName(ALL_NAME_TYPES[i]); 1250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (name != NULL) { 1251b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(ZNameInfo)); 1252b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (nameinfo != NULL) { 1253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->type = ALL_NAME_TYPES[i]; 1254b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->tzID = newKey; 1255b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nameinfo->mzID = NULL; 1256b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNamesTrie.put(name, nameinfo, status); 1257b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1258b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1259b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1260b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1261b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1262b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Should never happen with a valid input 1263b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tznames != NULL) { 1264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // It's not possible that we get a valid TZNames with unknown ID. 1265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // But just in case.. 1266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tznames; 1267b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tznames = NULL; 1268b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1269b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (cacheVal != EMPTY) { 1271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tznames = (TZNames *)cacheVal; 1272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1274b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return tznames; 1275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1277103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneNames::MatchInfoCollection* 1278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneNamesImpl::find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const { 1279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ZNameSearchHandler handler(types); 1280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); 1282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 128354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_lock(&gLock); 1284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 1285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); 1286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 128754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_unlock(&gLock); 1288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t maxLen = 0; 1294103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius TimeZoneNames::MatchInfoCollection* matches = handler.getMatches(maxLen); 1295103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (matches != NULL && ((maxLen == (text.length() - start)) || fNamesTrieFullyLoaded)) { 1296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // perfect match 1297103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return matches; 1298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1300103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete matches; 1301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1302b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // All names are not yet loaded into the trie 130354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_lock(&gLock); 1304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 1305b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!fNamesTrieFullyLoaded) { 1306b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString *id; 1307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1308b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // load strings for all zones 1309b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho StringEnumeration *tzIDs = TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status); 1310b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 1311b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while ((id = tzIDs->snext(status))) { 1312b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 1314b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1315b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // loadStrings also load related metazone strings 1316b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nonConstThis->loadStrings(*id); 1317b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1318b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1319b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tzIDs != NULL) { 1320b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete tzIDs; 1321b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1322b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 1323b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho nonConstThis->fNamesTrieFullyLoaded = TRUE; 1324b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1326b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 132754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_unlock(&gLock); 1328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1329b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1330b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 133354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_lock(&gLock); 1334b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho { 1335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // now try it again 1336b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); 1337b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 133854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_unlock(&gLock); 1339b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1340103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return handler.getMatches(maxLen); 1341b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1342b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 13438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar gEtcPrefix[] = { 0x45, 0x74, 0x63, 0x2F }; // "Etc/" 13448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const int32_t gEtcPrefixLen = 4; 13458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar gSystemVPrefix[] = { 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x56, 0x2F }; // "SystemV/ 13468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const int32_t gSystemVPrefixLen = 8; 13478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar gRiyadh8[] = { 0x52, 0x69, 0x79, 0x61, 0x64, 0x68, 0x38 }; // "Riyadh8" 13488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const int32_t gRiyadh8Len = 7; 13498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 13508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUnicodeString& U_EXPORT2 13518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneNamesImpl::getDefaultExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) { 13528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tzID.isEmpty() || tzID.startsWith(gEtcPrefix, gEtcPrefixLen) 13538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius || tzID.startsWith(gSystemVPrefix, gSystemVPrefixLen) || tzID.indexOf(gRiyadh8, gRiyadh8Len, 0) > 0) { 13548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius name.setToBogus(); 13558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return name; 13568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 13578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 13588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t sep = tzID.lastIndexOf((UChar)0x2F /* '/' */); 13598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (sep > 0 && sep + 1 < tzID.length()) { 13608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius name.setTo(tzID, sep + 1); 13618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius name.findAndReplace(UnicodeString((UChar)0x5f /* _ */), 13628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UnicodeString((UChar)0x20 /* space */)); 13638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else { 13648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius name.setToBogus(); 13658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 13668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return name; 13678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 13688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1369b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_NAMESPACE_END 1370b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1372b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#endif /* #if !UCONFIG_NO_FORMATTING */ 1373b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1374b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//eof 1375