2 *******************************************************************************
3 * Copyright (C) 2001-2014, 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"
21 #define UNDERSCORE_CHAR ((UChar)0x005f)
22 #define AT_SIGN_CHAR ((UChar)64)
23 #define PERIOD_CHAR ((UChar)46)
27 static UMutex llock
= U_MUTEX_INITIALIZER
;
28 ICULocaleService::ICULocaleService()
29 : fallbackLocale(Locale::getDefault())
33 ICULocaleService::ICULocaleService(const UnicodeString
& dname
)
35 , fallbackLocale(Locale::getDefault())
39 ICULocaleService::~ICULocaleService()
44 ICULocaleService::get(const Locale
& locale
, UErrorCode
& status
) const
46 return get(locale
, LocaleKey::KIND_ANY
, NULL
, status
);
50 ICULocaleService::get(const Locale
& locale
, int32_t kind
, UErrorCode
& status
) const
52 return get(locale
, kind
, NULL
, status
);
56 ICULocaleService::get(const Locale
& locale
, Locale
* actualReturn
, UErrorCode
& status
) const
58 return get(locale
, LocaleKey::KIND_ANY
, actualReturn
, status
);
62 ICULocaleService::get(const Locale
& locale
, int32_t kind
, Locale
* actualReturn
, UErrorCode
& status
) const
64 UObject
* result
= NULL
;
65 if (U_FAILURE(status
)) {
69 UnicodeString
locName(locale
.getName(), -1, US_INV
);
70 if (locName
.isBogus()) {
71 status
= U_MEMORY_ALLOCATION_ERROR
;
73 ICUServiceKey
* key
= createKey(&locName
, kind
, status
);
75 if (actualReturn
== NULL
) {
76 result
= getKey(*key
, status
);
79 result
= getKey(*key
, &temp
, status
);
82 key
->parseSuffix(temp
);
83 LocaleUtility::initLocaleFromName(temp
, *actualReturn
);
94 ICULocaleService::registerInstance(UObject
* objToAdopt
, const UnicodeString
& locale
,
95 UBool visible
, UErrorCode
& status
)
98 LocaleUtility::initLocaleFromName(locale
, loc
);
99 return registerInstance(objToAdopt
, loc
, LocaleKey::KIND_ANY
,
100 visible
? LocaleKeyFactory::VISIBLE
: LocaleKeyFactory::INVISIBLE
, status
);
104 ICULocaleService::registerInstance(UObject
* objToAdopt
, const Locale
& locale
, UErrorCode
& status
)
106 return registerInstance(objToAdopt
, locale
, LocaleKey::KIND_ANY
, LocaleKeyFactory::VISIBLE
, status
);
110 ICULocaleService::registerInstance(UObject
* objToAdopt
, const Locale
& locale
, int32_t kind
, UErrorCode
& status
)
112 return registerInstance(objToAdopt
, locale
, kind
, LocaleKeyFactory::VISIBLE
, status
);
116 ICULocaleService::registerInstance(UObject
* objToAdopt
, const Locale
& locale
, int32_t kind
, int32_t coverage
, UErrorCode
& status
)
118 ICUServiceFactory
* factory
= new SimpleLocaleKeyFactory(objToAdopt
, locale
, kind
, coverage
);
119 if (factory
!= NULL
) {
120 return registerFactory(factory
, status
);
128 ICULocaleService::registerInstance(UObject
* objToAdopt
, const UnicodeString
& locale
, UErrorCode
& status
)
130 return registerInstance(objToAdopt
, locale
, LocaleKey::KIND_ANY
, LocaleKeyFactory::VISIBLE
, status
);
134 ICULocaleService::registerInstance(UObject
* objToAdopt
, const UnicodeString
& locale
, UBool visible
, UErrorCode
& status
)
136 return registerInstance(objToAdopt
, locale
, LocaleKey::KIND_ANY
,
137 visible
? LocaleKeyFactory::VISIBLE
: LocaleKeyFactory::INVISIBLE
,
142 ICULocaleService::registerInstance(UObject
* objToAdopt
, const UnicodeString
& locale
, int32_t kind
, int32_t coverage
, UErrorCode
& status
)
144 ICUServiceFactory
* factory
= new SimpleLocaleKeyFactory(objToAdopt
, locale
, kind
, coverage
);
145 if (factory
!= NULL
) {
146 return registerFactory(factory
, status
);
153 class ServiceEnumeration
: public StringEnumeration
{
155 const ICULocaleService
* _service
;
161 ServiceEnumeration(const ICULocaleService
* service
, UErrorCode
&status
)
163 , _timestamp(service
->getTimestamp())
164 , _ids(uprv_deleteUObject
, NULL
, status
)
167 _service
->getVisibleIDs(_ids
, status
);
170 ServiceEnumeration(const ServiceEnumeration
&other
, UErrorCode
&status
)
171 : _service(other
._service
)
172 , _timestamp(other
._timestamp
)
173 , _ids(uprv_deleteUObject
, NULL
, status
)
176 if(U_SUCCESS(status
)) {
179 length
= other
._ids
.size();
180 for(i
= 0; i
< length
; ++i
) {
181 _ids
.addElement(((UnicodeString
*)other
._ids
.elementAt(i
))->clone(), status
);
184 if(U_SUCCESS(status
)) {
191 static ServiceEnumeration
* create(const ICULocaleService
* service
) {
192 UErrorCode status
= U_ZERO_ERROR
;
193 ServiceEnumeration
* result
= new ServiceEnumeration(service
, status
);
194 if (U_SUCCESS(status
)) {
201 virtual ~ServiceEnumeration();
203 virtual StringEnumeration
*clone() const {
204 UErrorCode status
= U_ZERO_ERROR
;
205 ServiceEnumeration
*cl
= new ServiceEnumeration(*this, status
);
206 if(U_FAILURE(status
)) {
213 UBool
upToDate(UErrorCode
& status
) const {
214 if (U_SUCCESS(status
)) {
215 if (_timestamp
== _service
->getTimestamp()) {
218 status
= U_ENUM_OUT_OF_SYNC_ERROR
;
223 virtual int32_t count(UErrorCode
& status
) const {
224 return upToDate(status
) ? _ids
.size() : 0;
227 virtual const UnicodeString
* snext(UErrorCode
& status
) {
228 if (upToDate(status
) && (_pos
< _ids
.size())) {
229 return (const UnicodeString
*)_ids
[_pos
++];
234 virtual void reset(UErrorCode
& status
) {
235 if (status
== U_ENUM_OUT_OF_SYNC_ERROR
) {
236 status
= U_ZERO_ERROR
;
238 if (U_SUCCESS(status
)) {
239 _timestamp
= _service
->getTimestamp();
241 _service
->getVisibleIDs(_ids
, status
);
246 static UClassID U_EXPORT2
getStaticClassID(void);
247 virtual UClassID
getDynamicClassID(void) const;
250 ServiceEnumeration::~ServiceEnumeration() {}
252 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceEnumeration
)
255 ICULocaleService::getAvailableLocales(void) const
257 return ServiceEnumeration::create(this);
261 ICULocaleService::validateFallbackLocale() const
263 const Locale
& loc
= Locale::getDefault();
264 ICULocaleService
* ncThis
= (ICULocaleService
*)this;
267 if (loc
!= fallbackLocale
) {
268 ncThis
->fallbackLocale
= loc
;
269 LocaleUtility::initNameFromLocale(loc
, ncThis
->fallbackLocaleName
);
270 ncThis
->clearServiceCache();
273 return fallbackLocaleName
;
277 ICULocaleService::createKey(const UnicodeString
* id
, UErrorCode
& status
) const
279 return LocaleKey::createWithCanonicalFallback(id
, &validateFallbackLocale(), status
);
283 ICULocaleService::createKey(const UnicodeString
* id
, int32_t kind
, UErrorCode
& status
) const
285 return LocaleKey::createWithCanonicalFallback(id
, &validateFallbackLocale(), kind
, status
);
290 /* !UCONFIG_NO_SERVICE */