1 /* 2 ******************************************************************************* 3 * Copyright (C) 2010, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 8 #include "unicode/utypes.h" 9 10 #if !UCONFIG_NO_FORMATTING 11 12 #include "unicode/locdspnm.h" 13 14 #include "unicode/msgfmt.h" 15 16 #include "cmemory.h" 17 #include "cstring.h" 18 #include "ulocimp.h" 19 #include "ureslocs.h" 20 21 #include <stdarg.h> 22 23 /** 24 * Concatenate a number of null-terminated strings to buffer, leaving a 25 * null-terminated string. The last argument should be the null pointer. 26 * Return the length of the string in the buffer, not counting the trailing 27 * null. Return -1 if there is an error (buffer is null, or buflen < 1). 28 */ 29 static int32_t ncat(char *buffer, uint32_t buflen, ...) { 30 va_list args; 31 char *str; 32 char *p = buffer; 33 const char* e = buffer + buflen - 1; 34 35 if (buffer == NULL || buflen < 1) { 36 return -1; 37 } 38 39 va_start(args, buflen); 40 while ((str = va_arg(args, char *))) { 41 char c; 42 while (p != e && (c = *str++)) { 43 *p++ = c; 44 } 45 } 46 *p = 0; 47 va_end(args); 48 49 return p - buffer; 50 } 51 52 U_NAMESPACE_BEGIN 53 54 //////////////////////////////////////////////////////////////////////////////////////////////////// 55 56 // Access resource data for locale components. 57 // Wrap code in uloc.c for now. 58 class ICUDataTable { 59 const char* path; 60 Locale locale; 61 62 public: 63 ICUDataTable(const char* path, const Locale& locale); 64 ~ICUDataTable(); 65 66 const Locale& getLocale(); 67 68 UnicodeString& get(const char* tableKey, const char* itemKey, 69 UnicodeString& result) const; 70 UnicodeString& get(const char* tableKey, const char* subTableKey, const char* itemKey, 71 UnicodeString& result) const; 72 73 UnicodeString& getNoFallback(const char* tableKey, const char* itemKey, 74 UnicodeString &result) const; 75 UnicodeString& getNoFallback(const char* tableKey, const char* subTableKey, const char* itemKey, 76 UnicodeString &result) const; 77 }; 78 79 inline UnicodeString & 80 ICUDataTable::get(const char* tableKey, const char* itemKey, UnicodeString& result) const { 81 return get(tableKey, NULL, itemKey, result); 82 } 83 84 inline UnicodeString & 85 ICUDataTable::getNoFallback(const char* tableKey, const char* itemKey, UnicodeString& result) const { 86 return getNoFallback(tableKey, NULL, itemKey, result); 87 } 88 89 ICUDataTable::ICUDataTable(const char* path, const Locale& locale) 90 : path(NULL), locale(Locale::getRoot()) 91 { 92 if (path) { 93 int32_t len = uprv_strlen(path); 94 this->path = (const char*) uprv_malloc(len + 1); 95 if (this->path) { 96 uprv_strcpy((char *)this->path, path); 97 this->locale = locale; 98 } 99 } 100 } 101 102 ICUDataTable::~ICUDataTable() { 103 if (path) { 104 uprv_free((void*) path); 105 path = NULL; 106 } 107 } 108 109 const Locale& 110 ICUDataTable::getLocale() { 111 return locale; 112 } 113 114 UnicodeString & 115 ICUDataTable::get(const char* tableKey, const char* subTableKey, const char* itemKey, 116 UnicodeString &result) const { 117 UErrorCode status = U_ZERO_ERROR; 118 int32_t len = 0; 119 120 const UChar *s = uloc_getTableStringWithFallback(path, locale.getName(), 121 tableKey, subTableKey, itemKey, 122 &len, &status); 123 if (U_SUCCESS(status)) { 124 return result.setTo(s, len); 125 } 126 return result.setTo(UnicodeString(itemKey, -1, US_INV)); 127 } 128 129 UnicodeString & 130 ICUDataTable::getNoFallback(const char* tableKey, const char* subTableKey, const char* itemKey, 131 UnicodeString& result) const { 132 UErrorCode status = U_ZERO_ERROR; 133 int32_t len = 0; 134 135 const UChar *s = uloc_getTableStringWithFallback(path, locale.getName(), 136 tableKey, subTableKey, itemKey, 137 &len, &status); 138 if (U_SUCCESS(status)) { 139 return result.setTo(s, len); 140 } 141 142 result.setToBogus(); 143 return result; 144 } 145 146 //////////////////////////////////////////////////////////////////////////////////////////////////// 147 148 UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(LocaleDisplayNames) 149 150 //////////////////////////////////////////////////////////////////////////////////////////////////// 151 152 #if 0 // currently unused 153 154 class DefaultLocaleDisplayNames : public LocaleDisplayNames { 155 UDialectHandling dialectHandling; 156 157 public: 158 // constructor 159 DefaultLocaleDisplayNames(UDialectHandling dialectHandling); 160 161 virtual ~DefaultLocaleDisplayNames(); 162 163 virtual const Locale& getLocale() const; 164 virtual UDialectHandling getDialectHandling() const; 165 virtual UnicodeString& localeDisplayName(const Locale& locale, 166 UnicodeString& result) const; 167 virtual UnicodeString& localeDisplayName(const char* localeId, 168 UnicodeString& result) const; 169 virtual UnicodeString& languageDisplayName(const char* lang, 170 UnicodeString& result) const; 171 virtual UnicodeString& scriptDisplayName(const char* script, 172 UnicodeString& result) const; 173 virtual UnicodeString& scriptDisplayName(UScriptCode scriptCode, 174 UnicodeString& result) const; 175 virtual UnicodeString& regionDisplayName(const char* region, 176 UnicodeString& result) const; 177 virtual UnicodeString& variantDisplayName(const char* variant, 178 UnicodeString& result) const; 179 virtual UnicodeString& keyDisplayName(const char* key, 180 UnicodeString& result) const; 181 virtual UnicodeString& keyValueDisplayName(const char* key, 182 const char* value, 183 UnicodeString& result) const; 184 }; 185 186 DefaultLocaleDisplayNames::DefaultLocaleDisplayNames(UDialectHandling dialectHandling) 187 : dialectHandling(dialectHandling) { 188 } 189 190 DefaultLocaleDisplayNames::~DefaultLocaleDisplayNames() { 191 } 192 193 const Locale& 194 DefaultLocaleDisplayNames::getLocale() const { 195 return Locale::getRoot(); 196 } 197 198 UDialectHandling 199 DefaultLocaleDisplayNames::getDialectHandling() const { 200 return dialectHandling; 201 } 202 203 UnicodeString& 204 DefaultLocaleDisplayNames::localeDisplayName(const Locale& locale, 205 UnicodeString& result) const { 206 return result = UnicodeString(locale.getName(), -1, US_INV); 207 } 208 209 UnicodeString& 210 DefaultLocaleDisplayNames::localeDisplayName(const char* localeId, 211 UnicodeString& result) const { 212 return result = UnicodeString(localeId, -1, US_INV); 213 } 214 215 UnicodeString& 216 DefaultLocaleDisplayNames::languageDisplayName(const char* lang, 217 UnicodeString& result) const { 218 return result = UnicodeString(lang, -1, US_INV); 219 } 220 221 UnicodeString& 222 DefaultLocaleDisplayNames::scriptDisplayName(const char* script, 223 UnicodeString& result) const { 224 return result = UnicodeString(script, -1, US_INV); 225 } 226 227 UnicodeString& 228 DefaultLocaleDisplayNames::scriptDisplayName(UScriptCode scriptCode, 229 UnicodeString& result) const { 230 const char* name = uscript_getName(scriptCode); 231 if (name) { 232 return result = UnicodeString(name, -1, US_INV); 233 } 234 return result.remove(); 235 } 236 237 UnicodeString& 238 DefaultLocaleDisplayNames::regionDisplayName(const char* region, 239 UnicodeString& result) const { 240 return result = UnicodeString(region, -1, US_INV); 241 } 242 243 UnicodeString& 244 DefaultLocaleDisplayNames::variantDisplayName(const char* variant, 245 UnicodeString& result) const { 246 return result = UnicodeString(variant, -1, US_INV); 247 } 248 249 UnicodeString& 250 DefaultLocaleDisplayNames::keyDisplayName(const char* key, 251 UnicodeString& result) const { 252 return result = UnicodeString(key, -1, US_INV); 253 } 254 255 UnicodeString& 256 DefaultLocaleDisplayNames::keyValueDisplayName(const char* /* key */, 257 const char* value, 258 UnicodeString& result) const { 259 return result = UnicodeString(value, -1, US_INV); 260 } 261 262 #endif // currently unused class DefaultLocaleDisplayNames 263 264 //////////////////////////////////////////////////////////////////////////////////////////////////// 265 266 class LocaleDisplayNamesImpl : public LocaleDisplayNames { 267 Locale locale; 268 UDialectHandling dialectHandling; 269 ICUDataTable langData; 270 ICUDataTable regionData; 271 UnicodeString sep; 272 MessageFormat *format; 273 274 public: 275 // constructor 276 LocaleDisplayNamesImpl(const Locale& locale, UDialectHandling dialectHandling); 277 virtual ~LocaleDisplayNamesImpl(); 278 279 virtual const Locale& getLocale() const; 280 virtual UDialectHandling getDialectHandling() const; 281 282 virtual UnicodeString& localeDisplayName(const Locale& locale, 283 UnicodeString& result) const; 284 virtual UnicodeString& localeDisplayName(const char* localeId, 285 UnicodeString& result) const; 286 virtual UnicodeString& languageDisplayName(const char* lang, 287 UnicodeString& result) const; 288 virtual UnicodeString& scriptDisplayName(const char* script, 289 UnicodeString& result) const; 290 virtual UnicodeString& scriptDisplayName(UScriptCode scriptCode, 291 UnicodeString& result) const; 292 virtual UnicodeString& regionDisplayName(const char* region, 293 UnicodeString& result) const; 294 virtual UnicodeString& variantDisplayName(const char* variant, 295 UnicodeString& result) const; 296 virtual UnicodeString& keyDisplayName(const char* key, 297 UnicodeString& result) const; 298 virtual UnicodeString& keyValueDisplayName(const char* key, 299 const char* value, 300 UnicodeString& result) const; 301 static UClassID U_EXPORT2 getStaticClassID(); 302 virtual UClassID getDynamicClassID() const; 303 private: 304 UnicodeString& localeIdName(const char* localeId, 305 UnicodeString& result) const; 306 UnicodeString& appendWithSep(UnicodeString& buffer, const UnicodeString& src) const; 307 }; 308 309 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LocaleDisplayNamesImpl) 310 311 LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale, 312 UDialectHandling dialectHandling) 313 : dialectHandling(dialectHandling) 314 , langData(U_ICUDATA_LANG, locale) 315 , regionData(U_ICUDATA_REGION, locale) 316 , format(NULL) 317 { 318 LocaleDisplayNamesImpl *nonConstThis = (LocaleDisplayNamesImpl *)this; 319 nonConstThis->locale = langData.getLocale() == Locale::getRoot() 320 ? regionData.getLocale() 321 : langData.getLocale(); 322 323 langData.getNoFallback("localeDisplayPattern", "separator", sep); 324 if (sep.isBogus()) { 325 sep = UnicodeString(", ", -1, US_INV); 326 } 327 328 UnicodeString pattern; 329 langData.getNoFallback("localeDisplayPattern", "pattern", pattern); 330 if (pattern.isBogus()) { 331 pattern = UnicodeString("{0} ({1})", -1, US_INV); 332 } 333 UErrorCode status = U_ZERO_ERROR; 334 format = new MessageFormat(pattern, status); 335 } 336 337 LocaleDisplayNamesImpl::~LocaleDisplayNamesImpl() { 338 delete format; 339 } 340 341 const Locale& 342 LocaleDisplayNamesImpl::getLocale() const { 343 return locale; 344 } 345 346 UDialectHandling 347 LocaleDisplayNamesImpl::getDialectHandling() const { 348 return dialectHandling; 349 } 350 351 UnicodeString& 352 LocaleDisplayNamesImpl::localeDisplayName(const Locale& locale, 353 UnicodeString& result) const { 354 UnicodeString resultName; 355 356 const char* lang = locale.getLanguage(); 357 if (uprv_strlen(lang) == 0) { 358 lang = "root"; 359 } 360 const char* script = locale.getScript(); 361 const char* country = locale.getCountry(); 362 const char* variant = locale.getVariant(); 363 364 UBool hasScript = uprv_strlen(script) > 0; 365 UBool hasCountry = uprv_strlen(country) > 0; 366 UBool hasVariant = uprv_strlen(variant) > 0; 367 368 if (dialectHandling == ULDN_DIALECT_NAMES) { 369 char buffer[ULOC_FULLNAME_CAPACITY]; 370 do { // loop construct is so we can break early out of search 371 if (hasScript && hasCountry) { 372 ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, "_", country, (char *)0); 373 localeIdName(buffer, resultName); 374 if (!resultName.isBogus()) { 375 hasScript = FALSE; 376 hasCountry = FALSE; 377 break; 378 } 379 } 380 if (hasScript) { 381 ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, (char *)0); 382 localeIdName(buffer, resultName); 383 if (!resultName.isBogus()) { 384 hasScript = FALSE; 385 break; 386 } 387 } 388 if (hasCountry) { 389 ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", country, (char*)0); 390 localeIdName(buffer, resultName); 391 if (!resultName.isBogus()) { 392 hasCountry = FALSE; 393 break; 394 } 395 } 396 } while (FALSE); 397 } 398 if (resultName.isBogus() || resultName.isEmpty()) { 399 localeIdName(lang, resultName); 400 } 401 402 UnicodeString resultRemainder; 403 UnicodeString temp; 404 StringEnumeration *e = NULL; 405 UErrorCode status = U_ZERO_ERROR; 406 407 if (hasScript) { 408 resultRemainder.append(scriptDisplayName(script, temp)); 409 } 410 if (hasCountry) { 411 appendWithSep(resultRemainder, regionDisplayName(country, temp)); 412 } 413 if (hasVariant) { 414 appendWithSep(resultRemainder, variantDisplayName(variant, temp)); 415 } 416 417 e = locale.createKeywords(status); 418 if (e && U_SUCCESS(status)) { 419 UnicodeString temp2; 420 char value[ULOC_KEYWORD_AND_VALUES_CAPACITY]; // sigh, no ULOC_VALUE_CAPACITY 421 const char* key; 422 while ((key = e->next((int32_t *)0, status)) != NULL) { 423 locale.getKeywordValue(key, value, ULOC_KEYWORD_AND_VALUES_CAPACITY, status); 424 appendWithSep(resultRemainder, keyDisplayName(key, temp)) 425 .append("=") 426 .append(keyValueDisplayName(key, value, temp2)); 427 } 428 delete e; 429 } 430 431 if (!resultRemainder.isEmpty()) { 432 Formattable data[] = { 433 resultName, 434 resultRemainder 435 }; 436 FieldPosition fpos; 437 status = U_ZERO_ERROR; 438 format->format(data, 2, result, fpos, status); 439 return result; 440 } 441 442 return result = resultName; 443 } 444 445 UnicodeString& 446 LocaleDisplayNamesImpl::appendWithSep(UnicodeString& buffer, const UnicodeString& src) const { 447 if (!buffer.isEmpty()) { 448 buffer.append(sep); 449 } 450 buffer.append(src); 451 return buffer; 452 } 453 454 UnicodeString& 455 LocaleDisplayNamesImpl::localeDisplayName(const char* localeId, 456 UnicodeString& result) const { 457 return localeDisplayName(Locale(localeId), result); 458 } 459 460 UnicodeString& 461 LocaleDisplayNamesImpl::localeIdName(const char* localeId, 462 UnicodeString& result) const { 463 return langData.getNoFallback("Languages", localeId, result); 464 } 465 466 UnicodeString& 467 LocaleDisplayNamesImpl::languageDisplayName(const char* lang, 468 UnicodeString& result) const { 469 if (uprv_strcmp("root", lang) == 0 || uprv_strchr(lang, '_') != NULL) { 470 return result = UnicodeString(lang, -1, US_INV); 471 } 472 return langData.get("Languages", lang, result); 473 } 474 475 UnicodeString& 476 LocaleDisplayNamesImpl::scriptDisplayName(const char* script, 477 UnicodeString& result) const { 478 return langData.get("Scripts", script, result); 479 } 480 481 UnicodeString& 482 LocaleDisplayNamesImpl::scriptDisplayName(UScriptCode scriptCode, 483 UnicodeString& result) const { 484 const char* name = uscript_getName(scriptCode); 485 return langData.get("Scripts", name, result); 486 } 487 488 UnicodeString& 489 LocaleDisplayNamesImpl::regionDisplayName(const char* region, 490 UnicodeString& result) const { 491 return regionData.get("Countries", region, result); 492 } 493 494 UnicodeString& 495 LocaleDisplayNamesImpl::variantDisplayName(const char* variant, 496 UnicodeString& result) const { 497 return langData.get("Variants", variant, result); 498 } 499 500 UnicodeString& 501 LocaleDisplayNamesImpl::keyDisplayName(const char* key, 502 UnicodeString& result) const { 503 return langData.get("Keys", key, result); 504 } 505 506 UnicodeString& 507 LocaleDisplayNamesImpl::keyValueDisplayName(const char* key, 508 const char* value, 509 UnicodeString& result) const { 510 return langData.get("Types", key, value, result); 511 } 512 513 //////////////////////////////////////////////////////////////////////////////////////////////////// 514 515 LocaleDisplayNames* 516 LocaleDisplayNames::createInstance(const Locale& locale, 517 UDialectHandling dialectHandling) { 518 return new LocaleDisplayNamesImpl(locale, dialectHandling); 519 } 520 521 U_NAMESPACE_END 522 523 //////////////////////////////////////////////////////////////////////////////////////////////////// 524 525 U_NAMESPACE_USE 526 527 U_DRAFT ULocaleDisplayNames * U_EXPORT2 528 uldn_open(const char * locale, 529 UDialectHandling dialectHandling, 530 UErrorCode *pErrorCode) { 531 if (U_FAILURE(*pErrorCode)) { 532 return 0; 533 } 534 if (locale == NULL) { 535 locale = uloc_getDefault(); 536 } 537 return (ULocaleDisplayNames *)LocaleDisplayNames::createInstance(Locale(locale), dialectHandling); 538 } 539 540 U_DRAFT void U_EXPORT2 541 uldn_close(ULocaleDisplayNames *ldn) { 542 delete (LocaleDisplayNames *)ldn; 543 } 544 545 U_DRAFT const char * U_EXPORT2 546 uldn_getLocale(const ULocaleDisplayNames *ldn) { 547 if (ldn) { 548 return ((const LocaleDisplayNames *)ldn)->getLocale().getName(); 549 } 550 return NULL; 551 } 552 553 U_DRAFT UDialectHandling U_EXPORT2 554 uldn_getDialectHandling(const ULocaleDisplayNames *ldn) { 555 if (ldn) { 556 return ((const LocaleDisplayNames *)ldn)->getDialectHandling(); 557 } 558 return ULDN_STANDARD_NAMES; 559 } 560 561 U_DRAFT int32_t U_EXPORT2 562 uldn_localeDisplayName(const ULocaleDisplayNames *ldn, 563 const char *locale, 564 UChar *result, 565 int32_t maxResultSize, 566 UErrorCode *pErrorCode) { 567 if (U_FAILURE(*pErrorCode)) { 568 return 0; 569 } 570 if (ldn == NULL || locale == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) { 571 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 572 return 0; 573 } 574 UnicodeString temp(result, 0, maxResultSize); 575 ((const LocaleDisplayNames *)ldn)->localeDisplayName(locale, temp); 576 return temp.extract(result, maxResultSize, *pErrorCode); 577 } 578 579 U_DRAFT int32_t U_EXPORT2 580 uldn_languageDisplayName(const ULocaleDisplayNames *ldn, 581 const char *lang, 582 UChar *result, 583 int32_t maxResultSize, 584 UErrorCode *pErrorCode) { 585 if (U_FAILURE(*pErrorCode)) { 586 return 0; 587 } 588 if (ldn == NULL || lang == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) { 589 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 590 return 0; 591 } 592 UnicodeString temp(result, 0, maxResultSize); 593 ((const LocaleDisplayNames *)ldn)->languageDisplayName(lang, temp); 594 return temp.extract(result, maxResultSize, *pErrorCode); 595 } 596 597 U_DRAFT int32_t U_EXPORT2 598 uldn_scriptDisplayName(const ULocaleDisplayNames *ldn, 599 const char *script, 600 UChar *result, 601 int32_t maxResultSize, 602 UErrorCode *pErrorCode) { 603 if (U_FAILURE(*pErrorCode)) { 604 return 0; 605 } 606 if (ldn == NULL || script == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) { 607 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 608 return 0; 609 } 610 UnicodeString temp(result, 0, maxResultSize); 611 ((const LocaleDisplayNames *)ldn)->scriptDisplayName(script, temp); 612 return temp.extract(result, maxResultSize, *pErrorCode); 613 } 614 615 U_DRAFT int32_t U_EXPORT2 616 uldn_scriptCodeDisplayName(const ULocaleDisplayNames *ldn, 617 UScriptCode scriptCode, 618 UChar *result, 619 int32_t maxResultSize, 620 UErrorCode *pErrorCode) { 621 return uldn_scriptDisplayName(ldn, uscript_getName(scriptCode), result, maxResultSize, pErrorCode); 622 } 623 624 U_DRAFT int32_t U_EXPORT2 625 uldn_regionDisplayName(const ULocaleDisplayNames *ldn, 626 const char *region, 627 UChar *result, 628 int32_t maxResultSize, 629 UErrorCode *pErrorCode) { 630 if (U_FAILURE(*pErrorCode)) { 631 return 0; 632 } 633 if (ldn == NULL || region == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) { 634 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 635 return 0; 636 } 637 UnicodeString temp(result, 0, maxResultSize); 638 ((const LocaleDisplayNames *)ldn)->regionDisplayName(region, temp); 639 return temp.extract(result, maxResultSize, *pErrorCode); 640 } 641 642 U_DRAFT int32_t U_EXPORT2 643 uldn_variantDisplayName(const ULocaleDisplayNames *ldn, 644 const char *variant, 645 UChar *result, 646 int32_t maxResultSize, 647 UErrorCode *pErrorCode) { 648 if (U_FAILURE(*pErrorCode)) { 649 return 0; 650 } 651 if (ldn == NULL || variant == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) { 652 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 653 return 0; 654 } 655 UnicodeString temp(result, 0, maxResultSize); 656 ((const LocaleDisplayNames *)ldn)->variantDisplayName(variant, temp); 657 return temp.extract(result, maxResultSize, *pErrorCode); 658 } 659 660 U_DRAFT int32_t U_EXPORT2 661 uldn_keyDisplayName(const ULocaleDisplayNames *ldn, 662 const char *key, 663 UChar *result, 664 int32_t maxResultSize, 665 UErrorCode *pErrorCode) { 666 if (U_FAILURE(*pErrorCode)) { 667 return 0; 668 } 669 if (ldn == NULL || key == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) { 670 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 671 return 0; 672 } 673 UnicodeString temp(result, 0, maxResultSize); 674 ((const LocaleDisplayNames *)ldn)->keyDisplayName(key, temp); 675 return temp.extract(result, maxResultSize, *pErrorCode); 676 } 677 678 U_DRAFT int32_t U_EXPORT2 679 uldn_keyValueDisplayName(const ULocaleDisplayNames *ldn, 680 const char *key, 681 const char *value, 682 UChar *result, 683 int32_t maxResultSize, 684 UErrorCode *pErrorCode) { 685 if (U_FAILURE(*pErrorCode)) { 686 return 0; 687 } 688 if (ldn == NULL || key == NULL || value == NULL || (result == NULL && maxResultSize > 0) 689 || maxResultSize < 0) { 690 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 691 return 0; 692 } 693 UnicodeString temp(result, 0, maxResultSize); 694 ((const LocaleDisplayNames *)ldn)->keyValueDisplayName(key, value, temp); 695 return temp.extract(result, maxResultSize, *pErrorCode); 696 } 697 698 #endif 699