servlk.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // © 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. /**
  4. *******************************************************************************
  5. * Copyright (C) 2001-2014, International Business Machines Corporation and *
  6. * others. All Rights Reserved. *
  7. *******************************************************************************
  8. *
  9. *******************************************************************************
  10. */
  11. #include "unicode/utypes.h"
  12. #if !UCONFIG_NO_SERVICE
  13. #include "unicode/resbund.h"
  14. #include "uresimp.h"
  15. #include "cmemory.h"
  16. #include "servloc.h"
  17. #include "ustrfmt.h"
  18. #include "uhash.h"
  19. #include "charstr.h"
  20. #include "uassert.h"
  21. #define UNDERSCORE_CHAR ((char16_t)0x005f)
  22. #define AT_SIGN_CHAR ((char16_t)64)
  23. #define PERIOD_CHAR ((char16_t)46)
  24. U_NAMESPACE_BEGIN
  25. LocaleKey*
  26. LocaleKey::createWithCanonicalFallback(const UnicodeString* primaryID,
  27. const UnicodeString* canonicalFallbackID,
  28. UErrorCode& status)
  29. {
  30. return LocaleKey::createWithCanonicalFallback(primaryID, canonicalFallbackID, KIND_ANY, status);
  31. }
  32. LocaleKey*
  33. LocaleKey::createWithCanonicalFallback(const UnicodeString* primaryID,
  34. const UnicodeString* canonicalFallbackID,
  35. int32_t kind,
  36. UErrorCode& status)
  37. {
  38. if (primaryID == nullptr || U_FAILURE(status)) {
  39. return nullptr;
  40. }
  41. UnicodeString canonicalPrimaryID;
  42. LocaleUtility::canonicalLocaleString(primaryID, canonicalPrimaryID);
  43. return new LocaleKey(*primaryID, canonicalPrimaryID, canonicalFallbackID, kind);
  44. }
  45. LocaleKey::LocaleKey(const UnicodeString& primaryID,
  46. const UnicodeString& canonicalPrimaryID,
  47. const UnicodeString* canonicalFallbackID,
  48. int32_t kind)
  49. : ICUServiceKey(primaryID)
  50. , _kind(kind)
  51. , _primaryID(canonicalPrimaryID)
  52. , _fallbackID()
  53. , _currentID()
  54. {
  55. _fallbackID.setToBogus();
  56. if (_primaryID.length() != 0) {
  57. if (canonicalFallbackID != nullptr && _primaryID != *canonicalFallbackID) {
  58. _fallbackID = *canonicalFallbackID;
  59. }
  60. }
  61. _currentID = _primaryID;
  62. }
  63. LocaleKey::~LocaleKey() {}
  64. UnicodeString&
  65. LocaleKey::prefix(UnicodeString& result) const {
  66. if (_kind != KIND_ANY) {
  67. char16_t buffer[64];
  68. uprv_itou(buffer, 64, _kind, 10, 0);
  69. UnicodeString temp(buffer);
  70. result.append(temp);
  71. }
  72. return result;
  73. }
  74. int32_t
  75. LocaleKey::kind() const {
  76. return _kind;
  77. }
  78. UnicodeString&
  79. LocaleKey::canonicalID(UnicodeString& result) const {
  80. return result.append(_primaryID);
  81. }
  82. UnicodeString&
  83. LocaleKey::currentID(UnicodeString& result) const {
  84. if (!_currentID.isBogus()) {
  85. result.append(_currentID);
  86. }
  87. return result;
  88. }
  89. UnicodeString&
  90. LocaleKey::currentDescriptor(UnicodeString& result) const {
  91. if (!_currentID.isBogus()) {
  92. prefix(result).append(PREFIX_DELIMITER).append(_currentID);
  93. } else {
  94. result.setToBogus();
  95. }
  96. return result;
  97. }
  98. Locale&
  99. LocaleKey::canonicalLocale(Locale& result) const {
  100. return LocaleUtility::initLocaleFromName(_primaryID, result);
  101. }
  102. Locale&
  103. LocaleKey::currentLocale(Locale& result) const {
  104. return LocaleUtility::initLocaleFromName(_currentID, result);
  105. }
  106. UBool
  107. LocaleKey::fallback() {
  108. if (!_currentID.isBogus()) {
  109. int x = _currentID.lastIndexOf(UNDERSCORE_CHAR);
  110. if (x != -1) {
  111. _currentID.remove(x); // truncate current or fallback, whichever we're pointing to
  112. return true;
  113. }
  114. if (!_fallbackID.isBogus()) {
  115. _currentID = _fallbackID;
  116. _fallbackID.setToBogus();
  117. return true;
  118. }
  119. if (_currentID.length() > 0) {
  120. _currentID.remove(0); // completely truncate
  121. return true;
  122. }
  123. _currentID.setToBogus();
  124. }
  125. return false;
  126. }
  127. UBool
  128. LocaleKey::isFallbackOf(const UnicodeString& id) const {
  129. UnicodeString temp(id);
  130. parseSuffix(temp);
  131. return temp.indexOf(_primaryID) == 0 &&
  132. (temp.length() == _primaryID.length() ||
  133. temp.charAt(_primaryID.length()) == UNDERSCORE_CHAR);
  134. }
  135. #ifdef SERVICE_DEBUG
  136. UnicodeString&
  137. LocaleKey::debug(UnicodeString& result) const
  138. {
  139. ICUServiceKey::debug(result);
  140. result.append((UnicodeString)" kind: ");
  141. result.append(_kind);
  142. result.append((UnicodeString)" primaryID: ");
  143. result.append(_primaryID);
  144. result.append((UnicodeString)" fallbackID: ");
  145. result.append(_fallbackID);
  146. result.append((UnicodeString)" currentID: ");
  147. result.append(_currentID);
  148. return result;
  149. }
  150. UnicodeString&
  151. LocaleKey::debugClass(UnicodeString& result) const
  152. {
  153. return result.append((UnicodeString)"LocaleKey ");
  154. }
  155. #endif
  156. UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LocaleKey)
  157. U_NAMESPACE_END
  158. /* !UCONFIG_NO_SERVICE */
  159. #endif