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 13 #if !UCONFIG_NO_SERVICE 14 15 #include "unicode/resbund.h" 16 #include "uresimp.h" 17 #include "cmemory.h" 18 #include "servloc.h" 19 #include "ustrfmt.h" 20 #include "uhash.h" 21 #include "charstr.h" 22 #include "uassert.h" 23 24 #define UNDERSCORE_CHAR ((UChar)0x005f) 25 #define AT_SIGN_CHAR ((UChar)64) 26 #define PERIOD_CHAR ((UChar)46) 27 28 U_NAMESPACE_BEGIN 29 30 LocaleKey* 31 LocaleKey::createWithCanonicalFallback(const UnicodeString* primaryID, 32 const UnicodeString* canonicalFallbackID, 33 UErrorCode& status) 34 { 35 return LocaleKey::createWithCanonicalFallback(primaryID, canonicalFallbackID, KIND_ANY, status); 36 } 37 38 LocaleKey* 39 LocaleKey::createWithCanonicalFallback(const UnicodeString* primaryID, 40 const UnicodeString* canonicalFallbackID, 41 int32_t kind, 42 UErrorCode& status) 43 { 44 if (primaryID == NULL || U_FAILURE(status)) { 45 return NULL; 46 } 47 UnicodeString canonicalPrimaryID; 48 LocaleUtility::canonicalLocaleString(primaryID, canonicalPrimaryID); 49 return new LocaleKey(*primaryID, canonicalPrimaryID, canonicalFallbackID, kind); 50 } 51 52 LocaleKey::LocaleKey(const UnicodeString& primaryID, 53 const UnicodeString& canonicalPrimaryID, 54 const UnicodeString* canonicalFallbackID, 55 int32_t kind) 56 : ICUServiceKey(primaryID) 57 , _kind(kind) 58 , _primaryID(canonicalPrimaryID) 59 , _fallbackID() 60 , _currentID() 61 { 62 _fallbackID.setToBogus(); 63 if (_primaryID.length() != 0) { 64 if (canonicalFallbackID != NULL && _primaryID != *canonicalFallbackID) { 65 _fallbackID = *canonicalFallbackID; 66 } 67 } 68 69 _currentID = _primaryID; 70 } 71 72 LocaleKey::~LocaleKey() {} 73 74 UnicodeString& 75 LocaleKey::prefix(UnicodeString& result) const { 76 if (_kind != KIND_ANY) { 77 UChar buffer[64]; 78 uprv_itou(buffer, 64, _kind, 10, 0); 79 UnicodeString temp(buffer); 80 result.append(temp); 81 } 82 return result; 83 } 84 85 int32_t 86 LocaleKey::kind() const { 87 return _kind; 88 } 89 90 UnicodeString& 91 LocaleKey::canonicalID(UnicodeString& result) const { 92 return result.append(_primaryID); 93 } 94 95 UnicodeString& 96 LocaleKey::currentID(UnicodeString& result) const { 97 if (!_currentID.isBogus()) { 98 result.append(_currentID); 99 } 100 return result; 101 } 102 103 UnicodeString& 104 LocaleKey::currentDescriptor(UnicodeString& result) const { 105 if (!_currentID.isBogus()) { 106 prefix(result).append(PREFIX_DELIMITER).append(_currentID); 107 } else { 108 result.setToBogus(); 109 } 110 return result; 111 } 112 113 Locale& 114 LocaleKey::canonicalLocale(Locale& result) const { 115 return LocaleUtility::initLocaleFromName(_primaryID, result); 116 } 117 118 Locale& 119 LocaleKey::currentLocale(Locale& result) const { 120 return LocaleUtility::initLocaleFromName(_currentID, result); 121 } 122 123 UBool 124 LocaleKey::fallback() { 125 if (!_currentID.isBogus()) { 126 int x = _currentID.lastIndexOf(UNDERSCORE_CHAR); 127 if (x != -1) { 128 _currentID.remove(x); // truncate current or fallback, whichever we're pointing to 129 return TRUE; 130 } 131 132 if (!_fallbackID.isBogus()) { 133 _currentID = _fallbackID; 134 _fallbackID.setToBogus(); 135 return TRUE; 136 } 137 138 if (_currentID.length() > 0) { 139 _currentID.remove(0); // completely truncate 140 return TRUE; 141 } 142 143 _currentID.setToBogus(); 144 } 145 146 return FALSE; 147 } 148 149 UBool 150 LocaleKey::isFallbackOf(const UnicodeString& id) const { 151 UnicodeString temp(id); 152 parseSuffix(temp); 153 return temp.indexOf(_primaryID) == 0 && 154 (temp.length() == _primaryID.length() || 155 temp.charAt(_primaryID.length()) == UNDERSCORE_CHAR); 156 } 157 158 #ifdef SERVICE_DEBUG 159 UnicodeString& 160 LocaleKey::debug(UnicodeString& result) const 161 { 162 ICUServiceKey::debug(result); 163 result.append((UnicodeString)" kind: "); 164 result.append(_kind); 165 result.append((UnicodeString)" primaryID: "); 166 result.append(_primaryID); 167 result.append((UnicodeString)" fallbackID: "); 168 result.append(_fallbackID); 169 result.append((UnicodeString)" currentID: "); 170 result.append(_currentID); 171 return result; 172 } 173 174 UnicodeString& 175 LocaleKey::debugClass(UnicodeString& result) const 176 { 177 return result.append((UnicodeString)"LocaleKey "); 178 } 179 #endif 180 181 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LocaleKey) 182 183 U_NAMESPACE_END 184 185 /* !UCONFIG_NO_SERVICE */ 186 #endif 187 188 189