150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/*
250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*******************************************************************************
350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius*   Copyright (C) 1997-2012, International Business Machines
550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   Corporation and others.  All Rights Reserved.
650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*******************************************************************************
850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   file name:  locdispnames.cpp
950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   encoding:   US-ASCII
1050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   tab size:   8 (not used)
1150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   indentation:4
1250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
1350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   created on: 2010feb25
1450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   created by: Markus W. Scherer
1550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
1650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   Code for locale display names, separated out from other .cpp files
1750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   that then do not depend on resource bundle code and display name data.
1850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*/
1950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/utypes.h"
2150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/brkiter.h"
2250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/locid.h"
2350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/uloc.h"
2450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/ures.h"
2550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/ustring.h"
2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cmemory.h"
2750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cstring.h"
2850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "putilimp.h"
2950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "ulocimp.h"
3050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "uresimp.h"
3150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "ureslocs.h"
3250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "ustr_imp.h"
3350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// C++ API ----------------------------------------------------------------- ***
3550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_BEGIN
3750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
3950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoLocale::getDisplayLanguage(UnicodeString& dispLang) const
4050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return this->getDisplayLanguage(getDefault(), dispLang);
4250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
4350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/*We cannot make any assumptions on the size of the output display strings
4550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* Yet, since we are calling through to a C API, we need to set limits on
4650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* buffer size. For all the following getDisplay functions we first attempt
4750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* to fill up a stack allocated buffer. If it is to small we heap allocated
4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* the exact buffer we need copy it to the UnicodeString and delete it*/
4950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
5150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoLocale::getDisplayLanguage(const Locale &displayLocale,
5250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           UnicodeString &result) const {
5350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UChar *buffer;
5450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode errorCode=U_ZERO_ERROR;
5550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t length;
5650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(buffer==0) {
5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result.truncate(0);
6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return result;
6150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
6250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
6350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    length=uloc_getDisplayLanguage(fullName, displayLocale.fullName,
6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                   buffer, result.getCapacity(),
6550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                   &errorCode);
6650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        buffer=result.getBuffer(length);
7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(buffer==0) {
7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            result.truncate(0);
7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            return result;
7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errorCode=U_ZERO_ERROR;
7550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        length=uloc_getDisplayLanguage(fullName, displayLocale.fullName,
7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                       buffer, result.getCapacity(),
7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                       &errorCode);
7850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
7950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
8050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return result;
8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
8450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
8550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoLocale::getDisplayScript(UnicodeString& dispScript) const
8650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
8750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return this->getDisplayScript(getDefault(), dispScript);
8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
8950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
9050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
9150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoLocale::getDisplayScript(const Locale &displayLocale,
9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          UnicodeString &result) const {
9350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UChar *buffer;
9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode errorCode=U_ZERO_ERROR;
9550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t length;
9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
9750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(buffer==0) {
9950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result.truncate(0);
10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return result;
10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    length=uloc_getDisplayScript(fullName, displayLocale.fullName,
10450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  buffer, result.getCapacity(),
10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  &errorCode);
10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
10850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
10950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        buffer=result.getBuffer(length);
11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(buffer==0) {
11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            result.truncate(0);
11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            return result;
11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errorCode=U_ZERO_ERROR;
11550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        length=uloc_getDisplayScript(fullName, displayLocale.fullName,
11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                      buffer, result.getCapacity(),
11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                      &errorCode);
11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return result;
12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
12450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
12550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoLocale::getDisplayCountry(UnicodeString& dispCntry) const
12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
12750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return this->getDisplayCountry(getDefault(), dispCntry);
12850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
13050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
13150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoLocale::getDisplayCountry(const Locale &displayLocale,
13250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          UnicodeString &result) const {
13350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UChar *buffer;
13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode errorCode=U_ZERO_ERROR;
13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t length;
13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(buffer==0) {
13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result.truncate(0);
14050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return result;
14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    length=uloc_getDisplayCountry(fullName, displayLocale.fullName,
14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  buffer, result.getCapacity(),
14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  &errorCode);
14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
14750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
14950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        buffer=result.getBuffer(length);
15050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(buffer==0) {
15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            result.truncate(0);
15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            return result;
15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
15450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errorCode=U_ZERO_ERROR;
15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        length=uloc_getDisplayCountry(fullName, displayLocale.fullName,
15650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                      buffer, result.getCapacity(),
15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                      &errorCode);
15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return result;
16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
16450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
16550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoLocale::getDisplayVariant(UnicodeString& dispVar) const
16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return this->getDisplayVariant(getDefault(), dispVar);
16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
17050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
17150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoLocale::getDisplayVariant(const Locale &displayLocale,
17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          UnicodeString &result) const {
17350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UChar *buffer;
17450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode errorCode=U_ZERO_ERROR;
17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t length;
17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(buffer==0) {
17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result.truncate(0);
18050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return result;
18150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    length=uloc_getDisplayVariant(fullName, displayLocale.fullName,
18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  buffer, result.getCapacity(),
18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                  &errorCode);
18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        buffer=result.getBuffer(length);
19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(buffer==0) {
19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            result.truncate(0);
19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            return result;
19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errorCode=U_ZERO_ERROR;
19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        length=uloc_getDisplayVariant(fullName, displayLocale.fullName,
19650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                      buffer, result.getCapacity(),
19750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                      &errorCode);
19850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
20050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
20150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return result;
20250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
20350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
20450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
20550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoLocale::getDisplayName( UnicodeString& name ) const
20650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
20750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return this->getDisplayName(getDefault(), name);
20850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
20950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
21050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
21150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoLocale::getDisplayName(const Locale &displayLocale,
21250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       UnicodeString &result) const {
21350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UChar *buffer;
21450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode errorCode=U_ZERO_ERROR;
21550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t length;
21650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
21750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
21850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(buffer==0) {
21950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result.truncate(0);
22050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return result;
22150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
22250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
22350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    length=uloc_getDisplayName(fullName, displayLocale.fullName,
22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               buffer, result.getCapacity(),
22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               &errorCode);
22650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        buffer=result.getBuffer(length);
23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(buffer==0) {
23150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            result.truncate(0);
23250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            return result;
23350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
23450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errorCode=U_ZERO_ERROR;
23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        length=uloc_getDisplayName(fullName, displayLocale.fullName,
23650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                   buffer, result.getCapacity(),
23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                   &errorCode);
23850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
24150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return result;
24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
24350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if ! UCONFIG_NO_BREAK_ITERATION
24550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
24650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
24750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Gets the objectLocale display name in the default locale language.
24850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString& U_EXPORT2
24950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoBreakIterator::getDisplayName(const Locale& objectLocale,
25050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                             UnicodeString& name)
25150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
25250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return objectLocale.getDisplayName(name);
25350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
25450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// -------------------------------------
25650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Gets the objectLocale display name in the displayLocale language.
25750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString& U_EXPORT2
25850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoBreakIterator::getDisplayName(const Locale& objectLocale,
25950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                             const Locale& displayLocale,
26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                             UnicodeString& name)
26150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
26250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return objectLocale.getDisplayName(displayLocale, name);
26350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
26450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
26650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
26750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
26850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_END
26950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// C API ------------------------------------------------------------------- ***
27150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
27250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_USE
27350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
27450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* ### Constants **************************************************/
27550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
27650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* These strings describe the resources we attempt to load from
27750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho the locale ResourceBundle data file.*/
27850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char _kLanguages[]       = "Languages";
27950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char _kScripts[]         = "Scripts";
280103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const char _kScriptsStandAlone[] = "Scripts%stand-alone";
28150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char _kCountries[]       = "Countries";
28250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char _kVariants[]        = "Variants";
28350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char _kKeys[]            = "Keys";
28450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char _kTypes[]           = "Types";
28554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const char _kRootName[]        = "root";
28650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char _kCurrency[]        = "currency";
28750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char _kCurrencies[]      = "Currencies";
28850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char _kLocaleDisplayPattern[] = "localeDisplayPattern";
28950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char _kPattern[]         = "pattern";
29050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char _kSeparator[]       = "separator";
29150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
29250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* ### Display name **************************************************/
29350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
29450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t
29550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho_getStringOrCopyKey(const char *path, const char *locale,
29650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    const char *tableKey,
29750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    const char* subTableKey,
29850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    const char *itemKey,
29950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    const char *substitute,
30050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    UChar *dest, int32_t destCapacity,
30150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    UErrorCode *pErrorCode) {
30250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const UChar *s = NULL;
30350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t length = 0;
30450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
30550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(itemKey==NULL) {
30650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /* top-level item: normal resource bundle access */
30750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UResourceBundle *rb;
30850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
30950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        rb=ures_open(path, locale, pErrorCode);
31050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
31150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_SUCCESS(*pErrorCode)) {
31250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            s=ures_getStringByKey(rb, tableKey, &length, pErrorCode);
31350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /* see comment about closing rb near "return item;" in _res_getTableStringWithFallback() */
31450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            ures_close(rb);
31550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
31650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /* Language code should not be a number. If it is, set the error code. */
31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (!uprv_strncmp(tableKey, "Languages", 9) && uprv_strtol(itemKey, NULL, 10)) {
31950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            *pErrorCode = U_MISSING_RESOURCE_ERROR;
32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        } else {
32150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /* second-level item, use special fallback */
32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            s=uloc_getTableStringWithFallback(path, locale,
32350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                               tableKey,
32450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                               subTableKey,
32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                               itemKey,
32650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                               &length,
32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                               pErrorCode);
32850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
33150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_SUCCESS(*pErrorCode)) {
33250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int32_t copyLength=uprv_min(length, destCapacity);
33350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(copyLength>0 && s != NULL) {
33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            u_memcpy(dest, s, copyLength);
33550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
33650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
33750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /* no string from a resource bundle: convert the substitute */
33850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        length=(int32_t)uprv_strlen(substitute);
33950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        u_charsToUChars(substitute, dest, uprv_min(length, destCapacity));
34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *pErrorCode=U_USING_DEFAULT_WARNING;
34150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
34250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
34350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return u_terminateUChars(dest, destCapacity, length, pErrorCode);
34450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
34550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
34650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotypedef  int32_t U_CALLCONV UDisplayNameGetter(const char *, char *, int32_t, UErrorCode *);
34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
34850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t
34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho_getDisplayNameForComponent(const char *locale,
35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                            const char *displayLocale,
35150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                            UChar *dest, int32_t destCapacity,
35250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                            UDisplayNameGetter *getter,
35350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                            const char *tag,
35450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                            UErrorCode *pErrorCode) {
35550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char localeBuffer[ULOC_FULLNAME_CAPACITY*4];
35650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t length;
35750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode localStatus;
35850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* root = NULL;
35950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /* argument checking */
36150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
36250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
36350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
36450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
36550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(destCapacity<0 || (destCapacity>0 && dest==NULL)) {
36650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
36750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
36850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
36950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
37050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    localStatus = U_ZERO_ERROR;
37150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    length=(*getter)(locale, localeBuffer, sizeof(localeBuffer), &localStatus);
37250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(localStatus) || localStatus==U_STRING_NOT_TERMINATED_WARNING) {
37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(length==0) {
37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return u_terminateUChars(dest, destCapacity, 0, pErrorCode);
37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
37950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
38050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    root = tag == _kCountries ? U_ICUDATA_REGION : U_ICUDATA_LANG;
38150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
38250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return _getStringOrCopyKey(root, displayLocale,
38350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               tag, NULL, localeBuffer,
38450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               localeBuffer,
38550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               dest, destCapacity,
38650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               pErrorCode);
38750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
38950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI int32_t U_EXPORT2
39050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouloc_getDisplayLanguage(const char *locale,
39150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        const char *displayLocale,
39250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        UChar *dest, int32_t destCapacity,
39350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        UErrorCode *pErrorCode) {
39450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
39550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                uloc_getLanguage, _kLanguages, pErrorCode);
39650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
39750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
39850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI int32_t U_EXPORT2
39950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouloc_getDisplayScript(const char* locale,
40050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      const char* displayLocale,
40150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      UChar *dest, int32_t destCapacity,
40250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                      UErrorCode *pErrorCode)
40350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
404103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius	UErrorCode err = U_ZERO_ERROR;
405103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius	int32_t res = _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
406103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                uloc_getScript, _kScriptsStandAlone, &err);
407103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
408103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius	if ( err == U_USING_DEFAULT_WARNING ) {
409103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
410103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    uloc_getScript, _kScripts, pErrorCode);
411103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius	} else {
412103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius		*pErrorCode = err;
413103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius		return res;
414103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius	}
415103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
416103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
417103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_INTERNAL int32_t U_EXPORT2
418103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusuloc_getDisplayScriptInContext(const char* locale,
419103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                      const char* displayLocale,
420103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                      UChar *dest, int32_t destCapacity,
421103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                      UErrorCode *pErrorCode)
422103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{
42350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
424103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    uloc_getScript, _kScripts, pErrorCode);
42550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
42650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
42750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI int32_t U_EXPORT2
42850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouloc_getDisplayCountry(const char *locale,
42950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       const char *displayLocale,
43050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       UChar *dest, int32_t destCapacity,
43150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       UErrorCode *pErrorCode) {
43250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
43350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                uloc_getCountry, _kCountries, pErrorCode);
43450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
43550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
43650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/*
43750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * TODO separate variant1_variant2_variant3...
43850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * by getting each tag's display string and concatenating them with ", "
43950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * in between - similar to uloc_getDisplayName()
44050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
44150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI int32_t U_EXPORT2
44250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouloc_getDisplayVariant(const char *locale,
44350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       const char *displayLocale,
44450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       UChar *dest, int32_t destCapacity,
44550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       UErrorCode *pErrorCode) {
44650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
44750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                uloc_getVariant, _kVariants, pErrorCode);
44850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
44950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
450b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* Instead of having a separate pass for 'special' patterns, reintegrate the two
451b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * so we don't get bitten by preflight bugs again.  We can be reasonably efficient
452b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * without two separate code paths, this code isn't that performance-critical.
453b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *
454b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * This code is general enough to deal with patterns that have a prefix or swap the
455b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * language and remainder components, since we gave developers enough rope to do such
456b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * things if they futz with the pattern data.  But since we don't give them a way to
457b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * specify a pattern for arbitrary combinations of components, there's not much use in
458b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * that.  I don't think our data includes such patterns, the only variable I know if is
459b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * whether there is a space before the open paren, or not.  Oh, and zh uses different
460b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * chars than the standard open/close paren (which ja and ko use, btw).
461b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */
46250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI int32_t U_EXPORT2
46350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouloc_getDisplayName(const char *locale,
46450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    const char *displayLocale,
46550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    UChar *dest, int32_t destCapacity,
46650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    UErrorCode *pErrorCode)
46750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
468b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    static const UChar defaultSeparator[3] = { 0x002c, 0x0020, 0x0000 }; /* comma + space */
469b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    static const int32_t defaultSepLen = 2;
470b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    static const UChar sub0[4] = { 0x007b, 0x0030, 0x007d , 0x0000 } ; /* {0} */
471b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    static const UChar sub1[4] = { 0x007b, 0x0031, 0x007d , 0x0000 } ; /* {1} */
472b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    static const int32_t subLen = 3;
473b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    static const UChar defaultPattern[10] = {
474b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        0x007b, 0x0030, 0x007d, 0x0020, 0x0028, 0x007b, 0x0031, 0x007d, 0x0029, 0x0000
475b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }; /* {0} ({1}) */
476b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    static const int32_t defaultPatLen = 9;
477b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    static const int32_t defaultSub0Pos = 0;
478b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    static const int32_t defaultSub1Pos = 5;
479b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
480b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t length; /* of formatted result */
481b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
482b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UChar *separator;
483b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t sepLen = 0;
484b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UChar *pattern;
485b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t patLen = 0;
486b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t sub0Pos, sub1Pos;
487b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
488b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UBool haveLang = TRUE; /* assume true, set false if we find we don't have
489b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                              a lang component in the locale */
490b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UBool haveRest = TRUE; /* assume true, set false if we find we don't have
491b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                              any other component in the locale */
492b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UBool retry = FALSE; /* set true if we need to retry, see below */
493b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
494b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t langi = 0; /* index of the language substitution (0 or 1), virtually always 0 */
49550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
49650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
49750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
49850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
50050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(destCapacity<0 || (destCapacity>0 && dest==NULL)) {
50150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
50250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
50350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
50450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
505b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    {
506b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UErrorCode status = U_ZERO_ERROR;
507b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UResourceBundle* locbundle=ures_open(U_ICUDATA_LANG, displayLocale, &status);
508b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UResourceBundle* dspbundle=ures_getByKeyWithFallback(locbundle, _kLocaleDisplayPattern,
509b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                                             NULL, &status);
51050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
511b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        separator=ures_getStringByKeyWithFallback(dspbundle, _kSeparator, &sepLen, &status);
512b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        pattern=ures_getStringByKeyWithFallback(dspbundle, _kPattern, &patLen, &status);
51350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
514b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        ures_close(dspbundle);
515b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        ures_close(locbundle);
51650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
51750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
518b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    /* If we couldn't find any data, then use the defaults */
519b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if(sepLen == 0) {
520b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho       separator = defaultSeparator;
521b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho       sepLen = defaultSepLen;
522b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
523b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
524b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if(patLen==0 || (patLen==defaultPatLen && !u_strncmp(pattern, defaultPattern, patLen))) {
525b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        pattern=defaultPattern;
526b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        patLen=defaultPatLen;
527b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        sub0Pos=defaultSub0Pos;
528b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        sub1Pos=defaultSub1Pos;
529b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else { /* non-default pattern */
530b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UChar *p0=u_strstr(pattern, sub0);
531b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UChar *p1=u_strstr(pattern, sub1);
532b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (p0==NULL || p1==NULL) {
533b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
534b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            return 0;
53550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
536b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        sub0Pos=p0-pattern;
537b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        sub1Pos=p1-pattern;
538b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (sub1Pos < sub0Pos) { /* a very odd pattern */
539b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            int32_t t=sub0Pos; sub0Pos=sub1Pos; sub1Pos=t;
540b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            langi=1;
54150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
54250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
54350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
544b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    /* We loop here because there is one case in which after the first pass we could need to
545b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     * reextract the data.  If there's initial padding before the first element, we put in
546b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     * the padding and then write that element.  If it turns out there's no second element,
547b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     * we didn't need the padding.  If we do need the data (no preflight), and the first element
548b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     * would have fit but for the padding, we need to reextract.  In this case (only) we
549b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     * adjust the parameters so padding is not added, and repeat.
550b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     */
551b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    do {
552b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UChar* p=dest;
553b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t patPos=0; /* position in the pattern, used for non-substitution portions */
554b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t langLen=0; /* length of language substitution */
555b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t langPos=0; /* position in output of language substitution */
556b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t restLen=0; /* length of 'everything else' substitution */
557b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t restPos=0; /* position in output of 'everything else' substitution */
558b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UEnumeration* kenum = NULL; /* keyword enumeration */
559b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
560b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        /* prefix of pattern, extremely likely to be empty */
561b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if(sub0Pos) {
562b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if(destCapacity >= sub0Pos) {
563b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                while (patPos < sub0Pos) {
564b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    *p++ = pattern[patPos++];
565b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
566b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            } else {
567b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                patPos=sub0Pos;
568b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
569b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            length=sub0Pos;
570b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else {
571b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            length=0;
57250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
57350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
574b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        for(int32_t subi=0,resti=0;subi<2;) { /* iterate through patterns 0 and 1*/
575b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UBool subdone = FALSE; /* set true when ready to move to next substitution */
57650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
577b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            /* prep p and cap for calls to get display components, pin cap to 0 since
578b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho               they complain if cap is negative */
579b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            int32_t cap=destCapacity-length;
580b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (cap <= 0) {
581b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                cap=0;
58250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            } else {
583b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                p=dest+length;
58450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
58550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
586b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (subi == langi) { /* {0}*/
587b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if(haveLang) {
588b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    langPos=length;
589b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    langLen=uloc_getDisplayLanguage(locale, displayLocale, p, cap, pErrorCode);
590b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    length+=langLen;
591b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    haveLang=langLen>0;
592b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
593b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                subdone=TRUE;
594b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            } else { /* {1} */
595b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if(!haveRest) {
596b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    subdone=TRUE;
597b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                } else {
598b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    int32_t len; /* length of component (plus other stuff) we just fetched */
599b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    switch(resti++) {
600b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        case 0:
601b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            restPos=length;
602103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            len=uloc_getDisplayScriptInContext(locale, displayLocale, p, cap, pErrorCode);
603b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            break;
604b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        case 1:
605b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            len=uloc_getDisplayCountry(locale, displayLocale, p, cap, pErrorCode);
606b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            break;
607b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        case 2:
608b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            len=uloc_getDisplayVariant(locale, displayLocale, p, cap, pErrorCode);
609b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            break;
610b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        case 3:
611b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            kenum = uloc_openKeywords(locale, pErrorCode);
612b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            /* fall through */
613b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        default: {
614b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            const char* kw=uenum_next(kenum, &len, pErrorCode);
615b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            if (kw == NULL) {
616b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                uenum_close(kenum);
617b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                len=0; /* mark that we didn't add a component */
618b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                subdone=TRUE;
619b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            } else {
620b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                /* incorporating this behavior into the loop made it even more complex,
621b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                   so just special case it here */
622b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                len = uloc_getDisplayKeyword(kw, displayLocale, p, cap, pErrorCode);
623b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                if(len) {
624b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    if(len < cap) {
625b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                        p[len]=0x3d; /* '=', assume we'll need it */
626b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    }
627b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    len+=1;
628b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
629b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    /* adjust for call to get keyword */
630b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    cap-=len;
631b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    if(cap <= 0) {
632b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                        cap=0;
633b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    } else {
634b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                        p+=len;
635b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    }
636b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                }
637b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                /* reset for call below */
638b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                if(*pErrorCode == U_BUFFER_OVERFLOW_ERROR) {
639b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    *pErrorCode=U_ZERO_ERROR;
640b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                }
641b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                int32_t vlen = uloc_getDisplayKeywordValue(locale, kw, displayLocale,
642b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                                                           p, cap, pErrorCode);
643b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                if(len) {
644b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    if(vlen==0) {
645b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                        --len; /* remove unneeded '=' */
646b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    }
647b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    /* restore cap and p to what they were at start */
648b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    cap=destCapacity-length;
649b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    if(cap <= 0) {
650b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                        cap=0;
651b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    } else {
652b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                        p=dest+length;
653b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                    }
654b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                }
655b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                len+=vlen; /* total we added for key + '=' + value */
656b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            }
657b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        } break;
658b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    } /* end switch */
659b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
660b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    if (len>0) {
661b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        /* we addeed a component, so add separator and write it if there's room. */
662b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        if(len+sepLen<=cap) {
663b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            p+=len;
664b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            for(int32_t i=0;i<sepLen;++i) {
665b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                *p++=separator[i];
666b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            }
667b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        }
668b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        length+=len+sepLen;
669b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    } else if(subdone) {
670b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        /* remove separator if we added it */
671b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        if (length!=restPos) {
672b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            length-=sepLen;
673b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        }
674b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        restLen=length-restPos;
675b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        haveRest=restLen>0;
676b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    }
677b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
678b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
67950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
680b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if(*pErrorCode == U_BUFFER_OVERFLOW_ERROR) {
681b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                *pErrorCode=U_ZERO_ERROR;
682b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
68350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
684b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if(subdone) {
685b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if(haveLang && haveRest) {
686b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    /* append internal portion of pattern, the first time,
687b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                       or last portion of pattern the second time */
688b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    int32_t padLen;
689b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    patPos+=subLen;
690b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    padLen=(subi==0 ? sub1Pos : patLen)-patPos;
691b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    if(length+padLen < destCapacity) {
692b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        p=dest+length;
693b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        for(int32_t i=0;i<padLen;++i) {
694b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            *p++=pattern[patPos++];
695b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        }
696b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    } else {
697b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        patPos+=padLen;
698b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    }
699b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    length+=padLen;
700b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                } else if(subi==0) {
701b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    /* don't have first component, reset for second component */
702b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    sub0Pos=0;
703b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    length=0;
704b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                } else if(length>0) {
705b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    /* true length is the length of just the component we got. */
706b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    length=haveLang?langLen:restLen;
707b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    if(dest && sub0Pos!=0) {
708b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        if (sub0Pos+length<=destCapacity) {
709b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            /* first component not at start of result,
710b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                               but we have full component in buffer. */
711b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            u_memmove(dest, dest+(haveLang?langPos:restPos), length);
712b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        } else {
713b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            /* would have fit, but didn't because of pattern prefix. */
714b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            sub0Pos=0; /* stops initial padding (and a second retry,
715b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                          so we won't end up here again) */
716b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                            retry=TRUE;
717b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        }
718b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    }
719b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
720b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
721b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                ++subi; /* move on to next substitution */
722b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
72350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
724b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } while(retry);
72550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
72650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return u_terminateUChars(dest, destCapacity, length, pErrorCode);
72750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
72850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
72950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI int32_t U_EXPORT2
73050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouloc_getDisplayKeyword(const char* keyword,
73150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       const char* displayLocale,
73250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       UChar* dest,
73350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       int32_t destCapacity,
73450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       UErrorCode* status){
73550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
73650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /* argument checking */
73750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(status==NULL || U_FAILURE(*status)) {
73850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
73950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
74050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
74150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(destCapacity<0 || (destCapacity>0 && dest==NULL)) {
74250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *status=U_ILLEGAL_ARGUMENT_ERROR;
74350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
74450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
74550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
74650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
74750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /* pass itemKey=NULL to look for a top-level item */
74850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return _getStringOrCopyKey(U_ICUDATA_LANG, displayLocale,
74950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               _kKeys, NULL,
75050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               keyword,
75150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               keyword,
75250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               dest, destCapacity,
75350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               status);
75450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
75550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
75650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
75750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
75850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define UCURRENCY_DISPLAY_NAME_INDEX 1
75950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
76050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI int32_t U_EXPORT2
76150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouloc_getDisplayKeywordValue(   const char* locale,
76250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               const char* keyword,
76350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               const char* displayLocale,
76450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               UChar* dest,
76550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               int32_t destCapacity,
76650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                               UErrorCode* status){
76750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
76850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
76950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char keywordValue[ULOC_FULLNAME_CAPACITY*4];
77050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t capacity = ULOC_FULLNAME_CAPACITY*4;
77150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t keywordValueLen =0;
77250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
77350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /* argument checking */
77450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(status==NULL || U_FAILURE(*status)) {
77550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
77650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
77750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
77850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(destCapacity<0 || (destCapacity>0 && dest==NULL)) {
77950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *status=U_ILLEGAL_ARGUMENT_ERROR;
78050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
78150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
78250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
78350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /* get the keyword value */
78450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    keywordValue[0]=0;
78550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    keywordValueLen = uloc_getKeywordValue(locale, keyword, keywordValue, capacity, status);
78650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
78750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /*
78850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * if the keyword is equal to currency .. then to get the display name
78950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * we need to do the fallback ourselves
79050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
79150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(uprv_stricmp(keyword, _kCurrency)==0){
79250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
79350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int32_t dispNameLen = 0;
79450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        const UChar *dispName = NULL;
79550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
79650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UResourceBundle *bundle     = ures_open(U_ICUDATA_CURR, displayLocale, status);
79750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UResourceBundle *currencies = ures_getByKey(bundle, _kCurrencies, NULL, status);
79850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UResourceBundle *currency   = ures_getByKeyWithFallback(currencies, keywordValue, NULL, status);
79950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
80050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dispName = ures_getStringByIndex(currency, UCURRENCY_DISPLAY_NAME_INDEX, &dispNameLen, status);
80150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
80250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /*close the bundles */
80350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        ures_close(currency);
80450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        ures_close(currencies);
80550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        ures_close(bundle);
80650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
80750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_FAILURE(*status)){
80850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if(*status == U_MISSING_RESOURCE_ERROR){
80950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                /* we just want to write the value over if nothing is available */
81050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                *status = U_USING_DEFAULT_WARNING;
81150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }else{
81250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                return 0;
81350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
81450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
81550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
81650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /* now copy the dispName over if not NULL */
81750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(dispName != NULL){
81850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if(dispNameLen <= destCapacity){
81950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                uprv_memcpy(dest, dispName, dispNameLen * U_SIZEOF_UCHAR);
82050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                return u_terminateUChars(dest, destCapacity, dispNameLen, status);
82150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }else{
82250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                *status = U_BUFFER_OVERFLOW_ERROR;
82350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                return dispNameLen;
82450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
82550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }else{
82650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /* we have not found the display name for the value .. just copy over */
82750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if(keywordValueLen <= destCapacity){
82850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                u_charsToUChars(keywordValue, dest, keywordValueLen);
82950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                return u_terminateUChars(dest, destCapacity, keywordValueLen, status);
83050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }else{
83150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 *status = U_BUFFER_OVERFLOW_ERROR;
83250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                return keywordValueLen;
83350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
83450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
83550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
83650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
83750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }else{
83850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
83950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return _getStringOrCopyKey(U_ICUDATA_LANG, displayLocale,
84050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                   _kTypes, keyword,
84150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                   keywordValue,
84250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                   keywordValue,
84350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                   dest, destCapacity,
84450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                   status);
84550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
84650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
847