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