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

Unified Diff: source/common/locdspnm.cpp

Issue 2440913002: Update ICU to 58.1
Patch Set: Created 4 years, 2 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/common/locdispnames.cpp ('k') | source/common/locid.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/common/locdspnm.cpp
diff --git a/source/i18n/locdspnm.cpp b/source/common/locdspnm.cpp
similarity index 82%
rename from source/i18n/locdspnm.cpp
rename to source/common/locdspnm.cpp
index c0934cd5dc816b6205736c4fe593138312d7d613..a17478ce6d8a611b8ad75d573af7efa74d2518d4 100644
--- a/source/i18n/locdspnm.cpp
+++ b/source/common/locdspnm.cpp
@@ -1,6 +1,8 @@
+// Copyright (C) 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
-* Copyright (C) 2010-2014, International Business Machines Corporation and
+* Copyright (C) 2010-2016, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
@@ -10,11 +12,11 @@
#if !UCONFIG_NO_FORMATTING
#include "unicode/locdspnm.h"
-#include "unicode/msgfmt.h"
+#include "unicode/simpleformatter.h"
#include "unicode/ures.h"
-#include "unicode/udisplaycontext.h"
+#include "unicode/udisplaycontext.h"
#include "unicode/brkiter.h"
-
+#include "unicode/ucurr.h"
#include "cmemory.h"
#include "cstring.h"
#include "mutex.h"
@@ -274,11 +276,15 @@ class LocaleDisplayNamesImpl : public LocaleDisplayNames {
UDialectHandling dialectHandling;
ICUDataTable langData;
ICUDataTable regionData;
- MessageFormat *separatorFormat;
- MessageFormat *format;
- MessageFormat *keyTypeFormat;
+ SimpleFormatter separatorFormat;
+ SimpleFormatter format;
+ SimpleFormatter keyTypeFormat;
UDisplayContext capitalizationContext;
- BreakIterator* capitalizationBrkIter;
+#if !UCONFIG_NO_BREAK_ITERATION
+ BreakIterator* capitalizationBrkIter;
+#else
+ UObject* capitalizationBrkIter;
+#endif
static UMutex capitalizationBrkIterLock;
UnicodeString formatOpenParen;
UnicodeString formatReplaceOpenParen;
@@ -334,7 +340,15 @@ private:
UnicodeString& result) const;
UnicodeString& appendWithSep(UnicodeString& buffer, const UnicodeString& src) const;
UnicodeString& adjustForUsageAndContext(CapContextUsage usage, UnicodeString& result) const;
+ UnicodeString& scriptDisplayName(const char* script, UnicodeString& result, UBool skipAdjust) const;
+ UnicodeString& regionDisplayName(const char* region, UnicodeString& result, UBool skipAdjust) const;
+ UnicodeString& variantDisplayName(const char* variant, UnicodeString& result, UBool skipAdjust) const;
+ UnicodeString& keyDisplayName(const char* key, UnicodeString& result, UBool skipAdjust) const;
+ UnicodeString& keyValueDisplayName(const char* key, const char* value,
+ UnicodeString& result, UBool skipAdjust) const;
void initialize(void);
+
+ struct CapitalizationContextSink;
};
UMutex LocaleDisplayNamesImpl::capitalizationBrkIterLock = U_MUTEX_INITIALIZER;
@@ -344,9 +358,6 @@ LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
: dialectHandling(dialectHandling)
, langData(U_ICUDATA_LANG, locale)
, regionData(U_ICUDATA_REGION, locale)
- , separatorFormat(NULL)
- , format(NULL)
- , keyTypeFormat(NULL)
, capitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
, capitalizationBrkIter(NULL)
, nameLength(UDISPCTX_LENGTH_FULL)
@@ -359,9 +370,6 @@ LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
: dialectHandling(ULDN_STANDARD_NAMES)
, langData(U_ICUDATA_LANG, locale)
, regionData(U_ICUDATA_REGION, locale)
- , separatorFormat(NULL)
- , format(NULL)
- , keyTypeFormat(NULL)
, capitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
, capitalizationBrkIter(NULL)
, nameLength(UDISPCTX_LENGTH_FULL)
@@ -386,6 +394,54 @@ LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
initialize();
}
+struct LocaleDisplayNamesImpl::CapitalizationContextSink : public ResourceSink {
+ UBool hasCapitalizationUsage;
+ LocaleDisplayNamesImpl& parent;
+
+ CapitalizationContextSink(LocaleDisplayNamesImpl& _parent)
+ : hasCapitalizationUsage(FALSE), parent(_parent) {}
+ virtual ~CapitalizationContextSink();
+
+ virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/,
+ UErrorCode &errorCode) {
+ ResourceTable contexts = value.getTable(errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+ for (int i = 0; contexts.getKeyAndValue(i, key, value); ++i) {
+
+ CapContextUsage usageEnum;
+ if (uprv_strcmp(key, "key") == 0) {
+ usageEnum = kCapContextUsageKey;
+ } else if (uprv_strcmp(key, "keyValue") == 0) {
+ usageEnum = kCapContextUsageKeyValue;
+ } else if (uprv_strcmp(key, "languages") == 0) {
+ usageEnum = kCapContextUsageLanguage;
+ } else if (uprv_strcmp(key, "script") == 0) {
+ usageEnum = kCapContextUsageScript;
+ } else if (uprv_strcmp(key, "territory") == 0) {
+ usageEnum = kCapContextUsageTerritory;
+ } else if (uprv_strcmp(key, "variant") == 0) {
+ usageEnum = kCapContextUsageVariant;
+ } else {
+ continue;
+ }
+
+ int32_t len = 0;
+ const int32_t* intVector = value.getIntVector(len, errorCode);
+ if (U_FAILURE(errorCode)) { return; }
+ if (len < 2) { continue; }
+
+ int32_t titlecaseInt = (parent.capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU) ? intVector[0] : intVector[1];
+ if (titlecaseInt == 0) { continue; }
+
+ parent.fCapitalization[usageEnum] = TRUE;
+ hasCapitalizationUsage = TRUE;
+ }
+ }
+};
+
+// Virtual destructors must be defined out of line.
+LocaleDisplayNamesImpl::CapitalizationContextSink::~CapitalizationContextSink() {}
+
void
LocaleDisplayNamesImpl::initialize(void) {
LocaleDisplayNamesImpl *nonConstThis = (LocaleDisplayNamesImpl *)this;
@@ -399,14 +455,14 @@ LocaleDisplayNamesImpl::initialize(void) {
sep = UnicodeString("{0}, {1}", -1, US_INV);
}
UErrorCode status = U_ZERO_ERROR;
- separatorFormat = new MessageFormat(sep, status);
+ separatorFormat.applyPatternMinMaxArguments(sep, 2, 2, status);
UnicodeString pattern;
langData.getNoFallback("localeDisplayPattern", "pattern", pattern);
if (pattern.isBogus()) {
pattern = UnicodeString("{0} ({1})", -1, US_INV);
}
- format = new MessageFormat(pattern, status);
+ format.applyPatternMinMaxArguments(pattern, 2, 2, status);
if (pattern.indexOf((UChar)0xFF08) >= 0) {
formatOpenParen.setTo((UChar)0xFF08); // fullwidth (
formatReplaceOpenParen.setTo((UChar)0xFF3B); // fullwidth [
@@ -424,62 +480,25 @@ LocaleDisplayNamesImpl::initialize(void) {
if (ktPattern.isBogus()) {
ktPattern = UnicodeString("{0}={1}", -1, US_INV);
}
- keyTypeFormat = new MessageFormat(ktPattern, status);
+ keyTypeFormat.applyPatternMinMaxArguments(ktPattern, 2, 2, status);
uprv_memset(fCapitalization, 0, sizeof(fCapitalization));
#if !UCONFIG_NO_BREAK_ITERATION
- // The following is basically copied from DateFormatSymbols::initializeData
- typedef struct {
- const char * usageName;
- LocaleDisplayNamesImpl::CapContextUsage usageEnum;
- } ContextUsageNameToEnum;
- 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 },
- { "variant", kCapContextUsageVariant },
- { NULL, (CapContextUsage)0 },
- };
// 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 *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);
- }
- ures_close(contextTransforms);
- }
- ures_close(localeBundle);
+ LocalUResourceBundlePointer resource(ures_open(NULL, locale.getName(), &status));
+ if (U_FAILURE(status)) { return; }
+ CapitalizationContextSink sink(*this);
+ ures_getAllItemsWithFallback(resource.getAlias(), "contextTransforms", sink, status);
+ if (status == U_MISSING_RESOURCE_ERROR) {
+ // Silently ignore. Not every locale has contextTransforms.
+ status = U_ZERO_ERROR;
+ } else if (U_FAILURE(status)) {
+ return;
}
+ needBrkIter = sink.hasCapitalizationUsage;
}
// Get a sentence break iterator if we will need it
if (needBrkIter || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE) {
@@ -494,11 +513,10 @@ LocaleDisplayNamesImpl::initialize(void) {
}
LocaleDisplayNamesImpl::~LocaleDisplayNamesImpl() {
- delete separatorFormat;
- delete format;
- delete keyTypeFormat;
+#if !UCONFIG_NO_BREAK_ITERATION
delete capitalizationBrkIter;
- }
+#endif
+}
const Locale&
LocaleDisplayNamesImpl::getLocale() const {
@@ -543,6 +561,10 @@ LocaleDisplayNamesImpl::adjustForUsageAndContext(CapContextUsage usage,
UnicodeString&
LocaleDisplayNamesImpl::localeDisplayName(const Locale& locale,
UnicodeString& result) const {
+ if (locale.isBogus()) {
+ result.setToBogus();
+ return result;
+ }
UnicodeString resultName;
const char* lang = locale.getLanguage();
@@ -593,45 +615,41 @@ LocaleDisplayNamesImpl::localeDisplayName(const Locale& locale,
UnicodeString resultRemainder;
UnicodeString temp;
- StringEnumeration *e = NULL;
UErrorCode status = U_ZERO_ERROR;
if (hasScript) {
- resultRemainder.append(scriptDisplayName(script, temp));
+ resultRemainder.append(scriptDisplayName(script, temp, TRUE));
}
if (hasCountry) {
- appendWithSep(resultRemainder, regionDisplayName(country, temp));
+ appendWithSep(resultRemainder, regionDisplayName(country, temp, TRUE));
}
if (hasVariant) {
- appendWithSep(resultRemainder, variantDisplayName(variant, temp));
+ appendWithSep(resultRemainder, variantDisplayName(variant, temp, TRUE));
}
resultRemainder.findAndReplace(formatOpenParen, formatReplaceOpenParen);
resultRemainder.findAndReplace(formatCloseParen, formatReplaceCloseParen);
- e = locale.createKeywords(status);
- if (e && U_SUCCESS(status)) {
+ LocalPointer<StringEnumeration> e(locale.createKeywords(status));
+ if (e.isValid() && 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);
+ if (U_FAILURE(status)) {
+ return result;
+ }
+ keyDisplayName(key, temp, TRUE);
temp.findAndReplace(formatOpenParen, formatReplaceOpenParen);
temp.findAndReplace(formatCloseParen, formatReplaceCloseParen);
- keyValueDisplayName(key, value, temp2);
+ keyValueDisplayName(key, value, temp2, TRUE);
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);
+ keyTypeFormat.format(temp, temp2, temp3, status);
appendWithSep(resultRemainder, temp3);
} else {
appendWithSep(resultRemainder, temp)
@@ -639,17 +657,10 @@ LocaleDisplayNamesImpl::localeDisplayName(const Locale& locale,
.append(temp2);
}
}
- delete e;
}
if (!resultRemainder.isEmpty()) {
- Formattable data[] = {
- resultName,
- resultRemainder
- };
- FieldPosition fpos;
- status = U_ZERO_ERROR;
- format->format(data, 2, result, fpos, status);
+ format.format(resultName, resultRemainder, result.remove(), status);
return adjustForUsageAndContext(kCapContextUsageLanguage, result);
}
@@ -662,17 +673,9 @@ LocaleDisplayNamesImpl::appendWithSep(UnicodeString& buffer, const UnicodeString
if (buffer.isEmpty()) {
buffer.setTo(src);
} else {
- UnicodeString combined;
- Formattable data[] = {
- buffer,
- src
- };
- FieldPosition fpos;
+ const UnicodeString *values[2] = { &buffer, &src };
UErrorCode status = U_ZERO_ERROR;
- separatorFormat->format(data, 2, combined, fpos, status);
- if (U_SUCCESS(status)) {
- buffer.setTo(combined);
- }
+ separatorFormat.formatAndReplace(values, 2, buffer, NULL, 0, status);
}
return buffer;
}
@@ -714,56 +717,86 @@ LocaleDisplayNamesImpl::languageDisplayName(const char* lang,
UnicodeString&
LocaleDisplayNamesImpl::scriptDisplayName(const char* script,
- UnicodeString& result) const {
+ UnicodeString& result,
+ UBool skipAdjust) const {
if (nameLength == UDISPCTX_LENGTH_SHORT) {
langData.get("Scripts%short", script, result);
if (!result.isBogus()) {
- return adjustForUsageAndContext(kCapContextUsageScript, result);
+ return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageScript, result);
}
}
langData.get("Scripts", script, result);
- return adjustForUsageAndContext(kCapContextUsageScript, result);
+ return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageScript, result);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::scriptDisplayName(const char* script,
+ UnicodeString& result) const {
+ return scriptDisplayName(script, result, FALSE);
}
UnicodeString&
LocaleDisplayNamesImpl::scriptDisplayName(UScriptCode scriptCode,
UnicodeString& result) const {
- return scriptDisplayName(uscript_getName(scriptCode), result);
+ return scriptDisplayName(uscript_getName(scriptCode), result, FALSE);
}
UnicodeString&
LocaleDisplayNamesImpl::regionDisplayName(const char* region,
- UnicodeString& result) const {
+ UnicodeString& result,
+ UBool skipAdjust) const {
if (nameLength == UDISPCTX_LENGTH_SHORT) {
regionData.get("Countries%short", region, result);
if (!result.isBogus()) {
- return adjustForUsageAndContext(kCapContextUsageTerritory, result);
+ return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageTerritory, result);
}
}
regionData.get("Countries", region, result);
- return adjustForUsageAndContext(kCapContextUsageTerritory, result);
+ return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageTerritory, result);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::regionDisplayName(const char* region,
+ UnicodeString& result) const {
+ return regionDisplayName(region, result, FALSE);
}
+
UnicodeString&
LocaleDisplayNamesImpl::variantDisplayName(const char* variant,
- UnicodeString& result) const {
+ UnicodeString& result,
+ UBool skipAdjust) const {
// don't have a resource for short variant names
langData.get("Variants", variant, result);
- return adjustForUsageAndContext(kCapContextUsageVariant, result);
+ return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageVariant, result);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::variantDisplayName(const char* variant,
+ UnicodeString& result) const {
+ return variantDisplayName(variant, result, FALSE);
}
UnicodeString&
LocaleDisplayNamesImpl::keyDisplayName(const char* key,
- UnicodeString& result) const {
+ UnicodeString& result,
+ UBool skipAdjust) const {
// don't have a resource for short key names
langData.get("Keys", key, result);
- return adjustForUsageAndContext(kCapContextUsageKey, result);
+ return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKey, result);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::keyDisplayName(const char* key,
+ UnicodeString& result) const {
+ return keyDisplayName(key, result, FALSE);
}
UnicodeString&
LocaleDisplayNamesImpl::keyValueDisplayName(const char* key,
const char* value,
- UnicodeString& result) const {
+ UnicodeString& result,
+ UBool skipAdjust) const {
if (uprv_strcmp(key, "currency") == 0) {
// ICU4C does not have ICU4J CurrencyDisplayInfo equivalent for now.
UErrorCode sts = U_ZERO_ERROR;
@@ -778,17 +811,24 @@ LocaleDisplayNamesImpl::keyValueDisplayName(const char* key,
return result;
}
result.setTo(currencyName, len);
- return adjustForUsageAndContext(kCapContextUsageKeyValue, result);
+ return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKeyValue, result);
}
if (nameLength == UDISPCTX_LENGTH_SHORT) {
langData.get("Types%short", key, value, result);
if (!result.isBogus()) {
- return adjustForUsageAndContext(kCapContextUsageKeyValue, result);
+ return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKeyValue, result);
}
}
langData.get("Types", key, value, result);
- return adjustForUsageAndContext(kCapContextUsageKeyValue, result);
+ return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKeyValue, result);
+}
+
+UnicodeString&
+LocaleDisplayNamesImpl::keyValueDisplayName(const char* key,
+ const char* value,
+ UnicodeString& result) const {
+ return keyValueDisplayName(key, value, result, FALSE);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -887,6 +927,10 @@ uldn_localeDisplayName(const ULocaleDisplayNames *ldn,
}
UnicodeString temp(result, 0, maxResultSize);
((const LocaleDisplayNames *)ldn)->localeDisplayName(locale, temp);
+ if (temp.isBogus()) {
+ *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+ return 0;
+ }
return temp.extract(result, maxResultSize, *pErrorCode);
}
« no previous file with comments | « source/common/locdispnames.cpp ('k') | source/common/locid.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698