UnicodeString formatReplaceCloseParen;
UnicodeString formatParenCloseOpen;
UDisplayContext nameLength;
+ UDisplayContext substitute;
// Constants for capitalization context usage types.
enum CapContextUsage {
UnicodeString& result) const;
private:
UnicodeString& localeIdName(const char* localeId,
- UnicodeString& result) const;
+ UnicodeString& result, bool substitute) const;
UnicodeString& regionShortDisplayName(const char* region, // Apple-specific
UnicodeString& result) const;
UnicodeString& appendWithSep(UnicodeString& buffer, const UnicodeString& src) const;
, capitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
, capitalizationBrkIter(NULL)
, nameLength(UDISPCTX_LENGTH_FULL)
+ , substitute(UDISPCTX_SUBSTITUTE)
{
initialize();
}
, capitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
, capitalizationBrkIter(NULL)
, nameLength(UDISPCTX_LENGTH_FULL)
+ , substitute(UDISPCTX_SUBSTITUTE)
{
while (length-- > 0) {
UDisplayContext value = *contexts++;
case UDISPCTX_TYPE_DISPLAY_LENGTH:
nameLength = value;
break;
+ case UDISPCTX_TYPE_SUBSTITUTE_HANDLING:
+ substitute = value;
+ break;
case UADISPCTX_TYPE_LENGTH: // Apple-specific
nameLength = (value == UADISPCTX_LENGTH_SHORT)? UDISPCTX_LENGTH_SHORT: UDISPCTX_LENGTH_FULL;
break;
return capitalizationContext;
case UDISPCTX_TYPE_DISPLAY_LENGTH:
return nameLength;
+ case UDISPCTX_TYPE_SUBSTITUTE_HANDLING:
+ return substitute;
case UADISPCTX_TYPE_LENGTH: // Apple-specific
return (nameLength == UDISPCTX_LENGTH_SHORT)? UADISPCTX_LENGTH_SHORT: UADISPCTX_LENGTH_STANDARD;
default:
LocaleDisplayNamesImpl::adjustForUsageAndContext(CapContextUsage usage,
UnicodeString& result) const {
#if !UCONFIG_NO_BREAK_ITERATION
- // check to see whether we need to titlecase result
- if ( result.length() > 0 && u_islower(result.char32At(0)) && capitalizationBrkIter!= NULL &&
+ // check to see whether we need to titlecase result-- we check the first word (up to the first space),
+ // and only titlecase the result if that first word contains no capital letters
+ UBool needToTitlecase = TRUE;
+ for (int32_t i = 0; needToTitlecase && i < result.length(); i++) {
+ UChar32 c = result.char32At(i);
+ if (u_isupper(c) || u_istitle(c)) {
+ needToTitlecase = FALSE;
+ } else if (u_isspace(c)) {
+ break;
+ }
+ }
+
+ if (needToTitlecase && capitalizationBrkIter!= NULL &&
( capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE || fCapitalization[usage] ) ) {
// note fCapitalization[usage] won't be set unless capitalizationContext is UI_LIST_OR_MENU or STANDALONE
- static UMutex *capitalizationBrkIterLock = STATIC_NEW(UMutex);
- Mutex lock(capitalizationBrkIterLock);
+ static UMutex capitalizationBrkIterLock;
+ Mutex lock(&capitalizationBrkIterLock);
result.toTitle(capitalizationBrkIter, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
}
#endif
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);
+ localeIdName(buffer, resultName, false);
if (!resultName.isBogus()) {
hasScript = FALSE;
hasCountry = FALSE;
}
if (hasScript) {
ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, (char *)0);
- localeIdName(buffer, resultName);
+ localeIdName(buffer, resultName, false);
if (!resultName.isBogus()) {
hasScript = FALSE;
break;
}
if (hasCountry) {
ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", country, (char*)0);
- localeIdName(buffer, resultName);
+ localeIdName(buffer, resultName, false);
if (!resultName.isBogus()) {
hasCountry = FALSE;
break;
} while (FALSE);
}
if (resultName.isBogus() || resultName.isEmpty()) {
- localeIdName(lang, resultName);
+ localeIdName(lang, resultName, substitute == UDISPCTX_SUBSTITUTE);
+ if (resultName.isBogus()) {
+ result.setToBogus();
+ return result;
+ }
}
UnicodeString resultRemainder;
UErrorCode status = U_ZERO_ERROR;
if (hasScript) {
- resultRemainder.append(scriptDisplayName(script, temp, TRUE));
+ UnicodeString script_str = scriptDisplayName(script, temp, TRUE);
+ if (script_str.isBogus()) {
+ result.setToBogus();
+ return result;
+ }
+ resultRemainder.append(script_str);
}
if (hasCountry) {
- appendWithSep(resultRemainder, regionShortDisplayName(country, temp)); // Apple modification
+ UnicodeString region_str = regionShortDisplayName(country, temp); // Apple modification
+ if (region_str.isBogus()) {
+ result.setToBogus();
+ return result;
+ }
+ appendWithSep(resultRemainder, region_str);
}
if (hasVariant) {
- appendWithSep(resultRemainder, variantDisplayName(variant, temp, TRUE));
+ UnicodeString variant_str = variantDisplayName(variant, temp, TRUE);
+ if (variant_str.isBogus()) {
+ result.setToBogus();
+ return result;
+ }
+ appendWithSep(resultRemainder, variant_str);
}
resultRemainder.findAndReplace(formatOpenParen, formatReplaceOpenParen);
resultRemainder.findAndReplace(formatCloseParen, formatReplaceCloseParen);
// private
UnicodeString&
LocaleDisplayNamesImpl::localeIdName(const char* localeId,
- UnicodeString& result) const {
+ UnicodeString& result, bool substitute) const {
if (nameLength == UDISPCTX_LENGTH_SHORT) {
langData.getNoFallback("Languages%short", localeId, result);
if (!result.isBogus()) {
return result;
}
}
- return langData.getNoFallback("Languages", localeId, result);
+ if (substitute) {
+ return langData.get("Languages", localeId, result);
+ } else {
+ return langData.getNoFallback("Languages", localeId, result);
+ }
}
UnicodeString&
return adjustForUsageAndContext(kCapContextUsageLanguage, result);
}
}
- langData.get("Languages", lang, result);
+ if (substitute == UDISPCTX_SUBSTITUTE) {
+ langData.get("Languages", lang, result);
+ } else {
+ langData.getNoFallback("Languages", lang, result);
+ }
return adjustForUsageAndContext(kCapContextUsageLanguage, result);
}
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageScript, result);
}
}
- langData.get("Scripts", script, result);
+ if (substitute == UDISPCTX_SUBSTITUTE) {
+ langData.get("Scripts", script, result);
+ } else {
+ langData.getNoFallback("Scripts", script, result);
+ }
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageScript, result);
}
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageTerritory, result);
}
}
- regionData.get("Countries", region, result);
+ if (substitute == UDISPCTX_SUBSTITUTE) {
+ regionData.get("Countries", region, result);
+ } else {
+ regionData.getNoFallback("Countries", region, result);
+ }
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageTerritory, result);
}
return result;
}
}
- regionData.get("Countries", region, result);
+ if (substitute == UDISPCTX_SUBSTITUTE) {
+ regionData.get("Countries", region, result);
+ } else {
+ regionData.getNoFallback("Countries", region, result);
+ }
return result;
}
UnicodeString& result,
UBool skipAdjust) const {
// don't have a resource for short variant names
- langData.get("Variants", variant, result);
+ if (substitute == UDISPCTX_SUBSTITUTE) {
+ langData.get("Variants", variant, result);
+ } else {
+ langData.getNoFallback("Variants", variant, result);
+ }
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageVariant, result);
}
UnicodeString& result,
UBool skipAdjust) const {
// don't have a resource for short key names
- langData.get("Keys", key, result);
+ if (substitute == UDISPCTX_SUBSTITUTE) {
+ langData.get("Keys", key, result);
+ } else {
+ langData.getNoFallback("Keys", key, result);
+ }
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKey, result);
}
UErrorCode sts = U_ZERO_ERROR;
UnicodeString ustrValue(value, -1, US_INV);
int32_t len;
- UBool isChoice = FALSE;
const UChar *currencyName = ucurr_getName(ustrValue.getTerminatedBuffer(),
- locale.getBaseName(), UCURR_LONG_NAME, &isChoice, &len, &sts);
+ locale.getBaseName(), UCURR_LONG_NAME, nullptr /* isChoiceFormat */, &len, &sts);
if (U_FAILURE(sts)) {
// Return the value as is on failure
result = ustrValue;
}
if (nameLength == UDISPCTX_LENGTH_SHORT) {
- langData.get("Types%short", key, value, result);
+ langData.getNoFallback("Types%short", key, value, result);
if (!result.isBogus()) {
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKeyValue, result);
}
}
- langData.get("Types", key, value, result);
+ if (substitute == UDISPCTX_SUBSTITUTE) {
+ langData.get("Types", key, value, result);
+ } else {
+ langData.getNoFallback("Types", key, value, result);
+ }
return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKeyValue, result);
}