]> git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/locdspnm.cpp
ICU-461.12.tar.gz
[apple/icu.git] / icuSources / i18n / locdspnm.cpp
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_NO_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 private:
302 UnicodeString& localeIdName(const char* localeId,
303 UnicodeString& result) const;
304 UnicodeString& appendWithSep(UnicodeString& buffer, const UnicodeString& src) const;
305 };
306
307 LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
308 UDialectHandling dialectHandling)
309 : dialectHandling(dialectHandling)
310 , langData(U_ICUDATA_LANG, locale)
311 , regionData(U_ICUDATA_REGION, locale)
312 , format(NULL)
313 {
314 LocaleDisplayNamesImpl *nonConstThis = (LocaleDisplayNamesImpl *)this;
315 nonConstThis->locale = langData.getLocale() == Locale::getRoot()
316 ? regionData.getLocale()
317 : langData.getLocale();
318
319 langData.getNoFallback("localeDisplayPattern", "separator", sep);
320 if (sep.isBogus()) {
321 sep = UnicodeString(", ", -1, US_INV);
322 }
323
324 UnicodeString pattern;
325 langData.getNoFallback("localeDisplayPattern", "pattern", pattern);
326 if (pattern.isBogus()) {
327 pattern = UnicodeString("{0} ({1})", -1, US_INV);
328 }
329 UErrorCode status = U_ZERO_ERROR;
330 format = new MessageFormat(pattern, status);
331 }
332
333 LocaleDisplayNamesImpl::~LocaleDisplayNamesImpl() {
334 delete format;
335 }
336
337 const Locale&
338 LocaleDisplayNamesImpl::getLocale() const {
339 return locale;
340 }
341
342 UDialectHandling
343 LocaleDisplayNamesImpl::getDialectHandling() const {
344 return dialectHandling;
345 }
346
347 UnicodeString&
348 LocaleDisplayNamesImpl::localeDisplayName(const Locale& locale,
349 UnicodeString& result) const {
350 UnicodeString resultName;
351
352 const char* lang = locale.getLanguage();
353 if (uprv_strlen(lang) == 0) {
354 lang = "root";
355 }
356 const char* script = locale.getScript();
357 const char* country = locale.getCountry();
358 const char* variant = locale.getVariant();
359
360 UBool hasScript = uprv_strlen(script) > 0;
361 UBool hasCountry = uprv_strlen(country) > 0;
362 UBool hasVariant = uprv_strlen(variant) > 0;
363
364 if (dialectHandling == ULDN_DIALECT_NAMES) {
365 char buffer[ULOC_FULLNAME_CAPACITY];
366 do { // loop construct is so we can break early out of search
367 if (hasScript && hasCountry) {
368 ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, "_", country, (char *)0);
369 localeIdName(buffer, resultName);
370 if (!resultName.isBogus()) {
371 hasScript = FALSE;
372 hasCountry = FALSE;
373 break;
374 }
375 }
376 if (hasScript) {
377 ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", script, (char *)0);
378 localeIdName(buffer, resultName);
379 if (!resultName.isBogus()) {
380 hasScript = FALSE;
381 break;
382 }
383 }
384 if (hasCountry) {
385 ncat(buffer, ULOC_FULLNAME_CAPACITY, lang, "_", country, (char*)0);
386 localeIdName(buffer, resultName);
387 if (!resultName.isBogus()) {
388 hasCountry = FALSE;
389 break;
390 }
391 }
392 } while (FALSE);
393 }
394 if (resultName.isBogus() || resultName.isEmpty()) {
395 localeIdName(lang, resultName);
396 }
397
398 UnicodeString resultRemainder;
399 UnicodeString temp;
400 StringEnumeration *e = NULL;
401 UErrorCode status = U_ZERO_ERROR;
402
403 if (hasScript) {
404 resultRemainder.append(scriptDisplayName(script, temp));
405 }
406 if (hasCountry) {
407 appendWithSep(resultRemainder, regionDisplayName(country, temp));
408 }
409 if (hasVariant) {
410 appendWithSep(resultRemainder, variantDisplayName(variant, temp));
411 }
412
413 e = locale.createKeywords(status);
414 if (e && U_SUCCESS(status)) {
415 UnicodeString temp2;
416 char value[ULOC_KEYWORD_AND_VALUES_CAPACITY]; // sigh, no ULOC_VALUE_CAPACITY
417 const char* key;
418 while ((key = e->next((int32_t *)0, status)) != NULL) {
419 locale.getKeywordValue(key, value, ULOC_KEYWORD_AND_VALUES_CAPACITY, status);
420 appendWithSep(resultRemainder, keyDisplayName(key, temp))
421 .append("=")
422 .append(keyValueDisplayName(key, value, temp2));
423 }
424 delete e;
425 }
426
427 if (!resultRemainder.isEmpty()) {
428 Formattable data[] = {
429 resultName,
430 resultRemainder
431 };
432 FieldPosition fpos;
433 status = U_ZERO_ERROR;
434 format->format(data, 2, result, fpos, status);
435 return result;
436 }
437
438 return result = resultName;
439 }
440
441 UnicodeString&
442 LocaleDisplayNamesImpl::appendWithSep(UnicodeString& buffer, const UnicodeString& src) const {
443 if (!buffer.isEmpty()) {
444 buffer.append(sep);
445 }
446 buffer.append(src);
447 return buffer;
448 }
449
450 UnicodeString&
451 LocaleDisplayNamesImpl::localeDisplayName(const char* localeId,
452 UnicodeString& result) const {
453 return localeDisplayName(Locale(localeId), result);
454 }
455
456 UnicodeString&
457 LocaleDisplayNamesImpl::localeIdName(const char* localeId,
458 UnicodeString& result) const {
459 return langData.getNoFallback("Languages", localeId, result);
460 }
461
462 UnicodeString&
463 LocaleDisplayNamesImpl::languageDisplayName(const char* lang,
464 UnicodeString& result) const {
465 if (uprv_strcmp("root", lang) == 0 || uprv_strchr(lang, '_') != NULL) {
466 return result = UnicodeString(lang, -1, US_INV);
467 }
468 return langData.get("Languages", lang, result);
469 }
470
471 UnicodeString&
472 LocaleDisplayNamesImpl::scriptDisplayName(const char* script,
473 UnicodeString& result) const {
474 return langData.get("Scripts", script, result);
475 }
476
477 UnicodeString&
478 LocaleDisplayNamesImpl::scriptDisplayName(UScriptCode scriptCode,
479 UnicodeString& result) const {
480 const char* name = uscript_getName(scriptCode);
481 return langData.get("Scripts", name, result);
482 }
483
484 UnicodeString&
485 LocaleDisplayNamesImpl::regionDisplayName(const char* region,
486 UnicodeString& result) const {
487 return regionData.get("Countries", region, result);
488 }
489
490 UnicodeString&
491 LocaleDisplayNamesImpl::variantDisplayName(const char* variant,
492 UnicodeString& result) const {
493 return langData.get("Variants", variant, result);
494 }
495
496 UnicodeString&
497 LocaleDisplayNamesImpl::keyDisplayName(const char* key,
498 UnicodeString& result) const {
499 return langData.get("Keys", key, result);
500 }
501
502 UnicodeString&
503 LocaleDisplayNamesImpl::keyValueDisplayName(const char* key,
504 const char* value,
505 UnicodeString& result) const {
506 return langData.get("Types", key, value, result);
507 }
508
509 ////////////////////////////////////////////////////////////////////////////////////////////////////
510
511 LocaleDisplayNames*
512 LocaleDisplayNames::createInstance(const Locale& locale,
513 UDialectHandling dialectHandling) {
514 return new LocaleDisplayNamesImpl(locale, dialectHandling);
515 }
516
517 U_NAMESPACE_END
518
519 ////////////////////////////////////////////////////////////////////////////////////////////////////
520
521 U_NAMESPACE_USE
522
523 U_DRAFT ULocaleDisplayNames * U_EXPORT2
524 uldn_open(const char * locale,
525 UDialectHandling dialectHandling,
526 UErrorCode *pErrorCode) {
527 if (U_FAILURE(*pErrorCode)) {
528 return 0;
529 }
530 if (locale == NULL) {
531 locale = uloc_getDefault();
532 }
533 return (ULocaleDisplayNames *)LocaleDisplayNames::createInstance(Locale(locale), dialectHandling);
534 }
535
536 U_DRAFT void U_EXPORT2
537 uldn_close(ULocaleDisplayNames *ldn) {
538 delete (LocaleDisplayNames *)ldn;
539 }
540
541 U_DRAFT const char * U_EXPORT2
542 uldn_getLocale(const ULocaleDisplayNames *ldn) {
543 if (ldn) {
544 return ((const LocaleDisplayNames *)ldn)->getLocale().getName();
545 }
546 return NULL;
547 }
548
549 U_DRAFT UDialectHandling U_EXPORT2
550 uldn_getDialectHandling(const ULocaleDisplayNames *ldn) {
551 if (ldn) {
552 return ((const LocaleDisplayNames *)ldn)->getDialectHandling();
553 }
554 return ULDN_STANDARD_NAMES;
555 }
556
557 U_DRAFT int32_t U_EXPORT2
558 uldn_localeDisplayName(const ULocaleDisplayNames *ldn,
559 const char *locale,
560 UChar *result,
561 int32_t maxResultSize,
562 UErrorCode *pErrorCode) {
563 if (U_FAILURE(*pErrorCode)) {
564 return 0;
565 }
566 if (ldn == NULL || locale == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
567 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
568 return 0;
569 }
570 UnicodeString temp(result, 0, maxResultSize);
571 ((const LocaleDisplayNames *)ldn)->localeDisplayName(locale, temp);
572 return temp.extract(result, maxResultSize, *pErrorCode);
573 }
574
575 U_DRAFT int32_t U_EXPORT2
576 uldn_languageDisplayName(const ULocaleDisplayNames *ldn,
577 const char *lang,
578 UChar *result,
579 int32_t maxResultSize,
580 UErrorCode *pErrorCode) {
581 if (U_FAILURE(*pErrorCode)) {
582 return 0;
583 }
584 if (ldn == NULL || lang == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
585 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
586 return 0;
587 }
588 UnicodeString temp(result, 0, maxResultSize);
589 ((const LocaleDisplayNames *)ldn)->languageDisplayName(lang, temp);
590 return temp.extract(result, maxResultSize, *pErrorCode);
591 }
592
593 U_DRAFT int32_t U_EXPORT2
594 uldn_scriptDisplayName(const ULocaleDisplayNames *ldn,
595 const char *script,
596 UChar *result,
597 int32_t maxResultSize,
598 UErrorCode *pErrorCode) {
599 if (U_FAILURE(*pErrorCode)) {
600 return 0;
601 }
602 if (ldn == NULL || script == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
603 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
604 return 0;
605 }
606 UnicodeString temp(result, 0, maxResultSize);
607 ((const LocaleDisplayNames *)ldn)->scriptDisplayName(script, temp);
608 return temp.extract(result, maxResultSize, *pErrorCode);
609 }
610
611 U_DRAFT int32_t U_EXPORT2
612 uldn_scriptCodeDisplayName(const ULocaleDisplayNames *ldn,
613 UScriptCode scriptCode,
614 UChar *result,
615 int32_t maxResultSize,
616 UErrorCode *pErrorCode) {
617 return uldn_scriptDisplayName(ldn, uscript_getName(scriptCode), result, maxResultSize, pErrorCode);
618 }
619
620 U_DRAFT int32_t U_EXPORT2
621 uldn_regionDisplayName(const ULocaleDisplayNames *ldn,
622 const char *region,
623 UChar *result,
624 int32_t maxResultSize,
625 UErrorCode *pErrorCode) {
626 if (U_FAILURE(*pErrorCode)) {
627 return 0;
628 }
629 if (ldn == NULL || region == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
630 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
631 return 0;
632 }
633 UnicodeString temp(result, 0, maxResultSize);
634 ((const LocaleDisplayNames *)ldn)->regionDisplayName(region, temp);
635 return temp.extract(result, maxResultSize, *pErrorCode);
636 }
637
638 U_DRAFT int32_t U_EXPORT2
639 uldn_variantDisplayName(const ULocaleDisplayNames *ldn,
640 const char *variant,
641 UChar *result,
642 int32_t maxResultSize,
643 UErrorCode *pErrorCode) {
644 if (U_FAILURE(*pErrorCode)) {
645 return 0;
646 }
647 if (ldn == NULL || variant == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
648 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
649 return 0;
650 }
651 UnicodeString temp(result, 0, maxResultSize);
652 ((const LocaleDisplayNames *)ldn)->variantDisplayName(variant, temp);
653 return temp.extract(result, maxResultSize, *pErrorCode);
654 }
655
656 U_DRAFT int32_t U_EXPORT2
657 uldn_keyDisplayName(const ULocaleDisplayNames *ldn,
658 const char *key,
659 UChar *result,
660 int32_t maxResultSize,
661 UErrorCode *pErrorCode) {
662 if (U_FAILURE(*pErrorCode)) {
663 return 0;
664 }
665 if (ldn == NULL || key == NULL || (result == NULL && maxResultSize > 0) || maxResultSize < 0) {
666 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
667 return 0;
668 }
669 UnicodeString temp(result, 0, maxResultSize);
670 ((const LocaleDisplayNames *)ldn)->keyDisplayName(key, temp);
671 return temp.extract(result, maxResultSize, *pErrorCode);
672 }
673
674 U_DRAFT int32_t U_EXPORT2
675 uldn_keyValueDisplayName(const ULocaleDisplayNames *ldn,
676 const char *key,
677 const char *value,
678 UChar *result,
679 int32_t maxResultSize,
680 UErrorCode *pErrorCode) {
681 if (U_FAILURE(*pErrorCode)) {
682 return 0;
683 }
684 if (ldn == NULL || key == NULL || value == NULL || (result == NULL && maxResultSize > 0)
685 || maxResultSize < 0) {
686 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
687 return 0;
688 }
689 UnicodeString temp(result, 0, maxResultSize);
690 ((const LocaleDisplayNames *)ldn)->keyValueDisplayName(key, value, temp);
691 return temp.extract(result, maxResultSize, *pErrorCode);
692 }
693
694 #endif