| /** |
| ******************************************************************************* |
| * Copyright (C) 2001-2003, International Business Machines Corporation and * |
| * others. All Rights Reserved. * |
| ******************************************************************************* |
| * |
| ******************************************************************************* |
| */ |
| #include "unicode/utypes.h" |
| |
| #if !UCONFIG_NO_SERVICE |
| |
| #include "unicode/resbund.h" |
| #include "cmemory.h" |
| #include "iculserv.h" |
| #include "ustrfmt.h" |
| |
| U_NAMESPACE_BEGIN |
| |
| static Hashtable * LocaleUtility_cache = NULL; |
| |
| #define UNDERSCORE_CHAR ((UChar)0x005f) |
| |
| /* |
| ****************************************************************** |
| */ |
| |
| UnicodeString& |
| LocaleUtility::canonicalLocaleString(const UnicodeString* id, UnicodeString& result) |
| { |
| if (id == NULL) { |
| result.setToBogus(); |
| } else { |
| result = *id; |
| int32_t i = 0; |
| int32_t n = result.indexOf(UNDERSCORE_CHAR); |
| if (n < 0) { |
| n = result.length(); |
| } |
| for (; i < n; ++i) { |
| UChar c = result.charAt(i); |
| if (c >= 0x0041 && c <= 0x005a) { |
| c += 0x20; |
| result.setCharAt(i, c); |
| } |
| } |
| for (n = result.length(); i < n; ++i) { |
| UChar c = result.charAt(i); |
| if (c >= 0x0061 && c <= 0x007a) { |
| c -= 0x20; |
| result.setCharAt(i, c); |
| } |
| } |
| } |
| return result; |
| } |
| |
| Locale& |
| LocaleUtility::initLocaleFromName(const UnicodeString& id, Locale& result) |
| { |
| if (id.isBogus()) { |
| result.setToBogus(); |
| } else { |
| const int32_t BUFLEN = 128; // larger than ever needed |
| char buffer[BUFLEN]; |
| int len = id.extract(0, BUFLEN, buffer); |
| if (len >= BUFLEN) { |
| result.setToBogus(); |
| } else { |
| buffer[len] = '\0'; |
| result = Locale::createFromName(buffer); |
| } |
| } |
| return result; |
| } |
| |
| UnicodeString& |
| LocaleUtility::initNameFromLocale(const Locale& locale, UnicodeString& result) |
| { |
| if (locale.isBogus()) { |
| result.setToBogus(); |
| } else { |
| result.append(locale.getName()); |
| } |
| return result; |
| } |
| |
| const Hashtable* |
| LocaleUtility::getAvailableLocaleNames(const UnicodeString& /* bundleID */) |
| { |
| // have to ignore bundleID for the moment, since we don't have easy C++ api. |
| // assume it's the default bundle |
| |
| Hashtable* htp; |
| umtx_lock(NULL); |
| htp = LocaleUtility_cache; |
| umtx_unlock(NULL); |
| |
| if (htp == NULL) { |
| htp = new Hashtable(); |
| if (htp) { |
| UErrorCode status = U_ZERO_ERROR; |
| int32_t count = uloc_countAvailable(); |
| for (int32_t i = 0; i < count; ++i) { |
| UnicodeString temp(uloc_getAvailable(i), ""); |
| htp->put(temp, (void*)htp, status); |
| if (U_FAILURE(status)) { |
| delete htp; |
| return NULL; |
| } |
| } |
| umtx_lock(NULL); |
| if (LocaleUtility_cache == NULL) { |
| LocaleUtility_cache = htp; |
| htp = NULL; |
| } |
| umtx_unlock(NULL); |
| delete htp; |
| } |
| } |
| return LocaleUtility_cache; |
| } |
| |
| UBool |
| LocaleUtility::isFallbackOf(const UnicodeString& root, const UnicodeString& child) |
| { |
| return child.indexOf(root) == 0 && |
| (child.length() == root.length() || |
| child.charAt(root.length()) == UNDERSCORE_CHAR); |
| } |
| |
| UBool |
| LocaleUtility::cleanup(void) { |
| if (LocaleUtility_cache) { |
| delete LocaleUtility_cache; |
| LocaleUtility_cache = NULL; |
| } |
| return TRUE; |
| } |
| |
| /* |
| ****************************************************************** |
| */ |
| |
| const int32_t LocaleKey::KIND_ANY = -1; |
| |
| LocaleKey* |
| LocaleKey::createWithCanonicalFallback(const UnicodeString* primaryID, |
| const UnicodeString* canonicalFallbackID, |
| UErrorCode& status) |
| { |
| return LocaleKey::createWithCanonicalFallback(primaryID, canonicalFallbackID, KIND_ANY, status); |
| } |
| |
| LocaleKey* |
| LocaleKey::createWithCanonicalFallback(const UnicodeString* primaryID, |
| const UnicodeString* canonicalFallbackID, |
| int32_t kind, |
| UErrorCode& status) |
| { |
| if (primaryID == NULL || U_FAILURE(status)) { |
| return NULL; |
| } |
| UnicodeString canonicalPrimaryID; |
| LocaleUtility::canonicalLocaleString(primaryID, canonicalPrimaryID); |
| return new LocaleKey(*primaryID, canonicalPrimaryID, canonicalFallbackID, kind); |
| } |
| |
| LocaleKey::LocaleKey(const UnicodeString& primaryID, |
| const UnicodeString& canonicalPrimaryID, |
| const UnicodeString* canonicalFallbackID, |
| int32_t kind) |
| : ICUServiceKey(primaryID) |
| , _kind(kind) |
| , _primaryID(canonicalPrimaryID) |
| , _fallbackID() |
| , _currentID() |
| { |
| _fallbackID.setToBogus(); |
| if (_primaryID.length() != 0) { |
| if (canonicalFallbackID != NULL && _primaryID != *canonicalFallbackID) { |
| _fallbackID = *canonicalFallbackID; |
| } |
| } |
| |
| _currentID = _primaryID; |
| } |
| |
| UnicodeString& |
| LocaleKey::prefix(UnicodeString& result) const { |
| if (_kind != KIND_ANY) { |
| UChar buffer[64]; |
| uprv_itou(buffer, 64, _kind, 10, 0); |
| UnicodeString temp(buffer); |
| result.append(temp); |
| } |
| return result; |
| } |
| |
| int32_t |
| LocaleKey::kind() const { |
| return _kind; |
| } |
| |
| UnicodeString& |
| LocaleKey::canonicalID(UnicodeString& result) const { |
| return result.append(_primaryID); |
| } |
| |
| UnicodeString& |
| LocaleKey::currentID(UnicodeString& result) const { |
| if (!_currentID.isBogus()) { |
| result.append(_currentID); |
| } |
| return result; |
| } |
| |
| UnicodeString& |
| LocaleKey::currentDescriptor(UnicodeString& result) const { |
| if (!_currentID.isBogus()) { |
| prefix(result).append(PREFIX_DELIMITER).append(_currentID); |
| } else { |
| result.setToBogus(); |
| } |
| return result; |
| } |
| |
| Locale& |
| LocaleKey::canonicalLocale(Locale& result) const { |
| return LocaleUtility::initLocaleFromName(_primaryID, result); |
| } |
| |
| Locale& |
| LocaleKey::currentLocale(Locale& result) const { |
| return LocaleUtility::initLocaleFromName(_currentID, result); |
| } |
| |
| UBool |
| LocaleKey::fallback() { |
| if (!_currentID.isBogus()) { |
| int x = _currentID.lastIndexOf(UNDERSCORE_CHAR); |
| if (x != -1) { |
| _currentID.remove(x); // truncate current or fallback, whichever we're pointing to |
| return TRUE; |
| } |
| |
| if (!_fallbackID.isBogus()) { |
| _currentID = _fallbackID; |
| _fallbackID.setToBogus(); |
| return TRUE; |
| } |
| |
| if (_currentID.length() > 0) { |
| _currentID.remove(0); // completely truncate |
| return TRUE; |
| } |
| |
| _currentID.setToBogus(); |
| } |
| |
| return FALSE; |
| } |
| |
| UBool |
| LocaleKey::isFallbackOf(const UnicodeString& id) const { |
| UnicodeString temp(id); |
| parseSuffix(temp); |
| return temp.indexOf(_primaryID) == 0 && |
| (temp.length() == _primaryID.length() || |
| temp.charAt(_primaryID.length()) == UNDERSCORE_CHAR); |
| } |
| |
| #ifdef SERVICE_DEBUG |
| UnicodeString& |
| LocaleKey::debug(UnicodeString& result) const |
| { |
| ICUServiceKey::debug(result); |
| result.append(" kind: "); |
| result.append(_kind); |
| result.append(" primaryID: "); |
| result.append(_primaryID); |
| result.append(" fallbackID: "); |
| result.append(_fallbackID); |
| result.append(" currentID: "); |
| result.append(_currentID); |
| return result; |
| } |
| |
| UnicodeString& |
| LocaleKey::debugClass(UnicodeString& result) const |
| { |
| return result.append("LocaleKey "); |
| } |
| #endif |
| |
| UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LocaleKey) |
| |
| /* |
| ****************************************************************** |
| */ |
| |
| LocaleKeyFactory::LocaleKeyFactory(int32_t coverage) |
| : _name() |
| , _coverage(coverage) |
| { |
| } |
| |
| LocaleKeyFactory::LocaleKeyFactory(int32_t coverage, const UnicodeString& name) |
| : _name(name) |
| , _coverage(coverage) |
| { |
| } |
| |
| LocaleKeyFactory::~LocaleKeyFactory() { |
| } |
| |
| UObject* |
| LocaleKeyFactory::create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const { |
| if (handlesKey(key, status)) { |
| const LocaleKey& lkey = (const LocaleKey&)key; |
| int32_t kind = lkey.kind(); |
| Locale loc; |
| lkey.currentLocale(loc); |
| |
| return handleCreate(loc, kind, service, status); |
| } |
| return NULL; |
| } |
| |
| UBool |
| LocaleKeyFactory::handlesKey(const ICUServiceKey& key, UErrorCode& status) const { |
| const Hashtable* supported = getSupportedIDs(status); |
| if (supported) { |
| UnicodeString id; |
| key.currentID(id); |
| return supported->get(id) != NULL; |
| } |
| return FALSE; |
| } |
| |
| void |
| LocaleKeyFactory::updateVisibleIDs(Hashtable& result, UErrorCode& status) const { |
| const Hashtable* supported = getSupportedIDs(status); |
| if (supported) { |
| UBool visible = (_coverage & 0x1) == 0; |
| |
| const UHashElement* elem = NULL; |
| int32_t pos = 0; |
| while ((elem = supported->nextElement(pos)) != NULL) { |
| const UnicodeString& id = *((const UnicodeString*)elem->key.pointer); |
| if (!visible) { |
| result.remove(id); |
| } else { |
| result.put(id, (void*)this, status); // this is dummy non-void marker used for set semantics |
| if (U_FAILURE(status)) { |
| break; |
| } |
| } |
| } |
| } |
| } |
| |
| UnicodeString& |
| LocaleKeyFactory::getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const { |
| if ((_coverage & 0x1) == 0) { |
| UErrorCode status = U_ZERO_ERROR; |
| if (isSupportedID(id, status)) { |
| Locale loc; |
| LocaleUtility::initLocaleFromName(id, loc); |
| return loc.getDisplayName(locale, result); |
| } |
| } |
| result.setToBogus(); |
| return result; |
| } |
| |
| UObject* |
| LocaleKeyFactory::handleCreate(const Locale& /* loc */, |
| int32_t /* kind */, |
| const ICUService* /* service */, |
| UErrorCode& /* status */) const { |
| return NULL; |
| } |
| |
| UBool |
| LocaleKeyFactory::isSupportedID(const UnicodeString& id, UErrorCode& status) const { |
| const Hashtable* ids = getSupportedIDs(status); |
| return ids && ids->get(id); |
| } |
| |
| const Hashtable* |
| LocaleKeyFactory::getSupportedIDs(UErrorCode& /* status */) const { |
| return NULL; |
| } |
| |
| #ifdef SERVICE_DEBUG |
| UnicodeString& |
| LocaleKeyFactory::debug(UnicodeString& result) const |
| { |
| debugClass(result); |
| result.append(", name: "); |
| result.append(_name); |
| result.append(", coverage: "); |
| result.append(_coverage); |
| return result; |
| } |
| |
| UnicodeString& |
| LocaleKeyFactory::debugClass(UnicodeString& result) const |
| { |
| return result.append("LocaleKeyFactory"); |
| } |
| #endif |
| |
| UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LocaleKeyFactory) |
| |
| /* |
| ****************************************************************** |
| */ |
| |
| SimpleLocaleKeyFactory::SimpleLocaleKeyFactory(UObject* objToAdopt, |
| const UnicodeString& locale, |
| int32_t kind, |
| int32_t coverage) |
| : LocaleKeyFactory(coverage) |
| , _obj(objToAdopt) |
| , _id(locale) |
| , _kind(kind) |
| { |
| } |
| |
| SimpleLocaleKeyFactory::SimpleLocaleKeyFactory(UObject* objToAdopt, |
| const Locale& locale, |
| int32_t kind, |
| int32_t coverage) |
| : LocaleKeyFactory(coverage) |
| , _obj(objToAdopt) |
| , _id() |
| , _kind(kind) |
| { |
| LocaleUtility::initNameFromLocale(locale, _id); |
| } |
| |
| SimpleLocaleKeyFactory::~SimpleLocaleKeyFactory() |
| { |
| delete _obj; |
| _obj = NULL; |
| } |
| |
| UObject* |
| SimpleLocaleKeyFactory::create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const |
| { |
| if (U_SUCCESS(status)) { |
| const LocaleKey& lkey = (const LocaleKey&)key; |
| if (_kind == LocaleKey::KIND_ANY || _kind == lkey.kind()) { |
| UnicodeString keyID; |
| lkey.currentID(keyID); |
| if (_id == keyID) { |
| return service->cloneInstance(_obj); |
| } |
| } |
| } |
| return NULL; |
| } |
| |
| UBool |
| SimpleLocaleKeyFactory::isSupportedID(const UnicodeString& id, UErrorCode& /* status */) const |
| { |
| return id == _id; |
| } |
| |
| void |
| SimpleLocaleKeyFactory::updateVisibleIDs(Hashtable& result, UErrorCode& status) const |
| { |
| if (U_SUCCESS(status)) { |
| if (_coverage & 0x1) { |
| result.remove(_id); |
| } else { |
| result.put(_id, (void*)this, status); |
| } |
| } |
| } |
| |
| #ifdef SERVICE_DEBUG |
| UnicodeString& |
| SimpleLocaleKeyFactory::debug(UnicodeString& result) const |
| { |
| LocaleKeyFactory::debug(result); |
| result.append(", id: "); |
| result.append(_id); |
| result.append(", kind: "); |
| result.append(_kind); |
| return result; |
| } |
| |
| UnicodeString& |
| SimpleLocaleKeyFactory::debugClass(UnicodeString& result) const |
| { |
| return result.append("SimpleLocaleKeyFactory"); |
| } |
| #endif |
| |
| UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleLocaleKeyFactory) |
| |
| /* |
| ****************************************************************** |
| */ |
| |
| ICUResourceBundleFactory::ICUResourceBundleFactory() |
| : LocaleKeyFactory(VISIBLE) |
| , _bundleName() |
| { |
| } |
| |
| ICUResourceBundleFactory::ICUResourceBundleFactory(const UnicodeString& bundleName) |
| : LocaleKeyFactory(VISIBLE) |
| , _bundleName(bundleName) |
| { |
| } |
| |
| const Hashtable* |
| ICUResourceBundleFactory::getSupportedIDs(UErrorCode& status) const |
| { |
| if (U_SUCCESS(status)) { |
| return LocaleUtility::getAvailableLocaleNames(_bundleName); |
| } |
| return NULL; |
| } |
| |
| UObject* |
| ICUResourceBundleFactory::handleCreate(const Locale& loc, int32_t /* kind */, const ICUService* /* service */, UErrorCode& status) const |
| { |
| if (U_SUCCESS(status)) { |
| return new ResourceBundle(_bundleName, loc, status); |
| } |
| return NULL; |
| } |
| |
| #ifdef SERVICE_DEBUG |
| UnicodeString& |
| ICUResourceBundleFactory::debug(UnicodeString& result) const |
| { |
| LocaleKeyFactory::debug(result); |
| result.append(", bundle: "); |
| return result.append(_bundleName); |
| } |
| |
| UnicodeString& |
| ICUResourceBundleFactory::debugClass(UnicodeString& result) const |
| { |
| return result.append("ICUResourceBundleFactory"); |
| } |
| #endif |
| |
| UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ICUResourceBundleFactory) |
| |
| /* |
| ****************************************************************** |
| */ |
| |
| ICULocaleService::ICULocaleService() |
| : fallbackLocale(Locale::getDefault()) |
| , llock(0) |
| { |
| umtx_init(&llock); |
| } |
| |
| ICULocaleService::ICULocaleService(const UnicodeString& dname) |
| : ICUService(dname) |
| , fallbackLocale(Locale::getDefault()) |
| , llock(0) |
| { |
| umtx_init(&llock); |
| } |
| |
| ICULocaleService::~ICULocaleService() |
| { |
| umtx_destroy(&llock); |
| } |
| |
| UObject* |
| ICULocaleService::get(const Locale& locale, UErrorCode& status) const |
| { |
| return get(locale, LocaleKey::KIND_ANY, NULL, status); |
| } |
| |
| UObject* |
| ICULocaleService::get(const Locale& locale, int32_t kind, UErrorCode& status) const |
| { |
| return get(locale, kind, NULL, status); |
| } |
| |
| UObject* |
| ICULocaleService::get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const |
| { |
| return get(locale, LocaleKey::KIND_ANY, actualReturn, status); |
| } |
| |
| UObject* |
| ICULocaleService::get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const |
| { |
| UObject* result = NULL; |
| if (U_FAILURE(status)) { |
| return result; |
| } |
| |
| UnicodeString locName(locale.getName(), ""); |
| if (locName.isBogus()) { |
| status = U_MEMORY_ALLOCATION_ERROR; |
| } else { |
| ICUServiceKey* key = createKey(&locName, kind, status); |
| if (key) { |
| if (actualReturn == NULL) { |
| result = getKey(*key, status); |
| } else { |
| UnicodeString temp; |
| result = getKey(*key, &temp, status); |
| |
| if (result != NULL) { |
| key->parseSuffix(temp); |
| LocaleUtility::initLocaleFromName(temp, *actualReturn); |
| } |
| } |
| delete key; |
| } |
| } |
| return result; |
| } |
| |
| |
| URegistryKey |
| ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, |
| UBool visible, UErrorCode& status) |
| { |
| Locale loc; |
| LocaleUtility::initLocaleFromName(locale, loc); |
| return registerInstance(objToAdopt, loc, LocaleKey::KIND_ANY, |
| visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE, status); |
| } |
| |
| URegistryKey |
| ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status) |
| { |
| return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status); |
| } |
| |
| URegistryKey |
| ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status) |
| { |
| return registerInstance(objToAdopt, locale, kind, LocaleKeyFactory::VISIBLE, status); |
| } |
| |
| URegistryKey |
| ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status) |
| { |
| ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage); |
| if (factory != NULL) { |
| return registerFactory(factory, status); |
| } |
| delete objToAdopt; |
| return NULL; |
| } |
| |
| #if 0 |
| URegistryKey |
| ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UErrorCode& status) |
| { |
| return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status); |
| } |
| |
| URegistryKey |
| ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status) |
| { |
| return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, |
| visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE, |
| status); |
| } |
| |
| URegistryKey |
| ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, int32_t kind, int32_t coverage, UErrorCode& status) |
| { |
| ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage); |
| if (factory != NULL) { |
| return registerFactory(factory, status); |
| } |
| delete objToAdopt; |
| return NULL; |
| } |
| #endif |
| |
| class ServiceEnumeration : public StringEnumeration { |
| private: |
| const ICULocaleService* _service; |
| int32_t _timestamp; |
| UVector _ids; |
| int32_t _pos; |
| |
| private: |
| ServiceEnumeration(const ICULocaleService* service, UErrorCode &status) |
| : _service(service) |
| , _timestamp(service->getTimestamp()) |
| , _ids(uhash_deleteUnicodeString, NULL, status) |
| , _pos(0) |
| { |
| _service->getVisibleIDs(_ids, status); |
| } |
| |
| ServiceEnumeration(const ServiceEnumeration &other, UErrorCode &status) |
| : _service(other._service) |
| , _timestamp(other._timestamp) |
| , _ids(uhash_deleteUnicodeString, NULL, status) |
| , _pos(0) |
| { |
| if(U_SUCCESS(status)) { |
| int32_t i, length; |
| |
| length = other._ids.size(); |
| for(i = 0; i < length; ++i) { |
| _ids.addElement(((UnicodeString *)other._ids.elementAt(i))->clone(), status); |
| } |
| |
| if(U_SUCCESS(status)) { |
| _pos = other._pos; |
| } |
| } |
| } |
| |
| public: |
| static ServiceEnumeration* create(const ICULocaleService* service) { |
| UErrorCode status = U_ZERO_ERROR; |
| ServiceEnumeration* result = new ServiceEnumeration(service, status); |
| if (U_SUCCESS(status)) { |
| return result; |
| } |
| delete result; |
| return NULL; |
| } |
| |
| virtual ~ServiceEnumeration() {} |
| |
| virtual StringEnumeration *clone() const { |
| UErrorCode status = U_ZERO_ERROR; |
| ServiceEnumeration *cl = new ServiceEnumeration(*this, status); |
| if(U_FAILURE(status)) { |
| delete cl; |
| cl = NULL; |
| } |
| return cl; |
| } |
| |
| virtual int32_t count(UErrorCode& status) const { |
| return upToDate(status) ? _ids.size() : 0; |
| } |
| |
| const UnicodeString* snext(UErrorCode& status) { |
| if (upToDate(status) && (_pos < _ids.size())) { |
| return (const UnicodeString*)_ids[_pos++]; |
| } |
| return NULL; |
| } |
| |
| UBool upToDate(UErrorCode& status) const { |
| if (U_SUCCESS(status)) { |
| if (_timestamp == _service->getTimestamp()) { |
| return TRUE; |
| } |
| status = U_ENUM_OUT_OF_SYNC_ERROR; |
| } |
| return FALSE; |
| } |
| |
| void reset(UErrorCode& status) { |
| if (status == U_ENUM_OUT_OF_SYNC_ERROR) { |
| status = U_ZERO_ERROR; |
| } |
| if (U_SUCCESS(status)) { |
| _timestamp = _service->getTimestamp(); |
| _pos = 0; |
| _service->getVisibleIDs(_ids, status); |
| } |
| } |
| |
| public: |
| static UClassID getStaticClassID(void); |
| virtual UClassID getDynamicClassID(void) const; |
| }; |
| |
| UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceEnumeration) |
| |
| StringEnumeration* |
| ICULocaleService::getAvailableLocales(void) const |
| { |
| return ServiceEnumeration::create(this); |
| } |
| |
| const UnicodeString& |
| ICULocaleService::validateFallbackLocale() const |
| { |
| const Locale& loc = Locale::getDefault(); |
| ICULocaleService* ncThis = (ICULocaleService*)this; |
| { |
| Mutex mutex(&ncThis->llock); |
| if (loc != fallbackLocale) { |
| ncThis->fallbackLocale = loc; |
| LocaleUtility::initNameFromLocale(loc, ncThis->fallbackLocaleName); |
| ncThis->clearServiceCache(); |
| } |
| } |
| return fallbackLocaleName; |
| } |
| |
| ICUServiceKey* |
| ICULocaleService::createKey(const UnicodeString* id, UErrorCode& status) const |
| { |
| return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), status); |
| } |
| |
| ICUServiceKey* |
| ICULocaleService::createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const |
| { |
| return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), kind, status); |
| } |
| |
| U_NAMESPACE_END |
| |
| // defined in ucln_cmn.h |
| |
| /** |
| * Release all static memory held by Locale Utility. |
| */ |
| U_CFUNC UBool service_cleanup(void) { |
| return LocaleUtility::cleanup(); |
| } |
| |
| /* !UCONFIG_NO_SERVICE */ |
| #endif |
| |
| |