Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/intl/icu/source/common/locavailable.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
*
6
*   Copyright (C) 1997-2013, International Business Machines
7
*   Corporation and others.  All Rights Reserved.
8
*
9
*******************************************************************************
10
*   file name:  locavailable.cpp
11
*   encoding:   UTF-8
12
*   tab size:   8 (not used)
13
*   indentation:4
14
*
15
*   created on: 2010feb25
16
*   created by: Markus W. Scherer
17
*
18
*   Code for available locales, separated out from other .cpp files
19
*   that then do not depend on resource bundle code and res_index bundles.
20
*/
21
22
#include "unicode/utypes.h"
23
#include "unicode/locid.h"
24
#include "unicode/uloc.h"
25
#include "unicode/ures.h"
26
#include "cmemory.h"
27
#include "ucln_cmn.h"
28
#include "uassert.h"
29
#include "umutex.h"
30
#include "uresimp.h"
31
32
// C++ API ----------------------------------------------------------------- ***
33
34
U_NAMESPACE_BEGIN
35
36
static icu::Locale*  availableLocaleList = NULL;
37
static int32_t  availableLocaleListCount;
38
static icu::UInitOnce gInitOnceLocale = U_INITONCE_INITIALIZER;
39
40
U_NAMESPACE_END
41
42
U_CDECL_BEGIN
43
44
static UBool U_CALLCONV locale_available_cleanup(void)
45
0
{
46
0
    U_NAMESPACE_USE
47
0
48
0
    if (availableLocaleList) {
49
0
        delete []availableLocaleList;
50
0
        availableLocaleList = NULL;
51
0
    }
52
0
    availableLocaleListCount = 0;
53
0
    gInitOnceLocale.reset();
54
0
55
0
    return TRUE;
56
0
}
57
58
U_CDECL_END
59
60
U_NAMESPACE_BEGIN
61
62
0
void U_CALLCONV locale_available_init() {
63
0
    // This function is a friend of class Locale.
64
0
    // This function is only invoked via umtx_initOnce().
65
0
    
66
0
    // for now, there is a hardcoded list, so just walk through that list and set it up.
67
0
    //  Note: this function is a friend of class Locale.
68
0
    availableLocaleListCount = uloc_countAvailable();
69
0
    if(availableLocaleListCount) {
70
0
       availableLocaleList = new Locale[availableLocaleListCount];
71
0
    }
72
0
    if (availableLocaleList == NULL) {
73
0
        availableLocaleListCount= 0;
74
0
    }
75
0
    for (int32_t locCount=availableLocaleListCount-1; locCount>=0; --locCount) {
76
0
        availableLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount));
77
0
    }
78
0
    ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup);
79
0
}
80
81
const Locale* U_EXPORT2
82
Locale::getAvailableLocales(int32_t& count)
83
0
{
84
0
    umtx_initOnce(gInitOnceLocale, &locale_available_init);
85
0
    count = availableLocaleListCount;
86
0
    return availableLocaleList;
87
0
}
88
89
90
U_NAMESPACE_END
91
92
// C API ------------------------------------------------------------------- ***
93
94
U_NAMESPACE_USE
95
96
/* ### Constants **************************************************/
97
98
/* These strings describe the resources we attempt to load from
99
 the locale ResourceBundle data file.*/
100
static const char _kIndexLocaleName[] = "res_index";
101
static const char _kIndexTag[]        = "InstalledLocales";
102
103
static char** _installedLocales = NULL;
104
static int32_t _installedLocalesCount = 0;
105
static icu::UInitOnce _installedLocalesInitOnce;
106
107
/* ### Get available **************************************************/
108
109
0
static UBool U_CALLCONV uloc_cleanup(void) {
110
0
    char ** temp;
111
0
112
0
    if (_installedLocales) {
113
0
        temp = _installedLocales;
114
0
        _installedLocales = NULL;
115
0
116
0
        _installedLocalesCount = 0;
117
0
        _installedLocalesInitOnce.reset();
118
0
119
0
        uprv_free(temp);
120
0
    }
121
0
    return TRUE;
122
0
}
123
124
// Load Installed Locales. This function will be called exactly once
125
//   via the initOnce mechanism.
126
127
0
static void U_CALLCONV loadInstalledLocales() {
128
0
    UResourceBundle *indexLocale = NULL;
129
0
    UResourceBundle installed;
130
0
    UErrorCode status = U_ZERO_ERROR;
131
0
    int32_t i = 0;
132
0
    int32_t localeCount;
133
0
    
134
0
    U_ASSERT(_installedLocales == NULL);
135
0
    U_ASSERT(_installedLocalesCount == 0);
136
0
137
0
    _installedLocalesCount = 0;
138
0
    ures_initStackObject(&installed);
139
0
    indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status);
140
0
    ures_getByKey(indexLocale, _kIndexTag, &installed, &status);
141
0
    
142
0
    if(U_SUCCESS(status)) {
143
0
        localeCount = ures_getSize(&installed);
144
0
        _installedLocales = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
145
0
        if (_installedLocales != NULL) {
146
0
            ures_resetIterator(&installed);
147
0
            while(ures_hasNext(&installed)) {
148
0
                ures_getNextString(&installed, NULL, (const char **)&_installedLocales[i++], &status);
149
0
            }
150
0
            _installedLocales[i] = NULL;
151
0
            _installedLocalesCount = localeCount;
152
0
            ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
153
0
        }
154
0
    }
155
0
    ures_close(&installed);
156
0
    ures_close(indexLocale);
157
0
}
158
159
static void _load_installedLocales()
160
0
{
161
0
    umtx_initOnce(_installedLocalesInitOnce, &loadInstalledLocales);
162
0
}
163
164
U_CAPI const char* U_EXPORT2
165
uloc_getAvailable(int32_t offset) 
166
0
{
167
0
    
168
0
    _load_installedLocales();
169
0
    
170
0
    if (offset > _installedLocalesCount)
171
0
        return NULL;
172
0
    return _installedLocales[offset];
173
0
}
174
175
U_CAPI int32_t  U_EXPORT2
176
uloc_countAvailable()
177
0
{
178
0
    _load_installedLocales();
179
0
    return _installedLocalesCount;
180
0
}
181