Coverage Report

Created: 2021-08-22 09:07

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