• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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