1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *******************************************************************************
3b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Copyright (C) 2001-2011, International Business Machines Corporation and    *
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * others. All Rights Reserved.                                                *
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *******************************************************************************
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *******************************************************************************
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/resbund.h"
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uresimp.h"
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h"
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "servloc.h"
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ustrfmt.h"
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uhash.h"
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "charstr.h"
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucln_cmn.h"
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uassert.h"
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UNDERSCORE_CHAR ((UChar)0x005f)
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define AT_SIGN_CHAR    ((UChar)64)
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define PERIOD_CHAR     ((UChar)46)
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
29b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic UMTX llock;
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::ICULocaleService()
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  : fallbackLocale(Locale::getDefault())
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::ICULocaleService(const UnicodeString& dname)
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  : ICUService(dname)
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  , fallbackLocale(Locale::getDefault())
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::~ICULocaleService()
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUObject*
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::get(const Locale& locale, UErrorCode& status) const
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return get(locale, LocaleKey::KIND_ANY, NULL, status);
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUObject*
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::get(const Locale& locale, int32_t kind, UErrorCode& status) const
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return get(locale, kind, NULL, status);
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUObject*
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return get(locale, LocaleKey::KIND_ANY, actualReturn, status);
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUObject*
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UObject* result = NULL;
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return result;
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString locName(locale.getName(), -1, US_INV);
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (locName.isBogus()) {
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_MEMORY_ALLOCATION_ERROR;
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ICUServiceKey* key = createKey(&locName, kind, status);
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (key) {
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (actualReturn == NULL) {
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                result = getKey(*key, status);
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                UnicodeString temp;
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                result = getKey(*key, &temp, status);
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (result != NULL) {
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    key->parseSuffix(temp);
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    LocaleUtility::initLocaleFromName(temp, *actualReturn);
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            delete key;
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result;
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruURegistryKey
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale,
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool visible, UErrorCode& status)
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    Locale loc;
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    LocaleUtility::initLocaleFromName(locale, loc);
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return registerInstance(objToAdopt, loc, LocaleKey::KIND_ANY,
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE, status);
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruURegistryKey
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status)
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status);
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruURegistryKey
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status)
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return registerInstance(objToAdopt, locale, kind, LocaleKeyFactory::VISIBLE, status);
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruURegistryKey
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status)
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage);
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (factory != NULL) {
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return registerFactory(factory, status);
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete objToAdopt;
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return NULL;
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if 0
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruURegistryKey
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UErrorCode& status)
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status);
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruURegistryKey
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status)
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY,
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE,
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            status);
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruURegistryKey
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, int32_t kind, int32_t coverage, UErrorCode& status)
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage);
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (factory != NULL) {
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return registerFactory(factory, status);
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete objToAdopt;
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return NULL;
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass ServiceEnumeration : public StringEnumeration {
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate:
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const ICULocaleService* _service;
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t _timestamp;
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UVector _ids;
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t _pos;
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate:
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ServiceEnumeration(const ICULocaleService* service, UErrorCode &status)
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        : _service(service)
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        , _timestamp(service->getTimestamp())
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        , _ids(uhash_deleteUnicodeString, NULL, status)
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        , _pos(0)
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        _service->getVisibleIDs(_ids, status);
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ServiceEnumeration(const ServiceEnumeration &other, UErrorCode &status)
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        : _service(other._service)
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        , _timestamp(other._timestamp)
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        , _ids(uhash_deleteUnicodeString, NULL, status)
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        , _pos(0)
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(U_SUCCESS(status)) {
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t i, length;
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            length = other._ids.size();
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            for(i = 0; i < length; ++i) {
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                _ids.addElement(((UnicodeString *)other._ids.elementAt(i))->clone(), status);
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(U_SUCCESS(status)) {
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                _pos = other._pos;
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic:
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static ServiceEnumeration* create(const ICULocaleService* service) {
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ServiceEnumeration* result = new ServiceEnumeration(service, status);
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_SUCCESS(status)) {
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return result;
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete result;
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return NULL;
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    virtual ~ServiceEnumeration() {}
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    virtual StringEnumeration *clone() const {
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ServiceEnumeration *cl = new ServiceEnumeration(*this, status);
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(U_FAILURE(status)) {
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            delete cl;
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            cl = NULL;
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return cl;
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool upToDate(UErrorCode& status) const {
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_SUCCESS(status)) {
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (_timestamp == _service->getTimestamp()) {
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return TRUE;
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            status = U_ENUM_OUT_OF_SYNC_ERROR;
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return FALSE;
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    virtual int32_t count(UErrorCode& status) const {
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return upToDate(status) ? _ids.size() : 0;
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    virtual const UnicodeString* snext(UErrorCode& status) {
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (upToDate(status) && (_pos < _ids.size())) {
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return (const UnicodeString*)_ids[_pos++];
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return NULL;
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    virtual void reset(UErrorCode& status) {
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (status == U_ENUM_OUT_OF_SYNC_ERROR) {
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            status = U_ZERO_ERROR;
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_SUCCESS(status)) {
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _timestamp = _service->getTimestamp();
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _pos = 0;
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _service->getVisibleIDs(_ids, status);
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic:
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static UClassID U_EXPORT2 getStaticClassID(void);
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    virtual UClassID getDynamicClassID(void) const;
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceEnumeration)
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringEnumeration*
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::getAvailableLocales(void) const
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return ServiceEnumeration::create(this);
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UnicodeString&
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::validateFallbackLocale() const
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const Locale&     loc    = Locale::getDefault();
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ICULocaleService* ncThis = (ICULocaleService*)this;
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        Mutex mutex(&llock);
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (loc != fallbackLocale) {
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ncThis->fallbackLocale = loc;
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            LocaleUtility::initNameFromLocale(loc, ncThis->fallbackLocaleName);
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ncThis->clearServiceCache();
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fallbackLocaleName;
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey*
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::createKey(const UnicodeString* id, UErrorCode& status) const
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), status);
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICUServiceKey*
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruICULocaleService::createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), kind, status);
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* !UCONFIG_NO_SERVICE */
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
294