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(), -1, US_INV); 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; }
UnicodeString& ICUService::getDisplayName(const UnicodeString& id, UnicodeString& result, const Locale& locale) const { { UErrorCode status = U_ZERO_ERROR; Mutex mutex(&lock); const Hashtable* map = getVisibleIDMap(status); if (map != NULL) { ICUServiceFactory* f = (ICUServiceFactory*)map->get(id); if (f != NULL) { f->getDisplayName(id, locale, result); return result; } // fallback UErrorCode status = U_ZERO_ERROR; ICUServiceKey* fallbackKey = createKey(&id, status); while (fallbackKey->fallback()) { UnicodeString us; fallbackKey->currentID(us); f = (ICUServiceFactory*)map->get(us); if (f != NULL) { f->getDisplayName(id, locale, result); delete fallbackKey; return result; } } delete fallbackKey; } } result.setToBogus(); return result; }
UVector& ICUService::getVisibleIDs(UVector& result, const UnicodeString* matchID, UErrorCode& status) const { result.removeAllElements(); if (U_FAILURE(status)) { return result; } ICUService * ncthis = (ICUService*)this; // cast away semantic const { Mutex mutex(&ncthis->lock); const Hashtable* map = getVisibleIDMap(status); if (map != NULL) { ICUServiceKey* fallbackKey = createKey(matchID, status); for (int32_t pos = -1;;) { const UHashElement* e = map->nextElement(pos); if (e == NULL) { break; } const UnicodeString* id = (const UnicodeString*)e->key.pointer; if (fallbackKey != NULL) { if (!fallbackKey->isFallbackOf(*id)) { continue; } } UnicodeString* idClone = new UnicodeString(*id); if (idClone == NULL || idClone->isBogus()) { delete idClone; status = U_MEMORY_ALLOCATION_ERROR; break; } result.addElement(idClone, status); if (U_FAILURE(status)) { delete idClone; break; } } delete fallbackKey; } } if (U_FAILURE(status)) { result.removeAllElements(); } return result; }
URegistryKey ICUService::registerInstance(UObject* objToAdopt, const UnicodeString& id, UBool visible, UErrorCode& status) { ICUServiceKey* key = createKey(&id, status); if (key != NULL) { UnicodeString canonicalID; key->canonicalID(canonicalID); delete key; ICUServiceFactory* f = createSimpleFactory(objToAdopt, canonicalID, visible, status); if (f != NULL) { return registerFactory(f, status); } } delete objToAdopt; 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; }
UVector& ICUService::getDisplayNames(UVector& result, const Locale& locale, const UnicodeString* matchID, UErrorCode& status) const { result.removeAllElements(); result.setDeleter(userv_deleteStringPair); if (U_SUCCESS(status)) { ICUService* ncthis = (ICUService*)this; // cast away semantic const Mutex mutex(&lock); if (dnCache != NULL && dnCache->locale != locale) { delete dnCache; ncthis->dnCache = NULL; } if (dnCache == NULL) { const Hashtable* m = getVisibleIDMap(status); if (U_FAILURE(status)) { return result; } ncthis->dnCache = new DNCache(locale); if (dnCache == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return result; } int32_t pos = UHASH_FIRST; const UHashElement* entry = NULL; while ((entry = m->nextElement(pos)) != NULL) { const UnicodeString* id = (const UnicodeString*)entry->key.pointer; ICUServiceFactory* f = (ICUServiceFactory*)entry->value.pointer; UnicodeString dname; f->getDisplayName(*id, locale, dname); if (dname.isBogus()) { status = U_MEMORY_ALLOCATION_ERROR; } else { dnCache->cache.put(dname, (void*)id, status); // share pointer with visibleIDMap if (U_SUCCESS(status)) { continue; } } delete dnCache; ncthis->dnCache = NULL; return result; } } } ICUServiceKey* matchKey = createKey(matchID, status); /* To ensure that all elements in the hashtable are iterated, set pos to -1. * nextElement(pos) will skip the position at pos and begin the iteration * at the next position, which in this case will be 0. */ int32_t pos = UHASH_FIRST; const UHashElement *entry = NULL; while ((entry = dnCache->cache.nextElement(pos)) != NULL) { const UnicodeString* id = (const UnicodeString*)entry->value.pointer; if (matchKey != NULL && !matchKey->isFallbackOf(*id)) { continue; } const UnicodeString* dn = (const UnicodeString*)entry->key.pointer; StringPair* sp = StringPair::create(*id, *dn, status); result.addElement(sp, status); if (U_FAILURE(status)) { result.removeAllElements(); break; } } delete matchKey; return result; }