16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 2001-2012, International Business Machines Corporation.
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* All Rights Reserved.
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h"
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_SERVICE
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "serv.h"
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "umutex.h"
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#undef SERVICE_REFCOUNT
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// in case we use the refcount stuff
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar ICUServiceKey::PREFIX_DELIMITER = 0x002F;   /* '/' */
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey::ICUServiceKey(const UnicodeString& id)
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: _id(id) {
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey::~ICUServiceKey()
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UnicodeString&
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey::getID() const
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return _id;
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey::canonicalID(UnicodeString& result) const
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result.append(_id);
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey::currentID(UnicodeString& result) const
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return canonicalID(result);
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey::currentDescriptor(UnicodeString& result) const
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    prefix(result);
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result.append(PREFIX_DELIMITER);
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return currentID(result);
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey::fallback()
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey::isFallbackOf(const UnicodeString& id) const
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return id == _id;
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey::prefix(UnicodeString& result) const
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey::parsePrefix(UnicodeString& result)
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t n = result.indexOf(PREFIX_DELIMITER);
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (n < 0) {
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        n = 0;
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result.remove(n);
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey::parseSuffix(UnicodeString& result)
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t n = result.indexOf(PREFIX_DELIMITER);
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (n >= 0) {
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result.remove(0, n+1);
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#ifdef SERVICE_DEBUG
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey::debug(UnicodeString& result) const
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    debugClass(result);
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result.append(" id: ");
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result.append(_id);
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey::debugClass(UnicodeString& result) const
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result.append("ICUServiceKey");
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(ICUServiceKey)
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceFactory::~ICUServiceFactory() {}
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSimpleFactory::SimpleFactory(UObject* instanceToAdopt, const UnicodeString& id, UBool visible)
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: _instance(instanceToAdopt), _id(id), _visible(visible)
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSimpleFactory::~SimpleFactory()
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete _instance;
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUObject*
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSimpleFactory::create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_SUCCESS(status)) {
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UnicodeString temp;
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (_id == key.currentID(temp)) {
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return service->cloneInstance(_instance);
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return NULL;
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSimpleFactory::updateVisibleIDs(Hashtable& result, UErrorCode& status) const
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (_visible) {
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result.put(_id, (void*)this, status); // cast away const
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result.remove(_id);
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSimpleFactory::getDisplayName(const UnicodeString& id, const Locale& /* locale */, UnicodeString& result) const
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (_visible && _id == id) {
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result = _id;
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result.setToBogus();
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#ifdef SERVICE_DEBUG
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSimpleFactory::debug(UnicodeString& toAppendTo) const
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    debugClass(toAppendTo);
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    toAppendTo.append(" id: ");
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    toAppendTo.append(_id);
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    toAppendTo.append(", visible: ");
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    toAppendTo.append(_visible ? "T" : "F");
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return toAppendTo;
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSimpleFactory::debugClass(UnicodeString& toAppendTo) const
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return toAppendTo.append("SimpleFactory");
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleFactory)
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgServiceListener::~ServiceListener() {}
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceListener)
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Record the actual id for this service in the cache, so we can return it
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// even if we succeed later with a different id.
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass CacheEntry : public UMemory {
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprivate:
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t refcount;
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic:
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeString actualDescriptor;
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UObject* service;
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /**
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    * Releases a reference to the shared resource.
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    */
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ~CacheEntry() {
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete service;
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    CacheEntry(const UnicodeString& _actualDescriptor, UObject* _service)
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        : refcount(1), actualDescriptor(_actualDescriptor), service(_service) {
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /**
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    * Instantiation creates an initial reference, so don't call this
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    * unless you're creating a new pointer to this.  Management of
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    * that pointer will have to know how to deal with refcounts.
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    * Return true if the resource has not already been released.
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    */
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    CacheEntry* ref() {
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ++refcount;
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return this;
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /**
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    * Destructions removes a reference, so don't call this unless
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    * you're removing pointer to this somewhere.  Management of that
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    * pointer will have to know how to deal with refcounts.  Once
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    * the refcount drops to zero, the resource is released.  Return
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    * false if the resouce has been released.
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    */
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    CacheEntry* unref() {
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if ((--refcount) == 0) {
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete this;
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return NULL;
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return this;
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /**
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    * Return TRUE if there is at least one reference to this and the
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    * resource has not been released.
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    */
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool isShared() const {
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return refcount > 1;
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// UObjectDeleter for serviceCache
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_BEGIN
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcacheDeleter(void* obj) {
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_NAMESPACE_USE ((CacheEntry*)obj)->unref();
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Deleter for UObjects
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdeleteUObject(void *obj) {
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_NAMESPACE_USE delete (UObject*) obj;
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_END
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass DNCache : public UMemory {
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic:
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Hashtable cache;
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const Locale locale;
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    DNCache(const Locale& _locale)
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        : cache(), locale(_locale)
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // cache.setKeyDeleter(uprv_deleteUObject);
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgStringPair*
2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgStringPair::create(const UnicodeString& displayName,
2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                   const UnicodeString& id,
2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                   UErrorCode& status)
2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_SUCCESS(status)) {
3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        StringPair* sp = new StringPair(displayName, id);
3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (sp == NULL || sp->isBogus()) {
3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_MEMORY_ALLOCATION_ERROR;
3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete sp;
3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return NULL;
3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return sp;
3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return NULL;
3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgStringPair::isBogus() const {
3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return displayName.isBogus() || id.isBogus();
3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgStringPair::StringPair(const UnicodeString& _displayName,
3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                       const UnicodeString& _id)
3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: displayName(_displayName)
3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org, id(_id)
3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_BEGIN
3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV
3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguserv_deleteStringPair(void *obj) {
3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_NAMESPACE_USE delete (StringPair*) obj;
3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_END
3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************
3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UMutex lock = U_MUTEX_INITIALIZER;
3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::ICUService()
3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: name()
3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org, timestamp(0)
3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org, factories(NULL)
3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org, serviceCache(NULL)
3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org, idCache(NULL)
3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org, dnCache(NULL)
3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::ICUService(const UnicodeString& newName)
3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: name(newName)
3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org, timestamp(0)
3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org, factories(NULL)
3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org, serviceCache(NULL)
3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org, idCache(NULL)
3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org, dnCache(NULL)
3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::~ICUService()
3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        Mutex mutex(&lock);
3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        clearCaches();
3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete factories;
3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        factories = NULL;
3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUObject*
3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::get(const UnicodeString& descriptor, UErrorCode& status) const
3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return get(descriptor, NULL, status);
3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUObject*
3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::get(const UnicodeString& descriptor, UnicodeString* actualReturn, UErrorCode& status) const
3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UObject* result = NULL;
3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ICUServiceKey* key = createKey(&descriptor, status);
3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (key) {
3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result = getKey(*key, actualReturn, status);
3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete key;
3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUObject*
3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::getKey(ICUServiceKey& key, UErrorCode& status) const
3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return getKey(key, NULL, status);
3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// this is a vector that subclasses of ICUService can override to further customize the result object
3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// before returning it.  All other public get functions should call this one.
3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUObject*
3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::getKey(ICUServiceKey& key, UnicodeString* actualReturn, UErrorCode& status) const
3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return getKey(key, actualReturn, NULL, status);
3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// make it possible to call reentrantly on systems that don't have reentrant mutexes.
4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// we can use this simple approach since we know the situation where we're calling
4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// reentrantly even without knowing the thread.
4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass XMutex : public UMemory {
4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic:
4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    inline XMutex(UMutex *mutex, UBool reentering)
4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        : fMutex(mutex)
4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        , fActive(!reentering)
4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fActive) umtx_lock(fMutex);
4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    inline ~XMutex() {
4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fActive) umtx_unlock(fMutex);
4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprivate:
4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UMutex  *fMutex;
4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool fActive;
4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstruct UVectorDeleter {
4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UVector* _obj;
4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UVectorDeleter() : _obj(NULL) {}
4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ~UVectorDeleter() { delete _obj; }
4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// called only by factories, treat as private
4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUObject*
4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::getKey(ICUServiceKey& key, UnicodeString* actualReturn, const ICUServiceFactory* factory, UErrorCode& status) const
4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return NULL;
4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (isDefault()) {
4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return handleDefault(key, actualReturn, status);
4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ICUService* ncthis = (ICUService*)this; // cast away semantic const
4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    CacheEntry* result = NULL;
4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // The factory list can't be modified until we're done,
4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // otherwise we might update the cache with an invalid result.
4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // The cache has to stay in synch with the factory list.
4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // ICU doesn't have monitors so we can't use rw locks, so
4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // we single-thread everything using this service, for now.
4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // if factory is not null, we're calling from within the mutex,
4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // and since some unix machines don't have reentrant mutexes we
4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // need to make sure not to try to lock it again.
4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        XMutex mutex(&lock, factory != NULL);
4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (serviceCache == NULL) {
4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ncthis->serviceCache = new Hashtable(status);
4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (ncthis->serviceCache == NULL) {
4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return NULL;
4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (U_FAILURE(status)) {
4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                delete serviceCache;
4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return NULL;
4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            serviceCache->setValueDeleter(cacheDeleter);
4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UnicodeString currentDescriptor;
4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UVectorDeleter cacheDescriptorList;
4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UBool putInCache = FALSE;
4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t startIndex = 0;
4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t limit = factories->size();
4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UBool cacheResult = TRUE;
4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (factory != NULL) {
4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            for (int32_t i = 0; i < limit; ++i) {
4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (factory == (const ICUServiceFactory*)factories->elementAt(i)) {
4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    startIndex = i + 1;
4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (startIndex == 0) {
4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                // throw new InternalError("Factory " + factory + "not registered with service: " + this);
4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                status = U_ILLEGAL_ARGUMENT_ERROR;
4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return NULL;
4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            cacheResult = FALSE;
4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        do {
4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            currentDescriptor.remove();
4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            key.currentDescriptor(currentDescriptor);
4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            result = (CacheEntry*)serviceCache->get(currentDescriptor);
4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (result != NULL) {
4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                break;
4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // first test of cache failed, so we'll have to update
4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // the cache if we eventually succeed-- that is, if we're
4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // going to update the cache at all.
4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            putInCache = TRUE;
4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t index = startIndex;
5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            while (index < limit) {
5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ICUServiceFactory* f = (ICUServiceFactory*)factories->elementAt(index++);
5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                UObject* service = f->create(key, this, status);
5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (U_FAILURE(status)) {
5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    delete service;
5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    return NULL;
5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (service != NULL) {
5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    result = new CacheEntry(currentDescriptor, service);
5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    if (result == NULL) {
5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        delete service;
5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        status = U_MEMORY_ALLOCATION_ERROR;
5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        return NULL;
5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    goto outerEnd;
5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // prepare to load the cache with all additional ids that
5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // will resolve to result, assuming we'll succeed.  We
5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // don't want to keep querying on an id that's going to
5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // fallback to the one that succeeded, we want to hit the
5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // cache the first time next goaround.
5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (cacheDescriptorList._obj == NULL) {
5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                cacheDescriptorList._obj = new UVector(uprv_deleteUObject, NULL, 5, status);
5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (U_FAILURE(status)) {
5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    return NULL;
5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UnicodeString* idToCache = new UnicodeString(currentDescriptor);
5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (idToCache == NULL || idToCache->isBogus()) {
5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                status = U_MEMORY_ALLOCATION_ERROR;
5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return NULL;
5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            cacheDescriptorList._obj->addElement(idToCache, status);
5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (U_FAILURE(status)) {
5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return NULL;
5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } while (key.fallback());
5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgouterEnd:
5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (result != NULL) {
5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (putInCache && cacheResult) {
5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                serviceCache->put(result->actualDescriptor, result, status);
5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (U_FAILURE(status)) {
5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    delete result;
5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    return NULL;
5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (cacheDescriptorList._obj != NULL) {
5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    for (int32_t i = cacheDescriptorList._obj->size(); --i >= 0;) {
5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        UnicodeString* desc = (UnicodeString*)cacheDescriptorList._obj->elementAt(i);
5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        serviceCache->put(*desc, result, status);
5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        if (U_FAILURE(status)) {
5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                            delete result;
5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                            return NULL;
5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        }
5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        result->ref();
5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        cacheDescriptorList._obj->removeElementAt(i);
5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (actualReturn != NULL) {
5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                // strip null prefix
5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (result->actualDescriptor.indexOf((UChar)0x2f) == 0) { // U+002f=slash (/)
5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    actualReturn->remove();
5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    actualReturn->append(result->actualDescriptor,
5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        1,
5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        result->actualDescriptor.length() - 1);
5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                } else {
5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    *actualReturn = result->actualDescriptor;
5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (actualReturn->isBogus()) {
5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    status = U_MEMORY_ALLOCATION_ERROR;
5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    delete result;
5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    return NULL;
5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UObject* service = cloneInstance(result->service);
5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (putInCache && !cacheResult) {
5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                delete result;
5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return service;
5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return handleDefault(key, actualReturn, status);
5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUObject*
5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::handleDefault(const ICUServiceKey& /* key */, UnicodeString* /* actualIDReturn */, UErrorCode& /* status */) const
5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return NULL;
6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUVector&
6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::getVisibleIDs(UVector& result, UErrorCode& status) const {
6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return getVisibleIDs(result, NULL, status);
6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUVector&
6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::getVisibleIDs(UVector& result, const UnicodeString* matchID, UErrorCode& status) const
6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result.removeAllElements();
6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return result;
6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        Mutex mutex(&lock);
6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const Hashtable* map = getVisibleIDMap(status);
6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (map != NULL) {
6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ICUServiceKey* fallbackKey = createKey(matchID, status);
6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            for (int32_t pos = -1;;) {
6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                const UHashElement* e = map->nextElement(pos);
6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (e == NULL) {
6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                const UnicodeString* id = (const UnicodeString*)e->key.pointer;
6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (fallbackKey != NULL) {
6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    if (!fallbackKey->isFallbackOf(*id)) {
6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        continue;
6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                UnicodeString* idClone = new UnicodeString(*id);
6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (idClone == NULL || idClone->isBogus()) {
6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    delete idClone;
6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    status = U_MEMORY_ALLOCATION_ERROR;
6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                result.addElement(idClone, status);
6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (U_FAILURE(status)) {
6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    delete idClone;
6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete fallbackKey;
6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result.removeAllElements();
6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst Hashtable*
6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::getVisibleIDMap(UErrorCode& status) const {
6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) return NULL;
6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // must only be called when lock is already held
6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ICUService* ncthis = (ICUService*)this; // cast away semantic const
6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (idCache == NULL) {
6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ncthis->idCache = new Hashtable(status);
6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (idCache == NULL) {
6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_MEMORY_ALLOCATION_ERROR;
6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if (factories != NULL) {
6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            for (int32_t pos = factories->size(); --pos >= 0;) {
6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ICUServiceFactory* f = (ICUServiceFactory*)factories->elementAt(pos);
6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                f->updateVisibleIDs(*idCache, status);
6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (U_FAILURE(status)) {
6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                delete idCache;
6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ncthis->idCache = NULL;
6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return idCache;
6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::getDisplayName(const UnicodeString& id, UnicodeString& result) const
6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return getDisplayName(id, result, Locale::getDefault());
6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::getDisplayName(const UnicodeString& id, UnicodeString& result, const Locale& locale) const
6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UErrorCode status = U_ZERO_ERROR;
6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        Mutex mutex(&lock);
6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const Hashtable* map = getVisibleIDMap(status);
6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (map != NULL) {
6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ICUServiceFactory* f = (ICUServiceFactory*)map->get(id);
6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (f != NULL) {
6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                f->getDisplayName(id, locale, result);
7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return result;
7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // fallback
7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UErrorCode status = U_ZERO_ERROR;
7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ICUServiceKey* fallbackKey = createKey(&id, status);
7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            while (fallbackKey->fallback()) {
7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                UnicodeString us;
7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                fallbackKey->currentID(us);
7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                f = (ICUServiceFactory*)map->get(us);
7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (f != NULL) {
7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    f->getDisplayName(id, locale, result);
7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    delete fallbackKey;
7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    return result;
7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete fallbackKey;
7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result.setToBogus();
7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUVector&
7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::getDisplayNames(UVector& result, UErrorCode& status) const
7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return getDisplayNames(result, Locale::getDefault(), NULL, status);
7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUVector&
7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::getDisplayNames(UVector& result, const Locale& locale, UErrorCode& status) const
7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return getDisplayNames(result, locale, NULL, status);
7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUVector&
7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::getDisplayNames(UVector& result,
7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                            const Locale& locale,
7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                            const UnicodeString* matchID,
7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                            UErrorCode& status) const
7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result.removeAllElements();
7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result.setDeleter(userv_deleteStringPair);
7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_SUCCESS(status)) {
7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ICUService* ncthis = (ICUService*)this; // cast away semantic const
7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        Mutex mutex(&lock);
7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (dnCache != NULL && dnCache->locale != locale) {
7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete dnCache;
7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ncthis->dnCache = NULL;
7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (dnCache == NULL) {
7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            const Hashtable* m = getVisibleIDMap(status);
7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (U_FAILURE(status)) {
7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return result;
7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ncthis->dnCache = new DNCache(locale);
7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (dnCache == NULL) {
7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                status = U_MEMORY_ALLOCATION_ERROR;
7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return result;
7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t pos = -1;
7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            const UHashElement* entry = NULL;
7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            while ((entry = m->nextElement(pos)) != NULL) {
7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                const UnicodeString* id = (const UnicodeString*)entry->key.pointer;
7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ICUServiceFactory* f = (ICUServiceFactory*)entry->value.pointer;
7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                UnicodeString dname;
7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                f->getDisplayName(*id, locale, dname);
7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (dname.isBogus()) {
7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    status = U_MEMORY_ALLOCATION_ERROR;
7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                } else {
7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    dnCache->cache.put(dname, (void*)id, status); // share pointer with visibleIDMap
7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    if (U_SUCCESS(status)) {
7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        continue;
7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    }
7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                delete dnCache;
7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ncthis->dnCache = NULL;
7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return result;
7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ICUServiceKey* matchKey = createKey(matchID, status);
7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* To ensure that all elements in the hashtable are iterated, set pos to -1.
7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * nextElement(pos) will skip the position at pos and begin the iteration
7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * at the next position, which in this case will be 0.
7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     */
7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t pos = -1;
7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UHashElement *entry = NULL;
7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while ((entry = dnCache->cache.nextElement(pos)) != NULL) {
7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const UnicodeString* id = (const UnicodeString*)entry->value.pointer;
7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (matchKey != NULL && !matchKey->isFallbackOf(*id)) {
7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            continue;
7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const UnicodeString* dn = (const UnicodeString*)entry->key.pointer;
7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        StringPair* sp = StringPair::create(*id, *dn, status);
8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result.addElement(sp, status);
8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (U_FAILURE(status)) {
8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            result.removeAllElements();
8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete matchKey;
8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgURegistryKey
8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::registerInstance(UObject* objToAdopt, const UnicodeString& id, UErrorCode& status)
8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return registerInstance(objToAdopt, id, TRUE, status);
8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgURegistryKey
8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::registerInstance(UObject* objToAdopt, const UnicodeString& id, UBool visible, UErrorCode& status)
8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ICUServiceKey* key = createKey(&id, status);
8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (key != NULL) {
8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UnicodeString canonicalID;
8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        key->canonicalID(canonicalID);
8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete key;
8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ICUServiceFactory* f = createSimpleFactory(objToAdopt, canonicalID, visible, status);
8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (f != NULL) {
8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return registerFactory(f, status);
8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete objToAdopt;
8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return NULL;
8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceFactory*
8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::createSimpleFactory(UObject* objToAdopt, const UnicodeString& id, UBool visible, UErrorCode& status)
8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_SUCCESS(status)) {
8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if ((objToAdopt != NULL) && (!id.isBogus())) {
8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return new SimpleFactory(objToAdopt, id, visible);
8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        status = U_ILLEGAL_ARGUMENT_ERROR;
8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return NULL;
8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgURegistryKey
8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::registerFactory(ICUServiceFactory* factoryToAdopt, UErrorCode& status)
8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_SUCCESS(status) && factoryToAdopt != NULL) {
8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        Mutex mutex(&lock);
8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (factories == NULL) {
8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            factories = new UVector(deleteUObject, NULL, status);
8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (U_FAILURE(status)) {
8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                delete factories;
8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return NULL;
8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        factories->insertElementAt(factoryToAdopt, 0, status);
8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (U_SUCCESS(status)) {
8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            clearCaches();
8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete factoryToAdopt;
8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            factoryToAdopt = NULL;
8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (factoryToAdopt != NULL) {
8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        notifyChanged();
8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (URegistryKey)factoryToAdopt;
8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::unregister(URegistryKey rkey, UErrorCode& status)
8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ICUServiceFactory *factory = (ICUServiceFactory*)rkey;
8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool result = FALSE;
8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (factory != NULL && factories != NULL) {
8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        Mutex mutex(&lock);
8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (factories->removeElement(factory)) {
8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            clearCaches();
8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            result = TRUE;
8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_ILLEGAL_ARGUMENT_ERROR;
8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete factory;
8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (result) {
8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        notifyChanged();
8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::reset()
9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        Mutex mutex(&lock);
9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        reInitializeFactories();
9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        clearCaches();
9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    notifyChanged();
9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::reInitializeFactories()
9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (factories != NULL) {
9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        factories->removeAllElements();
9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::isDefault() const
9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return countFactories() == 0;
9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey*
9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::createKey(const UnicodeString* id, UErrorCode& status) const
9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (U_FAILURE(status) || id == NULL) ? NULL : new ICUServiceKey(*id);
9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::clearCaches()
9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // callers synchronize before use
9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ++timestamp;
9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete dnCache;
9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dnCache = NULL;
9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete idCache;
9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    idCache = NULL;
9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete serviceCache; serviceCache = NULL;
9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
9426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::clearServiceCache()
9436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
9446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // callers synchronize before use
9456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete serviceCache; serviceCache = NULL;
9466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
9496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::acceptsListener(const EventListener& l) const
9506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
9516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return dynamic_cast<const ServiceListener*>(&l) != NULL;
9526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
9556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::notifyListener(EventListener& l) const
9566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
9576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ((ServiceListener&)l).serviceChanged(*this);
9586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
9616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::getName(UnicodeString& result) const
9626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
9636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result.append(name);
9646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t
9676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::countFactories() const
9686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
9696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return factories == NULL ? 0 : factories->size();
9706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t
9736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUService::getTimestamp() const
9746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
9756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return timestamp;
9766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END
9796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* UCONFIG_NO_SERVICE */
9816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
982