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 ((char16_t)0x005f)
25#define AT_SIGN_CHAR ((char16_t)64)
26#define PERIOD_CHAR ((char16_t)46)
27
28U_NAMESPACE_BEGIN
29
30LocaleKey*
31LocaleKey::createWithCanonicalFallback(const UnicodeString* primaryID,
32 const UnicodeString* canonicalFallbackID,
33 UErrorCode& status)
34{
35 return LocaleKey::createWithCanonicalFallback(primaryID, canonicalFallbackID, KIND_ANY, status);
36}
37
38LocaleKey*
39LocaleKey::createWithCanonicalFallback(const UnicodeString* primaryID,
40 const UnicodeString* canonicalFallbackID,
41 int32_t kind,
42 UErrorCode& status)
43{
44 if (primaryID == nullptr || U_FAILURE(status)) {
45 return nullptr;
46 }
47 UnicodeString canonicalPrimaryID;
48 LocaleUtility::canonicalLocaleString(primaryID, canonicalPrimaryID);
49 return new LocaleKey(*primaryID, canonicalPrimaryID, canonicalFallbackID, kind);
50}
51
52LocaleKey::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 != nullptr && _primaryID != *canonicalFallbackID) {
65 _fallbackID = *canonicalFallbackID;
66 }
67 }
68
69 _currentID = _primaryID;
70}
71
72LocaleKey::~LocaleKey() {}
73
74UnicodeString&
75LocaleKey::prefix(UnicodeString& result) const {
76 if (_kind != KIND_ANY) {
77 char16_t buffer[64];
78 uprv_itou(buffer, 64, _kind, 10, 0);
79 UnicodeString temp(buffer);
80 result.append(temp);
81 }
82 return result;
83}
84
85int32_t
86LocaleKey::kind() const {
87 return _kind;
88}
89
90UnicodeString&
91LocaleKey::canonicalID(UnicodeString& result) const {
92 return result.append(_primaryID);
93}
94
95UnicodeString&
96LocaleKey::currentID(UnicodeString& result) const {
97 if (!_currentID.isBogus()) {
98 result.append(_currentID);
99 }
100 return result;
101}
102
103UnicodeString&
104LocaleKey::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
113Locale&
114LocaleKey::canonicalLocale(Locale& result) const {
115 return LocaleUtility::initLocaleFromName(_primaryID, result);
116}
117
118Locale&
119LocaleKey::currentLocale(Locale& result) const {
120 return LocaleUtility::initLocaleFromName(_currentID, result);
121}
122
123UBool
124LocaleKey::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
149UBool
150LocaleKey::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
159UnicodeString&
160LocaleKey::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
174UnicodeString&
175LocaleKey::debugClass(UnicodeString& result) const
176{
177 return result.append((UnicodeString)"LocaleKey ");
178}
179#endif
180
181UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LocaleKey)
182
183U_NAMESPACE_END
184
185/* !UCONFIG_NO_SERVICE */
186#endif
187
188
189