1 // Copyright (C) 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*
createWithCanonicalFallback(const UnicodeString * primaryID,const UnicodeString * canonicalFallbackID,UErrorCode & status)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*
createWithCanonicalFallback(const UnicodeString * primaryID,const UnicodeString * canonicalFallbackID,int32_t kind,UErrorCode & status)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
LocaleKey(const UnicodeString & primaryID,const UnicodeString & canonicalPrimaryID,const UnicodeString * canonicalFallbackID,int32_t kind)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
~LocaleKey()72 LocaleKey::~LocaleKey() {}
73
74 UnicodeString&
prefix(UnicodeString & result) const75 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
kind() const86 LocaleKey::kind() const {
87 return _kind;
88 }
89
90 UnicodeString&
canonicalID(UnicodeString & result) const91 LocaleKey::canonicalID(UnicodeString& result) const {
92 return result.append(_primaryID);
93 }
94
95 UnicodeString&
currentID(UnicodeString & result) const96 LocaleKey::currentID(UnicodeString& result) const {
97 if (!_currentID.isBogus()) {
98 result.append(_currentID);
99 }
100 return result;
101 }
102
103 UnicodeString&
currentDescriptor(UnicodeString & result) const104 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&
canonicalLocale(Locale & result) const114 LocaleKey::canonicalLocale(Locale& result) const {
115 return LocaleUtility::initLocaleFromName(_primaryID, result);
116 }
117
118 Locale&
currentLocale(Locale & result) const119 LocaleKey::currentLocale(Locale& result) const {
120 return LocaleUtility::initLocaleFromName(_currentID, result);
121 }
122
123 UBool
fallback()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
isFallbackOf(const UnicodeString & id) const150 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&
debug(UnicodeString & result) const160 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&
debugClass(UnicodeString & result) const175 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