16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 2011-2013, International Business Machines Corporation and 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* others. All Rights Reserved. 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* File TZNAMES_IMPL.CPP 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_FORMATTING 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h" 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/timezone.h" 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "tznames_impl.h" 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h" 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "mutex.h" 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uresimp.h" 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ureslocs.h" 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "zonemeta.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucln_in.h" 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uvector.h" 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "olsontz.h" 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define ZID_KEY_MAX 128 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define MZ_PREFIX_LEN 5 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char gZoneStrings[] = "zoneStrings"; 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char gMZPrefix[] = "meta:"; 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char* KEYS[] = {"lg", "ls", "ld", "sg", "ss", "sd"}; 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int32_t KEYS_SIZE = (sizeof KEYS / sizeof KEYS[0]); 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char gEcTag[] = "ec"; 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char EMPTY[] = "<empty>"; // place holder for empty ZNames/TZNames 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UTimeZoneNameType ALL_NAME_TYPES[] = { 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTZNM_LONG_GENERIC, UTZNM_LONG_STANDARD, UTZNM_LONG_DAYLIGHT, 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTZNM_SHORT_GENERIC, UTZNM_SHORT_STANDARD, UTZNM_SHORT_DAYLIGHT, 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTZNM_EXEMPLAR_LOCATION, 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTZNM_UNKNOWN // unknown as the last one 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define DEFAULT_CHARACTERNODE_CAPACITY 1 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// CharacterNode class implementation 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CharacterNode::clear() { 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memset(this, 0, sizeof(*this)); 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CharacterNode::deleteValues(UObjectDeleter *valueDeleter) { 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fValues == NULL) { 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Do nothing. 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (!fHasValuesVector) { 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (valueDeleter) { 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org valueDeleter(fValues); 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete (UVector *)fValues; 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCharacterNode::addValue(void *value, UObjectDeleter *valueDeleter, UErrorCode &status) { 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (valueDeleter) { 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org valueDeleter(value); 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fValues == NULL) { 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fValues = value; 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // At least one value already. 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!fHasValuesVector) { 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // There is only one value so far, and not in a vector yet. 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Create a vector and add the old value. 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVector *values = new UVector(valueDeleter, NULL, DEFAULT_CHARACTERNODE_CAPACITY, status); 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (valueDeleter) { 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org valueDeleter(value); 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org values->addElement(fValues, status); 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fValues = values; 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fHasValuesVector = TRUE; 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Add the new value. 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((UVector *)fValues)->addElement(value, status); 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// TextTrieMapSearchResultHandler class implementation 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTextTrieMapSearchResultHandler::~TextTrieMapSearchResultHandler(){ 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// TextTrieMap class implementation 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTextTrieMap::TextTrieMap(UBool ignoreCase, UObjectDeleter *valueDeleter) 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: fIgnoreCase(ignoreCase), fNodes(NULL), fNodesCapacity(0), fNodesCount(0), 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLazyContents(NULL), fIsEmpty(TRUE), fValueDeleter(valueDeleter) { 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTextTrieMap::~TextTrieMap() { 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t index; 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (index = 0; index < fNodesCount; ++index) { 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNodes[index].deleteValues(fValueDeleter); 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(fNodes); 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fLazyContents != NULL) { 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i=0; i<fLazyContents->size(); i+=2) { 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fValueDeleter) { 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fValueDeleter(fLazyContents->elementAt(i+1)); 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete fLazyContents; 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t TextTrieMap::isEmpty() const { 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Use a separate field for fIsEmpty because it will remain unchanged once the 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Trie is built, while fNodes and fLazyContents change with the lazy init 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // of the nodes structure. Trying to test the changing fields has 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // thread safety complications. 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return fIsEmpty; 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// We defer actually building the TextTrieMap node structure until the first time a 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// search is performed. put() simply saves the parameters in case we do 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// eventually need to build it. 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTextTrieMap::put(const UnicodeString &key, void *value, ZNStringPool &sp, UErrorCode &status) { 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *s = sp.get(key, status); 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org put(s, value, status); 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// This method is for designed for a persistent key, such as string key stored in 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// resource bundle. 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTextTrieMap::put(const UChar *key, void *value, UErrorCode &status) { 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fIsEmpty = FALSE; 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fLazyContents == NULL) { 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLazyContents = new UVector(status); 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fLazyContents == NULL) { 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(fLazyContents != NULL); 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *s = const_cast<UChar *>(key); 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLazyContents->addElement(s, status); 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLazyContents->addElement(value, status); 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTextTrieMap::putImpl(const UnicodeString &key, void *value, UErrorCode &status) { 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fNodes == NULL) { 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNodesCapacity = 512; 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNodes = (CharacterNode *)uprv_malloc(fNodesCapacity * sizeof(CharacterNode)); 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNodes[0].clear(); // Init root node. 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNodesCount = 1; 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString foldedKey; 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *keyBuffer; 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t keyLength; 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fIgnoreCase) { 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Ok to use fastCopyFrom() because we discard the copy when we return. 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org foldedKey.fastCopyFrom(key).foldCase(); 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org keyBuffer = foldedKey.getBuffer(); 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org keyLength = foldedKey.length(); 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org keyBuffer = key.getBuffer(); 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org keyLength = key.length(); 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org CharacterNode *node = fNodes; 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t index; 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (index = 0; index < keyLength; ++index) { 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org node = addChildNode(node, keyBuffer[index], status); 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org node->addValue(value, fValueDeleter, status); 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTextTrieMap::growNodes() { 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fNodesCapacity == 0xffff) { 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; // We use 16-bit node indexes. 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t newCapacity = fNodesCapacity + 1000; 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (newCapacity > 0xffff) { 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newCapacity = 0xffff; 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org CharacterNode *newNodes = (CharacterNode *)uprv_malloc(newCapacity * sizeof(CharacterNode)); 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (newNodes == NULL) { 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(newNodes, fNodes, fNodesCount * sizeof(CharacterNode)); 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(fNodes); 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNodes = newNodes; 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNodesCapacity = newCapacity; 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCharacterNode* 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTextTrieMap::addChildNode(CharacterNode *parent, UChar c, UErrorCode &status) { 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Linear search of the sorted list of children. 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint16_t prevIndex = 0; 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint16_t nodeIndex = parent->fFirstChild; 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (nodeIndex > 0) { 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org CharacterNode *current = fNodes + nodeIndex; 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar childCharacter = current->fCharacter; 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (childCharacter == c) { 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return current; 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (childCharacter > c) { 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prevIndex = nodeIndex; 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nodeIndex = current->fNextSibling; 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Ensure capacity. Grow fNodes[] if needed. 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fNodesCount == fNodesCapacity) { 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t parentIndex = (int32_t)(parent - fNodes); 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!growNodes()) { 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org parent = fNodes + parentIndex; 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Insert a new child node with c in sorted order. 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org CharacterNode *node = fNodes + fNodesCount; 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org node->clear(); 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org node->fCharacter = c; 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org node->fNextSibling = nodeIndex; 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (prevIndex == 0) { 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org parent->fFirstChild = (uint16_t)fNodesCount; 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNodes[prevIndex].fNextSibling = (uint16_t)fNodesCount; 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++fNodesCount; 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return node; 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCharacterNode* 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTextTrieMap::getChildNode(CharacterNode *parent, UChar c) const { 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Linear search of the sorted list of children. 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint16_t nodeIndex = parent->fFirstChild; 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (nodeIndex > 0) { 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org CharacterNode *current = fNodes + nodeIndex; 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar childCharacter = current->fCharacter; 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (childCharacter == c) { 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return current; 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (childCharacter > c) { 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nodeIndex = current->fNextSibling; 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Mutex for protecting the lazy creation of the Trie node structure on the first call to search(). 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UMutex TextTrieMutex = U_MUTEX_INITIALIZER; 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// buildTrie() - The Trie node structure is needed. Create it from the data that was 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// saved at the time the ZoneStringFormatter was created. The Trie is only 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// needed for parsing operations, which are less common than formatting, 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// and the Trie is big, which is why its creation is deferred until first use. 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid TextTrieMap::buildTrie(UErrorCode &status) { 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fLazyContents != NULL) { 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i=0; i<fLazyContents->size(); i+=2) { 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *key = (UChar *)fLazyContents->elementAt(i); 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void *val = fLazyContents->elementAt(i+1); 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString keyString(TRUE, key, -1); // Aliasing UnicodeString constructor. 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org putImpl(keyString, val, status); 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete fLazyContents; 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLazyContents = NULL; 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTextTrieMap::search(const UnicodeString &text, int32_t start, 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TextTrieMapSearchResultHandler *handler, UErrorCode &status) const { 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // TODO: if locking the mutex for each check proves to be a performance problem, 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // add a flag of type atomic_int32_t to class TextTrieMap, and use only 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the ICU atomic safe functions for assigning and testing. 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Don't test the pointer fLazyContents. 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Don't do unless it's really required. 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Mutex lock(&TextTrieMutex); 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fLazyContents != NULL) { 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TextTrieMap *nonConstThis = const_cast<TextTrieMap *>(this); 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nonConstThis->buildTrie(status); 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fNodes == NULL) { 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org search(fNodes, text, start, start, handler, status); 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTextTrieMap::search(CharacterNode *node, const UnicodeString &text, int32_t start, 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t index, TextTrieMapSearchResultHandler *handler, UErrorCode &status) const { 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (node->hasValues()) { 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!handler->handleMatch(index - start, node, status)) { 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 c = text.char32At(index); 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fIgnoreCase) { 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // size of character may grow after fold operation 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString tmp(c); 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tmp.foldCase(); 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t tmpidx = 0; 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (tmpidx < tmp.length()) { 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c = tmp.char32At(tmpidx); 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org node = getChildNode(node, c); 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (node == NULL) { 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tmpidx = tmp.moveIndex32(tmpidx, 1); 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org node = getChildNode(node, c); 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (node != NULL) { 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org search(node, text, start, index+1, handler, status); 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ZNStringPool class implementation 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int32_t POOL_CHUNK_SIZE = 2000; 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstruct ZNStringPoolChunk: public UMemory { 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZNStringPoolChunk *fNext; // Ptr to next pool chunk 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t fLimit; // Index to start of unused area at end of fStrings 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar fStrings[POOL_CHUNK_SIZE]; // Strings array 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZNStringPoolChunk(); 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNStringPoolChunk::ZNStringPoolChunk() { 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNext = NULL; 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLimit = 0; 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNStringPool::ZNStringPool(UErrorCode &status) { 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fChunks = NULL; 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fHash = NULL; 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fChunks = new ZNStringPoolChunk; 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fChunks == NULL) { 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fHash = uhash_open(uhash_hashUChars /* keyHash */, 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_compareUChars /* keyComp */, 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_compareUChars /* valueComp */, 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org &status); 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNStringPool::~ZNStringPool() { 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fHash != NULL) { 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_close(fHash); 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fHash = NULL; 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (fChunks != NULL) { 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZNStringPoolChunk *nextChunk = fChunks->fNext; 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete fChunks; 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fChunks = nextChunk; 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar EmptyString = 0; 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar *ZNStringPool::get(const UChar *s, UErrorCode &status) { 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *pooledString; 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return &EmptyString; 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pooledString = static_cast<UChar *>(uhash_get(fHash, s)); 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pooledString != NULL) { 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pooledString; 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length = u_strlen(s); 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t remainingLength = POOL_CHUNK_SIZE - fChunks->fLimit; 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (remainingLength <= length) { 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(length < POOL_CHUNK_SIZE); 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (length >= POOL_CHUNK_SIZE) { 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_INTERNAL_PROGRAM_ERROR; 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return &EmptyString; 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZNStringPoolChunk *oldChunk = fChunks; 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fChunks = new ZNStringPoolChunk; 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fChunks == NULL) { 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return &EmptyString; 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fChunks->fNext = oldChunk; 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *destString = &fChunks->fStrings[fChunks->fLimit]; 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_strcpy(destString, s); 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fChunks->fLimit += (length + 1); 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_put(fHash, destString, destString, &status); 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return destString; 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ZNStringPool::adopt() Put a string into the hash, but do not copy the string data 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// into the pool's storage. Used for strings from resource bundles, 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// which will perisist for the life of the zone string formatter, and 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// therefore can be used directly without copying. 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar *ZNStringPool::adopt(const UChar * s, UErrorCode &status) { 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *pooledString; 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return &EmptyString; 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (s != NULL) { 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pooledString = static_cast<UChar *>(uhash_get(fHash, s)); 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pooledString == NULL) { 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *ncs = const_cast<UChar *>(s); 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_put(fHash, ncs, ncs, &status); 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return s; 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar *ZNStringPool::get(const UnicodeString &s, UErrorCode &status) { 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString &nonConstStr = const_cast<UnicodeString &>(s); 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return this->get(nonConstStr.getTerminatedBuffer(), status); 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * freeze(). Close the hash table that maps to the pooled strings. 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * After freezing, the pool can not be searched or added to, 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * but all existing references to pooled strings remain valid. 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The main purpose is to recover the storage used for the hash. 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid ZNStringPool::freeze() { 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_close(fHash); 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fHash = NULL; 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ZNames - names common for time zone and meta zone 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass ZNames : public UMemory { 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic: 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org virtual ~ZNames(); 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org static ZNames* createInstance(UResourceBundle* rb, const char* key); 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org virtual const UChar* getName(UTimeZoneNameType type); 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprotected: 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZNames(const UChar** names); 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org static const UChar** loadData(UResourceBundle* rb, const char* key); 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprivate: 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar** fNames; 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNames::ZNames(const UChar** names) 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: fNames(names) { 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNames::~ZNames() { 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fNames != NULL) { 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(fNames); 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNames* 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNames::createInstance(UResourceBundle* rb, const char* key) { 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar** names = loadData(rb, key); 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (names == NULL) { 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No names data available 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new ZNames(names); 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar* 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNames::getName(UTimeZoneNameType type) { 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fNames == NULL) { 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *name = NULL; 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(type) { 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UTZNM_LONG_GENERIC: 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name = fNames[0]; 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UTZNM_LONG_STANDARD: 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name = fNames[1]; 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UTZNM_LONG_DAYLIGHT: 5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name = fNames[2]; 5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UTZNM_SHORT_GENERIC: 5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name = fNames[3]; 5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UTZNM_SHORT_STANDARD: 5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name = fNames[4]; 5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UTZNM_SHORT_DAYLIGHT: 5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name = fNames[5]; 5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UTZNM_EXEMPLAR_LOCATION: // implemeted by subclass 5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name = NULL; 5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return name; 5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar** 5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNames::loadData(UResourceBundle* rb, const char* key) { 5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (rb == NULL || key == NULL || *key == 0) { 5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar **names = NULL; 5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle* rbTable = NULL; 5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rbTable = ures_getByKeyWithFallback(rb, key, rbTable, &status); 5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org names = (const UChar **)uprv_malloc(sizeof(const UChar*) * KEYS_SIZE); 5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (names != NULL) { 5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool isEmpty = TRUE; 5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 0; i < KEYS_SIZE; i++) { 5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ZERO_ERROR; 5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len = 0; 5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *value = ures_getStringByKeyWithFallback(rbTable, KEYS[i], &len, &status); 5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status) || len == 0) { 5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org names[i] = NULL; 5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org names[i] = value; 5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org isEmpty = FALSE; 5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (isEmpty) { 5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No need to keep the names array 5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(names); 5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org names = NULL; 5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(rbTable); 5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return names; 5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// TZNames - names for a time zone 5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass TZNames : public ZNames { 6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic: 6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org virtual ~TZNames(); 6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org static TZNames* createInstance(UResourceBundle* rb, const char* key, const UnicodeString& tzID); 6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org virtual const UChar* getName(UTimeZoneNameType type); 6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprivate: 6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TZNames(const UChar** names); 6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* fLocationName; 6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* fLocationNameOwned; 6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTZNames::TZNames(const UChar** names) 6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: ZNames(names), fLocationName(NULL), fLocationNameOwned(NULL) { 6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTZNames::~TZNames() { 6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fLocationNameOwned) { 6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(fLocationNameOwned); 6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar* 6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTZNames::getName(UTimeZoneNameType type) { 6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (type == UTZNM_EXEMPLAR_LOCATION) { 6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return fLocationName; 6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ZNames::getName(type); 6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTZNames* 6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTZNames::createInstance(UResourceBundle* rb, const char* key, const UnicodeString& tzID) { 6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (rb == NULL || key == NULL || *key == 0) { 6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar** names = loadData(rb, key); 6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* locationName = NULL; 6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* locationNameOwned = NULL; 6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len = 0; 6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle* table = ures_getByKeyWithFallback(rb, key, NULL, &status); 6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org locationName = ures_getStringByKeyWithFallback(table, gEcTag, &len, &status); 6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // ignore missing resource here 6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ZERO_ERROR; 6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(table); 6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (locationName == NULL) { 6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString tmpName; 6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t tmpNameLen = 0; 6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneNamesImpl::getDefaultExemplarLocationName(tzID, tmpName); 6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tmpNameLen = tmpName.length(); 6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tmpNameLen > 0) { 6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org locationNameOwned = (UChar*) uprv_malloc(sizeof(UChar) * (tmpNameLen + 1)); 6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (locationNameOwned) { 6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tmpName.extract(locationNameOwned, tmpNameLen + 1, status); 6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org locationName = locationNameOwned; 6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TZNames* tznames = NULL; 6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (locationName != NULL || names != NULL) { 6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tznames = new TZNames(names); 6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tznames == NULL) { 6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (locationNameOwned) { 6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(locationNameOwned); 6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tznames->fLocationName = locationName; 6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tznames->fLocationNameOwned = locationNameOwned; 6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return tznames; 6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// The meta zone ID enumeration class 6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass MetaZoneIDsEnumeration : public StringEnumeration { 6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic: 6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MetaZoneIDsEnumeration(); 6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MetaZoneIDsEnumeration(const UVector& mzIDs); 6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MetaZoneIDsEnumeration(UVector* mzIDs); 6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org virtual ~MetaZoneIDsEnumeration(); 6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org static UClassID U_EXPORT2 getStaticClassID(void); 6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org virtual UClassID getDynamicClassID(void) const; 6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org virtual const UnicodeString* snext(UErrorCode& status); 6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org virtual void reset(UErrorCode& status); 6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org virtual int32_t count(UErrorCode& status) const; 6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprivate: 6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t fLen; 6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t fPos; 6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UVector* fMetaZoneIDs; 6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVector *fLocalVector; 7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(MetaZoneIDsEnumeration) 7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMetaZoneIDsEnumeration::MetaZoneIDsEnumeration() 7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: fLen(0), fPos(0), fMetaZoneIDs(NULL), fLocalVector(NULL) { 7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMetaZoneIDsEnumeration::MetaZoneIDsEnumeration(const UVector& mzIDs) 7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: fPos(0), fMetaZoneIDs(&mzIDs), fLocalVector(NULL) { 7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLen = fMetaZoneIDs->size(); 7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMetaZoneIDsEnumeration::MetaZoneIDsEnumeration(UVector *mzIDs) 7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: fLen(0), fPos(0), fMetaZoneIDs(mzIDs), fLocalVector(mzIDs) { 7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fMetaZoneIDs) { 7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLen = fMetaZoneIDs->size(); 7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UnicodeString* 7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMetaZoneIDsEnumeration::snext(UErrorCode& status) { 7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status) && fMetaZoneIDs != NULL && fPos < fLen) { 7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unistr.setTo((const UChar*)fMetaZoneIDs->elementAt(fPos++), -1); 7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return &unistr; 7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMetaZoneIDsEnumeration::reset(UErrorCode& /*status*/) { 7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fPos = 0; 7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t 7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMetaZoneIDsEnumeration::count(UErrorCode& /*status*/) const { 7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return fLen; 7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMetaZoneIDsEnumeration::~MetaZoneIDsEnumeration() { 7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fLocalVector) { 7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete fLocalVector; 7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_BEGIN 7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * ZNameInfo stores zone name information in the trie 7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtypedef struct ZNameInfo { 7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTimeZoneNameType type; 7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* tzID; 7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* mzID; 7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} ZNameInfo; 7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * ZMatchInfo stores zone name match information used by find method 7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtypedef struct ZMatchInfo { 7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const ZNameInfo* znameInfo; 7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t matchLength; 7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} ZMatchInfo; 7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_END 7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ZNameSearchHandler 7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass ZNameSearchHandler : public TextTrieMapSearchResultHandler { 7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic: 7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZNameSearchHandler(uint32_t types); 7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org virtual ~ZNameSearchHandler(); 7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status); 7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneNames::MatchInfoCollection* getMatches(int32_t& maxMatchLen); 7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprivate: 7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t fTypes; 7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t fMaxMatchLen; 7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneNames::MatchInfoCollection* fResults; 7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNameSearchHandler::ZNameSearchHandler(uint32_t types) 7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: fTypes(types), fMaxMatchLen(0), fResults(NULL) { 7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNameSearchHandler::~ZNameSearchHandler() { 7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fResults != NULL) { 7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete fResults; 7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool 7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNameSearchHandler::handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status) { 7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (node->hasValues()) { 7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t valuesCount = node->countValues(); 7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 0; i < valuesCount; i++) { 8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZNameInfo *nameinfo = (ZNameInfo *)node->getValue(i); 8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (nameinfo == NULL) { 8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((nameinfo->type & fTypes) != 0) { 8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // matches a requested type 8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fResults == NULL) { 8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fResults = new TimeZoneNames::MatchInfoCollection(); 8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fResults == NULL) { 8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(fResults != NULL); 8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (nameinfo->tzID) { 8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fResults->addZone(nameinfo->type, matchLength, UnicodeString(nameinfo->tzID, -1), status); 8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(nameinfo->mzID); 8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fResults->addMetaZone(nameinfo->type, matchLength, UnicodeString(nameinfo->mzID, -1), status); 8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status) && matchLength > fMaxMatchLen) { 8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fMaxMatchLen = matchLength; 8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNames::MatchInfoCollection* 8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNameSearchHandler::getMatches(int32_t& maxMatchLen) { 8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // give the ownership to the caller 8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneNames::MatchInfoCollection* results = fResults; 8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org maxMatchLen = fMaxMatchLen; 8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // reset 8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fResults = NULL; 8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fMaxMatchLen = 0; 8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return results; 8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// TimeZoneNamesImpl 8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// TimeZoneNames implementation class. This is the main 8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// part of this module. 8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --------------------------------------------------- 8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_BEGIN 8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Deleter for ZNames 8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV 8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdeleteZNames(void *obj) { 8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (obj != EMPTY) { 8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete (ZNames *)obj; 8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Deleter for TZNames 8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV 8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdeleteTZNames(void *obj) { 8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (obj != EMPTY) { 8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete (TZNames *)obj; 8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Deleter for ZNameInfo 8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV 8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdeleteZNameInfo(void *obj) { 8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(obj); 8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_END 8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UMutex gLock = U_MUTEX_INITIALIZER; 8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::TimeZoneNamesImpl(const Locale& locale, UErrorCode& status) 8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: fLocale(locale), 8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fZoneStrings(NULL), 8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fTZNamesMap(NULL), 8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fMZNamesMap(NULL), 8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNamesTrieFullyLoaded(FALSE), 8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNamesTrie(TRUE, deleteZNameInfo) { 8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org initialize(locale, status); 8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::initialize(const Locale& locale, UErrorCode& status) { 8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Load zoneStrings bundle 8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode tmpsts = U_ZERO_ERROR; // OK with fallback warning.. 8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fZoneStrings = ures_open(U_ICUDATA_ZONE, locale.getName(), &tmpsts); 9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fZoneStrings = ures_getByKeyWithFallback(fZoneStrings, gZoneStrings, fZoneStrings, &tmpsts); 9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(tmpsts)) { 9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = tmpsts; 9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cleanup(); 9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Initialize hashtables holding time zone/meta zone names 9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fMZNamesMap = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status); 9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fTZNamesMap = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status); 9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cleanup(); 9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_setValueDeleter(fMZNamesMap, deleteZNames); 9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_setValueDeleter(fTZNamesMap, deleteTZNames); 9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // no key deleters for name maps 9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // preload zone strings for the default zone 9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZone *tz = TimeZone::createDefault(); 9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *tzID = ZoneMeta::getCanonicalCLDRID(*tz); 9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tzID != NULL) { 9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org loadStrings(UnicodeString(tzID)); 9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tz; 9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This method updates the cache and must be called with a lock, 9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * except initializer. 9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::loadStrings(const UnicodeString& tzCanonicalID) { 9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org loadTimeZoneNames(tzCanonicalID); 9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org StringEnumeration *mzIDs = getAvailableMetaZoneIDs(tzCanonicalID, status); 9406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status) && mzIDs != NULL) { 9416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString *mzID; 9426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while ((mzID = mzIDs->snext(status))) { 9436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 9446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 9456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org loadMetaZoneNames(*mzID); 9476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete mzIDs; 9496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::~TimeZoneNamesImpl() { 9536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cleanup(); 9546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 9576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::cleanup() { 9586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fZoneStrings != NULL) { 9596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(fZoneStrings); 9606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fZoneStrings = NULL; 9616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fMZNamesMap != NULL) { 9636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_close(fMZNamesMap); 9646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fMZNamesMap = NULL; 9656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fTZNamesMap != NULL) { 9676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_close(fTZNamesMap); 9686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fTZNamesMap = NULL; 9696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool 9736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::operator==(const TimeZoneNames& other) const { 9746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (this == &other) { 9756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 9766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No implementation for now 9786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 9796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNames* 9826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::clone() const { 9836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 9846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new TimeZoneNamesImpl(fLocale, status); 9856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgStringEnumeration* 9886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::getAvailableMetaZoneIDs(UErrorCode& status) const { 9896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 9906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 9916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UVector* mzIDs = ZoneMeta::getAvailableMetazoneIDs(); 9936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mzIDs == NULL) { 9946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new MetaZoneIDsEnumeration(); 9956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new MetaZoneIDsEnumeration(*mzIDs); 9976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgStringEnumeration* 10006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const { 10016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 10026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 10036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UVector* mappings = ZoneMeta::getMetazoneMappings(tzID); 10056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mappings == NULL) { 10066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new MetaZoneIDsEnumeration(); 10076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MetaZoneIDsEnumeration *senum = NULL; 10106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVector* mzIDs = new UVector(NULL, uhash_compareUChars, status); 10116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mzIDs == NULL) { 10126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 10136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 10156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(mzIDs != NULL); 10166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 0; U_SUCCESS(status) && i < mappings->size(); i++) { 10176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org OlsonToMetaMappingEntry *map = (OlsonToMetaMappingEntry *)mappings->elementAt(i); 10196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *mzID = map->mzid; 10206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!mzIDs->contains((void *)mzID)) { 10216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mzIDs->addElement((void *)mzID, status); 10226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 10256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org senum = new MetaZoneIDsEnumeration(mzIDs); 10266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 10276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete mzIDs; 10286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return senum; 10316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 10326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 10346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const { 10356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZoneMeta::getMetazoneID(tzID, date, mzID); 10366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return mzID; 10376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 10386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 10406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const { 10416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZoneMeta::getZoneIdByMetazone(mzID, UnicodeString(region, -1, US_INV), tzID); 10426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return tzID; 10436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 10446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 10466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::getMetaZoneDisplayName(const UnicodeString& mzID, 10476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTimeZoneNameType type, 10486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& name) const { 10496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name.setToBogus(); // cleanup result. 10506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mzID.isEmpty()) { 10516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return name; 10526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZNames *znames = NULL; 10556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); 10566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(&gLock); 10586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 10596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org znames = nonConstThis->loadMetaZoneNames(mzID); 10606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(&gLock); 10626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (znames != NULL) { 10646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* s = znames->getName(type); 10656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (s != NULL) { 10666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name.setTo(TRUE, s, -1); 10676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return name; 10706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 10716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 10736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, UnicodeString& name) const { 10746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name.setToBogus(); // cleanup result. 10756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tzID.isEmpty()) { 10766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return name; 10776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TZNames *tznames = NULL; 10806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); 10816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(&gLock); 10836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 10846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tznames = nonConstThis->loadTimeZoneNames(tzID); 10856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(&gLock); 10876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tznames != NULL) { 10896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *s = tznames->getName(type); 10906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (s != NULL) { 10916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name.setTo(TRUE, s, -1); 10926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return name; 10956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 10966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 10986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::getExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) const { 10996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name.setToBogus(); // cleanup result. 11006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* locName = NULL; 11016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TZNames *tznames = NULL; 11026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); 11036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(&gLock); 11056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 11066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tznames = nonConstThis->loadTimeZoneNames(tzID); 11076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(&gLock); 11096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tznames != NULL) { 11116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org locName = tznames->getName(UTZNM_EXEMPLAR_LOCATION); 11126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (locName != NULL) { 11146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name.setTo(TRUE, locName, -1); 11156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return name; 11186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 11196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Merge the MZ_PREFIX and mzId 11226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void mergeTimeZoneKey(const UnicodeString& mzID, char* result) { 11236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mzID.isEmpty()) { 11246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result[0] = '\0'; 11256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 11266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char mzIdChar[ZID_KEY_MAX + 1]; 11296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t keyLen; 11306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t prefixLen = uprv_strlen(gMZPrefix); 11316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org keyLen = mzID.extract(0, mzID.length(), mzIdChar, ZID_KEY_MAX + 1, US_INV); 11326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy((void *)result, (void *)gMZPrefix, prefixLen); 11336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy((void *)(result + prefixLen), (void *)mzIdChar, keyLen); 11346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result[keyLen + prefixLen] = '\0'; 11356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 11366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 11386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This method updates the cache and must be called with a lock 11396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 11406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgZNames* 11416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::loadMetaZoneNames(const UnicodeString& mzID) { 11426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (mzID.length() > (ZID_KEY_MAX - MZ_PREFIX_LEN)) { 11436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 11446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZNames *znames = NULL; 11476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 11496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar mzIDKey[ZID_KEY_MAX + 1]; 11506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mzID.extract(mzIDKey, ZID_KEY_MAX + 1, status); 11516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(status == U_ZERO_ERROR); // already checked length above 11526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mzIDKey[mzID.length()] = 0; 11536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void *cacheVal = uhash_get(fMZNamesMap, mzIDKey); 11556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cacheVal == NULL) { 11566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char key[ZID_KEY_MAX + 1]; 11576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mergeTimeZoneKey(mzID, key); 11586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org znames = ZNames::createInstance(fZoneStrings, key); 11596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (znames == NULL) { 11616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cacheVal = (void *)EMPTY; 11626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cacheVal = znames; 11646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Use the persistent ID as the resource key, so we can 11666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // avoid duplications. 11676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* newKey = ZoneMeta::findMetaZoneID(mzID); 11686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (newKey != NULL) { 11696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_put(fMZNamesMap, (void *)newKey, cacheVal, &status); 11706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 11716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (znames != NULL) { 11726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete znames; 11736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (znames != NULL) { 11756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // put the name info into the trie 11766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 0; ALL_NAME_TYPES[i] != UTZNM_UNKNOWN; i++) { 11776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* name = znames->getName(ALL_NAME_TYPES[i]); 11786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (name != NULL) { 11796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(ZNameInfo)); 11806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (nameinfo != NULL) { 11816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nameinfo->type = ALL_NAME_TYPES[i]; 11826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nameinfo->tzID = NULL; 11836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nameinfo->mzID = newKey; 11846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNamesTrie.put(name, nameinfo, status); 11856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Should never happen with a valid input 11926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (znames != NULL) { 11936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // It's not possible that we get a valid ZNames with unknown ID. 11946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // But just in case.. 11956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete znames; 11966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org znames = NULL; 11976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (cacheVal != EMPTY) { 12006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org znames = (ZNames *)cacheVal; 12016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return znames; 12046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 12076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This method updates the cache and must be called with a lock 12086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 12096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTZNames* 12106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::loadTimeZoneNames(const UnicodeString& tzID) { 12116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tzID.length() > ZID_KEY_MAX) { 12126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 12136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TZNames *tznames = NULL; 12166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 12186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar tzIDKey[ZID_KEY_MAX + 1]; 12196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t tzIDKeyLen = tzID.extract(tzIDKey, ZID_KEY_MAX + 1, status); 12206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(status == U_ZERO_ERROR); // already checked length above 12216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tzIDKey[tzIDKeyLen] = 0; 12226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void *cacheVal = uhash_get(fTZNamesMap, tzIDKey); 12246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cacheVal == NULL) { 12256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char key[ZID_KEY_MAX + 1]; 12266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 12276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Replace "/" with ":". 12286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString uKey(tzID); 12296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 0; i < uKey.length(); i++) { 12306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (uKey.charAt(i) == (UChar)0x2F) { 12316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uKey.setCharAt(i, (UChar)0x3A); 12326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uKey.extract(0, uKey.length(), key, sizeof(key), US_INV); 12356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tznames = TZNames::createInstance(fZoneStrings, key, tzID); 12366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tznames == NULL) { 12386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cacheVal = (void *)EMPTY; 12396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 12406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cacheVal = tznames; 12416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Use the persistent ID as the resource key, so we can 12436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // avoid duplications. 12446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* newKey = ZoneMeta::findTimeZoneID(tzID); 12456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (newKey != NULL) { 12466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_put(fTZNamesMap, (void *)newKey, cacheVal, &status); 12476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 12486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tznames != NULL) { 12496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tznames; 12506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (tznames != NULL) { 12526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // put the name info into the trie 12536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 0; ALL_NAME_TYPES[i] != UTZNM_UNKNOWN; i++) { 12546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* name = tznames->getName(ALL_NAME_TYPES[i]); 12556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (name != NULL) { 12566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZNameInfo *nameinfo = (ZNameInfo *)uprv_malloc(sizeof(ZNameInfo)); 12576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (nameinfo != NULL) { 12586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nameinfo->type = ALL_NAME_TYPES[i]; 12596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nameinfo->tzID = newKey; 12606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nameinfo->mzID = NULL; 12616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNamesTrie.put(name, nameinfo, status); 12626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 12676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Should never happen with a valid input 12686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tznames != NULL) { 12696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // It's not possible that we get a valid TZNames with unknown ID. 12706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // But just in case.. 12716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tznames; 12726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tznames = NULL; 12736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (cacheVal != EMPTY) { 12766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tznames = (TZNames *)cacheVal; 12776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return tznames; 12806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNames::MatchInfoCollection* 12836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const { 12846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ZNameSearchHandler handler(types); 12856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); 12876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(&gLock); 12896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 12906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); 12916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(&gLock); 12936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 12956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 12966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t maxLen = 0; 12996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneNames::MatchInfoCollection* matches = handler.getMatches(maxLen); 13006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (matches != NULL && ((maxLen == (text.length() - start)) || fNamesTrieFullyLoaded)) { 13016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // perfect match 13026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return matches; 13036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete matches; 13066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // All names are not yet loaded into the trie 13086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(&gLock); 13096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 13106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!fNamesTrieFullyLoaded) { 13116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString *id; 13126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // load strings for all zones 13146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org StringEnumeration *tzIDs = TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status); 13156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 13166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while ((id = tzIDs->snext(status))) { 13176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 13186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 13196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // loadStrings also load related metazone strings 13216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nonConstThis->loadStrings(*id); 13226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tzIDs != NULL) { 13256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tzIDs; 13266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 13286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nonConstThis->fNamesTrieFullyLoaded = TRUE; 13296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(&gLock); 13336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 13356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 13366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(&gLock); 13396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 13406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // now try it again 13416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); 13426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(&gLock); 13446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return handler.getMatches(maxLen); 13466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar gEtcPrefix[] = { 0x45, 0x74, 0x63, 0x2F }; // "Etc/" 13496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int32_t gEtcPrefixLen = 4; 13506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar gSystemVPrefix[] = { 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x56, 0x2F }; // "SystemV/ 13516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int32_t gSystemVPrefixLen = 8; 13526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar gRiyadh8[] = { 0x52, 0x69, 0x79, 0x61, 0x64, 0x68, 0x38 }; // "Riyadh8" 13536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int32_t gRiyadh8Len = 7; 13546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& U_EXPORT2 13566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneNamesImpl::getDefaultExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) { 13576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tzID.isEmpty() || tzID.startsWith(gEtcPrefix, gEtcPrefixLen) 13586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || tzID.startsWith(gSystemVPrefix, gSystemVPrefixLen) || tzID.indexOf(gRiyadh8, gRiyadh8Len, 0) > 0) { 13596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name.setToBogus(); 13606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return name; 13616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t sep = tzID.lastIndexOf((UChar)0x2F /* '/' */); 13646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (sep > 0 && sep + 1 < tzID.length()) { 13656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name.setTo(tzID, sep + 1); 13666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name.findAndReplace(UnicodeString((UChar)0x5f /* _ */), 13676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString((UChar)0x20 /* space */)); 13686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 13696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name.setToBogus(); 13706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return name; 13726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END 13756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_FORMATTING */ 13786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//eof 1380