2 *******************************************************************************
4 * Copyright (C) 1997-2010, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * file name: locdispnames.cpp
10 * tab size: 8 (not used)
13 * created on: 2010feb25
14 * created by: Markus W. Scherer
16 * Code for locale display names, separated out from other .cpp files
17 * that then do not depend on resource bundle code and display name data.
20 #include "unicode/utypes.h"
21 #include "unicode/brkiter.h"
22 #include "unicode/locid.h"
23 #include "unicode/uloc.h"
24 #include "unicode/ures.h"
25 #include "unicode/ustring.h"
34 // C++ API ----------------------------------------------------------------- ***
39 Locale::getDisplayLanguage(UnicodeString
& dispLang
) const
41 return this->getDisplayLanguage(getDefault(), dispLang
);
44 /*We cannot make any assumptions on the size of the output display strings
45 * Yet, since we are calling through to a C API, we need to set limits on
46 * buffer size. For all the following getDisplay functions we first attempt
47 * to fill up a stack allocated buffer. If it is to small we heap allocated
48 * the exact buffer we need copy it to the UnicodeString and delete it*/
51 Locale::getDisplayLanguage(const Locale
&displayLocale
,
52 UnicodeString
&result
) const {
54 UErrorCode errorCode
=U_ZERO_ERROR
;
57 buffer
=result
.getBuffer(ULOC_FULLNAME_CAPACITY
);
63 length
=uloc_getDisplayLanguage(fullName
, displayLocale
.fullName
,
64 buffer
, result
.getCapacity(),
66 result
.releaseBuffer(U_SUCCESS(errorCode
) ? length
: 0);
68 if(errorCode
==U_BUFFER_OVERFLOW_ERROR
) {
69 buffer
=result
.getBuffer(length
);
74 errorCode
=U_ZERO_ERROR
;
75 length
=uloc_getDisplayLanguage(fullName
, displayLocale
.fullName
,
76 buffer
, result
.getCapacity(),
78 result
.releaseBuffer(U_SUCCESS(errorCode
) ? length
: 0);
85 Locale::getDisplayScript(UnicodeString
& dispScript
) const
87 return this->getDisplayScript(getDefault(), dispScript
);
91 Locale::getDisplayScript(const Locale
&displayLocale
,
92 UnicodeString
&result
) const {
94 UErrorCode errorCode
=U_ZERO_ERROR
;
97 buffer
=result
.getBuffer(ULOC_FULLNAME_CAPACITY
);
103 length
=uloc_getDisplayScript(fullName
, displayLocale
.fullName
,
104 buffer
, result
.getCapacity(),
106 result
.releaseBuffer(U_SUCCESS(errorCode
) ? length
: 0);
108 if(errorCode
==U_BUFFER_OVERFLOW_ERROR
) {
109 buffer
=result
.getBuffer(length
);
114 errorCode
=U_ZERO_ERROR
;
115 length
=uloc_getDisplayScript(fullName
, displayLocale
.fullName
,
116 buffer
, result
.getCapacity(),
118 result
.releaseBuffer(U_SUCCESS(errorCode
) ? length
: 0);
125 Locale::getDisplayCountry(UnicodeString
& dispCntry
) const
127 return this->getDisplayCountry(getDefault(), dispCntry
);
131 Locale::getDisplayCountry(const Locale
&displayLocale
,
132 UnicodeString
&result
) const {
134 UErrorCode errorCode
=U_ZERO_ERROR
;
137 buffer
=result
.getBuffer(ULOC_FULLNAME_CAPACITY
);
143 length
=uloc_getDisplayCountry(fullName
, displayLocale
.fullName
,
144 buffer
, result
.getCapacity(),
146 result
.releaseBuffer(U_SUCCESS(errorCode
) ? length
: 0);
148 if(errorCode
==U_BUFFER_OVERFLOW_ERROR
) {
149 buffer
=result
.getBuffer(length
);
154 errorCode
=U_ZERO_ERROR
;
155 length
=uloc_getDisplayCountry(fullName
, displayLocale
.fullName
,
156 buffer
, result
.getCapacity(),
158 result
.releaseBuffer(U_SUCCESS(errorCode
) ? length
: 0);
165 Locale::getDisplayVariant(UnicodeString
& dispVar
) const
167 return this->getDisplayVariant(getDefault(), dispVar
);
171 Locale::getDisplayVariant(const Locale
&displayLocale
,
172 UnicodeString
&result
) const {
174 UErrorCode errorCode
=U_ZERO_ERROR
;
177 buffer
=result
.getBuffer(ULOC_FULLNAME_CAPACITY
);
183 length
=uloc_getDisplayVariant(fullName
, displayLocale
.fullName
,
184 buffer
, result
.getCapacity(),
186 result
.releaseBuffer(U_SUCCESS(errorCode
) ? length
: 0);
188 if(errorCode
==U_BUFFER_OVERFLOW_ERROR
) {
189 buffer
=result
.getBuffer(length
);
194 errorCode
=U_ZERO_ERROR
;
195 length
=uloc_getDisplayVariant(fullName
, displayLocale
.fullName
,
196 buffer
, result
.getCapacity(),
198 result
.releaseBuffer(U_SUCCESS(errorCode
) ? length
: 0);
205 Locale::getDisplayName( UnicodeString
& name
) const
207 return this->getDisplayName(getDefault(), name
);
211 Locale::getDisplayName(const Locale
&displayLocale
,
212 UnicodeString
&result
) const {
214 UErrorCode errorCode
=U_ZERO_ERROR
;
217 buffer
=result
.getBuffer(ULOC_FULLNAME_CAPACITY
);
223 length
=uloc_getDisplayName(fullName
, displayLocale
.fullName
,
224 buffer
, result
.getCapacity(),
226 result
.releaseBuffer(U_SUCCESS(errorCode
) ? length
: 0);
228 if(errorCode
==U_BUFFER_OVERFLOW_ERROR
) {
229 buffer
=result
.getBuffer(length
);
234 errorCode
=U_ZERO_ERROR
;
235 length
=uloc_getDisplayName(fullName
, displayLocale
.fullName
,
236 buffer
, result
.getCapacity(),
238 result
.releaseBuffer(U_SUCCESS(errorCode
) ? length
: 0);
244 #if ! UCONFIG_NO_BREAK_ITERATION
246 // -------------------------------------
247 // Gets the objectLocale display name in the default locale language.
248 UnicodeString
& U_EXPORT2
249 BreakIterator::getDisplayName(const Locale
& objectLocale
,
252 return objectLocale
.getDisplayName(name
);
255 // -------------------------------------
256 // Gets the objectLocale display name in the displayLocale language.
257 UnicodeString
& U_EXPORT2
258 BreakIterator::getDisplayName(const Locale
& objectLocale
,
259 const Locale
& displayLocale
,
262 return objectLocale
.getDisplayName(displayLocale
, name
);
270 // C API ------------------------------------------------------------------- ***
274 /* ### Constants **************************************************/
276 /* These strings describe the resources we attempt to load from
277 the locale ResourceBundle data file.*/
278 static const char _kLanguages
[] = "Languages";
279 static const char _kScripts
[] = "Scripts";
280 static const char _kCountries
[] = "Countries";
281 static const char _kVariants
[] = "Variants";
282 static const char _kKeys
[] = "Keys";
283 static const char _kTypes
[] = "Types";
284 static const char _kRootName
[] = "root";
285 static const char _kCurrency
[] = "currency";
286 static const char _kCurrencies
[] = "Currencies";
287 static const char _kLocaleDisplayPattern
[] = "localeDisplayPattern";
288 static const char _kPattern
[] = "pattern";
289 static const char _kSeparator
[] = "separator";
291 /* ### Display name **************************************************/
294 _getStringOrCopyKey(const char *path
, const char *locale
,
295 const char *tableKey
,
296 const char* subTableKey
,
298 const char *substitute
,
299 UChar
*dest
, int32_t destCapacity
,
300 UErrorCode
*pErrorCode
) {
301 const UChar
*s
= NULL
;
305 /* top-level item: normal resource bundle access */
308 rb
=ures_open(path
, locale
, pErrorCode
);
310 if(U_SUCCESS(*pErrorCode
)) {
311 s
=ures_getStringByKey(rb
, tableKey
, &length
, pErrorCode
);
312 /* see comment about closing rb near "return item;" in _res_getTableStringWithFallback() */
316 /* Language code should not be a number. If it is, set the error code. */
317 if (!uprv_strncmp(tableKey
, "Languages", 9) && uprv_strtol(itemKey
, NULL
, 10)) {
318 *pErrorCode
= U_MISSING_RESOURCE_ERROR
;
320 /* second-level item, use special fallback */
321 s
=uloc_getTableStringWithFallback(path
, locale
,
330 if(U_SUCCESS(*pErrorCode
)) {
331 int32_t copyLength
=uprv_min(length
, destCapacity
);
332 if(copyLength
>0 && s
!= NULL
) {
333 u_memcpy(dest
, s
, copyLength
);
336 /* no string from a resource bundle: convert the substitute */
337 length
=(int32_t)uprv_strlen(substitute
);
338 u_charsToUChars(substitute
, dest
, uprv_min(length
, destCapacity
));
339 *pErrorCode
=U_USING_DEFAULT_WARNING
;
342 return u_terminateUChars(dest
, destCapacity
, length
, pErrorCode
);
345 typedef int32_t U_CALLCONV
UDisplayNameGetter(const char *, char *, int32_t, UErrorCode
*);
348 _getDisplayNameForComponent(const char *locale
,
349 const char *displayLocale
,
350 UChar
*dest
, int32_t destCapacity
,
351 UDisplayNameGetter
*getter
,
353 UErrorCode
*pErrorCode
) {
354 char localeBuffer
[ULOC_FULLNAME_CAPACITY
*4];
356 UErrorCode localStatus
;
357 const char* root
= NULL
;
359 /* argument checking */
360 if(pErrorCode
==NULL
|| U_FAILURE(*pErrorCode
)) {
364 if(destCapacity
<0 || (destCapacity
>0 && dest
==NULL
)) {
365 *pErrorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
369 localStatus
= U_ZERO_ERROR
;
370 length
=(*getter
)(locale
, localeBuffer
, sizeof(localeBuffer
), &localStatus
);
371 if(U_FAILURE(localStatus
) || localStatus
==U_STRING_NOT_TERMINATED_WARNING
) {
372 *pErrorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
376 return u_terminateUChars(dest
, destCapacity
, 0, pErrorCode
);
379 root
= tag
== _kCountries
? U_ICUDATA_REGION
: U_ICUDATA_LANG
;
381 return _getStringOrCopyKey(root
, displayLocale
,
382 tag
, NULL
, localeBuffer
,
388 U_CAPI
int32_t U_EXPORT2
389 uloc_getDisplayLanguage(const char *locale
,
390 const char *displayLocale
,
391 UChar
*dest
, int32_t destCapacity
,
392 UErrorCode
*pErrorCode
) {
393 return _getDisplayNameForComponent(locale
, displayLocale
, dest
, destCapacity
,
394 uloc_getLanguage
, _kLanguages
, pErrorCode
);
397 U_CAPI
int32_t U_EXPORT2
398 uloc_getDisplayScript(const char* locale
,
399 const char* displayLocale
,
400 UChar
*dest
, int32_t destCapacity
,
401 UErrorCode
*pErrorCode
)
403 return _getDisplayNameForComponent(locale
, displayLocale
, dest
, destCapacity
,
404 uloc_getScript
, _kScripts
, pErrorCode
);
407 U_CAPI
int32_t U_EXPORT2
408 uloc_getDisplayCountry(const char *locale
,
409 const char *displayLocale
,
410 UChar
*dest
, int32_t destCapacity
,
411 UErrorCode
*pErrorCode
) {
412 return _getDisplayNameForComponent(locale
, displayLocale
, dest
, destCapacity
,
413 uloc_getCountry
, _kCountries
, pErrorCode
);
417 * TODO separate variant1_variant2_variant3...
418 * by getting each tag's display string and concatenating them with ", "
419 * in between - similar to uloc_getDisplayName()
421 U_CAPI
int32_t U_EXPORT2
422 uloc_getDisplayVariant(const char *locale
,
423 const char *displayLocale
,
424 UChar
*dest
, int32_t destCapacity
,
425 UErrorCode
*pErrorCode
) {
426 return _getDisplayNameForComponent(locale
, displayLocale
, dest
, destCapacity
,
427 uloc_getVariant
, _kVariants
, pErrorCode
);
430 U_CAPI
int32_t U_EXPORT2
431 uloc_getDisplayName(const char *locale
,
432 const char *displayLocale
,
433 UChar
*dest
, int32_t destCapacity
,
434 UErrorCode
*pErrorCode
)
436 int32_t length
, length2
, length3
= 0;
437 UBool hasLanguage
, hasScript
, hasCountry
, hasVariant
, hasKeywords
;
438 UEnumeration
* keywordEnum
= NULL
;
439 int32_t keywordCount
= 0;
440 const char *keyword
= NULL
;
441 int32_t keywordLen
= 0;
442 char keywordValue
[256];
443 int32_t keywordValueLen
= 0;
445 int32_t locSepLen
= 0;
446 int32_t locPatLen
= 0;
448 int32_t defaultPatternLen
= 9;
449 const UChar
*dispLocSeparator
;
450 const UChar
*dispLocPattern
;
451 static const UChar defaultSeparator
[3] = { 0x002c, 0x0020 , 0x0000 }; /* comma + space */
452 static const UChar defaultPattern
[10] = { 0x007b, 0x0030, 0x007d, 0x0020, 0x0028, 0x007b, 0x0031, 0x007d, 0x0029, 0x0000 }; /* {0} ({1}) */
453 static const UChar pat0
[4] = { 0x007b, 0x0030, 0x007d , 0x0000 } ; /* {0} */
454 static const UChar pat1
[4] = { 0x007b, 0x0031, 0x007d , 0x0000 } ; /* {1} */
456 UResourceBundle
*bundle
= NULL
;
457 UResourceBundle
*locdsppat
= NULL
;
459 UErrorCode status
= U_ZERO_ERROR
;
461 /* argument checking */
462 if(pErrorCode
==NULL
|| U_FAILURE(*pErrorCode
)) {
466 if(destCapacity
<0 || (destCapacity
>0 && dest
==NULL
)) {
467 *pErrorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
471 bundle
= ures_open(U_ICUDATA_LANG
, displayLocale
, &status
);
473 locdsppat
= ures_getByKeyWithFallback(bundle
, _kLocaleDisplayPattern
, NULL
, &status
);
474 dispLocSeparator
= ures_getStringByKeyWithFallback(locdsppat
, _kSeparator
, &locSepLen
, &status
);
475 dispLocPattern
= ures_getStringByKeyWithFallback(locdsppat
, _kPattern
, &locPatLen
, &status
);
477 /*close the bundles */
478 ures_close(locdsppat
);
481 /* If we couldn't find any data, then use the defaults */
482 if ( locSepLen
== 0) {
483 dispLocSeparator
= defaultSeparator
;
487 if ( locPatLen
== 0) {
488 dispLocPattern
= defaultPattern
;
493 * if there is a language, then write "language (country, variant)"
494 * otherwise write "country, variant"
497 /* write the language */
498 length
=uloc_getDisplayLanguage(locale
, displayLocale
,
501 hasLanguage
= length
>0;
507 if(length
<destCapacity
) {
511 if(length
<destCapacity
) {
517 if(*pErrorCode
==U_BUFFER_OVERFLOW_ERROR
) {
518 /* keep preflighting */
519 *pErrorCode
=U_ZERO_ERROR
;
522 /* append the script */
523 if(length
<destCapacity
) {
524 length2
=uloc_getDisplayScript(locale
, displayLocale
,
525 dest
+length
, destCapacity
-length
,
528 length2
=uloc_getDisplayScript(locale
, displayLocale
,
532 hasScript
= length2
>0;
536 /* append separator */
537 if(length
+locSepLen
<=destCapacity
) {
538 u_memcpy(dest
+length
,dispLocSeparator
,locSepLen
);
543 if(*pErrorCode
==U_BUFFER_OVERFLOW_ERROR
) {
544 /* keep preflighting */
545 *pErrorCode
=U_ZERO_ERROR
;
548 /* append the country */
549 if(length
<destCapacity
) {
550 length2
=uloc_getDisplayCountry(locale
, displayLocale
,
551 dest
+length
, destCapacity
-length
,
554 length2
=uloc_getDisplayCountry(locale
, displayLocale
,
558 hasCountry
= length2
>0;
562 /* append separator */
563 if(length
+locSepLen
<=destCapacity
) {
564 u_memcpy(dest
+length
,dispLocSeparator
,locSepLen
);
569 if(*pErrorCode
==U_BUFFER_OVERFLOW_ERROR
) {
570 /* keep preflighting */
571 *pErrorCode
=U_ZERO_ERROR
;
574 /* append the variant */
575 if(length
<destCapacity
) {
576 length2
=uloc_getDisplayVariant(locale
, displayLocale
,
577 dest
+length
, destCapacity
-length
,
580 length2
=uloc_getDisplayVariant(locale
, displayLocale
,
584 hasVariant
= length2
>0;
588 /* append separator */
589 if(length
+locSepLen
<=destCapacity
) {
590 u_memcpy(dest
+length
,dispLocSeparator
,locSepLen
);
595 keywordEnum
= uloc_openKeywords(locale
, pErrorCode
);
597 for(keywordCount
= uenum_count(keywordEnum
, pErrorCode
); keywordCount
> 0 ; keywordCount
--){
598 if(U_FAILURE(*pErrorCode
)){
601 /* the uenum_next returns NUL terminated string */
602 keyword
= uenum_next(keywordEnum
, &keywordLen
, pErrorCode
);
603 if(length
+ length3
< destCapacity
) {
604 length3
+= uloc_getDisplayKeyword(keyword
, displayLocale
, dest
+length
+length3
, destCapacity
-length
-length3
, pErrorCode
);
606 length3
+= uloc_getDisplayKeyword(keyword
, displayLocale
, NULL
, 0, pErrorCode
);
608 if(*pErrorCode
==U_BUFFER_OVERFLOW_ERROR
) {
609 /* keep preflighting */
610 *pErrorCode
=U_ZERO_ERROR
;
612 keywordValueLen
= uloc_getKeywordValue(locale
, keyword
, keywordValue
, 256, pErrorCode
);
613 if(keywordValueLen
) {
614 if(length
+ length3
< destCapacity
) {
615 dest
[length
+ length3
] = 0x3D;
618 if(length
+ length3
< destCapacity
) {
619 length3
+= uloc_getDisplayKeywordValue(locale
, keyword
, displayLocale
, dest
+length
+length3
, destCapacity
-length
-length3
, pErrorCode
);
621 length3
+= uloc_getDisplayKeywordValue(locale
, keyword
, displayLocale
, NULL
, 0, pErrorCode
);
623 if(*pErrorCode
==U_BUFFER_OVERFLOW_ERROR
) {
624 /* keep preflighting */
625 *pErrorCode
=U_ZERO_ERROR
;
628 if(keywordCount
> 1) {
629 if(length
+ length3
+ locSepLen
<= destCapacity
&& keywordCount
) {
630 u_memcpy(dest
+length
+length3
,dispLocSeparator
,locSepLen
);
635 uenum_close(keywordEnum
);
637 hasKeywords
= length3
> 0;
641 if ((hasScript
&& !hasCountry
)
642 || ((hasScript
|| hasCountry
) && !hasVariant
&& !hasKeywords
)
643 || ((hasScript
|| hasCountry
|| hasVariant
) && !hasKeywords
)) {
644 /* Remove separator */
646 } else if (hasLanguage
&& !hasScript
&& !hasCountry
&& !hasVariant
&& !hasKeywords
) {
651 if (hasLanguage
&& (hasScript
|| hasCountry
|| hasVariant
|| hasKeywords
)) {
653 if(length
<destCapacity
) {
658 /* If the localized display pattern is something other than the default pattern of "{0} ({1})", then
659 * then we need to do the formatting here. It would be easier to use a messageFormat to do this, but we
660 * can't since we don't have the APIs in the i18n library available to us at this point.
662 if (locPatLen
!= defaultPatternLen
|| u_strcmp(dispLocPattern
,defaultPattern
)) { /* Something other than the default pattern */
663 UChar
*p0
= u_strstr(dispLocPattern
,pat0
);
664 UChar
*p1
= u_strstr(dispLocPattern
,pat1
);
665 u_terminateUChars(dest
, destCapacity
, length
, pErrorCode
);
667 if ( p0
!= NULL
&& p1
!= NULL
) { /* The pattern is well formed */
670 UChar
*result
= (UChar
*)uprv_malloc((length
+1)*sizeof(UChar
));
671 UChar
*upos
= (UChar
*)dispLocPattern
;
672 u_strcpy(result
,dest
);
675 if ( upos
== p0
) { /* Handle {0} substitution */
676 u_strncat(dest
,result
,p0Len
);
678 dest
[destLen
] = 0; /* Null terminate */
680 } else if ( upos
== p1
) { /* Handle {1} substitution */
681 UChar
*p1Start
= &result
[p0Len
+2];
682 u_strncat(dest
,p1Start
,length
-p0Len
-3);
683 destLen
+= (length
-p0Len
-3);
684 dest
[destLen
] = 0; /* Null terminate */
686 } else { /* Something from the pattern not {0} or {1} */
687 u_strncat(dest
,upos
,1);
690 dest
[destLen
] = 0; /* Null terminate */
699 if(*pErrorCode
==U_BUFFER_OVERFLOW_ERROR
) {
700 /* keep preflighting */
701 *pErrorCode
=U_ZERO_ERROR
;
704 return u_terminateUChars(dest
, destCapacity
, length
, pErrorCode
);
707 U_CAPI
int32_t U_EXPORT2
708 uloc_getDisplayKeyword(const char* keyword
,
709 const char* displayLocale
,
711 int32_t destCapacity
,
714 /* argument checking */
715 if(status
==NULL
|| U_FAILURE(*status
)) {
719 if(destCapacity
<0 || (destCapacity
>0 && dest
==NULL
)) {
720 *status
=U_ILLEGAL_ARGUMENT_ERROR
;
725 /* pass itemKey=NULL to look for a top-level item */
726 return _getStringOrCopyKey(U_ICUDATA_LANG
, displayLocale
,
736 #define UCURRENCY_DISPLAY_NAME_INDEX 1
738 U_CAPI
int32_t U_EXPORT2
739 uloc_getDisplayKeywordValue( const char* locale
,
741 const char* displayLocale
,
743 int32_t destCapacity
,
747 char keywordValue
[ULOC_FULLNAME_CAPACITY
*4];
748 int32_t capacity
= ULOC_FULLNAME_CAPACITY
*4;
749 int32_t keywordValueLen
=0;
751 /* argument checking */
752 if(status
==NULL
|| U_FAILURE(*status
)) {
756 if(destCapacity
<0 || (destCapacity
>0 && dest
==NULL
)) {
757 *status
=U_ILLEGAL_ARGUMENT_ERROR
;
761 /* get the keyword value */
763 keywordValueLen
= uloc_getKeywordValue(locale
, keyword
, keywordValue
, capacity
, status
);
766 * if the keyword is equal to currency .. then to get the display name
767 * we need to do the fallback ourselves
769 if(uprv_stricmp(keyword
, _kCurrency
)==0){
771 int32_t dispNameLen
= 0;
772 const UChar
*dispName
= NULL
;
774 UResourceBundle
*bundle
= ures_open(U_ICUDATA_CURR
, displayLocale
, status
);
775 UResourceBundle
*currencies
= ures_getByKey(bundle
, _kCurrencies
, NULL
, status
);
776 UResourceBundle
*currency
= ures_getByKeyWithFallback(currencies
, keywordValue
, NULL
, status
);
778 dispName
= ures_getStringByIndex(currency
, UCURRENCY_DISPLAY_NAME_INDEX
, &dispNameLen
, status
);
780 /*close the bundles */
781 ures_close(currency
);
782 ures_close(currencies
);
785 if(U_FAILURE(*status
)){
786 if(*status
== U_MISSING_RESOURCE_ERROR
){
787 /* we just want to write the value over if nothing is available */
788 *status
= U_USING_DEFAULT_WARNING
;
794 /* now copy the dispName over if not NULL */
795 if(dispName
!= NULL
){
796 if(dispNameLen
<= destCapacity
){
797 uprv_memcpy(dest
, dispName
, dispNameLen
* U_SIZEOF_UCHAR
);
798 return u_terminateUChars(dest
, destCapacity
, dispNameLen
, status
);
800 *status
= U_BUFFER_OVERFLOW_ERROR
;
804 /* we have not found the display name for the value .. just copy over */
805 if(keywordValueLen
<= destCapacity
){
806 u_charsToUChars(keywordValue
, dest
, keywordValueLen
);
807 return u_terminateUChars(dest
, destCapacity
, keywordValueLen
, status
);
809 *status
= U_BUFFER_OVERFLOW_ERROR
;
810 return keywordValueLen
;
817 return _getStringOrCopyKey(U_ICUDATA_LANG
, displayLocale
,