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