Coverage Report

Created: 2018-09-25 14:53

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