/** * Returns an enumeration over the IDs of all the regions that are children of this region anywhere in the region * hierarchy and match the given type. This API may return an empty enumeration if this region doesn't have any * sub-regions that match the given type. For example, calling this method with region "150" (Europe) and type * "URGN_TERRITORY" returns a set containing all the territories in Europe ( "FR" (France) - "IT" (Italy) - "DE" (Germany) etc. ) */ StringEnumeration* Region::getContainedRegions( URegionType type, UErrorCode &status ) const { umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); // returns immediately if U_FAILURE(status) if (U_FAILURE(status)) { return NULL; } UVector *result = new UVector(NULL, uhash_compareChars, status); StringEnumeration *cr = getContainedRegions(status); for ( int32_t i = 0 ; i < cr->count(status) ; i++ ) { const char *id = cr->next(NULL,status); const Region *r = Region::getInstance(id,status); if ( r->getType() == type ) { result->addElement((void *)&r->idStr,status); } else { StringEnumeration *children = r->getContainedRegions(type, status); for ( int32_t j = 0 ; j < children->count(status) ; j++ ) { const char *id2 = children->next(NULL,status); const Region *r2 = Region::getInstance(id2,status); result->addElement((void *)&r2->idStr,status); } delete children; } } delete cr; StringEnumeration* resultEnumeration = new RegionNameEnumeration(result,status); delete result; return resultEnumeration; }
/** * Returns an enumeration over the IDs of all the regions that are children of this region anywhere in the region * hierarchy and match the given type. This API may return an empty enumeration if this region doesn't have any * sub-regions that match the given type. For example, calling this method with region "150" (Europe) and type * "URGN_TERRITORY" returns a set containing all the territories in Europe ( "FR" (France) - "IT" (Italy) - "DE" (Germany) etc. ) */ StringEnumeration* Region::getContainedRegions( URegionType type ) const { loadRegionData(); UErrorCode status = U_ZERO_ERROR; UVector *result = new UVector(NULL, uhash_compareChars, status); StringEnumeration *cr = getContainedRegions(); for ( int32_t i = 0 ; i < cr->count(status) ; i++ ) { const char *id = cr->next(NULL,status); const Region *r = Region::getInstance(id,status); if ( r->getType() == type ) { result->addElement((void *)&r->idStr,status); } else { StringEnumeration *children = r->getContainedRegions(type); for ( int32_t j = 0 ; j < children->count(status) ; j++ ) { const char *id2 = children->next(NULL,status); const Region *r2 = Region::getInstance(id2,status); result->addElement((void *)&r2->idStr,status); } delete children; } } delete cr; StringEnumeration* resultEnumeration = new RegionNameEnumeration(result,status); delete result; return resultEnumeration; }
status_t BLocaleRoster::GetAvailableTimeZonesForCountry(BMessage* timeZones, const char* countryCode) const { if (!timeZones) return B_BAD_VALUE; status_t status = B_OK; StringEnumeration* zoneList = TimeZone::createEnumeration(countryCode); // countryCode == NULL will yield all timezones not bound to a country UErrorCode icuStatus = U_ZERO_ERROR; int32 count = zoneList->count(icuStatus); if (U_SUCCESS(icuStatus)) { for (int i = 0; i < count; ++i) { const char* zoneID = zoneList->next(NULL, icuStatus); if (zoneID == NULL || !U_SUCCESS(icuStatus)) { status = B_ERROR; break; } timeZones->AddString("timeZone", zoneID); } } else status = B_ERROR; delete zoneList; return status; }
void TimeUnitFormat::checkConsistency(EStyle style, const char* key, UErrorCode& err) { if (U_FAILURE(err)) { return; } // there should be patterns for each plural rule in each time unit. // For each time unit, // for each plural rule, following is unit pattern fall-back rule: // ( for example: "one" hour ) // look for its unit pattern in its locale tree. // if pattern is not found in its own locale, such as de_DE, // look for the pattern in its parent, such as de, // keep looking till found or till root. // if the pattern is not found in root either, // fallback to plural count "other", // look for the pattern of "other" in the locale tree: // "de_DE" to "de" to "root". // If not found, fall back to value of // static variable DEFAULT_PATTERN_FOR_xxx, such as "{0} h". // // Following is consistency check to create pattern for each // plural rule in each time unit using above fall-back rule. // StringEnumeration* keywords = fPluralRules->getKeywords(err); if (U_SUCCESS(err)) { const char* pluralCount; while ((pluralCount = keywords->next(NULL, err)) != NULL) { if ( U_SUCCESS(err) ) { for (int32_t i = 0; i < TimeUnit::UTIMEUNIT_FIELD_COUNT; ++i) { // for each time unit, // get all the patterns for each plural rule in this locale. Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i]; if ( countToPatterns == NULL ) { countToPatterns = initHash(err); if (U_FAILURE(err)) { delete countToPatterns; return; } fTimeUnitToCountToPatterns[i] = countToPatterns; } MessageFormat** formatters = (MessageFormat**)countToPatterns->get(pluralCount); if( formatters == NULL || formatters[style] == NULL ) { // look through parents const char* localeName = fLocale.getName(); searchInLocaleChain(style, key, localeName, (TimeUnit::UTimeUnitFields)i, pluralCount, pluralCount, countToPatterns, err); } } } } } delete keywords; }
status_t BLocaleRoster::GetAvailableTimeZonesWithRegionInfo(BMessage* timeZones) const { if (!timeZones) return B_BAD_VALUE; status_t status = B_OK; UErrorCode icuStatus = U_ZERO_ERROR; StringEnumeration* zoneList = TimeZone::createTimeZoneIDEnumeration( UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, icuStatus); int32 count = zoneList->count(icuStatus); if (U_SUCCESS(icuStatus)) { for (int i = 0; i < count; ++i) { const char* zoneID = zoneList->next(NULL, icuStatus); if (zoneID == NULL || !U_SUCCESS(icuStatus)) { status = B_ERROR; break; } timeZones->AddString("timeZone", zoneID); char region[5]; icuStatus = U_ZERO_ERROR; TimeZone::getRegion(zoneID, region, 5, icuStatus); if (!U_SUCCESS(icuStatus)) { status = B_ERROR; break; } timeZones->AddString("region", region); } } else status = B_ERROR; delete zoneList; return status; }
void CurrencyPluralInfo::setupCurrencyPluralPattern(const Locale& loc, UErrorCode& status) { if (U_FAILURE(status)) { return; } fPluralCountToCurrencyUnitPattern = initHash(status); if (U_FAILURE(status)) { return; } UErrorCode ec = U_ZERO_ERROR; UResourceBundle *rb = ures_open(NULL, loc.getName(), &ec); UResourceBundle *numberPatterns = ures_getByKey(rb, gNumberPatternsTag, NULL, &ec); int32_t ptnLen; // TODO: 0 to be NumberFormat::fNumberStyle const UChar* numberStylePattern = ures_getStringByIndex(numberPatterns, 0, &ptnLen, &ec); int32_t numberStylePatternLen = ptnLen; const UChar* negNumberStylePattern = NULL; int32_t negNumberStylePatternLen = 0; // TODO: Java // parse to check whether there is ";" separator in the numberStylePattern UBool hasSeparator = false; if (U_SUCCESS(ec)) { for (int32_t styleCharIndex = 0; styleCharIndex < ptnLen; ++styleCharIndex) { if (numberStylePattern[styleCharIndex] == gNumberPatternSeparator) { hasSeparator = true; // split the number style pattern into positive and negative negNumberStylePattern = numberStylePattern + styleCharIndex + 1; negNumberStylePatternLen = ptnLen - styleCharIndex - 1; numberStylePatternLen = styleCharIndex; } } } ures_close(numberPatterns); if (U_FAILURE(ec)) { ures_close(rb); return; } UResourceBundle *currencyRes = ures_getByKeyWithFallback(rb, gCurrUnitPtnTag, NULL, &ec); #ifdef CURRENCY_PLURAL_INFO_DEBUG std::cout << "in set up\n"; #endif StringEnumeration* keywords = fPluralRules->getKeywords(ec); if (U_SUCCESS(ec)) { const char* pluralCount; while ((pluralCount = keywords->next(NULL, ec)) != NULL) { if ( U_SUCCESS(ec) ) { int32_t ptnLen; UErrorCode err = U_ZERO_ERROR; const UChar* patternChars = ures_getStringByKeyWithFallback( currencyRes, pluralCount, &ptnLen, &err); if (U_SUCCESS(err) && ptnLen > 0) { UnicodeString* pattern = new UnicodeString(patternChars, ptnLen); #ifdef CURRENCY_PLURAL_INFO_DEBUG char result_1[1000]; pattern->extract(0, pattern->length(), result_1, "UTF-8"); std::cout << "pluralCount: " << pluralCount << "; pattern: " << result_1 << "\n"; #endif pattern->findAndReplace(gPart0, UnicodeString(numberStylePattern, numberStylePatternLen)); pattern->findAndReplace(gPart1, gTripleCurrencySign); if (hasSeparator) { UnicodeString negPattern(patternChars, ptnLen); negPattern.findAndReplace(gPart0, UnicodeString(negNumberStylePattern, negNumberStylePatternLen)); negPattern.findAndReplace(gPart1, gTripleCurrencySign); pattern->append(gNumberPatternSeparator); pattern->append(negPattern); } #ifdef CURRENCY_PLURAL_INFO_DEBUG pattern->extract(0, pattern->length(), result_1, "UTF-8"); std::cout << "pluralCount: " << pluralCount << "; pattern: " << result_1 << "\n"; #endif fPluralCountToCurrencyUnitPattern->put(UnicodeString(pluralCount), pattern, status); } } } } delete keywords; ures_close(currencyRes); ures_close(rb); }
void CurrencyPluralInfo::setupCurrencyPluralPattern(const Locale& loc, UErrorCode& status) { if (U_FAILURE(status)) { return; } if (fPluralCountToCurrencyUnitPattern) { deleteHash(fPluralCountToCurrencyUnitPattern); } fPluralCountToCurrencyUnitPattern = initHash(status); if (U_FAILURE(status)) { return; } NumberingSystem *ns = NumberingSystem::createInstance(loc,status); UErrorCode ec = U_ZERO_ERROR; UResourceBundle *rb = ures_open(NULL, loc.getName(), &ec); UResourceBundle *numElements = ures_getByKeyWithFallback(rb, gNumberElementsTag, NULL, &ec); rb = ures_getByKeyWithFallback(numElements, ns->getName(), rb, &ec); rb = ures_getByKeyWithFallback(rb, gPatternsTag, rb, &ec); int32_t ptnLen; const UChar* numberStylePattern = ures_getStringByKeyWithFallback(rb, gDecimalFormatTag, &ptnLen, &ec); // Fall back to "latn" if num sys specific pattern isn't there. if ( ec == U_MISSING_RESOURCE_ERROR && uprv_strcmp(ns->getName(),gLatnTag)) { ec = U_ZERO_ERROR; rb = ures_getByKeyWithFallback(numElements, gLatnTag, rb, &ec); rb = ures_getByKeyWithFallback(rb, gPatternsTag, rb, &ec); numberStylePattern = ures_getStringByKeyWithFallback(rb, gDecimalFormatTag, &ptnLen, &ec); } int32_t numberStylePatternLen = ptnLen; const UChar* negNumberStylePattern = NULL; int32_t negNumberStylePatternLen = 0; // TODO: Java // parse to check whether there is ";" separator in the numberStylePattern UBool hasSeparator = false; if (U_SUCCESS(ec)) { for (int32_t styleCharIndex = 0; styleCharIndex < ptnLen; ++styleCharIndex) { if (numberStylePattern[styleCharIndex] == gNumberPatternSeparator) { hasSeparator = true; // split the number style pattern into positive and negative negNumberStylePattern = numberStylePattern + styleCharIndex + 1; negNumberStylePatternLen = ptnLen - styleCharIndex - 1; numberStylePatternLen = styleCharIndex; } } } ures_close(numElements); ures_close(rb); delete ns; if (U_FAILURE(ec)) { return; } UResourceBundle *currRb = ures_open(U_ICUDATA_CURR, loc.getName(), &ec); UResourceBundle *currencyRes = ures_getByKeyWithFallback(currRb, gCurrUnitPtnTag, NULL, &ec); #ifdef CURRENCY_PLURAL_INFO_DEBUG std::cout << "in set up\n"; #endif StringEnumeration* keywords = fPluralRules->getKeywords(ec); if (U_SUCCESS(ec)) { const char* pluralCount; while ((pluralCount = keywords->next(NULL, ec)) != NULL) { if ( U_SUCCESS(ec) ) { int32_t ptnLen; UErrorCode err = U_ZERO_ERROR; const UChar* patternChars = ures_getStringByKeyWithFallback( currencyRes, pluralCount, &ptnLen, &err); if (U_SUCCESS(err) && ptnLen > 0) { UnicodeString* pattern = new UnicodeString(patternChars, ptnLen); #ifdef CURRENCY_PLURAL_INFO_DEBUG char result_1[1000]; pattern->extract(0, pattern->length(), result_1, "UTF-8"); std::cout << "pluralCount: " << pluralCount << "; pattern: " << result_1 << "\n"; #endif pattern->findAndReplace(UnicodeString(TRUE, gPart0, 3), UnicodeString(numberStylePattern, numberStylePatternLen)); pattern->findAndReplace(UnicodeString(TRUE, gPart1, 3), UnicodeString(TRUE, gTripleCurrencySign, 3)); if (hasSeparator) { UnicodeString negPattern(patternChars, ptnLen); negPattern.findAndReplace(UnicodeString(TRUE, gPart0, 3), UnicodeString(negNumberStylePattern, negNumberStylePatternLen)); negPattern.findAndReplace(UnicodeString(TRUE, gPart1, 3), UnicodeString(TRUE, gTripleCurrencySign, 3)); pattern->append(gNumberPatternSeparator); pattern->append(negPattern); } #ifdef CURRENCY_PLURAL_INFO_DEBUG pattern->extract(0, pattern->length(), result_1, "UTF-8"); std::cout << "pluralCount: " << pluralCount << "; pattern: " << result_1 << "\n"; #endif fPluralCountToCurrencyUnitPattern->put(UnicodeString(pluralCount, -1, US_INV), pattern, status); } } } } delete keywords; ures_close(currencyRes); ures_close(currRb); }
UnicodeString& LocaleDisplayNamesImpl::localeDisplayName(const Locale& locale, UnicodeString& result) const { UnicodeString resultName; const char* lang = locale.getLanguage(); if (uprv_strlen(lang) == 0) { lang = "root"; } const char* script = locale.getScript(); const char* country = locale.getCountry(); const char* variant = locale.getVariant(); UBool hasScript = uprv_strlen(script) > 0; UBool hasCountry = uprv_strlen(country) > 0; UBool hasVariant = uprv_strlen(variant) > 0; if (dialectHandling == ULDN_DIALECT_NAMES) { char buffer[ULOC_FULLNAME_CAPACITY]; do { // loop construct is so we can break early out of search if (hasScript && hasCountry) { ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, "_", country, (char *)0); localeIdName(buffer, resultName); if (!resultName.isBogus()) { hasScript = FALSE; hasCountry = FALSE; break; } } if (hasScript) { ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, (char *)0); localeIdName(buffer, resultName); if (!resultName.isBogus()) { hasScript = FALSE; break; } } if (hasCountry) { ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", country, (char*)0); localeIdName(buffer, resultName); if (!resultName.isBogus()) { hasCountry = FALSE; break; } } } while (FALSE); } if (resultName.isBogus() || resultName.isEmpty()) { localeIdName(lang, resultName); } UnicodeString resultRemainder; UnicodeString temp; StringEnumeration *e = NULL; UErrorCode status = U_ZERO_ERROR; if (hasScript) { resultRemainder.append(scriptDisplayName(script, temp)); } if (hasCountry) { appendWithSep(resultRemainder, regionDisplayName(country, temp)); } if (hasVariant) { appendWithSep(resultRemainder, variantDisplayName(variant, temp)); } resultRemainder.findAndReplace(formatOpenParen, formatReplaceOpenParen); resultRemainder.findAndReplace(formatCloseParen, formatReplaceCloseParen); e = locale.createKeywords(status); if (e && U_SUCCESS(status)) { UnicodeString temp2; char value[ULOC_KEYWORD_AND_VALUES_CAPACITY]; // sigh, no ULOC_VALUE_CAPACITY const char* key; while ((key = e->next((int32_t *)0, status)) != NULL) { locale.getKeywordValue(key, value, ULOC_KEYWORD_AND_VALUES_CAPACITY, status); keyDisplayName(key, temp); temp.findAndReplace(formatOpenParen, formatReplaceOpenParen); temp.findAndReplace(formatCloseParen, formatReplaceCloseParen); keyValueDisplayName(key, value, temp2); temp2.findAndReplace(formatOpenParen, formatReplaceOpenParen); temp2.findAndReplace(formatCloseParen, formatReplaceCloseParen); if (temp2 != UnicodeString(value, -1, US_INV)) { appendWithSep(resultRemainder, temp2); } else if (temp != UnicodeString(key, -1, US_INV)) { UnicodeString temp3; Formattable data[] = { temp, temp2 }; FieldPosition fpos; status = U_ZERO_ERROR; keyTypeFormat->format(data, 2, temp3, fpos, status); appendWithSep(resultRemainder, temp3); } else { appendWithSep(resultRemainder, temp) .append((UChar)0x3d /* = */) .append(temp2); } } delete e; } if (!resultRemainder.isEmpty()) { Formattable data[] = { resultName, resultRemainder }; FieldPosition fpos; status = U_ZERO_ERROR; format->format(data, 2, result, fpos, status); return adjustForUsageAndContext(kCapContextUsageLanguage, result); } result = resultName; return adjustForUsageAndContext(kCapContextUsageLanguage, result); }
void PluralRulesTest::testAvailbleLocales() { // Hash set of (char *) strings. UErrorCode status = U_ZERO_ERROR; UHashtable *localeSet = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, uhash_compareLong, &status); uhash_setKeyDeleter(localeSet, uprv_deleteUObject); if (U_FAILURE(status)) { errln("file %s, line %d: Error status = %s", __FILE__, __LINE__, u_errorName(status)); return; } // Check that each locale returned by the iterator is unique. StringEnumeration *localesEnum = PluralRules::getAvailableLocales(status); int localeCount = 0; for (;;) { const char *locale = localesEnum->next(NULL, status); if (U_FAILURE(status)) { dataerrln("file %s, line %d: Error status = %s", __FILE__, __LINE__, u_errorName(status)); return; } if (locale == NULL) { break; } localeCount++; int32_t oldVal = uhash_puti(localeSet, new UnicodeString(locale), 1, &status); if (oldVal != 0) { errln("file %s, line %d: locale %s was seen before.", __FILE__, __LINE__, locale); } } // Reset the iterator, verify that we get the same count. localesEnum->reset(status); int32_t localeCount2 = 0; while (localesEnum->next(NULL, status) != NULL) { if (U_FAILURE(status)) { errln("file %s, line %d: Error status = %s", __FILE__, __LINE__, u_errorName(status)); break; } localeCount2++; } if (localeCount != localeCount2) { errln("file %s, line %d: locale counts differ. They are (%d, %d)", __FILE__, __LINE__, localeCount, localeCount2); } // Instantiate plural rules for each available locale. localesEnum->reset(status); for (;;) { status = U_ZERO_ERROR; const char *localeName = localesEnum->next(NULL, status); if (U_FAILURE(status)) { errln("file %s, line %d: Error status = %s, locale = %s", __FILE__, __LINE__, u_errorName(status), localeName); return; } if (localeName == NULL) { break; } Locale locale = Locale::createFromName(localeName); PluralRules *pr = PluralRules::forLocale(locale, status); if (U_FAILURE(status)) { errln("file %s, line %d: Error %s creating plural rules for locale %s", __FILE__, __LINE__, u_errorName(status), localeName); continue; } if (pr == NULL) { errln("file %s, line %d: Null plural rules for locale %s", __FILE__, __LINE__, localeName); continue; } // Pump some numbers through the plural rules. Can't check for correct results, // mostly this to tickle any asserts or crashes that may be lurking. for (double n=0; n<120.0; n+=0.5) { UnicodeString keyword = pr->select(n); if (keyword.length() == 0) { errln("file %s, line %d, empty keyword for n = %g, locale %s", __FILE__, __LINE__, n, localeName); } } delete pr; } uhash_close(localeSet); delete localesEnum; }