intl/icu/source/common/servls.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /**
michael@0 2 *******************************************************************************
michael@0 3 * Copyright (C) 2001-2012, International Business Machines Corporation and *
michael@0 4 * others. All Rights Reserved. *
michael@0 5 *******************************************************************************
michael@0 6 *
michael@0 7 *******************************************************************************
michael@0 8 */
michael@0 9 #include "unicode/utypes.h"
michael@0 10
michael@0 11 #if !UCONFIG_NO_SERVICE
michael@0 12
michael@0 13 #include "unicode/resbund.h"
michael@0 14 #include "uresimp.h"
michael@0 15 #include "cmemory.h"
michael@0 16 #include "servloc.h"
michael@0 17 #include "ustrfmt.h"
michael@0 18 #include "charstr.h"
michael@0 19 #include "ucln_cmn.h"
michael@0 20 #include "uassert.h"
michael@0 21
michael@0 22 #define UNDERSCORE_CHAR ((UChar)0x005f)
michael@0 23 #define AT_SIGN_CHAR ((UChar)64)
michael@0 24 #define PERIOD_CHAR ((UChar)46)
michael@0 25
michael@0 26 U_NAMESPACE_BEGIN
michael@0 27
michael@0 28 static UMutex llock = U_MUTEX_INITIALIZER;
michael@0 29 ICULocaleService::ICULocaleService()
michael@0 30 : fallbackLocale(Locale::getDefault())
michael@0 31 {
michael@0 32 }
michael@0 33
michael@0 34 ICULocaleService::ICULocaleService(const UnicodeString& dname)
michael@0 35 : ICUService(dname)
michael@0 36 , fallbackLocale(Locale::getDefault())
michael@0 37 {
michael@0 38 }
michael@0 39
michael@0 40 ICULocaleService::~ICULocaleService()
michael@0 41 {
michael@0 42 }
michael@0 43
michael@0 44 UObject*
michael@0 45 ICULocaleService::get(const Locale& locale, UErrorCode& status) const
michael@0 46 {
michael@0 47 return get(locale, LocaleKey::KIND_ANY, NULL, status);
michael@0 48 }
michael@0 49
michael@0 50 UObject*
michael@0 51 ICULocaleService::get(const Locale& locale, int32_t kind, UErrorCode& status) const
michael@0 52 {
michael@0 53 return get(locale, kind, NULL, status);
michael@0 54 }
michael@0 55
michael@0 56 UObject*
michael@0 57 ICULocaleService::get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const
michael@0 58 {
michael@0 59 return get(locale, LocaleKey::KIND_ANY, actualReturn, status);
michael@0 60 }
michael@0 61
michael@0 62 UObject*
michael@0 63 ICULocaleService::get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const
michael@0 64 {
michael@0 65 UObject* result = NULL;
michael@0 66 if (U_FAILURE(status)) {
michael@0 67 return result;
michael@0 68 }
michael@0 69
michael@0 70 UnicodeString locName(locale.getName(), -1, US_INV);
michael@0 71 if (locName.isBogus()) {
michael@0 72 status = U_MEMORY_ALLOCATION_ERROR;
michael@0 73 } else {
michael@0 74 ICUServiceKey* key = createKey(&locName, kind, status);
michael@0 75 if (key) {
michael@0 76 if (actualReturn == NULL) {
michael@0 77 result = getKey(*key, status);
michael@0 78 } else {
michael@0 79 UnicodeString temp;
michael@0 80 result = getKey(*key, &temp, status);
michael@0 81
michael@0 82 if (result != NULL) {
michael@0 83 key->parseSuffix(temp);
michael@0 84 LocaleUtility::initLocaleFromName(temp, *actualReturn);
michael@0 85 }
michael@0 86 }
michael@0 87 delete key;
michael@0 88 }
michael@0 89 }
michael@0 90 return result;
michael@0 91 }
michael@0 92
michael@0 93
michael@0 94 URegistryKey
michael@0 95 ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale,
michael@0 96 UBool visible, UErrorCode& status)
michael@0 97 {
michael@0 98 Locale loc;
michael@0 99 LocaleUtility::initLocaleFromName(locale, loc);
michael@0 100 return registerInstance(objToAdopt, loc, LocaleKey::KIND_ANY,
michael@0 101 visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE, status);
michael@0 102 }
michael@0 103
michael@0 104 URegistryKey
michael@0 105 ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status)
michael@0 106 {
michael@0 107 return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status);
michael@0 108 }
michael@0 109
michael@0 110 URegistryKey
michael@0 111 ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status)
michael@0 112 {
michael@0 113 return registerInstance(objToAdopt, locale, kind, LocaleKeyFactory::VISIBLE, status);
michael@0 114 }
michael@0 115
michael@0 116 URegistryKey
michael@0 117 ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status)
michael@0 118 {
michael@0 119 ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage);
michael@0 120 if (factory != NULL) {
michael@0 121 return registerFactory(factory, status);
michael@0 122 }
michael@0 123 delete objToAdopt;
michael@0 124 return NULL;
michael@0 125 }
michael@0 126
michael@0 127 #if 0
michael@0 128 URegistryKey
michael@0 129 ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UErrorCode& status)
michael@0 130 {
michael@0 131 return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status);
michael@0 132 }
michael@0 133
michael@0 134 URegistryKey
michael@0 135 ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status)
michael@0 136 {
michael@0 137 return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY,
michael@0 138 visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE,
michael@0 139 status);
michael@0 140 }
michael@0 141
michael@0 142 URegistryKey
michael@0 143 ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, int32_t kind, int32_t coverage, UErrorCode& status)
michael@0 144 {
michael@0 145 ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage);
michael@0 146 if (factory != NULL) {
michael@0 147 return registerFactory(factory, status);
michael@0 148 }
michael@0 149 delete objToAdopt;
michael@0 150 return NULL;
michael@0 151 }
michael@0 152 #endif
michael@0 153
michael@0 154 class ServiceEnumeration : public StringEnumeration {
michael@0 155 private:
michael@0 156 const ICULocaleService* _service;
michael@0 157 int32_t _timestamp;
michael@0 158 UVector _ids;
michael@0 159 int32_t _pos;
michael@0 160
michael@0 161 private:
michael@0 162 ServiceEnumeration(const ICULocaleService* service, UErrorCode &status)
michael@0 163 : _service(service)
michael@0 164 , _timestamp(service->getTimestamp())
michael@0 165 , _ids(uprv_deleteUObject, NULL, status)
michael@0 166 , _pos(0)
michael@0 167 {
michael@0 168 _service->getVisibleIDs(_ids, status);
michael@0 169 }
michael@0 170
michael@0 171 ServiceEnumeration(const ServiceEnumeration &other, UErrorCode &status)
michael@0 172 : _service(other._service)
michael@0 173 , _timestamp(other._timestamp)
michael@0 174 , _ids(uprv_deleteUObject, NULL, status)
michael@0 175 , _pos(0)
michael@0 176 {
michael@0 177 if(U_SUCCESS(status)) {
michael@0 178 int32_t i, length;
michael@0 179
michael@0 180 length = other._ids.size();
michael@0 181 for(i = 0; i < length; ++i) {
michael@0 182 _ids.addElement(((UnicodeString *)other._ids.elementAt(i))->clone(), status);
michael@0 183 }
michael@0 184
michael@0 185 if(U_SUCCESS(status)) {
michael@0 186 _pos = other._pos;
michael@0 187 }
michael@0 188 }
michael@0 189 }
michael@0 190
michael@0 191 public:
michael@0 192 static ServiceEnumeration* create(const ICULocaleService* service) {
michael@0 193 UErrorCode status = U_ZERO_ERROR;
michael@0 194 ServiceEnumeration* result = new ServiceEnumeration(service, status);
michael@0 195 if (U_SUCCESS(status)) {
michael@0 196 return result;
michael@0 197 }
michael@0 198 delete result;
michael@0 199 return NULL;
michael@0 200 }
michael@0 201
michael@0 202 virtual ~ServiceEnumeration();
michael@0 203
michael@0 204 virtual StringEnumeration *clone() const {
michael@0 205 UErrorCode status = U_ZERO_ERROR;
michael@0 206 ServiceEnumeration *cl = new ServiceEnumeration(*this, status);
michael@0 207 if(U_FAILURE(status)) {
michael@0 208 delete cl;
michael@0 209 cl = NULL;
michael@0 210 }
michael@0 211 return cl;
michael@0 212 }
michael@0 213
michael@0 214 UBool upToDate(UErrorCode& status) const {
michael@0 215 if (U_SUCCESS(status)) {
michael@0 216 if (_timestamp == _service->getTimestamp()) {
michael@0 217 return TRUE;
michael@0 218 }
michael@0 219 status = U_ENUM_OUT_OF_SYNC_ERROR;
michael@0 220 }
michael@0 221 return FALSE;
michael@0 222 }
michael@0 223
michael@0 224 virtual int32_t count(UErrorCode& status) const {
michael@0 225 return upToDate(status) ? _ids.size() : 0;
michael@0 226 }
michael@0 227
michael@0 228 virtual const UnicodeString* snext(UErrorCode& status) {
michael@0 229 if (upToDate(status) && (_pos < _ids.size())) {
michael@0 230 return (const UnicodeString*)_ids[_pos++];
michael@0 231 }
michael@0 232 return NULL;
michael@0 233 }
michael@0 234
michael@0 235 virtual void reset(UErrorCode& status) {
michael@0 236 if (status == U_ENUM_OUT_OF_SYNC_ERROR) {
michael@0 237 status = U_ZERO_ERROR;
michael@0 238 }
michael@0 239 if (U_SUCCESS(status)) {
michael@0 240 _timestamp = _service->getTimestamp();
michael@0 241 _pos = 0;
michael@0 242 _service->getVisibleIDs(_ids, status);
michael@0 243 }
michael@0 244 }
michael@0 245
michael@0 246 public:
michael@0 247 static UClassID U_EXPORT2 getStaticClassID(void);
michael@0 248 virtual UClassID getDynamicClassID(void) const;
michael@0 249 };
michael@0 250
michael@0 251 ServiceEnumeration::~ServiceEnumeration() {}
michael@0 252
michael@0 253 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceEnumeration)
michael@0 254
michael@0 255 StringEnumeration*
michael@0 256 ICULocaleService::getAvailableLocales(void) const
michael@0 257 {
michael@0 258 return ServiceEnumeration::create(this);
michael@0 259 }
michael@0 260
michael@0 261 const UnicodeString&
michael@0 262 ICULocaleService::validateFallbackLocale() const
michael@0 263 {
michael@0 264 const Locale& loc = Locale::getDefault();
michael@0 265 ICULocaleService* ncThis = (ICULocaleService*)this;
michael@0 266 {
michael@0 267 Mutex mutex(&llock);
michael@0 268 if (loc != fallbackLocale) {
michael@0 269 ncThis->fallbackLocale = loc;
michael@0 270 LocaleUtility::initNameFromLocale(loc, ncThis->fallbackLocaleName);
michael@0 271 ncThis->clearServiceCache();
michael@0 272 }
michael@0 273 }
michael@0 274 return fallbackLocaleName;
michael@0 275 }
michael@0 276
michael@0 277 ICUServiceKey*
michael@0 278 ICULocaleService::createKey(const UnicodeString* id, UErrorCode& status) const
michael@0 279 {
michael@0 280 return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), status);
michael@0 281 }
michael@0 282
michael@0 283 ICUServiceKey*
michael@0 284 ICULocaleService::createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const
michael@0 285 {
michael@0 286 return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), kind, status);
michael@0 287 }
michael@0 288
michael@0 289 U_NAMESPACE_END
michael@0 290
michael@0 291 /* !UCONFIG_NO_SERVICE */
michael@0 292 #endif
michael@0 293
michael@0 294

mercurial