OLD | NEW |
1 /* | 1 /* |
2 ******************************************************************************* | 2 ******************************************************************************* |
3 * Copyright (C) 2010-2013, International Business Machines Corporation and | 3 * Copyright (C) 2010-2014, International Business Machines Corporation and |
4 * others. All Rights Reserved. | 4 * others. All Rights Reserved. |
5 ******************************************************************************* | 5 ******************************************************************************* |
6 */ | 6 */ |
7 | 7 |
8 #include "unicode/utypes.h" | 8 #include "unicode/utypes.h" |
9 | 9 |
10 #if !UCONFIG_NO_FORMATTING | 10 #if !UCONFIG_NO_FORMATTING |
11 | 11 |
12 #include "unicode/locdspnm.h" | 12 #include "unicode/locdspnm.h" |
13 #include "unicode/msgfmt.h" | 13 #include "unicode/msgfmt.h" |
14 #include "unicode/ures.h" | 14 #include "unicode/ures.h" |
| 15 #include "unicode/udisplaycontext.h" |
15 #include "unicode/brkiter.h" | 16 #include "unicode/brkiter.h" |
16 | 17 |
17 #include "cmemory.h" | 18 #include "cmemory.h" |
18 #include "cstring.h" | 19 #include "cstring.h" |
| 20 #include "mutex.h" |
19 #include "ulocimp.h" | 21 #include "ulocimp.h" |
| 22 #include "umutex.h" |
20 #include "ureslocs.h" | 23 #include "ureslocs.h" |
21 #include "uresimp.h" | 24 #include "uresimp.h" |
22 | 25 |
23 #include <stdarg.h> | 26 #include <stdarg.h> |
24 | 27 |
25 /** | 28 /** |
26 * Concatenate a number of null-terminated strings to buffer, leaving a | 29 * Concatenate a number of null-terminated strings to buffer, leaving a |
27 * null-terminated string. The last argument should be the null pointer. | 30 * null-terminated string. The last argument should be the null pointer. |
28 * Return the length of the string in the buffer, not counting the trailing | 31 * Return the length of the string in the buffer, not counting the trailing |
29 * null. Return -1 if there is an error (buffer is null, or buflen < 1). | 32 * null. Return -1 if there is an error (buffer is null, or buflen < 1). |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 | 271 |
269 class LocaleDisplayNamesImpl : public LocaleDisplayNames { | 272 class LocaleDisplayNamesImpl : public LocaleDisplayNames { |
270 Locale locale; | 273 Locale locale; |
271 UDialectHandling dialectHandling; | 274 UDialectHandling dialectHandling; |
272 ICUDataTable langData; | 275 ICUDataTable langData; |
273 ICUDataTable regionData; | 276 ICUDataTable regionData; |
274 MessageFormat *separatorFormat; | 277 MessageFormat *separatorFormat; |
275 MessageFormat *format; | 278 MessageFormat *format; |
276 MessageFormat *keyTypeFormat; | 279 MessageFormat *keyTypeFormat; |
277 UDisplayContext capitalizationContext; | 280 UDisplayContext capitalizationContext; |
| 281 BreakIterator* capitalizationBrkIter; |
| 282 static UMutex capitalizationBrkIterLock; |
278 UnicodeString formatOpenParen; | 283 UnicodeString formatOpenParen; |
279 UnicodeString formatReplaceOpenParen; | 284 UnicodeString formatReplaceOpenParen; |
280 UnicodeString formatCloseParen; | 285 UnicodeString formatCloseParen; |
281 UnicodeString formatReplaceCloseParen; | 286 UnicodeString formatReplaceCloseParen; |
| 287 UDisplayContext nameLength; |
282 | 288 |
283 // Constants for capitalization context usage types. | 289 // Constants for capitalization context usage types. |
284 enum CapContextUsage { | 290 enum CapContextUsage { |
285 kCapContextUsageLanguage, | 291 kCapContextUsageLanguage, |
286 kCapContextUsageScript, | 292 kCapContextUsageScript, |
287 kCapContextUsageTerritory, | 293 kCapContextUsageTerritory, |
288 kCapContextUsageVariant, | 294 kCapContextUsageVariant, |
289 kCapContextUsageKey, | 295 kCapContextUsageKey, |
290 kCapContextUsageType, | 296 kCapContextUsageKeyValue, |
291 kCapContextUsageCount | 297 kCapContextUsageCount |
292 }; | 298 }; |
293 // Capitalization transforms. For each usage type, the first array element i
ndicates | 299 // Capitalization transforms. For each usage type, indicates whether to titl
ecase for |
294 // whether to titlecase for uiListOrMenu context, the second indicates wheth
er to | 300 // the context specified in capitalizationContext (which we know at construc
tion time) |
295 // titlecase for stand-alone context. | 301 UBool fCapitalization[kCapContextUsageCount]; |
296 UBool fCapitalization[kCapContextUsageCount][2]; | |
297 | 302 |
298 public: | 303 public: |
299 // constructor | 304 // constructor |
300 LocaleDisplayNamesImpl(const Locale& locale, UDialectHandling dialectHandlin
g); | 305 LocaleDisplayNamesImpl(const Locale& locale, UDialectHandling dialectHandlin
g); |
301 LocaleDisplayNamesImpl(const Locale& locale, UDisplayContext *contexts, int3
2_t length); | 306 LocaleDisplayNamesImpl(const Locale& locale, UDisplayContext *contexts, int3
2_t length); |
302 virtual ~LocaleDisplayNamesImpl(); | 307 virtual ~LocaleDisplayNamesImpl(); |
303 | 308 |
304 virtual const Locale& getLocale() const; | 309 virtual const Locale& getLocale() const; |
305 virtual UDialectHandling getDialectHandling() const; | 310 virtual UDialectHandling getDialectHandling() const; |
306 virtual UDisplayContext getContext(UDisplayContextType type) const; | 311 virtual UDisplayContext getContext(UDisplayContextType type) const; |
(...skipping 18 matching lines...) Expand all Loading... |
325 const char* value, | 330 const char* value, |
326 UnicodeString& result) const; | 331 UnicodeString& result) const; |
327 private: | 332 private: |
328 UnicodeString& localeIdName(const char* localeId, | 333 UnicodeString& localeIdName(const char* localeId, |
329 UnicodeString& result) const; | 334 UnicodeString& result) const; |
330 UnicodeString& appendWithSep(UnicodeString& buffer, const UnicodeString& src
) const; | 335 UnicodeString& appendWithSep(UnicodeString& buffer, const UnicodeString& src
) const; |
331 UnicodeString& adjustForUsageAndContext(CapContextUsage usage, UnicodeString
& result) const; | 336 UnicodeString& adjustForUsageAndContext(CapContextUsage usage, UnicodeString
& result) const; |
332 void initialize(void); | 337 void initialize(void); |
333 }; | 338 }; |
334 | 339 |
| 340 UMutex LocaleDisplayNamesImpl::capitalizationBrkIterLock = U_MUTEX_INITIALIZER; |
| 341 |
335 LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale, | 342 LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale, |
336 UDialectHandling dialectHandling) | 343 UDialectHandling dialectHandling) |
337 : dialectHandling(dialectHandling) | 344 : dialectHandling(dialectHandling) |
338 , langData(U_ICUDATA_LANG, locale) | 345 , langData(U_ICUDATA_LANG, locale) |
339 , regionData(U_ICUDATA_REGION, locale) | 346 , regionData(U_ICUDATA_REGION, locale) |
340 , separatorFormat(NULL) | 347 , separatorFormat(NULL) |
341 , format(NULL) | 348 , format(NULL) |
342 , keyTypeFormat(NULL) | 349 , keyTypeFormat(NULL) |
343 , capitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | 350 , capitalizationContext(UDISPCTX_CAPITALIZATION_NONE) |
| 351 , capitalizationBrkIter(NULL) |
| 352 , nameLength(UDISPCTX_LENGTH_FULL) |
344 { | 353 { |
345 initialize(); | 354 initialize(); |
346 } | 355 } |
347 | 356 |
348 LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale, | 357 LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale, |
349 UDisplayContext *contexts, int32_
t length) | 358 UDisplayContext *contexts, int32_
t length) |
350 : dialectHandling(ULDN_STANDARD_NAMES) | 359 : dialectHandling(ULDN_STANDARD_NAMES) |
351 , langData(U_ICUDATA_LANG, locale) | 360 , langData(U_ICUDATA_LANG, locale) |
352 , regionData(U_ICUDATA_REGION, locale) | 361 , regionData(U_ICUDATA_REGION, locale) |
353 , separatorFormat(NULL) | 362 , separatorFormat(NULL) |
354 , format(NULL) | 363 , format(NULL) |
355 , keyTypeFormat(NULL) | 364 , keyTypeFormat(NULL) |
356 , capitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | 365 , capitalizationContext(UDISPCTX_CAPITALIZATION_NONE) |
| 366 , capitalizationBrkIter(NULL) |
| 367 , nameLength(UDISPCTX_LENGTH_FULL) |
357 { | 368 { |
358 while (length-- > 0) { | 369 while (length-- > 0) { |
359 UDisplayContext value = *contexts++; | 370 UDisplayContext value = *contexts++; |
360 UDisplayContextType selector = (UDisplayContextType)((uint32_t)value >>
8); | 371 UDisplayContextType selector = (UDisplayContextType)((uint32_t)value >>
8); |
361 switch (selector) { | 372 switch (selector) { |
362 case UDISPCTX_TYPE_DIALECT_HANDLING: | 373 case UDISPCTX_TYPE_DIALECT_HANDLING: |
363 dialectHandling = (UDialectHandling)value; | 374 dialectHandling = (UDialectHandling)value; |
364 break; | 375 break; |
365 case UDISPCTX_TYPE_CAPITALIZATION: | 376 case UDISPCTX_TYPE_CAPITALIZATION: |
366 capitalizationContext = value; | 377 capitalizationContext = value; |
367 break; | 378 break; |
| 379 case UDISPCTX_TYPE_DISPLAY_LENGTH: |
| 380 nameLength = value; |
| 381 break; |
368 default: | 382 default: |
369 break; | 383 break; |
370 } | 384 } |
371 } | 385 } |
372 initialize(); | 386 initialize(); |
373 } | 387 } |
374 | 388 |
375 void | 389 void |
376 LocaleDisplayNamesImpl::initialize(void) { | 390 LocaleDisplayNamesImpl::initialize(void) { |
377 LocaleDisplayNamesImpl *nonConstThis = (LocaleDisplayNamesImpl *)this; | 391 LocaleDisplayNamesImpl *nonConstThis = (LocaleDisplayNamesImpl *)this; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 uprv_memset(fCapitalization, 0, sizeof(fCapitalization)); | 429 uprv_memset(fCapitalization, 0, sizeof(fCapitalization)); |
416 #if !UCONFIG_NO_BREAK_ITERATION | 430 #if !UCONFIG_NO_BREAK_ITERATION |
417 // The following is basically copied from DateFormatSymbols::initializeData | 431 // The following is basically copied from DateFormatSymbols::initializeData |
418 typedef struct { | 432 typedef struct { |
419 const char * usageName; | 433 const char * usageName; |
420 LocaleDisplayNamesImpl::CapContextUsage usageEnum; | 434 LocaleDisplayNamesImpl::CapContextUsage usageEnum; |
421 } ContextUsageNameToEnum; | 435 } ContextUsageNameToEnum; |
422 const ContextUsageNameToEnum contextUsageTypeMap[] = { | 436 const ContextUsageNameToEnum contextUsageTypeMap[] = { |
423 // Entries must be sorted by usageTypeName; entry with NULL name terminat
es list. | 437 // Entries must be sorted by usageTypeName; entry with NULL name terminat
es list. |
424 { "key", kCapContextUsageKey }, | 438 { "key", kCapContextUsageKey }, |
| 439 { "keyValue", kCapContextUsageKeyValue }, |
425 { "languages", kCapContextUsageLanguage }, | 440 { "languages", kCapContextUsageLanguage }, |
426 { "script", kCapContextUsageScript }, | 441 { "script", kCapContextUsageScript }, |
427 { "territory", kCapContextUsageTerritory }, | 442 { "territory", kCapContextUsageTerritory }, |
428 { "type", kCapContextUsageType }, | |
429 { "variant", kCapContextUsageVariant }, | 443 { "variant", kCapContextUsageVariant }, |
430 { NULL, (CapContextUsage)0 }, | 444 { NULL, (CapContextUsage)0 }, |
431 }; | 445 }; |
432 int32_t len = 0; | 446 // Only get the context data if we need it! This is a const object so we kno
w now... |
433 UResourceBundle *localeBundle = ures_open(NULL, locale.getName(), &status); | 447 // Also check whether we will need a break iterator (depends on the data) |
434 if (U_SUCCESS(status)) { | 448 UBool needBrkIter = FALSE; |
435 UResourceBundle *contextTransforms = ures_getByKeyWithFallback(localeBun
dle, "contextTransforms", NULL, &status); | 449 if (capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU ||
capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_STANDALONE) { |
| 450 int32_t len = 0; |
| 451 UResourceBundle *localeBundle = ures_open(NULL, locale.getName(), &statu
s); |
436 if (U_SUCCESS(status)) { | 452 if (U_SUCCESS(status)) { |
437 UResourceBundle *contextTransformUsage; | 453 UResourceBundle *contextTransforms = ures_getByKeyWithFallback(local
eBundle, "contextTransforms", NULL, &status); |
438 while ( (contextTransformUsage = ures_getNextResource(contextTransfo
rms, NULL, &status)) != NULL ) { | 454 if (U_SUCCESS(status)) { |
439 const int32_t * intVector = ures_getIntVector(contextTransformUs
age, &len, &status); | 455 UResourceBundle *contextTransformUsage; |
440 if (U_SUCCESS(status) && intVector != NULL && len >= 2) { | 456 while ( (contextTransformUsage = ures_getNextResource(contextTra
nsforms, NULL, &status)) != NULL ) { |
441 const char* usageKey = ures_getKey(contextTransformUsage); | 457 const int32_t * intVector = ures_getIntVector(contextTransfo
rmUsage, &len, &status); |
442 if (usageKey != NULL) { | 458 if (U_SUCCESS(status) && intVector != NULL && len >= 2) { |
443 const ContextUsageNameToEnum * typeMapPtr = contextUsage
TypeMap; | 459 const char* usageKey = ures_getKey(contextTransformUsage
); |
444 int32_t compResult = 0; | 460 if (usageKey != NULL) { |
445 // linear search; list is short and we cannot be sure th
at bsearch is available | 461 const ContextUsageNameToEnum * typeMapPtr = contextU
sageTypeMap; |
446 while ( typeMapPtr->usageName != NULL && (compResult = u
prv_strcmp(usageKey, typeMapPtr->usageName)) > 0 ) { | 462 int32_t compResult = 0; |
447 ++typeMapPtr; | 463 // linear search; list is short and we cannot be sur
e that bsearch is available |
448 } | 464 while ( typeMapPtr->usageName != NULL && (compResult
= uprv_strcmp(usageKey, typeMapPtr->usageName)) > 0 ) { |
449 if (typeMapPtr->usageName != NULL && compResult == 0) { | 465 ++typeMapPtr; |
450 fCapitalization[typeMapPtr->usageEnum][0] = intVecto
r[0]; | 466 } |
451 fCapitalization[typeMapPtr->usageEnum][1] = intVecto
r[1]; | 467 if (typeMapPtr->usageName != NULL && compResult == 0
) { |
| 468 int32_t titlecaseInt = (capitalizationContext ==
UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU)? intVector[0]: intVector[1]; |
| 469 if (titlecaseInt != 0) { |
| 470 fCapitalization[typeMapPtr->usageEnum] = TRU
E;; |
| 471 needBrkIter = TRUE; |
| 472 } |
| 473 } |
452 } | 474 } |
453 } | 475 } |
| 476 status = U_ZERO_ERROR; |
| 477 ures_close(contextTransformUsage); |
454 } | 478 } |
455 status = U_ZERO_ERROR; | 479 ures_close(contextTransforms); |
456 ures_close(contextTransformUsage); | |
457 } | 480 } |
458 ures_close(contextTransforms); | 481 ures_close(localeBundle); |
459 } | 482 } |
460 ures_close(localeBundle); | 483 } |
| 484 // Get a sentence break iterator if we will need it |
| 485 if (needBrkIter || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_BEGI
NNING_OF_SENTENCE) { |
| 486 status = U_ZERO_ERROR; |
| 487 capitalizationBrkIter = BreakIterator::createSentenceInstance(locale, st
atus); |
| 488 if (U_FAILURE(status)) { |
| 489 delete capitalizationBrkIter; |
| 490 capitalizationBrkIter = NULL; |
| 491 } |
461 } | 492 } |
462 #endif | 493 #endif |
463 } | 494 } |
464 | 495 |
465 LocaleDisplayNamesImpl::~LocaleDisplayNamesImpl() { | 496 LocaleDisplayNamesImpl::~LocaleDisplayNamesImpl() { |
466 delete separatorFormat; | 497 delete separatorFormat; |
467 delete format; | 498 delete format; |
468 delete keyTypeFormat; | 499 delete keyTypeFormat; |
| 500 delete capitalizationBrkIter; |
469 } | 501 } |
470 | 502 |
471 const Locale& | 503 const Locale& |
472 LocaleDisplayNamesImpl::getLocale() const { | 504 LocaleDisplayNamesImpl::getLocale() const { |
473 return locale; | 505 return locale; |
474 } | 506 } |
475 | 507 |
476 UDialectHandling | 508 UDialectHandling |
477 LocaleDisplayNamesImpl::getDialectHandling() const { | 509 LocaleDisplayNamesImpl::getDialectHandling() const { |
478 return dialectHandling; | 510 return dialectHandling; |
479 } | 511 } |
480 | 512 |
481 UDisplayContext | 513 UDisplayContext |
482 LocaleDisplayNamesImpl::getContext(UDisplayContextType type) const { | 514 LocaleDisplayNamesImpl::getContext(UDisplayContextType type) const { |
483 switch (type) { | 515 switch (type) { |
484 case UDISPCTX_TYPE_DIALECT_HANDLING: | 516 case UDISPCTX_TYPE_DIALECT_HANDLING: |
485 return (UDisplayContext)dialectHandling; | 517 return (UDisplayContext)dialectHandling; |
486 case UDISPCTX_TYPE_CAPITALIZATION: | 518 case UDISPCTX_TYPE_CAPITALIZATION: |
487 return capitalizationContext; | 519 return capitalizationContext; |
| 520 case UDISPCTX_TYPE_DISPLAY_LENGTH: |
| 521 return nameLength; |
488 default: | 522 default: |
489 break; | 523 break; |
490 } | 524 } |
491 return (UDisplayContext)0; | 525 return (UDisplayContext)0; |
492 } | 526 } |
493 | 527 |
494 UnicodeString& | 528 UnicodeString& |
495 LocaleDisplayNamesImpl::adjustForUsageAndContext(CapContextUsage usage, | 529 LocaleDisplayNamesImpl::adjustForUsageAndContext(CapContextUsage usage, |
496 UnicodeString& result) const { | 530 UnicodeString& result) const { |
497 #if !UCONFIG_NO_BREAK_ITERATION | 531 #if !UCONFIG_NO_BREAK_ITERATION |
498 // check to see whether we need to titlecase result | 532 // check to see whether we need to titlecase result |
499 UBool titlecase = FALSE; | 533 if ( result.length() > 0 && u_islower(result.char32At(0)) && capitalizationB
rkIter!= NULL && |
500 switch (capitalizationContext) { | 534 ( capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENT
ENCE || fCapitalization[usage] ) ) { |
501 case UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE: | 535 // note fCapitalization[usage] won't be set unless capitalizationContext
is UI_LIST_OR_MENU or STANDALONE |
502 titlecase = TRUE; | 536 Mutex lock(&capitalizationBrkIterLock); |
503 break; | 537 result.toTitle(capitalizationBrkIter, locale, U_TITLECASE_NO_LOWERCASE |
U_TITLECASE_NO_BREAK_ADJUSTMENT); |
504 case UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU: | |
505 titlecase = fCapitalization[usage][0]; | |
506 break; | |
507 case UDISPCTX_CAPITALIZATION_FOR_STANDALONE: | |
508 titlecase = fCapitalization[usage][1]; | |
509 break; | |
510 default: | |
511 // titlecase = FALSE; | |
512 break; | |
513 } | |
514 if (titlecase) { | |
515 // TODO: Fix this titlecase hack when we figure out something better to
do. | |
516 // We don't want to titlecase the whole text, only something like the fi
rst word, | |
517 // of the first segment long enough to have a complete cluster, whicheve
r is | |
518 // shorter. We could have keep a word break iterator around, but I am no
t sure | |
519 // that will do the ight thing for the purposes here. For now we assume
that in | |
520 // languages for which titlecasing makes a difference, we can stop at no
n-letter | |
521 // characters in 0x0000-0x00FF and only titlecase up to the first occurr
ence of | |
522 // any of those, or to a small number of chars, whichever comes first. | |
523 int32_t stopPos, stopPosLimit = 8, len = result.length(); | |
524 if ( stopPosLimit > len ) { | |
525 stopPosLimit = len; | |
526 } | |
527 for ( stopPos = 0; stopPos < stopPosLimit; stopPos++ ) { | |
528 UChar32 ch = result.char32At(stopPos); | |
529 if ( (ch < 0x41) || (ch > 0x5A && ch < 0x61) || (ch > 0x7A && ch < 0
xC0) ) { | |
530 break; | |
531 } | |
532 if (ch >= 0x10000) { | |
533 stopPos++; | |
534 } | |
535 } | |
536 if ( stopPos > 0 && stopPos < len ) { | |
537 UnicodeString firstWord(result, 0, stopPos); | |
538 firstWord.toTitle(NULL, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECA
SE_NO_BREAK_ADJUSTMENT); | |
539 result.replaceBetween(0, stopPos, firstWord); | |
540 } else { | |
541 // no stopPos, titlecase the whole text | |
542 result.toTitle(NULL, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_
NO_BREAK_ADJUSTMENT); | |
543 } | |
544 } | 538 } |
545 #endif | 539 #endif |
546 return result; | 540 return result; |
547 } | 541 } |
548 | 542 |
549 UnicodeString& | 543 UnicodeString& |
550 LocaleDisplayNamesImpl::localeDisplayName(const Locale& locale, | 544 LocaleDisplayNamesImpl::localeDisplayName(const Locale& locale, |
551 UnicodeString& result) const { | 545 UnicodeString& result) const { |
552 UnicodeString resultName; | 546 UnicodeString resultName; |
553 | 547 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 UnicodeString& | 680 UnicodeString& |
687 LocaleDisplayNamesImpl::localeDisplayName(const char* localeId, | 681 LocaleDisplayNamesImpl::localeDisplayName(const char* localeId, |
688 UnicodeString& result) const { | 682 UnicodeString& result) const { |
689 return localeDisplayName(Locale(localeId), result); | 683 return localeDisplayName(Locale(localeId), result); |
690 } | 684 } |
691 | 685 |
692 // private | 686 // private |
693 UnicodeString& | 687 UnicodeString& |
694 LocaleDisplayNamesImpl::localeIdName(const char* localeId, | 688 LocaleDisplayNamesImpl::localeIdName(const char* localeId, |
695 UnicodeString& result) const { | 689 UnicodeString& result) const { |
| 690 if (nameLength == UDISPCTX_LENGTH_SHORT) { |
| 691 langData.getNoFallback("LanguagesShort", localeId, result); |
| 692 if (!result.isBogus()) { |
| 693 return result; |
| 694 } |
| 695 } |
696 return langData.getNoFallback("Languages", localeId, result); | 696 return langData.getNoFallback("Languages", localeId, result); |
697 } | 697 } |
698 | 698 |
699 UnicodeString& | 699 UnicodeString& |
700 LocaleDisplayNamesImpl::languageDisplayName(const char* lang, | 700 LocaleDisplayNamesImpl::languageDisplayName(const char* lang, |
701 UnicodeString& result) const { | 701 UnicodeString& result) const { |
702 if (uprv_strcmp("root", lang) == 0 || uprv_strchr(lang, '_') != NULL) { | 702 if (uprv_strcmp("root", lang) == 0 || uprv_strchr(lang, '_') != NULL) { |
703 return result = UnicodeString(lang, -1, US_INV); | 703 return result = UnicodeString(lang, -1, US_INV); |
704 } | 704 } |
| 705 if (nameLength == UDISPCTX_LENGTH_SHORT) { |
| 706 langData.get("LanguagesShort", lang, result); |
| 707 if (!result.isBogus()) { |
| 708 return adjustForUsageAndContext(kCapContextUsageLanguage, result); |
| 709 } |
| 710 } |
705 langData.get("Languages", lang, result); | 711 langData.get("Languages", lang, result); |
706 return adjustForUsageAndContext(kCapContextUsageLanguage, result); | 712 return adjustForUsageAndContext(kCapContextUsageLanguage, result); |
707 } | 713 } |
708 | 714 |
709 UnicodeString& | 715 UnicodeString& |
710 LocaleDisplayNamesImpl::scriptDisplayName(const char* script, | 716 LocaleDisplayNamesImpl::scriptDisplayName(const char* script, |
711 UnicodeString& result) const { | 717 UnicodeString& result) const { |
| 718 if (nameLength == UDISPCTX_LENGTH_SHORT) { |
| 719 langData.get("Scripts%short", script, result); |
| 720 if (!result.isBogus()) { |
| 721 return adjustForUsageAndContext(kCapContextUsageScript, result); |
| 722 } |
| 723 } |
712 langData.get("Scripts", script, result); | 724 langData.get("Scripts", script, result); |
713 return adjustForUsageAndContext(kCapContextUsageScript, result); | 725 return adjustForUsageAndContext(kCapContextUsageScript, result); |
714 } | 726 } |
715 | 727 |
716 UnicodeString& | 728 UnicodeString& |
717 LocaleDisplayNamesImpl::scriptDisplayName(UScriptCode scriptCode, | 729 LocaleDisplayNamesImpl::scriptDisplayName(UScriptCode scriptCode, |
718 UnicodeString& result) const { | 730 UnicodeString& result) const { |
719 const char* name = uscript_getName(scriptCode); | 731 return scriptDisplayName(uscript_getName(scriptCode), result); |
720 langData.get("Scripts", name, result); | |
721 return adjustForUsageAndContext(kCapContextUsageScript, result); | |
722 } | 732 } |
723 | 733 |
724 UnicodeString& | 734 UnicodeString& |
725 LocaleDisplayNamesImpl::regionDisplayName(const char* region, | 735 LocaleDisplayNamesImpl::regionDisplayName(const char* region, |
726 UnicodeString& result) const { | 736 UnicodeString& result) const { |
| 737 if (nameLength == UDISPCTX_LENGTH_SHORT) { |
| 738 regionData.get("CountriesShort", region, result); |
| 739 if (!result.isBogus()) { |
| 740 return adjustForUsageAndContext(kCapContextUsageTerritory, result); |
| 741 } |
| 742 } |
727 regionData.get("Countries", region, result); | 743 regionData.get("Countries", region, result); |
728 return adjustForUsageAndContext(kCapContextUsageTerritory, result); | 744 return adjustForUsageAndContext(kCapContextUsageTerritory, result); |
729 } | 745 } |
730 | 746 |
731 UnicodeString& | 747 UnicodeString& |
732 LocaleDisplayNamesImpl::variantDisplayName(const char* variant, | 748 LocaleDisplayNamesImpl::variantDisplayName(const char* variant, |
733 UnicodeString& result) const { | 749 UnicodeString& result) const { |
| 750 // don't have a resource for short variant names |
734 langData.get("Variants", variant, result); | 751 langData.get("Variants", variant, result); |
735 return adjustForUsageAndContext(kCapContextUsageVariant, result); | 752 return adjustForUsageAndContext(kCapContextUsageVariant, result); |
736 } | 753 } |
737 | 754 |
738 UnicodeString& | 755 UnicodeString& |
739 LocaleDisplayNamesImpl::keyDisplayName(const char* key, | 756 LocaleDisplayNamesImpl::keyDisplayName(const char* key, |
740 UnicodeString& result) const { | 757 UnicodeString& result) const { |
| 758 // don't have a resource for short key names |
741 langData.get("Keys", key, result); | 759 langData.get("Keys", key, result); |
742 return adjustForUsageAndContext(kCapContextUsageKey, result); | 760 return adjustForUsageAndContext(kCapContextUsageKey, result); |
743 } | 761 } |
744 | 762 |
745 UnicodeString& | 763 UnicodeString& |
746 LocaleDisplayNamesImpl::keyValueDisplayName(const char* key, | 764 LocaleDisplayNamesImpl::keyValueDisplayName(const char* key, |
747 const char* value, | 765 const char* value, |
748 UnicodeString& result) const { | 766 UnicodeString& result) const { |
| 767 if (nameLength == UDISPCTX_LENGTH_SHORT) { |
| 768 langData.get("Types%short", key, value, result); |
| 769 if (!result.isBogus()) { |
| 770 return adjustForUsageAndContext(kCapContextUsageKeyValue, result); |
| 771 } |
| 772 } |
749 langData.get("Types", key, value, result); | 773 langData.get("Types", key, value, result); |
750 return adjustForUsageAndContext(kCapContextUsageType, result); | 774 return adjustForUsageAndContext(kCapContextUsageKeyValue, result); |
751 } | 775 } |
752 | 776 |
753 ////////////////////////////////////////////////////////////////////////////////
//////////////////// | 777 ////////////////////////////////////////////////////////////////////////////////
//////////////////// |
754 | 778 |
755 LocaleDisplayNames* | 779 LocaleDisplayNames* |
756 LocaleDisplayNames::createInstance(const Locale& locale, | 780 LocaleDisplayNames::createInstance(const Locale& locale, |
757 UDialectHandling dialectHandling) { | 781 UDialectHandling dialectHandling) { |
758 return new LocaleDisplayNamesImpl(locale, dialectHandling); | 782 return new LocaleDisplayNamesImpl(locale, dialectHandling); |
759 } | 783 } |
760 | 784 |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 || maxResultSize < 0) { | 986 || maxResultSize < 0) { |
963 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; | 987 *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; |
964 return 0; | 988 return 0; |
965 } | 989 } |
966 UnicodeString temp(result, 0, maxResultSize); | 990 UnicodeString temp(result, 0, maxResultSize); |
967 ((const LocaleDisplayNames *)ldn)->keyValueDisplayName(key, value, temp); | 991 ((const LocaleDisplayNames *)ldn)->keyValueDisplayName(key, value, temp); |
968 return temp.extract(result, maxResultSize, *pErrorCode); | 992 return temp.extract(result, maxResultSize, *pErrorCode); |
969 } | 993 } |
970 | 994 |
971 #endif | 995 #endif |
OLD | NEW |