16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *******************************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copyright (C) 2001-2012, International Business Machines Corporation and    *
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * others. All Rights Reserved.                                                *
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *******************************************************************************
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *******************************************************************************
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h"
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_SERVICE
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/resbund.h"
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uresimp.h"
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h"
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "servloc.h"
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ustrfmt.h"
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "charstr.h"
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucln_cmn.h"
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h"
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define UNDERSCORE_CHAR ((UChar)0x005f)
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define AT_SIGN_CHAR    ((UChar)64)
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define PERIOD_CHAR     ((UChar)46)
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UMutex llock = U_MUTEX_INITIALIZER;
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::ICULocaleService()
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  : fallbackLocale(Locale::getDefault())
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::ICULocaleService(const UnicodeString& dname)
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  : ICUService(dname)
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  , fallbackLocale(Locale::getDefault())
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::~ICULocaleService()
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUObject*
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::get(const Locale& locale, UErrorCode& status) const
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return get(locale, LocaleKey::KIND_ANY, NULL, status);
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUObject*
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::get(const Locale& locale, int32_t kind, UErrorCode& status) const
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return get(locale, kind, NULL, status);
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUObject*
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return get(locale, LocaleKey::KIND_ANY, actualReturn, status);
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUObject*
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UObject* result = NULL;
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return result;
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeString locName(locale.getName(), -1, US_INV);
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (locName.isBogus()) {
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        status = U_MEMORY_ALLOCATION_ERROR;
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ICUServiceKey* key = createKey(&locName, kind, status);
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (key) {
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (actualReturn == NULL) {
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                result = getKey(*key, status);
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                UnicodeString temp;
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                result = getKey(*key, &temp, status);
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (result != NULL) {
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    key->parseSuffix(temp);
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    LocaleUtility::initLocaleFromName(temp, *actualReturn);
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete key;
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgURegistryKey
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale,
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool visible, UErrorCode& status)
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Locale loc;
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    LocaleUtility::initLocaleFromName(locale, loc);
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return registerInstance(objToAdopt, loc, LocaleKey::KIND_ANY,
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE, status);
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgURegistryKey
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status)
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status);
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgURegistryKey
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status)
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return registerInstance(objToAdopt, locale, kind, LocaleKeyFactory::VISIBLE, status);
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgURegistryKey
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status)
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage);
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (factory != NULL) {
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return registerFactory(factory, status);
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete objToAdopt;
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return NULL;
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if 0
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgURegistryKey
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UErrorCode& status)
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status);
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgURegistryKey
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status)
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY,
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                            visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE,
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                            status);
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgURegistryKey
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, int32_t kind, int32_t coverage, UErrorCode& status)
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage);
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (factory != NULL) {
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return registerFactory(factory, status);
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete objToAdopt;
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return NULL;
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass ServiceEnumeration : public StringEnumeration {
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprivate:
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const ICULocaleService* _service;
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t _timestamp;
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UVector _ids;
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t _pos;
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprivate:
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ServiceEnumeration(const ICULocaleService* service, UErrorCode &status)
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        : _service(service)
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        , _timestamp(service->getTimestamp())
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        , _ids(uprv_deleteUObject, NULL, status)
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        , _pos(0)
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        _service->getVisibleIDs(_ids, status);
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ServiceEnumeration(const ServiceEnumeration &other, UErrorCode &status)
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        : _service(other._service)
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        , _timestamp(other._timestamp)
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        , _ids(uprv_deleteUObject, NULL, status)
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        , _pos(0)
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(U_SUCCESS(status)) {
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t i, length;
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            length = other._ids.size();
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            for(i = 0; i < length; ++i) {
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                _ids.addElement(((UnicodeString *)other._ids.elementAt(i))->clone(), status);
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(U_SUCCESS(status)) {
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                _pos = other._pos;
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic:
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static ServiceEnumeration* create(const ICULocaleService* service) {
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UErrorCode status = U_ZERO_ERROR;
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ServiceEnumeration* result = new ServiceEnumeration(service, status);
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (U_SUCCESS(status)) {
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return result;
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete result;
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return NULL;
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    virtual ~ServiceEnumeration();
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    virtual StringEnumeration *clone() const {
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UErrorCode status = U_ZERO_ERROR;
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ServiceEnumeration *cl = new ServiceEnumeration(*this, status);
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(U_FAILURE(status)) {
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete cl;
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            cl = NULL;
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return cl;
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool upToDate(UErrorCode& status) const {
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (U_SUCCESS(status)) {
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (_timestamp == _service->getTimestamp()) {
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return TRUE;
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_ENUM_OUT_OF_SYNC_ERROR;
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    virtual int32_t count(UErrorCode& status) const {
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return upToDate(status) ? _ids.size() : 0;
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    virtual const UnicodeString* snext(UErrorCode& status) {
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (upToDate(status) && (_pos < _ids.size())) {
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return (const UnicodeString*)_ids[_pos++];
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return NULL;
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    virtual void reset(UErrorCode& status) {
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (status == U_ENUM_OUT_OF_SYNC_ERROR) {
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_ZERO_ERROR;
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (U_SUCCESS(status)) {
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            _timestamp = _service->getTimestamp();
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            _pos = 0;
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            _service->getVisibleIDs(_ids, status);
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic:
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static UClassID U_EXPORT2 getStaticClassID(void);
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    virtual UClassID getDynamicClassID(void) const;
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgServiceEnumeration::~ServiceEnumeration() {}
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceEnumeration)
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgStringEnumeration*
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::getAvailableLocales(void) const
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ServiceEnumeration::create(this);
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UnicodeString&
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::validateFallbackLocale() const
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const Locale&     loc    = Locale::getDefault();
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ICULocaleService* ncThis = (ICULocaleService*)this;
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        Mutex mutex(&llock);
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (loc != fallbackLocale) {
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ncThis->fallbackLocale = loc;
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            LocaleUtility::initNameFromLocale(loc, ncThis->fallbackLocaleName);
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ncThis->clearServiceCache();
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return fallbackLocaleName;
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey*
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::createKey(const UnicodeString* id, UErrorCode& status) const
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), status);
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICUServiceKey*
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgICULocaleService::createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), kind, status);
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* !UCONFIG_NO_SERVICE */
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
295