2 *******************************************************************************
3 * Copyright (C) 2001-2004, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
7 *******************************************************************************
9 #include "unicode/utypes.h"
11 #if !UCONFIG_NO_SERVICE
13 #include "unicode/resbund.h"
23 #define UNDERSCORE_CHAR ((UChar)0x005f)
24 #define AT_SIGN_CHAR ((UChar)64)
25 #define PERIOD_CHAR ((UChar)46)
29 ICULocaleService::ICULocaleService()
30 : fallbackLocale(Locale::getDefault())
36 ICULocaleService::ICULocaleService(const UnicodeString
& dname
)
38 , fallbackLocale(Locale::getDefault())
44 ICULocaleService::~ICULocaleService()
50 ICULocaleService::get(const Locale
& locale
, UErrorCode
& status
) const
52 return get(locale
, LocaleKey::KIND_ANY
, NULL
, status
);
56 ICULocaleService::get(const Locale
& locale
, int32_t kind
, UErrorCode
& status
) const
58 return get(locale
, kind
, NULL
, status
);
62 ICULocaleService::get(const Locale
& locale
, Locale
* actualReturn
, UErrorCode
& status
) const
64 return get(locale
, LocaleKey::KIND_ANY
, actualReturn
, status
);
68 ICULocaleService::get(const Locale
& locale
, int32_t kind
, Locale
* actualReturn
, UErrorCode
& status
) const
70 UObject
* result
= NULL
;
71 if (U_FAILURE(status
)) {
75 UnicodeString
locName(locale
.getName(), -1, US_INV
);
76 if (locName
.isBogus()) {
77 status
= U_MEMORY_ALLOCATION_ERROR
;
79 ICUServiceKey
* key
= createKey(&locName
, kind
, status
);
81 if (actualReturn
== NULL
) {
82 result
= getKey(*key
, status
);
85 result
= getKey(*key
, &temp
, status
);
88 key
->parseSuffix(temp
);
89 LocaleUtility::initLocaleFromName(temp
, *actualReturn
);
100 ICULocaleService::registerInstance(UObject
* objToAdopt
, const UnicodeString
& locale
,
101 UBool visible
, UErrorCode
& status
)
104 LocaleUtility::initLocaleFromName(locale
, loc
);
105 return registerInstance(objToAdopt
, loc
, LocaleKey::KIND_ANY
,
106 visible
? LocaleKeyFactory::VISIBLE
: LocaleKeyFactory::INVISIBLE
, status
);
110 ICULocaleService::registerInstance(UObject
* objToAdopt
, const Locale
& locale
, UErrorCode
& status
)
112 return registerInstance(objToAdopt
, locale
, LocaleKey::KIND_ANY
, LocaleKeyFactory::VISIBLE
, status
);
116 ICULocaleService::registerInstance(UObject
* objToAdopt
, const Locale
& locale
, int32_t kind
, UErrorCode
& status
)
118 return registerInstance(objToAdopt
, locale
, kind
, LocaleKeyFactory::VISIBLE
, status
);
122 ICULocaleService::registerInstance(UObject
* objToAdopt
, const Locale
& locale
, int32_t kind
, int32_t coverage
, UErrorCode
& status
)
124 ICUServiceFactory
* factory
= new SimpleLocaleKeyFactory(objToAdopt
, locale
, kind
, coverage
);
125 if (factory
!= NULL
) {
126 return registerFactory(factory
, status
);
134 ICULocaleService::registerInstance(UObject
* objToAdopt
, const UnicodeString
& locale
, UErrorCode
& status
)
136 return registerInstance(objToAdopt
, locale
, LocaleKey::KIND_ANY
, LocaleKeyFactory::VISIBLE
, status
);
140 ICULocaleService::registerInstance(UObject
* objToAdopt
, const UnicodeString
& locale
, UBool visible
, UErrorCode
& status
)
142 return registerInstance(objToAdopt
, locale
, LocaleKey::KIND_ANY
,
143 visible
? LocaleKeyFactory::VISIBLE
: LocaleKeyFactory::INVISIBLE
,
148 ICULocaleService::registerInstance(UObject
* objToAdopt
, const UnicodeString
& locale
, int32_t kind
, int32_t coverage
, UErrorCode
& status
)
150 ICUServiceFactory
* factory
= new SimpleLocaleKeyFactory(objToAdopt
, locale
, kind
, coverage
);
151 if (factory
!= NULL
) {
152 return registerFactory(factory
, status
);
159 class ServiceEnumeration
: public StringEnumeration
{
161 const ICULocaleService
* _service
;
167 ServiceEnumeration(const ICULocaleService
* service
, UErrorCode
&status
)
169 , _timestamp(service
->getTimestamp())
170 , _ids(uhash_deleteUnicodeString
, NULL
, status
)
173 _service
->getVisibleIDs(_ids
, status
);
176 ServiceEnumeration(const ServiceEnumeration
&other
, UErrorCode
&status
)
177 : _service(other
._service
)
178 , _timestamp(other
._timestamp
)
179 , _ids(uhash_deleteUnicodeString
, NULL
, status
)
182 if(U_SUCCESS(status
)) {
185 length
= other
._ids
.size();
186 for(i
= 0; i
< length
; ++i
) {
187 _ids
.addElement(((UnicodeString
*)other
._ids
.elementAt(i
))->clone(), status
);
190 if(U_SUCCESS(status
)) {
197 static ServiceEnumeration
* create(const ICULocaleService
* service
) {
198 UErrorCode status
= U_ZERO_ERROR
;
199 ServiceEnumeration
* result
= new ServiceEnumeration(service
, status
);
200 if (U_SUCCESS(status
)) {
207 virtual ~ServiceEnumeration() {}
209 virtual StringEnumeration
*clone() const {
210 UErrorCode status
= U_ZERO_ERROR
;
211 ServiceEnumeration
*cl
= new ServiceEnumeration(*this, status
);
212 if(U_FAILURE(status
)) {
219 UBool
upToDate(UErrorCode
& status
) const {
220 if (U_SUCCESS(status
)) {
221 if (_timestamp
== _service
->getTimestamp()) {
224 status
= U_ENUM_OUT_OF_SYNC_ERROR
;
229 virtual int32_t count(UErrorCode
& status
) const {
230 return upToDate(status
) ? _ids
.size() : 0;
233 virtual const UnicodeString
* snext(UErrorCode
& status
) {
234 if (upToDate(status
) && (_pos
< _ids
.size())) {
235 return (const UnicodeString
*)_ids
[_pos
++];
240 virtual void reset(UErrorCode
& status
) {
241 if (status
== U_ENUM_OUT_OF_SYNC_ERROR
) {
242 status
= U_ZERO_ERROR
;
244 if (U_SUCCESS(status
)) {
245 _timestamp
= _service
->getTimestamp();
247 _service
->getVisibleIDs(_ids
, status
);
252 static UClassID U_EXPORT2
getStaticClassID(void);
253 virtual UClassID
getDynamicClassID(void) const;
256 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceEnumeration
)
259 ICULocaleService::getAvailableLocales(void) const
261 return ServiceEnumeration::create(this);
265 ICULocaleService::validateFallbackLocale() const
267 const Locale
& loc
= Locale::getDefault();
268 ICULocaleService
* ncThis
= (ICULocaleService
*)this;
270 Mutex
mutex(&ncThis
->llock
);
271 if (loc
!= fallbackLocale
) {
272 ncThis
->fallbackLocale
= loc
;
273 LocaleUtility::initNameFromLocale(loc
, ncThis
->fallbackLocaleName
);
274 ncThis
->clearServiceCache();
277 return fallbackLocaleName
;
281 ICULocaleService::createKey(const UnicodeString
* id
, UErrorCode
& status
) const
283 return LocaleKey::createWithCanonicalFallback(id
, &validateFallbackLocale(), status
);
287 ICULocaleService::createKey(const UnicodeString
* id
, int32_t kind
, UErrorCode
& status
) const
289 return LocaleKey::createWithCanonicalFallback(id
, &validateFallbackLocale(), kind
, status
);
294 /* !UCONFIG_NO_SERVICE */