ICU-10244 (C) Handle localeDisplayPattern/separator as pattern

X-SVN-Rev: 33889
This commit is contained in:
Peter Edberg 2013-07-08 06:34:53 +00:00
parent 8d826958fd
commit 76d880b44f
2 changed files with 44 additions and 11 deletions

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 1997-2012, International Business Machines
* Copyright (C) 1997-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -465,8 +465,7 @@ uloc_getDisplayName(const char *locale,
UChar *dest, int32_t destCapacity,
UErrorCode *pErrorCode)
{
static const UChar defaultSeparator[3] = { 0x002c, 0x0020, 0x0000 }; /* comma + space */
static const int32_t defaultSepLen = 2;
static const UChar defaultSeparator[9] = { 0x007b, 0x0030, 0x007d, 0x002c, 0x0020, 0x007b, 0x0031, 0x007d, 0x0000 }; /* "{0}, {1}" */
static const UChar sub0[4] = { 0x007b, 0x0030, 0x007d , 0x0000 } ; /* {0} */
static const UChar sub1[4] = { 0x007b, 0x0031, 0x007d , 0x0000 } ; /* {1} */
static const int32_t subLen = 3;
@ -518,7 +517,25 @@ uloc_getDisplayName(const char *locale,
/* If we couldn't find any data, then use the defaults */
if(sepLen == 0) {
separator = defaultSeparator;
sepLen = defaultSepLen;
}
/* #10244: Even though separator is now a pattern, it is awkward to handle it as such
* here since we are trying to build the display string in place in the dest buffer,
* and to handle it as a pattern would entail having separate storage for the
* substrings that need to be combined (the first of which may be the result of
* previous such combinations). So for now we continue to treat the portion between
* {0} and {1} as a string to be appended when joining substrings, ignoring anything
* that is before {0} or after {1} (no existing separator pattern has any such thing).
* This is similar to how pattern is handled below.
*/
{
UChar *p0=u_strstr(separator, sub0);
UChar *p1=u_strstr(separator, sub1);
if (p0==NULL || p1==NULL || p1<p0) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
separator = (const UChar *)p0 + subLen;
sepLen = p1 - separator;
}
if(patLen==0 || (patLen==defaultPatLen && !u_strncmp(pattern, defaultPattern, patLen))) {

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2010-2012, International Business Machines Corporation and
* Copyright (C) 2010-2013, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
@ -271,7 +271,7 @@ class LocaleDisplayNamesImpl : public LocaleDisplayNames {
UDialectHandling dialectHandling;
ICUDataTable langData;
ICUDataTable regionData;
UnicodeString sep;
MessageFormat *separatorFormat;
MessageFormat *format;
MessageFormat *keyTypeFormat;
UDisplayContext capitalizationContext;
@ -333,6 +333,7 @@ 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)
@ -345,6 +346,7 @@ 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)
@ -373,17 +375,19 @@ LocaleDisplayNamesImpl::initialize(void) {
? regionData.getLocale()
: langData.getLocale();
UnicodeString sep;
langData.getNoFallback("localeDisplayPattern", "separator", sep);
if (sep.isBogus()) {
sep = UnicodeString(", ", -1, US_INV);
sep = UnicodeString("{0}, {1}", -1, US_INV);
}
UErrorCode status = U_ZERO_ERROR;
separatorFormat = new MessageFormat(sep, status);
UnicodeString pattern;
langData.getNoFallback("localeDisplayPattern", "pattern", pattern);
if (pattern.isBogus()) {
pattern = UnicodeString("{0} ({1})", -1, US_INV);
}
UErrorCode status = U_ZERO_ERROR;
format = new MessageFormat(pattern, status);
UnicodeString ktPattern;
@ -444,6 +448,7 @@ LocaleDisplayNamesImpl::initialize(void) {
}
LocaleDisplayNamesImpl::~LocaleDisplayNamesImpl() {
delete separatorFormat;
delete format;
delete keyTypeFormat;
}
@ -639,10 +644,21 @@ LocaleDisplayNamesImpl::localeDisplayName(const Locale& locale,
UnicodeString&
LocaleDisplayNamesImpl::appendWithSep(UnicodeString& buffer, const UnicodeString& src) const {
if (!buffer.isEmpty()) {
buffer.append(sep);
if (buffer.isEmpty()) {
buffer.setTo(src);
} else {
UnicodeString combined;
Formattable data[] = {
buffer,
src
};
FieldPosition fpos;
UErrorCode status = U_ZERO_ERROR;
separatorFormat->format(data, 2, combined, fpos, status);
if (U_SUCCESS(status)) {
buffer.setTo(combined);
}
}
buffer.append(src);
return buffer;
}