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