1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/common/servls.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,294 @@ 1.4 +/** 1.5 + ******************************************************************************* 1.6 + * Copyright (C) 2001-2012, International Business Machines Corporation and * 1.7 + * others. All Rights Reserved. * 1.8 + ******************************************************************************* 1.9 + * 1.10 + ******************************************************************************* 1.11 + */ 1.12 +#include "unicode/utypes.h" 1.13 + 1.14 +#if !UCONFIG_NO_SERVICE 1.15 + 1.16 +#include "unicode/resbund.h" 1.17 +#include "uresimp.h" 1.18 +#include "cmemory.h" 1.19 +#include "servloc.h" 1.20 +#include "ustrfmt.h" 1.21 +#include "charstr.h" 1.22 +#include "ucln_cmn.h" 1.23 +#include "uassert.h" 1.24 + 1.25 +#define UNDERSCORE_CHAR ((UChar)0x005f) 1.26 +#define AT_SIGN_CHAR ((UChar)64) 1.27 +#define PERIOD_CHAR ((UChar)46) 1.28 + 1.29 +U_NAMESPACE_BEGIN 1.30 + 1.31 +static UMutex llock = U_MUTEX_INITIALIZER; 1.32 +ICULocaleService::ICULocaleService() 1.33 + : fallbackLocale(Locale::getDefault()) 1.34 +{ 1.35 +} 1.36 + 1.37 +ICULocaleService::ICULocaleService(const UnicodeString& dname) 1.38 + : ICUService(dname) 1.39 + , fallbackLocale(Locale::getDefault()) 1.40 +{ 1.41 +} 1.42 + 1.43 +ICULocaleService::~ICULocaleService() 1.44 +{ 1.45 +} 1.46 + 1.47 +UObject* 1.48 +ICULocaleService::get(const Locale& locale, UErrorCode& status) const 1.49 +{ 1.50 + return get(locale, LocaleKey::KIND_ANY, NULL, status); 1.51 +} 1.52 + 1.53 +UObject* 1.54 +ICULocaleService::get(const Locale& locale, int32_t kind, UErrorCode& status) const 1.55 +{ 1.56 + return get(locale, kind, NULL, status); 1.57 +} 1.58 + 1.59 +UObject* 1.60 +ICULocaleService::get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const 1.61 +{ 1.62 + return get(locale, LocaleKey::KIND_ANY, actualReturn, status); 1.63 +} 1.64 + 1.65 +UObject* 1.66 +ICULocaleService::get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const 1.67 +{ 1.68 + UObject* result = NULL; 1.69 + if (U_FAILURE(status)) { 1.70 + return result; 1.71 + } 1.72 + 1.73 + UnicodeString locName(locale.getName(), -1, US_INV); 1.74 + if (locName.isBogus()) { 1.75 + status = U_MEMORY_ALLOCATION_ERROR; 1.76 + } else { 1.77 + ICUServiceKey* key = createKey(&locName, kind, status); 1.78 + if (key) { 1.79 + if (actualReturn == NULL) { 1.80 + result = getKey(*key, status); 1.81 + } else { 1.82 + UnicodeString temp; 1.83 + result = getKey(*key, &temp, status); 1.84 + 1.85 + if (result != NULL) { 1.86 + key->parseSuffix(temp); 1.87 + LocaleUtility::initLocaleFromName(temp, *actualReturn); 1.88 + } 1.89 + } 1.90 + delete key; 1.91 + } 1.92 + } 1.93 + return result; 1.94 +} 1.95 + 1.96 + 1.97 +URegistryKey 1.98 +ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, 1.99 + UBool visible, UErrorCode& status) 1.100 +{ 1.101 + Locale loc; 1.102 + LocaleUtility::initLocaleFromName(locale, loc); 1.103 + return registerInstance(objToAdopt, loc, LocaleKey::KIND_ANY, 1.104 + visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE, status); 1.105 +} 1.106 + 1.107 +URegistryKey 1.108 +ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status) 1.109 +{ 1.110 + return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status); 1.111 +} 1.112 + 1.113 +URegistryKey 1.114 +ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status) 1.115 +{ 1.116 + return registerInstance(objToAdopt, locale, kind, LocaleKeyFactory::VISIBLE, status); 1.117 +} 1.118 + 1.119 +URegistryKey 1.120 +ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status) 1.121 +{ 1.122 + ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage); 1.123 + if (factory != NULL) { 1.124 + return registerFactory(factory, status); 1.125 + } 1.126 + delete objToAdopt; 1.127 + return NULL; 1.128 +} 1.129 + 1.130 +#if 0 1.131 +URegistryKey 1.132 +ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UErrorCode& status) 1.133 +{ 1.134 + return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status); 1.135 +} 1.136 + 1.137 +URegistryKey 1.138 +ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status) 1.139 +{ 1.140 + return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, 1.141 + visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE, 1.142 + status); 1.143 +} 1.144 + 1.145 +URegistryKey 1.146 +ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, int32_t kind, int32_t coverage, UErrorCode& status) 1.147 +{ 1.148 + ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage); 1.149 + if (factory != NULL) { 1.150 + return registerFactory(factory, status); 1.151 + } 1.152 + delete objToAdopt; 1.153 + return NULL; 1.154 +} 1.155 +#endif 1.156 + 1.157 +class ServiceEnumeration : public StringEnumeration { 1.158 +private: 1.159 + const ICULocaleService* _service; 1.160 + int32_t _timestamp; 1.161 + UVector _ids; 1.162 + int32_t _pos; 1.163 + 1.164 +private: 1.165 + ServiceEnumeration(const ICULocaleService* service, UErrorCode &status) 1.166 + : _service(service) 1.167 + , _timestamp(service->getTimestamp()) 1.168 + , _ids(uprv_deleteUObject, NULL, status) 1.169 + , _pos(0) 1.170 + { 1.171 + _service->getVisibleIDs(_ids, status); 1.172 + } 1.173 + 1.174 + ServiceEnumeration(const ServiceEnumeration &other, UErrorCode &status) 1.175 + : _service(other._service) 1.176 + , _timestamp(other._timestamp) 1.177 + , _ids(uprv_deleteUObject, NULL, status) 1.178 + , _pos(0) 1.179 + { 1.180 + if(U_SUCCESS(status)) { 1.181 + int32_t i, length; 1.182 + 1.183 + length = other._ids.size(); 1.184 + for(i = 0; i < length; ++i) { 1.185 + _ids.addElement(((UnicodeString *)other._ids.elementAt(i))->clone(), status); 1.186 + } 1.187 + 1.188 + if(U_SUCCESS(status)) { 1.189 + _pos = other._pos; 1.190 + } 1.191 + } 1.192 + } 1.193 + 1.194 +public: 1.195 + static ServiceEnumeration* create(const ICULocaleService* service) { 1.196 + UErrorCode status = U_ZERO_ERROR; 1.197 + ServiceEnumeration* result = new ServiceEnumeration(service, status); 1.198 + if (U_SUCCESS(status)) { 1.199 + return result; 1.200 + } 1.201 + delete result; 1.202 + return NULL; 1.203 + } 1.204 + 1.205 + virtual ~ServiceEnumeration(); 1.206 + 1.207 + virtual StringEnumeration *clone() const { 1.208 + UErrorCode status = U_ZERO_ERROR; 1.209 + ServiceEnumeration *cl = new ServiceEnumeration(*this, status); 1.210 + if(U_FAILURE(status)) { 1.211 + delete cl; 1.212 + cl = NULL; 1.213 + } 1.214 + return cl; 1.215 + } 1.216 + 1.217 + UBool upToDate(UErrorCode& status) const { 1.218 + if (U_SUCCESS(status)) { 1.219 + if (_timestamp == _service->getTimestamp()) { 1.220 + return TRUE; 1.221 + } 1.222 + status = U_ENUM_OUT_OF_SYNC_ERROR; 1.223 + } 1.224 + return FALSE; 1.225 + } 1.226 + 1.227 + virtual int32_t count(UErrorCode& status) const { 1.228 + return upToDate(status) ? _ids.size() : 0; 1.229 + } 1.230 + 1.231 + virtual const UnicodeString* snext(UErrorCode& status) { 1.232 + if (upToDate(status) && (_pos < _ids.size())) { 1.233 + return (const UnicodeString*)_ids[_pos++]; 1.234 + } 1.235 + return NULL; 1.236 + } 1.237 + 1.238 + virtual void reset(UErrorCode& status) { 1.239 + if (status == U_ENUM_OUT_OF_SYNC_ERROR) { 1.240 + status = U_ZERO_ERROR; 1.241 + } 1.242 + if (U_SUCCESS(status)) { 1.243 + _timestamp = _service->getTimestamp(); 1.244 + _pos = 0; 1.245 + _service->getVisibleIDs(_ids, status); 1.246 + } 1.247 + } 1.248 + 1.249 +public: 1.250 + static UClassID U_EXPORT2 getStaticClassID(void); 1.251 + virtual UClassID getDynamicClassID(void) const; 1.252 +}; 1.253 + 1.254 +ServiceEnumeration::~ServiceEnumeration() {} 1.255 + 1.256 +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceEnumeration) 1.257 + 1.258 +StringEnumeration* 1.259 +ICULocaleService::getAvailableLocales(void) const 1.260 +{ 1.261 + return ServiceEnumeration::create(this); 1.262 +} 1.263 + 1.264 +const UnicodeString& 1.265 +ICULocaleService::validateFallbackLocale() const 1.266 +{ 1.267 + const Locale& loc = Locale::getDefault(); 1.268 + ICULocaleService* ncThis = (ICULocaleService*)this; 1.269 + { 1.270 + Mutex mutex(&llock); 1.271 + if (loc != fallbackLocale) { 1.272 + ncThis->fallbackLocale = loc; 1.273 + LocaleUtility::initNameFromLocale(loc, ncThis->fallbackLocaleName); 1.274 + ncThis->clearServiceCache(); 1.275 + } 1.276 + } 1.277 + return fallbackLocaleName; 1.278 +} 1.279 + 1.280 +ICUServiceKey* 1.281 +ICULocaleService::createKey(const UnicodeString* id, UErrorCode& status) const 1.282 +{ 1.283 + return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), status); 1.284 +} 1.285 + 1.286 +ICUServiceKey* 1.287 +ICULocaleService::createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const 1.288 +{ 1.289 + return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), kind, status); 1.290 +} 1.291 + 1.292 +U_NAMESPACE_END 1.293 + 1.294 +/* !UCONFIG_NO_SERVICE */ 1.295 +#endif 1.296 + 1.297 +