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