1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
5 * Copyright (C) 2001-2014, International Business Machines Corporation and *
6 * others. All Rights Reserved. *
7 *******************************************************************************
9 *******************************************************************************
11 #include "unicode/utypes.h"
13 #if !UCONFIG_NO_SERVICE
15 #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())
34 ICULocaleService::ICULocaleService(const UnicodeString
& dname
)
36 , fallbackLocale(Locale::getDefault())
40 ICULocaleService::~ICULocaleService()
45 ICULocaleService::get(const Locale
& locale
, UErrorCode
& status
) const
47 return get(locale
, LocaleKey::KIND_ANY
, NULL
, status
);
51 ICULocaleService::get(const Locale
& locale
, int32_t kind
, UErrorCode
& status
) const
53 return get(locale
, kind
, NULL
, status
);
57 ICULocaleService::get(const Locale
& locale
, Locale
* actualReturn
, UErrorCode
& status
) const
59 return get(locale
, LocaleKey::KIND_ANY
, actualReturn
, status
);
63 ICULocaleService::get(const Locale
& locale
, int32_t kind
, Locale
* actualReturn
, UErrorCode
& status
) const
65 UObject
* result
= NULL
;
66 if (U_FAILURE(status
)) {
70 UnicodeString
locName(locale
.getName(), -1, US_INV
);
71 if (locName
.isBogus()) {
72 status
= U_MEMORY_ALLOCATION_ERROR
;
74 ICUServiceKey
* key
= createKey(&locName
, kind
, status
);
76 if (actualReturn
== NULL
) {
77 result
= getKey(*key
, status
);
80 result
= getKey(*key
, &temp
, status
);
83 key
->parseSuffix(temp
);
84 LocaleUtility::initLocaleFromName(temp
, *actualReturn
);
95 ICULocaleService::registerInstance(UObject
* objToAdopt
, const UnicodeString
& locale
,
96 UBool visible
, UErrorCode
& status
)
99 LocaleUtility::initLocaleFromName(locale
, loc
);
100 return registerInstance(objToAdopt
, loc
, LocaleKey::KIND_ANY
,
101 visible
? LocaleKeyFactory::VISIBLE
: LocaleKeyFactory::INVISIBLE
, status
);
105 ICULocaleService::registerInstance(UObject
* objToAdopt
, const Locale
& locale
, UErrorCode
& status
)
107 return registerInstance(objToAdopt
, locale
, LocaleKey::KIND_ANY
, LocaleKeyFactory::VISIBLE
, status
);
111 ICULocaleService::registerInstance(UObject
* objToAdopt
, const Locale
& locale
, int32_t kind
, UErrorCode
& status
)
113 return registerInstance(objToAdopt
, locale
, kind
, LocaleKeyFactory::VISIBLE
, status
);
117 ICULocaleService::registerInstance(UObject
* objToAdopt
, const Locale
& locale
, int32_t kind
, int32_t coverage
, UErrorCode
& status
)
119 ICUServiceFactory
* factory
= new SimpleLocaleKeyFactory(objToAdopt
, locale
, kind
, coverage
);
120 if (factory
!= NULL
) {
121 return registerFactory(factory
, status
);
129 ICULocaleService::registerInstance(UObject
* objToAdopt
, const UnicodeString
& locale
, UErrorCode
& status
)
131 return registerInstance(objToAdopt
, locale
, LocaleKey::KIND_ANY
, LocaleKeyFactory::VISIBLE
, status
);
135 ICULocaleService::registerInstance(UObject
* objToAdopt
, const UnicodeString
& locale
, UBool visible
, UErrorCode
& status
)
137 return registerInstance(objToAdopt
, locale
, LocaleKey::KIND_ANY
,
138 visible
? LocaleKeyFactory::VISIBLE
: LocaleKeyFactory::INVISIBLE
,
143 ICULocaleService::registerInstance(UObject
* objToAdopt
, const UnicodeString
& locale
, int32_t kind
, int32_t coverage
, UErrorCode
& status
)
145 ICUServiceFactory
* factory
= new SimpleLocaleKeyFactory(objToAdopt
, locale
, kind
, coverage
);
146 if (factory
!= NULL
) {
147 return registerFactory(factory
, status
);
154 class ServiceEnumeration
: public StringEnumeration
{
156 const ICULocaleService
* _service
;
162 ServiceEnumeration(const ICULocaleService
* service
, UErrorCode
&status
)
164 , _timestamp(service
->getTimestamp())
165 , _ids(uprv_deleteUObject
, NULL
, status
)
168 _service
->getVisibleIDs(_ids
, status
);
171 ServiceEnumeration(const ServiceEnumeration
&other
, UErrorCode
&status
)
172 : _service(other
._service
)
173 , _timestamp(other
._timestamp
)
174 , _ids(uprv_deleteUObject
, NULL
, status
)
177 if(U_SUCCESS(status
)) {
180 length
= other
._ids
.size();
181 for(i
= 0; i
< length
; ++i
) {
182 _ids
.addElement(((UnicodeString
*)other
._ids
.elementAt(i
))->clone(), status
);
185 if(U_SUCCESS(status
)) {
192 static ServiceEnumeration
* create(const ICULocaleService
* service
) {
193 UErrorCode status
= U_ZERO_ERROR
;
194 ServiceEnumeration
* result
= new ServiceEnumeration(service
, status
);
195 if (U_SUCCESS(status
)) {
202 virtual ~ServiceEnumeration();
204 virtual StringEnumeration
*clone() const {
205 UErrorCode status
= U_ZERO_ERROR
;
206 ServiceEnumeration
*cl
= new ServiceEnumeration(*this, status
);
207 if(U_FAILURE(status
)) {
214 UBool
upToDate(UErrorCode
& status
) const {
215 if (U_SUCCESS(status
)) {
216 if (_timestamp
== _service
->getTimestamp()) {
219 status
= U_ENUM_OUT_OF_SYNC_ERROR
;
224 virtual int32_t count(UErrorCode
& status
) const {
225 return upToDate(status
) ? _ids
.size() : 0;
228 virtual const UnicodeString
* snext(UErrorCode
& status
) {
229 if (upToDate(status
) && (_pos
< _ids
.size())) {
230 return (const UnicodeString
*)_ids
[_pos
++];
235 virtual void reset(UErrorCode
& status
) {
236 if (status
== U_ENUM_OUT_OF_SYNC_ERROR
) {
237 status
= U_ZERO_ERROR
;
239 if (U_SUCCESS(status
)) {
240 _timestamp
= _service
->getTimestamp();
242 _service
->getVisibleIDs(_ids
, status
);
247 static UClassID U_EXPORT2
getStaticClassID(void);
248 virtual UClassID
getDynamicClassID(void) const;
251 ServiceEnumeration::~ServiceEnumeration() {}
253 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceEnumeration
)
256 ICULocaleService::getAvailableLocales(void) const
258 return ServiceEnumeration::create(this);
262 ICULocaleService::validateFallbackLocale() const
264 const Locale
& loc
= Locale::getDefault();
265 ICULocaleService
* ncThis
= (ICULocaleService
*)this;
269 if (loc
!= fallbackLocale
) {
270 ncThis
->fallbackLocale
= loc
;
271 LocaleUtility::initNameFromLocale(loc
, ncThis
->fallbackLocaleName
);
272 ncThis
->clearServiceCache();
275 return fallbackLocaleName
;
279 ICULocaleService::createKey(const UnicodeString
* id
, UErrorCode
& status
) const
281 return LocaleKey::createWithCanonicalFallback(id
, &validateFallbackLocale(), status
);
285 ICULocaleService::createKey(const UnicodeString
* id
, int32_t kind
, UErrorCode
& status
) const
287 return LocaleKey::createWithCanonicalFallback(id
, &validateFallbackLocale(), kind
, status
);
292 /* !UCONFIG_NO_SERVICE */