]> git.saurik.com Git - apple/icu.git/blame - icuSources/common/servls.cpp
ICU-62141.0.1.tar.gz
[apple/icu.git] / icuSources / common / servls.cpp
CommitLineData
f3c0d7a5
A
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
73c04bcf
A
3/**
4 *******************************************************************************
b331163b 5 * Copyright (C) 2001-2014, International Business Machines Corporation and *
73c04bcf
A
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"
73c04bcf 20#include "charstr.h"
73c04bcf
A
21#include "uassert.h"
22
23#define UNDERSCORE_CHAR ((UChar)0x005f)
24#define AT_SIGN_CHAR ((UChar)64)
25#define PERIOD_CHAR ((UChar)46)
26
27U_NAMESPACE_BEGIN
28
51004dcb 29static UMutex llock = U_MUTEX_INITIALIZER;
73c04bcf
A
30ICULocaleService::ICULocaleService()
31 : fallbackLocale(Locale::getDefault())
73c04bcf 32{
73c04bcf
A
33}
34
35ICULocaleService::ICULocaleService(const UnicodeString& dname)
36 : ICUService(dname)
37 , fallbackLocale(Locale::getDefault())
73c04bcf 38{
73c04bcf
A
39}
40
41ICULocaleService::~ICULocaleService()
42{
73c04bcf
A
43}
44
45UObject*
46ICULocaleService::get(const Locale& locale, UErrorCode& status) const
47{
48 return get(locale, LocaleKey::KIND_ANY, NULL, status);
49}
50
51UObject*
52ICULocaleService::get(const Locale& locale, int32_t kind, UErrorCode& status) const
53{
54 return get(locale, kind, NULL, status);
55}
56
57UObject*
58ICULocaleService::get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const
59{
60 return get(locale, LocaleKey::KIND_ANY, actualReturn, status);
61}
62
63UObject*
64ICULocaleService::get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const
65{
66 UObject* result = NULL;
67 if (U_FAILURE(status)) {
68 return result;
69 }
70
71 UnicodeString locName(locale.getName(), -1, US_INV);
72 if (locName.isBogus()) {
73 status = U_MEMORY_ALLOCATION_ERROR;
74 } else {
75 ICUServiceKey* key = createKey(&locName, kind, status);
76 if (key) {
77 if (actualReturn == NULL) {
78 result = getKey(*key, status);
79 } else {
80 UnicodeString temp;
81 result = getKey(*key, &temp, status);
82
83 if (result != NULL) {
84 key->parseSuffix(temp);
85 LocaleUtility::initLocaleFromName(temp, *actualReturn);
86 }
87 }
88 delete key;
89 }
90 }
91 return result;
92}
93
94
95URegistryKey
96ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale,
97 UBool visible, UErrorCode& status)
98{
99 Locale loc;
100 LocaleUtility::initLocaleFromName(locale, loc);
101 return registerInstance(objToAdopt, loc, LocaleKey::KIND_ANY,
102 visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE, status);
103}
104
105URegistryKey
106ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status)
107{
108 return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status);
109}
110
111URegistryKey
112ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status)
113{
114 return registerInstance(objToAdopt, locale, kind, LocaleKeyFactory::VISIBLE, status);
115}
116
117URegistryKey
118ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status)
119{
120 ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage);
121 if (factory != NULL) {
122 return registerFactory(factory, status);
123 }
124 delete objToAdopt;
125 return NULL;
126}
127
128#if 0
129URegistryKey
130ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UErrorCode& status)
131{
132 return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status);
133}
134
135URegistryKey
136ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status)
137{
138 return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY,
139 visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE,
140 status);
141}
142
143URegistryKey
144ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, int32_t kind, int32_t coverage, UErrorCode& status)
145{
146 ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage);
147 if (factory != NULL) {
148 return registerFactory(factory, status);
149 }
150 delete objToAdopt;
151 return NULL;
152}
153#endif
154
155class ServiceEnumeration : public StringEnumeration {
156private:
157 const ICULocaleService* _service;
158 int32_t _timestamp;
159 UVector _ids;
160 int32_t _pos;
161
162private:
163 ServiceEnumeration(const ICULocaleService* service, UErrorCode &status)
164 : _service(service)
165 , _timestamp(service->getTimestamp())
4388f060 166 , _ids(uprv_deleteUObject, NULL, status)
73c04bcf
A
167 , _pos(0)
168 {
169 _service->getVisibleIDs(_ids, status);
170 }
171
172 ServiceEnumeration(const ServiceEnumeration &other, UErrorCode &status)
173 : _service(other._service)
174 , _timestamp(other._timestamp)
4388f060 175 , _ids(uprv_deleteUObject, NULL, status)
73c04bcf
A
176 , _pos(0)
177 {
178 if(U_SUCCESS(status)) {
179 int32_t i, length;
180
181 length = other._ids.size();
182 for(i = 0; i < length; ++i) {
183 _ids.addElement(((UnicodeString *)other._ids.elementAt(i))->clone(), status);
184 }
185
186 if(U_SUCCESS(status)) {
187 _pos = other._pos;
188 }
189 }
190 }
191
192public:
193 static ServiceEnumeration* create(const ICULocaleService* service) {
194 UErrorCode status = U_ZERO_ERROR;
195 ServiceEnumeration* result = new ServiceEnumeration(service, status);
196 if (U_SUCCESS(status)) {
197 return result;
198 }
199 delete result;
200 return NULL;
201 }
202
4388f060 203 virtual ~ServiceEnumeration();
73c04bcf
A
204
205 virtual StringEnumeration *clone() const {
206 UErrorCode status = U_ZERO_ERROR;
207 ServiceEnumeration *cl = new ServiceEnumeration(*this, status);
208 if(U_FAILURE(status)) {
209 delete cl;
210 cl = NULL;
211 }
212 return cl;
213 }
214
215 UBool upToDate(UErrorCode& status) const {
216 if (U_SUCCESS(status)) {
217 if (_timestamp == _service->getTimestamp()) {
218 return TRUE;
219 }
220 status = U_ENUM_OUT_OF_SYNC_ERROR;
221 }
222 return FALSE;
223 }
224
225 virtual int32_t count(UErrorCode& status) const {
226 return upToDate(status) ? _ids.size() : 0;
227 }
228
229 virtual const UnicodeString* snext(UErrorCode& status) {
230 if (upToDate(status) && (_pos < _ids.size())) {
231 return (const UnicodeString*)_ids[_pos++];
232 }
233 return NULL;
234 }
235
236 virtual void reset(UErrorCode& status) {
237 if (status == U_ENUM_OUT_OF_SYNC_ERROR) {
238 status = U_ZERO_ERROR;
239 }
240 if (U_SUCCESS(status)) {
241 _timestamp = _service->getTimestamp();
242 _pos = 0;
243 _service->getVisibleIDs(_ids, status);
244 }
245 }
246
247public:
248 static UClassID U_EXPORT2 getStaticClassID(void);
249 virtual UClassID getDynamicClassID(void) const;
250};
251
4388f060
A
252ServiceEnumeration::~ServiceEnumeration() {}
253
73c04bcf
A
254UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceEnumeration)
255
256StringEnumeration*
257ICULocaleService::getAvailableLocales(void) const
258{
259 return ServiceEnumeration::create(this);
260}
261
262const UnicodeString&
263ICULocaleService::validateFallbackLocale() const
264{
265 const Locale& loc = Locale::getDefault();
266 ICULocaleService* ncThis = (ICULocaleService*)this;
267 {
4388f060 268 Mutex mutex(&llock);
73c04bcf
A
269 if (loc != fallbackLocale) {
270 ncThis->fallbackLocale = loc;
271 LocaleUtility::initNameFromLocale(loc, ncThis->fallbackLocaleName);
272 ncThis->clearServiceCache();
273 }
274 }
275 return fallbackLocaleName;
276}
277
278ICUServiceKey*
279ICULocaleService::createKey(const UnicodeString* id, UErrorCode& status) const
280{
281 return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), status);
282}
283
284ICUServiceKey*
285ICULocaleService::createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const
286{
287 return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), kind, status);
288}
289
290U_NAMESPACE_END
291
292/* !UCONFIG_NO_SERVICE */
293#endif
294
295