2 *******************************************************************************
3 * Copyright (C) 2001-2012, 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"
22 #define UNDERSCORE_CHAR ((UChar)0x005f)
23 #define AT_SIGN_CHAR ((UChar)64)
24 #define PERIOD_CHAR ((UChar)46)
28 static UMutex llock = U_MUTEX_INITIALIZER;
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;
268 if (loc != fallbackLocale) {
269 ncThis->fallbackLocale = loc;
270 LocaleUtility::initNameFromLocale(loc, ncThis->fallbackLocaleName);
271 ncThis->clearServiceCache();
274 return fallbackLocaleName;
278 ICULocaleService::createKey(const UnicodeString* id, UErrorCode& status) const
280 return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), status);
284 ICULocaleService::createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const
286 return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), kind, status);
291 /* !UCONFIG_NO_SERVICE */