LCOV - code coverage report
Current view: top level - intl/icu/source/common - locdspnm.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 394 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 54 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // © 2016 and later: Unicode, Inc. and others.
       2             : // License & terms of use: http://www.unicode.org/copyright.html
       3             : /*
       4             : *******************************************************************************
       5             : * Copyright (C) 2010-2016, International Business Machines Corporation and
       6             : * others. All Rights Reserved.
       7             : *******************************************************************************
       8             : */
       9             : 
      10             : #include "unicode/utypes.h"
      11             : 
      12             : #if !UCONFIG_NO_FORMATTING
      13             : 
      14             : #include "unicode/locdspnm.h"
      15             : #include "unicode/simpleformatter.h"
      16             : #include "unicode/ucasemap.h"
      17             : #include "unicode/ures.h"
      18             : #include "unicode/udisplaycontext.h"
      19             : #include "unicode/brkiter.h"
      20             : #include "unicode/ucurr.h"
      21             : #include "cmemory.h"
      22             : #include "cstring.h"
      23             : #include "mutex.h"
      24             : #include "ulocimp.h"
      25             : #include "umutex.h"
      26             : #include "ureslocs.h"
      27             : #include "uresimp.h"
      28             : 
      29             : #include <stdarg.h>
      30             : 
      31             : /**
      32             :  * Concatenate a number of null-terminated strings to buffer, leaving a
      33             :  * null-terminated string.  The last argument should be the null pointer.
      34             :  * Return the length of the string in the buffer, not counting the trailing
      35             :  * null.  Return -1 if there is an error (buffer is null, or buflen < 1).
      36             :  */
      37           0 : static int32_t ncat(char *buffer, uint32_t buflen, ...) {
      38             :   va_list args;
      39             :   char *str;
      40           0 :   char *p = buffer;
      41           0 :   const char* e = buffer + buflen - 1;
      42             : 
      43           0 :   if (buffer == NULL || buflen < 1) {
      44           0 :     return -1;
      45             :   }
      46             : 
      47           0 :   va_start(args, buflen);
      48           0 :   while ((str = va_arg(args, char *))) {
      49             :     char c;
      50           0 :     while (p != e && (c = *str++)) {
      51           0 :       *p++ = c;
      52             :     }
      53             :   }
      54           0 :   *p = 0;
      55           0 :   va_end(args);
      56             : 
      57           0 :   return p - buffer;
      58             : }
      59             : 
      60             : U_NAMESPACE_BEGIN
      61             : 
      62             : ////////////////////////////////////////////////////////////////////////////////////////////////////
      63             : 
      64             : // Access resource data for locale components.
      65             : // Wrap code in uloc.c for now.
      66             : class ICUDataTable {
      67             :     const char* path;
      68             :     Locale locale;
      69             : 
      70             : public:
      71             :     ICUDataTable(const char* path, const Locale& locale);
      72             :     ~ICUDataTable();
      73             : 
      74             :     const Locale& getLocale();
      75             : 
      76             :     UnicodeString& get(const char* tableKey, const char* itemKey,
      77             :                         UnicodeString& result) const;
      78             :     UnicodeString& get(const char* tableKey, const char* subTableKey, const char* itemKey,
      79             :                         UnicodeString& result) const;
      80             : 
      81             :     UnicodeString& getNoFallback(const char* tableKey, const char* itemKey,
      82             :                                 UnicodeString &result) const;
      83             :     UnicodeString& getNoFallback(const char* tableKey, const char* subTableKey, const char* itemKey,
      84             :                                 UnicodeString &result) const;
      85             : };
      86             : 
      87             : inline UnicodeString &
      88           0 : ICUDataTable::get(const char* tableKey, const char* itemKey, UnicodeString& result) const {
      89           0 :     return get(tableKey, NULL, itemKey, result);
      90             : }
      91             : 
      92             : inline UnicodeString &
      93           0 : ICUDataTable::getNoFallback(const char* tableKey, const char* itemKey, UnicodeString& result) const {
      94           0 :     return getNoFallback(tableKey, NULL, itemKey, result);
      95             : }
      96             : 
      97           0 : ICUDataTable::ICUDataTable(const char* path, const Locale& locale)
      98           0 :     : path(NULL), locale(Locale::getRoot())
      99             : {
     100           0 :   if (path) {
     101           0 :     int32_t len = uprv_strlen(path);
     102           0 :     this->path = (const char*) uprv_malloc(len + 1);
     103           0 :     if (this->path) {
     104           0 :       uprv_strcpy((char *)this->path, path);
     105           0 :       this->locale = locale;
     106             :     }
     107             :   }
     108           0 : }
     109             : 
     110           0 : ICUDataTable::~ICUDataTable() {
     111           0 :   if (path) {
     112           0 :     uprv_free((void*) path);
     113           0 :     path = NULL;
     114             :   }
     115           0 : }
     116             : 
     117             : const Locale&
     118           0 : ICUDataTable::getLocale() {
     119           0 :   return locale;
     120             : }
     121             : 
     122             : UnicodeString &
     123           0 : ICUDataTable::get(const char* tableKey, const char* subTableKey, const char* itemKey,
     124             :                   UnicodeString &result) const {
     125           0 :   UErrorCode status = U_ZERO_ERROR;
     126           0 :   int32_t len = 0;
     127             : 
     128           0 :   const UChar *s = uloc_getTableStringWithFallback(path, locale.getName(),
     129             :                                                    tableKey, subTableKey, itemKey,
     130           0 :                                                    &len, &status);
     131           0 :   if (U_SUCCESS(status) && len > 0) {
     132           0 :     return result.setTo(s, len);
     133             :   }
     134           0 :   return result.setTo(UnicodeString(itemKey, -1, US_INV));
     135             : }
     136             : 
     137             : UnicodeString &
     138           0 : ICUDataTable::getNoFallback(const char* tableKey, const char* subTableKey, const char* itemKey,
     139             :                             UnicodeString& result) const {
     140           0 :   UErrorCode status = U_ZERO_ERROR;
     141           0 :   int32_t len = 0;
     142             : 
     143           0 :   const UChar *s = uloc_getTableStringWithFallback(path, locale.getName(),
     144             :                                                    tableKey, subTableKey, itemKey,
     145           0 :                                                    &len, &status);
     146           0 :   if (U_SUCCESS(status)) {
     147           0 :     return result.setTo(s, len);
     148             :   }
     149             : 
     150           0 :   result.setToBogus();
     151           0 :   return result;
     152             : }
     153             : 
     154             : ////////////////////////////////////////////////////////////////////////////////////////////////////
     155             : 
     156           0 : LocaleDisplayNames::~LocaleDisplayNames() {}
     157             : 
     158             : ////////////////////////////////////////////////////////////////////////////////////////////////////
     159             : 
     160             : #if 0  // currently unused
     161             : 
     162             : class DefaultLocaleDisplayNames : public LocaleDisplayNames {
     163             :   UDialectHandling dialectHandling;
     164             : 
     165             : public:
     166             :   // constructor
     167             :   DefaultLocaleDisplayNames(UDialectHandling dialectHandling);
     168             : 
     169             :   virtual ~DefaultLocaleDisplayNames();
     170             : 
     171             :   virtual const Locale& getLocale() const;
     172             :   virtual UDialectHandling getDialectHandling() const;
     173             : 
     174             :   virtual UnicodeString& localeDisplayName(const Locale& locale,
     175             :                                            UnicodeString& result) const;
     176             :   virtual UnicodeString& localeDisplayName(const char* localeId,
     177             :                                            UnicodeString& result) const;
     178             :   virtual UnicodeString& languageDisplayName(const char* lang,
     179             :                                              UnicodeString& result) const;
     180             :   virtual UnicodeString& scriptDisplayName(const char* script,
     181             :                                            UnicodeString& result) const;
     182             :   virtual UnicodeString& scriptDisplayName(UScriptCode scriptCode,
     183             :                                            UnicodeString& result) const;
     184             :   virtual UnicodeString& regionDisplayName(const char* region,
     185             :                                            UnicodeString& result) const;
     186             :   virtual UnicodeString& variantDisplayName(const char* variant,
     187             :                                             UnicodeString& result) const;
     188             :   virtual UnicodeString& keyDisplayName(const char* key,
     189             :                                         UnicodeString& result) const;
     190             :   virtual UnicodeString& keyValueDisplayName(const char* key,
     191             :                                              const char* value,
     192             :                                              UnicodeString& result) const;
     193             : };
     194             : 
     195             : DefaultLocaleDisplayNames::DefaultLocaleDisplayNames(UDialectHandling dialectHandling)
     196             :     : dialectHandling(dialectHandling) {
     197             : }
     198             : 
     199             : DefaultLocaleDisplayNames::~DefaultLocaleDisplayNames() {
     200             : }
     201             : 
     202             : const Locale&
     203             : DefaultLocaleDisplayNames::getLocale() const {
     204             :   return Locale::getRoot();
     205             : }
     206             : 
     207             : UDialectHandling
     208             : DefaultLocaleDisplayNames::getDialectHandling() const {
     209             :   return dialectHandling;
     210             : }
     211             : 
     212             : UnicodeString&
     213             : DefaultLocaleDisplayNames::localeDisplayName(const Locale& locale,
     214             :                                              UnicodeString& result) const {
     215             :   return result = UnicodeString(locale.getName(), -1, US_INV);
     216             : }
     217             : 
     218             : UnicodeString&
     219             : DefaultLocaleDisplayNames::localeDisplayName(const char* localeId,
     220             :                                              UnicodeString& result) const {
     221             :   return result = UnicodeString(localeId, -1, US_INV);
     222             : }
     223             : 
     224             : UnicodeString&
     225             : DefaultLocaleDisplayNames::languageDisplayName(const char* lang,
     226             :                                                UnicodeString& result) const {
     227             :   return result = UnicodeString(lang, -1, US_INV);
     228             : }
     229             : 
     230             : UnicodeString&
     231             : DefaultLocaleDisplayNames::scriptDisplayName(const char* script,
     232             :                                              UnicodeString& result) const {
     233             :   return result = UnicodeString(script, -1, US_INV);
     234             : }
     235             : 
     236             : UnicodeString&
     237             : DefaultLocaleDisplayNames::scriptDisplayName(UScriptCode scriptCode,
     238             :                                              UnicodeString& result) const {
     239             :   const char* name = uscript_getName(scriptCode);
     240             :   if (name) {
     241             :     return result = UnicodeString(name, -1, US_INV);
     242             :   }
     243             :   return result.remove();
     244             : }
     245             : 
     246             : UnicodeString&
     247             : DefaultLocaleDisplayNames::regionDisplayName(const char* region,
     248             :                                              UnicodeString& result) const {
     249             :   return result = UnicodeString(region, -1, US_INV);
     250             : }
     251             : 
     252             : UnicodeString&
     253             : DefaultLocaleDisplayNames::variantDisplayName(const char* variant,
     254             :                                               UnicodeString& result) const {
     255             :   return result = UnicodeString(variant, -1, US_INV);
     256             : }
     257             : 
     258             : UnicodeString&
     259             : DefaultLocaleDisplayNames::keyDisplayName(const char* key,
     260             :                                           UnicodeString& result) const {
     261             :   return result = UnicodeString(key, -1, US_INV);
     262             : }
     263             : 
     264             : UnicodeString&
     265             : DefaultLocaleDisplayNames::keyValueDisplayName(const char* /* key */,
     266             :                                                const char* value,
     267             :                                                UnicodeString& result) const {
     268             :   return result = UnicodeString(value, -1, US_INV);
     269             : }
     270             : 
     271             : #endif  // currently unused class DefaultLocaleDisplayNames
     272             : 
     273             : ////////////////////////////////////////////////////////////////////////////////////////////////////
     274             : 
     275             : class LocaleDisplayNamesImpl : public LocaleDisplayNames {
     276             :     Locale locale;
     277             :     UDialectHandling dialectHandling;
     278             :     ICUDataTable langData;
     279             :     ICUDataTable regionData;
     280             :     SimpleFormatter separatorFormat;
     281             :     SimpleFormatter format;
     282             :     SimpleFormatter keyTypeFormat;
     283             :     UDisplayContext capitalizationContext;
     284             : #if !UCONFIG_NO_BREAK_ITERATION
     285             :     BreakIterator* capitalizationBrkIter;
     286             : #else
     287             :     UObject* capitalizationBrkIter;
     288             : #endif
     289             :     static UMutex  capitalizationBrkIterLock;
     290             :     UnicodeString formatOpenParen;
     291             :     UnicodeString formatReplaceOpenParen;
     292             :     UnicodeString formatCloseParen;
     293             :     UnicodeString formatReplaceCloseParen;
     294             :     UDisplayContext nameLength;
     295             : 
     296             :     // Constants for capitalization context usage types.
     297             :     enum CapContextUsage {
     298             :         kCapContextUsageLanguage,
     299             :         kCapContextUsageScript,
     300             :         kCapContextUsageTerritory,
     301             :         kCapContextUsageVariant,
     302             :         kCapContextUsageKey,
     303             :         kCapContextUsageKeyValue,
     304             :         kCapContextUsageCount
     305             :     };
     306             :     // Capitalization transforms. For each usage type, indicates whether to titlecase for
     307             :     // the context specified in capitalizationContext (which we know at construction time)
     308             :      UBool fCapitalization[kCapContextUsageCount];
     309             : 
     310             : public:
     311             :     // constructor
     312             :     LocaleDisplayNamesImpl(const Locale& locale, UDialectHandling dialectHandling);
     313             :     LocaleDisplayNamesImpl(const Locale& locale, UDisplayContext *contexts, int32_t length);
     314             :     virtual ~LocaleDisplayNamesImpl();
     315             : 
     316             :     virtual const Locale& getLocale() const;
     317             :     virtual UDialectHandling getDialectHandling() const;
     318             :     virtual UDisplayContext getContext(UDisplayContextType type) const;
     319             : 
     320             :     virtual UnicodeString& localeDisplayName(const Locale& locale,
     321             :                                                 UnicodeString& result) const;
     322             :     virtual UnicodeString& localeDisplayName(const char* localeId,
     323             :                                                 UnicodeString& result) const;
     324             :     virtual UnicodeString& languageDisplayName(const char* lang,
     325             :                                                UnicodeString& result) const;
     326             :     virtual UnicodeString& scriptDisplayName(const char* script,
     327             :                                                 UnicodeString& result) const;
     328             :     virtual UnicodeString& scriptDisplayName(UScriptCode scriptCode,
     329             :                                                 UnicodeString& result) const;
     330             :     virtual UnicodeString& regionDisplayName(const char* region,
     331             :                                                 UnicodeString& result) const;
     332             :     virtual UnicodeString& variantDisplayName(const char* variant,
     333             :                                                 UnicodeString& result) const;
     334             :     virtual UnicodeString& keyDisplayName(const char* key,
     335             :                                                 UnicodeString& result) const;
     336             :     virtual UnicodeString& keyValueDisplayName(const char* key,
     337             :                                                 const char* value,
     338             :                                                 UnicodeString& result) const;
     339             : private:
     340             :     UnicodeString& localeIdName(const char* localeId,
     341             :                                 UnicodeString& result) const;
     342             :     UnicodeString& appendWithSep(UnicodeString& buffer, const UnicodeString& src) const;
     343             :     UnicodeString& adjustForUsageAndContext(CapContextUsage usage, UnicodeString& result) const;
     344             :     UnicodeString& scriptDisplayName(const char* script, UnicodeString& result, UBool skipAdjust) const;
     345             :     UnicodeString& regionDisplayName(const char* region, UnicodeString& result, UBool skipAdjust) const;
     346             :     UnicodeString& variantDisplayName(const char* variant, UnicodeString& result, UBool skipAdjust) const;
     347             :     UnicodeString& keyDisplayName(const char* key, UnicodeString& result, UBool skipAdjust) const;
     348             :     UnicodeString& keyValueDisplayName(const char* key, const char* value,
     349             :                                         UnicodeString& result, UBool skipAdjust) const;
     350             :     void initialize(void);
     351             : 
     352             :     struct CapitalizationContextSink;
     353             : };
     354             : 
     355             : UMutex LocaleDisplayNamesImpl::capitalizationBrkIterLock = U_MUTEX_INITIALIZER;
     356             : 
     357           0 : LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
     358           0 :                                                UDialectHandling dialectHandling)
     359             :     : dialectHandling(dialectHandling)
     360             :     , langData(U_ICUDATA_LANG, locale)
     361             :     , regionData(U_ICUDATA_REGION, locale)
     362             :     , capitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
     363             :     , capitalizationBrkIter(NULL)
     364           0 :     , nameLength(UDISPCTX_LENGTH_FULL)
     365             : {
     366           0 :     initialize();
     367           0 : }
     368             : 
     369           0 : LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
     370           0 :                                                UDisplayContext *contexts, int32_t length)
     371             :     : dialectHandling(ULDN_STANDARD_NAMES)
     372             :     , langData(U_ICUDATA_LANG, locale)
     373             :     , regionData(U_ICUDATA_REGION, locale)
     374             :     , capitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
     375             :     , capitalizationBrkIter(NULL)
     376           0 :     , nameLength(UDISPCTX_LENGTH_FULL)
     377             : {
     378           0 :     while (length-- > 0) {
     379           0 :         UDisplayContext value = *contexts++;
     380           0 :         UDisplayContextType selector = (UDisplayContextType)((uint32_t)value >> 8);
     381           0 :         switch (selector) {
     382             :             case UDISPCTX_TYPE_DIALECT_HANDLING:
     383           0 :                 dialectHandling = (UDialectHandling)value;
     384           0 :                 break;
     385             :             case UDISPCTX_TYPE_CAPITALIZATION:
     386           0 :                 capitalizationContext = value;
     387           0 :                 break;
     388             :             case UDISPCTX_TYPE_DISPLAY_LENGTH:
     389           0 :                 nameLength = value;
     390           0 :                 break;
     391             :             default:
     392           0 :                 break;
     393             :         }
     394             :     }
     395           0 :     initialize();
     396           0 : }
     397             : 
     398             : struct LocaleDisplayNamesImpl::CapitalizationContextSink : public ResourceSink {
     399             :     UBool hasCapitalizationUsage;
     400             :     LocaleDisplayNamesImpl& parent;
     401             : 
     402             :     CapitalizationContextSink(LocaleDisplayNamesImpl& _parent)
     403             :       : hasCapitalizationUsage(FALSE), parent(_parent) {}
     404             :     virtual ~CapitalizationContextSink();
     405             : 
     406           0 :     virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/,
     407             :             UErrorCode &errorCode) {
     408           0 :         ResourceTable contexts = value.getTable(errorCode);
     409           0 :         if (U_FAILURE(errorCode)) { return; }
     410           0 :         for (int i = 0; contexts.getKeyAndValue(i, key, value); ++i) {
     411             : 
     412             :             CapContextUsage usageEnum;
     413           0 :             if (uprv_strcmp(key, "key") == 0) {
     414           0 :                 usageEnum = kCapContextUsageKey;
     415           0 :             } else if (uprv_strcmp(key, "keyValue") == 0) {
     416           0 :                 usageEnum = kCapContextUsageKeyValue;
     417           0 :             } else if (uprv_strcmp(key, "languages") == 0) {
     418           0 :                 usageEnum = kCapContextUsageLanguage;
     419           0 :             } else if (uprv_strcmp(key, "script") == 0) {
     420           0 :                 usageEnum = kCapContextUsageScript;
     421           0 :             } else if (uprv_strcmp(key, "territory") == 0) {
     422           0 :                 usageEnum = kCapContextUsageTerritory;
     423           0 :             } else if (uprv_strcmp(key, "variant") == 0) {
     424           0 :                 usageEnum = kCapContextUsageVariant;
     425             :             } else {
     426           0 :                 continue;
     427             :             }
     428             : 
     429           0 :             int32_t len = 0;
     430           0 :             const int32_t* intVector = value.getIntVector(len, errorCode);
     431           0 :             if (U_FAILURE(errorCode)) { return; }
     432           0 :             if (len < 2) { continue; }
     433             : 
     434           0 :             int32_t titlecaseInt = (parent.capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU) ? intVector[0] : intVector[1];
     435           0 :             if (titlecaseInt == 0) { continue; }
     436             : 
     437           0 :             parent.fCapitalization[usageEnum] = TRUE;
     438           0 :             hasCapitalizationUsage = TRUE;
     439             :         }
     440             :     }
     441             : };
     442             : 
     443             : // Virtual destructors must be defined out of line.
     444           0 : LocaleDisplayNamesImpl::CapitalizationContextSink::~CapitalizationContextSink() {}
     445             : 
     446             : void
     447           0 : LocaleDisplayNamesImpl::initialize(void) {
     448           0 :     LocaleDisplayNamesImpl *nonConstThis = (LocaleDisplayNamesImpl *)this;
     449           0 :     nonConstThis->locale = langData.getLocale() == Locale::getRoot()
     450           0 :         ? regionData.getLocale()
     451           0 :         : langData.getLocale();
     452             : 
     453           0 :     UnicodeString sep;
     454           0 :     langData.getNoFallback("localeDisplayPattern", "separator", sep);
     455           0 :     if (sep.isBogus()) {
     456           0 :         sep = UnicodeString("{0}, {1}", -1, US_INV);
     457             :     }
     458           0 :     UErrorCode status = U_ZERO_ERROR;
     459           0 :     separatorFormat.applyPatternMinMaxArguments(sep, 2, 2, status);
     460             : 
     461           0 :     UnicodeString pattern;
     462           0 :     langData.getNoFallback("localeDisplayPattern", "pattern", pattern);
     463           0 :     if (pattern.isBogus()) {
     464           0 :         pattern = UnicodeString("{0} ({1})", -1, US_INV);
     465             :     }
     466           0 :     format.applyPatternMinMaxArguments(pattern, 2, 2, status);
     467           0 :     if (pattern.indexOf((UChar)0xFF08) >= 0) {
     468           0 :         formatOpenParen.setTo((UChar)0xFF08);         // fullwidth (
     469           0 :         formatReplaceOpenParen.setTo((UChar)0xFF3B);  // fullwidth [
     470           0 :         formatCloseParen.setTo((UChar)0xFF09);        // fullwidth )
     471           0 :         formatReplaceCloseParen.setTo((UChar)0xFF3D); // fullwidth ]
     472             :     } else {
     473           0 :         formatOpenParen.setTo((UChar)0x0028);         // (
     474           0 :         formatReplaceOpenParen.setTo((UChar)0x005B);  // [
     475           0 :         formatCloseParen.setTo((UChar)0x0029);        // )
     476           0 :         formatReplaceCloseParen.setTo((UChar)0x005D); // ]
     477             :     }
     478             : 
     479           0 :     UnicodeString ktPattern;
     480           0 :     langData.get("localeDisplayPattern", "keyTypePattern", ktPattern);
     481           0 :     if (ktPattern.isBogus()) {
     482           0 :         ktPattern = UnicodeString("{0}={1}", -1, US_INV);
     483             :     }
     484           0 :     keyTypeFormat.applyPatternMinMaxArguments(ktPattern, 2, 2, status);
     485             : 
     486           0 :     uprv_memset(fCapitalization, 0, sizeof(fCapitalization));
     487             : #if !UCONFIG_NO_BREAK_ITERATION
     488             :     // Only get the context data if we need it! This is a const object so we know now...
     489             :     // Also check whether we will need a break iterator (depends on the data)
     490             :     UBool needBrkIter = FALSE;
     491             :     if (capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_STANDALONE) {
     492             :         LocalUResourceBundlePointer resource(ures_open(NULL, locale.getName(), &status));
     493             :         if (U_FAILURE(status)) { return; }
     494             :         CapitalizationContextSink sink(*this);
     495             :         ures_getAllItemsWithFallback(resource.getAlias(), "contextTransforms", sink, status);
     496             :         if (status == U_MISSING_RESOURCE_ERROR) {
     497             :             // Silently ignore.  Not every locale has contextTransforms.
     498             :             status = U_ZERO_ERROR;
     499             :         } else if (U_FAILURE(status)) {
     500             :             return;
     501             :         }
     502             :         needBrkIter = sink.hasCapitalizationUsage;
     503             :     }
     504             :     // Get a sentence break iterator if we will need it
     505             :     if (needBrkIter || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE) {
     506             :         status = U_ZERO_ERROR;
     507             :         capitalizationBrkIter = BreakIterator::createSentenceInstance(locale, status);
     508             :         if (U_FAILURE(status)) {
     509             :             delete capitalizationBrkIter;
     510             :             capitalizationBrkIter = NULL;
     511             :         }
     512             :     }
     513             : #endif
     514           0 : }
     515             : 
     516           0 : LocaleDisplayNamesImpl::~LocaleDisplayNamesImpl() {
     517             : #if !UCONFIG_NO_BREAK_ITERATION
     518             :     delete capitalizationBrkIter;
     519             : #endif
     520           0 : }
     521             : 
     522             : const Locale&
     523           0 : LocaleDisplayNamesImpl::getLocale() const {
     524           0 :     return locale;
     525             : }
     526             : 
     527             : UDialectHandling
     528           0 : LocaleDisplayNamesImpl::getDialectHandling() const {
     529           0 :     return dialectHandling;
     530             : }
     531             : 
     532             : UDisplayContext
     533           0 : LocaleDisplayNamesImpl::getContext(UDisplayContextType type) const {
     534           0 :     switch (type) {
     535             :         case UDISPCTX_TYPE_DIALECT_HANDLING:
     536           0 :             return (UDisplayContext)dialectHandling;
     537             :         case UDISPCTX_TYPE_CAPITALIZATION:
     538           0 :             return capitalizationContext;
     539             :         case UDISPCTX_TYPE_DISPLAY_LENGTH:
     540           0 :             return nameLength;
     541             :         default:
     542           0 :             break;
     543             :     }
     544           0 :     return (UDisplayContext)0;
     545             : }
     546             : 
     547             : UnicodeString&
     548           0 : LocaleDisplayNamesImpl::adjustForUsageAndContext(CapContextUsage usage,
     549             :                                                 UnicodeString& result) const {
     550             : #if !UCONFIG_NO_BREAK_ITERATION
     551             :     // check to see whether we need to titlecase result
     552             :     if ( result.length() > 0 && u_islower(result.char32At(0)) && capitalizationBrkIter!= NULL &&
     553             :           ( capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE || fCapitalization[usage] ) ) {
     554             :         // note fCapitalization[usage] won't be set unless capitalizationContext is UI_LIST_OR_MENU or STANDALONE
     555             :         Mutex lock(&capitalizationBrkIterLock);
     556             :         result.toTitle(capitalizationBrkIter, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
     557             :     }
     558             : #endif
     559           0 :     return result;
     560             : }
     561             : 
     562             : UnicodeString&
     563           0 : LocaleDisplayNamesImpl::localeDisplayName(const Locale& locale,
     564             :                                           UnicodeString& result) const {
     565           0 :   if (locale.isBogus()) {
     566           0 :     result.setToBogus();
     567           0 :     return result;
     568             :   }
     569           0 :   UnicodeString resultName;
     570             : 
     571           0 :   const char* lang = locale.getLanguage();
     572           0 :   if (uprv_strlen(lang) == 0) {
     573           0 :     lang = "root";
     574             :   }
     575           0 :   const char* script = locale.getScript();
     576           0 :   const char* country = locale.getCountry();
     577           0 :   const char* variant = locale.getVariant();
     578             : 
     579           0 :   UBool hasScript = uprv_strlen(script) > 0;
     580           0 :   UBool hasCountry = uprv_strlen(country) > 0;
     581           0 :   UBool hasVariant = uprv_strlen(variant) > 0;
     582             : 
     583           0 :   if (dialectHandling == ULDN_DIALECT_NAMES) {
     584             :     char buffer[ULOC_FULLNAME_CAPACITY];
     585             :     do { // loop construct is so we can break early out of search
     586           0 :       if (hasScript && hasCountry) {
     587           0 :         ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, "_", country, (char *)0);
     588           0 :         localeIdName(buffer, resultName);
     589           0 :         if (!resultName.isBogus()) {
     590           0 :           hasScript = FALSE;
     591           0 :           hasCountry = FALSE;
     592           0 :           break;
     593             :         }
     594             :       }
     595           0 :       if (hasScript) {
     596           0 :         ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, (char *)0);
     597           0 :         localeIdName(buffer, resultName);
     598           0 :         if (!resultName.isBogus()) {
     599           0 :           hasScript = FALSE;
     600           0 :           break;
     601             :         }
     602             :       }
     603           0 :       if (hasCountry) {
     604           0 :         ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", country, (char*)0);
     605           0 :         localeIdName(buffer, resultName);
     606           0 :         if (!resultName.isBogus()) {
     607           0 :           hasCountry = FALSE;
     608           0 :           break;
     609             :         }
     610             :       }
     611             :     } while (FALSE);
     612             :   }
     613           0 :   if (resultName.isBogus() || resultName.isEmpty()) {
     614           0 :     localeIdName(lang, resultName);
     615             :   }
     616             : 
     617           0 :   UnicodeString resultRemainder;
     618           0 :   UnicodeString temp;
     619           0 :   UErrorCode status = U_ZERO_ERROR;
     620             : 
     621           0 :   if (hasScript) {
     622           0 :     resultRemainder.append(scriptDisplayName(script, temp, TRUE));
     623             :   }
     624           0 :   if (hasCountry) {
     625           0 :     appendWithSep(resultRemainder, regionDisplayName(country, temp, TRUE));
     626             :   }
     627           0 :   if (hasVariant) {
     628           0 :     appendWithSep(resultRemainder, variantDisplayName(variant, temp, TRUE));
     629             :   }
     630           0 :   resultRemainder.findAndReplace(formatOpenParen, formatReplaceOpenParen);
     631           0 :   resultRemainder.findAndReplace(formatCloseParen, formatReplaceCloseParen);
     632             : 
     633           0 :   LocalPointer<StringEnumeration> e(locale.createKeywords(status));
     634           0 :   if (e.isValid() && U_SUCCESS(status)) {
     635           0 :     UnicodeString temp2;
     636             :     char value[ULOC_KEYWORD_AND_VALUES_CAPACITY]; // sigh, no ULOC_VALUE_CAPACITY
     637             :     const char* key;
     638           0 :     while ((key = e->next((int32_t *)0, status)) != NULL) {
     639           0 :       locale.getKeywordValue(key, value, ULOC_KEYWORD_AND_VALUES_CAPACITY, status);
     640           0 :       if (U_FAILURE(status)) {
     641           0 :         return result;
     642             :       }
     643           0 :       keyDisplayName(key, temp, TRUE);
     644           0 :       temp.findAndReplace(formatOpenParen, formatReplaceOpenParen);
     645           0 :       temp.findAndReplace(formatCloseParen, formatReplaceCloseParen);
     646           0 :       keyValueDisplayName(key, value, temp2, TRUE);
     647           0 :       temp2.findAndReplace(formatOpenParen, formatReplaceOpenParen);
     648           0 :       temp2.findAndReplace(formatCloseParen, formatReplaceCloseParen);
     649           0 :       if (temp2 != UnicodeString(value, -1, US_INV)) {
     650           0 :         appendWithSep(resultRemainder, temp2);
     651           0 :       } else if (temp != UnicodeString(key, -1, US_INV)) {
     652           0 :         UnicodeString temp3;
     653           0 :         keyTypeFormat.format(temp, temp2, temp3, status);
     654           0 :         appendWithSep(resultRemainder, temp3);
     655             :       } else {
     656           0 :         appendWithSep(resultRemainder, temp)
     657           0 :           .append((UChar)0x3d /* = */)
     658           0 :           .append(temp2);
     659             :       }
     660             :     }
     661             :   }
     662             : 
     663           0 :   if (!resultRemainder.isEmpty()) {
     664           0 :     format.format(resultName, resultRemainder, result.remove(), status);
     665           0 :     return adjustForUsageAndContext(kCapContextUsageLanguage, result);
     666             :   }
     667             : 
     668           0 :   result = resultName;
     669           0 :   return adjustForUsageAndContext(kCapContextUsageLanguage, result);
     670             : }
     671             : 
     672             : UnicodeString&
     673           0 : LocaleDisplayNamesImpl::appendWithSep(UnicodeString& buffer, const UnicodeString& src) const {
     674           0 :     if (buffer.isEmpty()) {
     675           0 :         buffer.setTo(src);
     676             :     } else {
     677           0 :         const UnicodeString *values[2] = { &buffer, &src };
     678           0 :         UErrorCode status = U_ZERO_ERROR;
     679           0 :         separatorFormat.formatAndReplace(values, 2, buffer, NULL, 0, status);
     680             :     }
     681           0 :     return buffer;
     682             : }
     683             : 
     684             : UnicodeString&
     685           0 : LocaleDisplayNamesImpl::localeDisplayName(const char* localeId,
     686             :                                           UnicodeString& result) const {
     687           0 :     return localeDisplayName(Locale(localeId), result);
     688             : }
     689             : 
     690             : // private
     691             : UnicodeString&
     692           0 : LocaleDisplayNamesImpl::localeIdName(const char* localeId,
     693             :                                      UnicodeString& result) const {
     694           0 :     if (nameLength == UDISPCTX_LENGTH_SHORT) {
     695           0 :         langData.getNoFallback("Languages%short", localeId, result);
     696           0 :         if (!result.isBogus()) {
     697           0 :             return result;
     698             :         }
     699             :     }
     700           0 :     return langData.getNoFallback("Languages", localeId, result);
     701             : }
     702             : 
     703             : UnicodeString&
     704           0 : LocaleDisplayNamesImpl::languageDisplayName(const char* lang,
     705             :                                             UnicodeString& result) const {
     706           0 :     if (uprv_strcmp("root", lang) == 0 || uprv_strchr(lang, '_') != NULL) {
     707           0 :         return result = UnicodeString(lang, -1, US_INV);
     708             :     }
     709           0 :     if (nameLength == UDISPCTX_LENGTH_SHORT) {
     710           0 :         langData.get("Languages%short", lang, result);
     711           0 :         if (!result.isBogus()) {
     712           0 :             return adjustForUsageAndContext(kCapContextUsageLanguage, result);
     713             :         }
     714             :     }
     715           0 :     langData.get("Languages", lang, result);
     716           0 :     return adjustForUsageAndContext(kCapContextUsageLanguage, result);
     717             : }
     718             : 
     719             : UnicodeString&
     720           0 : LocaleDisplayNamesImpl::scriptDisplayName(const char* script,
     721             :                                           UnicodeString& result,
     722             :                                           UBool skipAdjust) const {
     723           0 :     if (nameLength == UDISPCTX_LENGTH_SHORT) {
     724           0 :         langData.get("Scripts%short", script, result);
     725           0 :         if (!result.isBogus()) {
     726           0 :             return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageScript, result);
     727             :         }
     728             :     }
     729           0 :     langData.get("Scripts", script, result);
     730           0 :     return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageScript, result);
     731             : }
     732             : 
     733             : UnicodeString&
     734           0 : LocaleDisplayNamesImpl::scriptDisplayName(const char* script,
     735             :                                           UnicodeString& result) const {
     736           0 :     return scriptDisplayName(script, result, FALSE);
     737             : }
     738             : 
     739             : UnicodeString&
     740           0 : LocaleDisplayNamesImpl::scriptDisplayName(UScriptCode scriptCode,
     741             :                                           UnicodeString& result) const {
     742           0 :     return scriptDisplayName(uscript_getName(scriptCode), result, FALSE);
     743             : }
     744             : 
     745             : UnicodeString&
     746           0 : LocaleDisplayNamesImpl::regionDisplayName(const char* region,
     747             :                                           UnicodeString& result,
     748             :                                           UBool skipAdjust) const {
     749           0 :     if (nameLength == UDISPCTX_LENGTH_SHORT) {
     750           0 :         regionData.get("Countries%short", region, result);
     751           0 :         if (!result.isBogus()) {
     752           0 :             return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageTerritory, result);
     753             :         }
     754             :     }
     755           0 :     regionData.get("Countries", region, result);
     756           0 :     return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageTerritory, result);
     757             : }
     758             : 
     759             : UnicodeString&
     760           0 : LocaleDisplayNamesImpl::regionDisplayName(const char* region,
     761             :                                           UnicodeString& result) const {
     762           0 :     return regionDisplayName(region, result, FALSE);
     763             : }
     764             : 
     765             : 
     766             : UnicodeString&
     767           0 : LocaleDisplayNamesImpl::variantDisplayName(const char* variant,
     768             :                                            UnicodeString& result,
     769             :                                            UBool skipAdjust) const {
     770             :     // don't have a resource for short variant names
     771           0 :     langData.get("Variants", variant, result);
     772           0 :     return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageVariant, result);
     773             : }
     774             : 
     775             : UnicodeString&
     776           0 : LocaleDisplayNamesImpl::variantDisplayName(const char* variant,
     777             :                                            UnicodeString& result) const {
     778           0 :     return variantDisplayName(variant, result, FALSE);
     779             : }
     780             : 
     781             : UnicodeString&
     782           0 : LocaleDisplayNamesImpl::keyDisplayName(const char* key,
     783             :                                        UnicodeString& result,
     784             :                                        UBool skipAdjust) const {
     785             :     // don't have a resource for short key names
     786           0 :     langData.get("Keys", key, result);
     787           0 :     return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKey, result);
     788             : }
     789             : 
     790             : UnicodeString&
     791           0 : LocaleDisplayNamesImpl::keyDisplayName(const char* key,
     792             :                                        UnicodeString& result) const {
     793           0 :     return keyDisplayName(key, result, FALSE);
     794             : }
     795             : 
     796             : UnicodeString&
     797           0 : LocaleDisplayNamesImpl::keyValueDisplayName(const char* key,
     798             :                                             const char* value,
     799             :                                             UnicodeString& result,
     800             :                                             UBool skipAdjust) const {
     801           0 :     if (uprv_strcmp(key, "currency") == 0) {
     802             :         // ICU4C does not have ICU4J CurrencyDisplayInfo equivalent for now.
     803           0 :         UErrorCode sts = U_ZERO_ERROR;
     804           0 :         UnicodeString ustrValue(value, -1, US_INV);
     805             :         int32_t len;
     806           0 :         UBool isChoice = FALSE;
     807           0 :         const UChar *currencyName = ucurr_getName(ustrValue.getTerminatedBuffer(),
     808           0 :             locale.getBaseName(), UCURR_LONG_NAME, &isChoice, &len, &sts);
     809           0 :         if (U_FAILURE(sts)) {
     810             :             // Return the value as is on failure
     811           0 :             result = ustrValue;
     812           0 :             return result;
     813             :         }
     814           0 :         result.setTo(currencyName, len);
     815           0 :         return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKeyValue, result);
     816             :     }
     817             : 
     818           0 :     if (nameLength == UDISPCTX_LENGTH_SHORT) {
     819           0 :         langData.get("Types%short", key, value, result);
     820           0 :         if (!result.isBogus()) {
     821           0 :             return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKeyValue, result);
     822             :         }
     823             :     }
     824           0 :     langData.get("Types", key, value, result);
     825           0 :     return skipAdjust? result: adjustForUsageAndContext(kCapContextUsageKeyValue, result);
     826             : }
     827             : 
     828             : UnicodeString&
     829           0 : LocaleDisplayNamesImpl::keyValueDisplayName(const char* key,
     830             :                                             const char* value,
     831             :                                             UnicodeString& result) const {
     832           0 :     return keyValueDisplayName(key, value, result, FALSE);
     833             : }
     834             : 
     835             : ////////////////////////////////////////////////////////////////////////////////////////////////////
     836             : 
     837             : LocaleDisplayNames*
     838           0 : LocaleDisplayNames::createInstance(const Locale& locale,
     839             :                                    UDialectHandling dialectHandling) {
     840           0 :     return new LocaleDisplayNamesImpl(locale, dialectHandling);
     841             : }
     842             : 
     843             : LocaleDisplayNames*
     844           0 : LocaleDisplayNames::createInstance(const Locale& locale,
     845             :                                    UDisplayContext *contexts, int32_t length) {
     846           0 :     if (contexts == NULL) {
     847           0 :         length = 0;
     848             :     }
     849           0 :     return new LocaleDisplayNamesImpl(locale, contexts, length);
     850             : }
     851             : 
     852             : U_NAMESPACE_END
     853             : 
     854             : ////////////////////////////////////////////////////////////////////////////////////////////////////
     855             : 
     856             : U_NAMESPACE_USE
     857             : 
     858             : U_CAPI ULocaleDisplayNames * U_EXPORT2
     859           0 : uldn_open(const char * locale,
     860             :           UDialectHandling dialectHandling,
     861             :           UErrorCode *pErrorCode) {
     862           0 :   if (U_FAILURE(*pErrorCode)) {
     863           0 :     return 0;
     864             :   }
     865           0 :   if (locale == NULL) {
     866           0 :     locale = uloc_getDefault();
     867             :   }
     868           0 :   return (ULocaleDisplayNames *)LocaleDisplayNames::createInstance(Locale(locale), dialectHandling);
     869             : }
     870             : 
     871             : U_CAPI ULocaleDisplayNames * U_EXPORT2
     872           0 : uldn_openForContext(const char * locale,
     873             :                     UDisplayContext *contexts, int32_t length,
     874             :                     UErrorCode *pErrorCode) {
     875           0 :   if (U_FAILURE(*pErrorCode)) {
     876           0 :     return 0;
     877             :   }
     878           0 :   if (locale == NULL) {
     879           0 :     locale = uloc_getDefault();
     880             :   }
     881           0 :   return (ULocaleDisplayNames *)LocaleDisplayNames::createInstance(Locale(locale), contexts, length);
     882             : }
     883             : 
     884             : 
     885             : U_CAPI void U_EXPORT2
     886           0 : uldn_close(ULocaleDisplayNames *ldn) {
     887           0 :   delete (LocaleDisplayNames *)ldn;
     888           0 : }
     889             : 
     890             : U_CAPI const char * U_EXPORT2
     891           0 : uldn_getLocale(const ULocaleDisplayNames *ldn) {
     892           0 :   if (ldn) {
     893           0 :     return ((const LocaleDisplayNames *)ldn)->getLocale().getName();
     894             :   }
     895           0 :   return NULL;
     896             : }
     897             : 
     898             : U_CAPI UDialectHandling U_EXPORT2
     899           0 : uldn_getDialectHandling(const ULocaleDisplayNames *ldn) {
     900           0 :   if (ldn) {
     901           0 :     return ((const LocaleDisplayNames *)ldn)->getDialectHandling();
     902             :   }
     903           0 :   return ULDN_STANDARD_NAMES;
     904             : }
     905             : 
     906             : U_CAPI UDisplayContext U_EXPORT2
     907           0 : uldn_getContext(const ULocaleDisplayNames *ldn,
     908             :               UDisplayContextType type,
     909             :               UErrorCode *pErrorCode) {
     910           0 :   if (U_FAILURE(*pErrorCode)) {
     911           0 :     return (UDisplayContext)0;
     912             :   }
     913           0 :   return ((const LocaleDisplayNames *)ldn)->getContext(type);
     914             : }
     915             : 
     916             : U_CAPI int32_t U_EXPORT2
     917           0 : uldn_localeDisplayName(const ULocaleDisplayNames *ldn,
     918             :                        const char *locale,
     919             :                        UChar *result,
     920             :                        int32_t maxResultSize,
     921             :                        UErrorCode *pErrorCode) {
     922           0 :   if (U_FAILURE(*pErrorCode)) {
     923           0 :     return 0;
     924             :   }
     925           0 :   if (ldn == NULL || locale == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
     926           0 :     *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
     927           0 :     return 0;
     928             :   }
     929           0 :   UnicodeString temp(result, 0, maxResultSize);
     930           0 :   ((const LocaleDisplayNames *)ldn)->localeDisplayName(locale, temp);
     931           0 :   if (temp.isBogus()) {
     932           0 :     *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
     933           0 :     return 0;
     934             :   }
     935           0 :   return temp.extract(result, maxResultSize, *pErrorCode);
     936             : }
     937             : 
     938             : U_CAPI int32_t U_EXPORT2
     939           0 : uldn_languageDisplayName(const ULocaleDisplayNames *ldn,
     940             :                          const char *lang,
     941             :                          UChar *result,
     942             :                          int32_t maxResultSize,
     943             :                          UErrorCode *pErrorCode) {
     944           0 :   if (U_FAILURE(*pErrorCode)) {
     945           0 :     return 0;
     946             :   }
     947           0 :   if (ldn == NULL || lang == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
     948           0 :     *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
     949           0 :     return 0;
     950             :   }
     951           0 :   UnicodeString temp(result, 0, maxResultSize);
     952           0 :   ((const LocaleDisplayNames *)ldn)->languageDisplayName(lang, temp);
     953           0 :   return temp.extract(result, maxResultSize, *pErrorCode);
     954             : }
     955             : 
     956             : U_CAPI int32_t U_EXPORT2
     957           0 : uldn_scriptDisplayName(const ULocaleDisplayNames *ldn,
     958             :                        const char *script,
     959             :                        UChar *result,
     960             :                        int32_t maxResultSize,
     961             :                        UErrorCode *pErrorCode) {
     962           0 :   if (U_FAILURE(*pErrorCode)) {
     963           0 :     return 0;
     964             :   }
     965           0 :   if (ldn == NULL || script == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
     966           0 :     *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
     967           0 :     return 0;
     968             :   }
     969           0 :   UnicodeString temp(result, 0, maxResultSize);
     970           0 :   ((const LocaleDisplayNames *)ldn)->scriptDisplayName(script, temp);
     971           0 :   return temp.extract(result, maxResultSize, *pErrorCode);
     972             : }
     973             : 
     974             : U_CAPI int32_t U_EXPORT2
     975           0 : uldn_scriptCodeDisplayName(const ULocaleDisplayNames *ldn,
     976             :                            UScriptCode scriptCode,
     977             :                            UChar *result,
     978             :                            int32_t maxResultSize,
     979             :                            UErrorCode *pErrorCode) {
     980           0 :   return uldn_scriptDisplayName(ldn, uscript_getName(scriptCode), result, maxResultSize, pErrorCode);
     981             : }
     982             : 
     983             : U_CAPI int32_t U_EXPORT2
     984           0 : uldn_regionDisplayName(const ULocaleDisplayNames *ldn,
     985             :                        const char *region,
     986             :                        UChar *result,
     987             :                        int32_t maxResultSize,
     988             :                        UErrorCode *pErrorCode) {
     989           0 :   if (U_FAILURE(*pErrorCode)) {
     990           0 :     return 0;
     991             :   }
     992           0 :   if (ldn == NULL || region == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
     993           0 :     *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
     994           0 :     return 0;
     995             :   }
     996           0 :   UnicodeString temp(result, 0, maxResultSize);
     997           0 :   ((const LocaleDisplayNames *)ldn)->regionDisplayName(region, temp);
     998           0 :   return temp.extract(result, maxResultSize, *pErrorCode);
     999             : }
    1000             : 
    1001             : U_CAPI int32_t U_EXPORT2
    1002           0 : uldn_variantDisplayName(const ULocaleDisplayNames *ldn,
    1003             :                         const char *variant,
    1004             :                         UChar *result,
    1005             :                         int32_t maxResultSize,
    1006             :                         UErrorCode *pErrorCode) {
    1007           0 :   if (U_FAILURE(*pErrorCode)) {
    1008           0 :     return 0;
    1009             :   }
    1010           0 :   if (ldn == NULL || variant == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
    1011           0 :     *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
    1012           0 :     return 0;
    1013             :   }
    1014           0 :   UnicodeString temp(result, 0, maxResultSize);
    1015           0 :   ((const LocaleDisplayNames *)ldn)->variantDisplayName(variant, temp);
    1016           0 :   return temp.extract(result, maxResultSize, *pErrorCode);
    1017             : }
    1018             : 
    1019             : U_CAPI int32_t U_EXPORT2
    1020           0 : uldn_keyDisplayName(const ULocaleDisplayNames *ldn,
    1021             :                     const char *key,
    1022             :                     UChar *result,
    1023             :                     int32_t maxResultSize,
    1024             :                     UErrorCode *pErrorCode) {
    1025           0 :   if (U_FAILURE(*pErrorCode)) {
    1026           0 :     return 0;
    1027             :   }
    1028           0 :   if (ldn == NULL || key == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
    1029           0 :     *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
    1030           0 :     return 0;
    1031             :   }
    1032           0 :   UnicodeString temp(result, 0, maxResultSize);
    1033           0 :   ((const LocaleDisplayNames *)ldn)->keyDisplayName(key, temp);
    1034           0 :   return temp.extract(result, maxResultSize, *pErrorCode);
    1035             : }
    1036             : 
    1037             : U_CAPI int32_t U_EXPORT2
    1038           0 : uldn_keyValueDisplayName(const ULocaleDisplayNames *ldn,
    1039             :                          const char *key,
    1040             :                          const char *value,
    1041             :                          UChar *result,
    1042             :                          int32_t maxResultSize,
    1043             :                          UErrorCode *pErrorCode) {
    1044           0 :   if (U_FAILURE(*pErrorCode)) {
    1045           0 :     return 0;
    1046             :   }
    1047           0 :   if (ldn == NULL || key == NULL || value == NULL || (result == NULL && maxResultSize > 0)
    1048           0 :       || maxResultSize < 0) {
    1049           0 :     *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
    1050           0 :     return 0;
    1051             :   }
    1052           0 :   UnicodeString temp(result, 0, maxResultSize);
    1053           0 :   ((const LocaleDisplayNames *)ldn)->keyValueDisplayName(key, value, temp);
    1054           0 :   return temp.extract(result, maxResultSize, *pErrorCode);
    1055             : }
    1056             : 
    1057             : #endif

Generated by: LCOV version 1.13