Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(661)

Unified Diff: source/i18n/locdspnm.cpp

Issue 845603002: Update ICU to 54.1 step 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@master
Patch Set: remove unusued directories Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/i18n/islamcal.cpp ('k') | source/i18n/measfmt.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/i18n/locdspnm.cpp
diff --git a/source/i18n/locdspnm.cpp b/source/i18n/locdspnm.cpp
index 30fb17db63db1732cad2f15a95eae39c6f2f4589..65ac4a3d90cd8a08335fd0d3042286dea1cd21e0 100644
--- a/source/i18n/locdspnm.cpp
+++ b/source/i18n/locdspnm.cpp
@@ -1,6 +1,6 @@
/*
*******************************************************************************
-* Copyright (C) 2010-2013, International Business Machines Corporation and
+* Copyright (C) 2010-2014, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
@@ -12,11 +12,14 @@
#include "unicode/locdspnm.h"
#include "unicode/msgfmt.h"
#include "unicode/ures.h"
+#include "unicode/udisplaycontext.h"
#include "unicode/brkiter.h"
#include "cmemory.h"
#include "cstring.h"
+#include "mutex.h"
#include "ulocimp.h"
+#include "umutex.h"
#include "ureslocs.h"
#include "uresimp.h"
@@ -275,10 +278,13 @@ class LocaleDisplayNamesImpl : public LocaleDisplayNames {
MessageFormat *format;
MessageFormat *keyTypeFormat;
UDisplayContext capitalizationContext;
+ BreakIterator* capitalizationBrkIter;
+ static UMutex capitalizationBrkIterLock;
UnicodeString formatOpenParen;
UnicodeString formatReplaceOpenParen;
UnicodeString formatCloseParen;
UnicodeString formatReplaceCloseParen;
+ UDisplayContext nameLength;
// Constants for capitalization context usage types.
enum CapContextUsage {
@@ -287,13 +293,12 @@ class LocaleDisplayNamesImpl : public LocaleDisplayNames {
kCapContextUsageTerritory,
kCapContextUsageVariant,
kCapContextUsageKey,
- kCapContextUsageType,
+ kCapContextUsageKeyValue,
kCapContextUsageCount
};
- // Capitalization transforms. For each usage type, the first array element indicates
- // whether to titlecase for uiListOrMenu context, the second indicates whether to
- // titlecase for stand-alone context.
- UBool fCapitalization[kCapContextUsageCount][2];
+ // Capitalization transforms. For each usage type, indicates whether to titlecase for
+ // the context specified in capitalizationContext (which we know at construction time)
+ UBool fCapitalization[kCapContextUsageCount];
public:
// constructor
@@ -332,6 +337,8 @@ private:
void initialize(void);
};
+UMutex LocaleDisplayNamesImpl::capitalizationBrkIterLock = U_MUTEX_INITIALIZER;
+
LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
UDialectHandling dialectHandling)
: dialectHandling(dialectHandling)
@@ -341,6 +348,8 @@ LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
, format(NULL)
, keyTypeFormat(NULL)
, capitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+ , capitalizationBrkIter(NULL)
+ , nameLength(UDISPCTX_LENGTH_FULL)
{
initialize();
}
@@ -354,6 +363,8 @@ LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
, format(NULL)
, keyTypeFormat(NULL)
, capitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+ , capitalizationBrkIter(NULL)
+ , nameLength(UDISPCTX_LENGTH_FULL)
{
while (length-- > 0) {
UDisplayContext value = *contexts++;
@@ -365,6 +376,9 @@ LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
case UDISPCTX_TYPE_CAPITALIZATION:
capitalizationContext = value;
break;
+ case UDISPCTX_TYPE_DISPLAY_LENGTH:
+ nameLength = value;
+ break;
default:
break;
}
@@ -422,42 +436,59 @@ LocaleDisplayNamesImpl::initialize(void) {
const ContextUsageNameToEnum contextUsageTypeMap[] = {
// Entries must be sorted by usageTypeName; entry with NULL name terminates list.
{ "key", kCapContextUsageKey },
+ { "keyValue", kCapContextUsageKeyValue },
{ "languages", kCapContextUsageLanguage },
{ "script", kCapContextUsageScript },
{ "territory", kCapContextUsageTerritory },
- { "type", kCapContextUsageType },
{ "variant", kCapContextUsageVariant },
{ NULL, (CapContextUsage)0 },
};
- int32_t len = 0;
- UResourceBundle *localeBundle = ures_open(NULL, locale.getName(), &status);
- if (U_SUCCESS(status)) {
- UResourceBundle *contextTransforms = ures_getByKeyWithFallback(localeBundle, "contextTransforms", NULL, &status);
+ // Only get the context data if we need it! This is a const object so we know now...
+ // Also check whether we will need a break iterator (depends on the data)
+ UBool needBrkIter = FALSE;
+ if (capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_STANDALONE) {
+ int32_t len = 0;
+ UResourceBundle *localeBundle = ures_open(NULL, locale.getName(), &status);
if (U_SUCCESS(status)) {
- UResourceBundle *contextTransformUsage;
- while ( (contextTransformUsage = ures_getNextResource(contextTransforms, NULL, &status)) != NULL ) {
- const int32_t * intVector = ures_getIntVector(contextTransformUsage, &len, &status);
- if (U_SUCCESS(status) && intVector != NULL && len >= 2) {
- const char* usageKey = ures_getKey(contextTransformUsage);
- if (usageKey != NULL) {
- const ContextUsageNameToEnum * typeMapPtr = contextUsageTypeMap;
- int32_t compResult = 0;
- // linear search; list is short and we cannot be sure that bsearch is available
- while ( typeMapPtr->usageName != NULL && (compResult = uprv_strcmp(usageKey, typeMapPtr->usageName)) > 0 ) {
- ++typeMapPtr;
- }
- if (typeMapPtr->usageName != NULL && compResult == 0) {
- fCapitalization[typeMapPtr->usageEnum][0] = intVector[0];
- fCapitalization[typeMapPtr->usageEnum][1] = intVector[1];
+ UResourceBundle *contextTransforms = ures_getByKeyWithFallback(localeBundle, "contextTransforms", NULL, &status);
+ if (U_SUCCESS(status)) {
+ UResourceBundle *contextTransformUsage;
+ while ( (contextTransformUsage = ures_getNextResource(contextTransforms, NULL, &status)) != NULL ) {
+ const int32_t * intVector = ures_getIntVector(contextTransformUsage, &len, &status);
+ if (U_SUCCESS(status) && intVector != NULL && len >= 2) {
+ const char* usageKey = ures_getKey(contextTransformUsage);
+ if (usageKey != NULL) {
+ const ContextUsageNameToEnum * typeMapPtr = contextUsageTypeMap;
+ int32_t compResult = 0;
+ // linear search; list is short and we cannot be sure that bsearch is available
+ while ( typeMapPtr->usageName != NULL && (compResult = uprv_strcmp(usageKey, typeMapPtr->usageName)) > 0 ) {
+ ++typeMapPtr;
+ }
+ if (typeMapPtr->usageName != NULL && compResult == 0) {
+ int32_t titlecaseInt = (capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU)? intVector[0]: intVector[1];
+ if (titlecaseInt != 0) {
+ fCapitalization[typeMapPtr->usageEnum] = TRUE;;
+ needBrkIter = TRUE;
+ }
+ }
}
}
+ status = U_ZERO_ERROR;
+ ures_close(contextTransformUsage);
}
- status = U_ZERO_ERROR;
- ures_close(contextTransformUsage);
+ ures_close(contextTransforms);
}
- ures_close(contextTransforms);
+ ures_close(localeBundle);
+ }
+ }
+ // Get a sentence break iterator if we will need it
+ if (needBrkIter || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE) {
+ status = U_ZERO_ERROR;
+ capitalizationBrkIter = BreakIterator::createSentenceInstance(locale, status);
+ if (U_FAILURE(status)) {
+ delete capitalizationBrkIter;
+ capitalizationBrkIter = NULL;
}
- ures_close(localeBundle);
}
#endif
}
@@ -466,6 +497,7 @@ LocaleDisplayNamesImpl::~LocaleDisplayNamesImpl() {
delete separatorFormat;
delete format;
delete keyTypeFormat;
+ delete capitalizationBrkIter;
}
const Locale&
@@ -485,6 +517,8 @@ LocaleDisplayNamesImpl::getContext(UDisplayContextType type) const {
return (UDisplayContext)dialectHandling;
case UDISPCTX_TYPE_CAPITALIZATION:
return capitalizationContext;
+ case UDISPCTX_TYPE_DISPLAY_LENGTH:
+ return nameLength;
default:
break;
}
@@ -496,51 +530,11 @@ LocaleDisplayNamesImpl::adjustForUsageAndContext(CapContextUsage usage,
UnicodeString& result) const {
#if !UCONFIG_NO_BREAK_ITERATION
// check to see whether we need to titlecase result
- UBool titlecase = FALSE;
- switch (capitalizationContext) {
- case UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE:
- titlecase = TRUE;
- break;
- case UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU:
- titlecase = fCapitalization[usage][0];
- break;
- case UDISPCTX_CAPITALIZATION_FOR_STANDALONE:
- titlecase = fCapitalization[usage][1];
- break;
- default:
- // titlecase = FALSE;
- break;
- }
- if (titlecase) {
- // TODO: Fix this titlecase hack when we figure out something better to do.
- // We don't want to titlecase the whole text, only something like the first word,
- // of the first segment long enough to have a complete cluster, whichever is
- // shorter. We could have keep a word break iterator around, but I am not sure
- // that will do the ight thing for the purposes here. For now we assume that in
- // languages for which titlecasing makes a difference, we can stop at non-letter
- // characters in 0x0000-0x00FF and only titlecase up to the first occurrence of
- // any of those, or to a small number of chars, whichever comes first.
- int32_t stopPos, stopPosLimit = 8, len = result.length();
- if ( stopPosLimit > len ) {
- stopPosLimit = len;
- }
- for ( stopPos = 0; stopPos < stopPosLimit; stopPos++ ) {
- UChar32 ch = result.char32At(stopPos);
- if ( (ch < 0x41) || (ch > 0x5A && ch < 0x61) || (ch > 0x7A && ch < 0xC0) ) {
- break;
- }
- if (ch >= 0x10000) {
- stopPos++;
- }
- }
- if ( stopPos > 0 && stopPos < len ) {
- UnicodeString firstWord(result, 0, stopPos);
- firstWord.toTitle(NULL, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
- result.replaceBetween(0, stopPos, firstWord);
- } else {
- // no stopPos, titlecase the whole text
- result.toTitle(NULL, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
- }
+ if ( result.length() > 0 && u_islower(result.char32At(0)) && 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
+ Mutex lock(&capitalizationBrkIterLock);
+ result.toTitle(capitalizationBrkIter, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
}
#endif
return result;
@@ -693,6 +687,12 @@ LocaleDisplayNamesImpl::localeDisplayName(const char* localeId,
UnicodeString&
LocaleDisplayNamesImpl::localeIdName(const char* localeId,
UnicodeString& result) const {
+ if (nameLength == UDISPCTX_LENGTH_SHORT) {
+ langData.getNoFallback("LanguagesShort", localeId, result);
+ if (!result.isBogus()) {
+ return result;
+ }
+ }
return langData.getNoFallback("Languages", localeId, result);
}
@@ -702,6 +702,12 @@ LocaleDisplayNamesImpl::languageDisplayName(const char* lang,
if (uprv_strcmp("root", lang) == 0 || uprv_strchr(lang, '_') != NULL) {
return result = UnicodeString(lang, -1, US_INV);
}
+ if (nameLength == UDISPCTX_LENGTH_SHORT) {
+ langData.get("LanguagesShort", lang, result);
+ if (!result.isBogus()) {
+ return adjustForUsageAndContext(kCapContextUsageLanguage, result);
+ }
+ }
langData.get("Languages", lang, result);
return adjustForUsageAndContext(kCapContextUsageLanguage, result);
}
@@ -709,6 +715,12 @@ LocaleDisplayNamesImpl::languageDisplayName(const char* lang,
UnicodeString&
LocaleDisplayNamesImpl::scriptDisplayName(const char* script,
UnicodeString& result) const {
+ if (nameLength == UDISPCTX_LENGTH_SHORT) {
+ langData.get("Scripts%short", script, result);
+ if (!result.isBogus()) {
+ return adjustForUsageAndContext(kCapContextUsageScript, result);
+ }
+ }
langData.get("Scripts", script, result);
return adjustForUsageAndContext(kCapContextUsageScript, result);
}
@@ -716,14 +728,18 @@ LocaleDisplayNamesImpl::scriptDisplayName(const char* script,
UnicodeString&
LocaleDisplayNamesImpl::scriptDisplayName(UScriptCode scriptCode,
UnicodeString& result) const {
- const char* name = uscript_getName(scriptCode);
- langData.get("Scripts", name, result);
- return adjustForUsageAndContext(kCapContextUsageScript, result);
+ return scriptDisplayName(uscript_getName(scriptCode), result);
}
UnicodeString&
LocaleDisplayNamesImpl::regionDisplayName(const char* region,
UnicodeString& result) const {
+ if (nameLength == UDISPCTX_LENGTH_SHORT) {
+ regionData.get("CountriesShort", region, result);
+ if (!result.isBogus()) {
+ return adjustForUsageAndContext(kCapContextUsageTerritory, result);
+ }
+ }
regionData.get("Countries", region, result);
return adjustForUsageAndContext(kCapContextUsageTerritory, result);
}
@@ -731,6 +747,7 @@ LocaleDisplayNamesImpl::regionDisplayName(const char* region,
UnicodeString&
LocaleDisplayNamesImpl::variantDisplayName(const char* variant,
UnicodeString& result) const {
+ // don't have a resource for short variant names
langData.get("Variants", variant, result);
return adjustForUsageAndContext(kCapContextUsageVariant, result);
}
@@ -738,6 +755,7 @@ LocaleDisplayNamesImpl::variantDisplayName(const char* variant,
UnicodeString&
LocaleDisplayNamesImpl::keyDisplayName(const char* key,
UnicodeString& result) const {
+ // don't have a resource for short key names
langData.get("Keys", key, result);
return adjustForUsageAndContext(kCapContextUsageKey, result);
}
@@ -746,8 +764,14 @@ UnicodeString&
LocaleDisplayNamesImpl::keyValueDisplayName(const char* key,
const char* value,
UnicodeString& result) const {
+ if (nameLength == UDISPCTX_LENGTH_SHORT) {
+ langData.get("Types%short", key, value, result);
+ if (!result.isBogus()) {
+ return adjustForUsageAndContext(kCapContextUsageKeyValue, result);
+ }
+ }
langData.get("Types", key, value, result);
- return adjustForUsageAndContext(kCapContextUsageType, result);
+ return adjustForUsageAndContext(kCapContextUsageKeyValue, result);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
« no previous file with comments | « source/i18n/islamcal.cpp ('k') | source/i18n/measfmt.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698