Commit | Line | Data |
---|---|---|
f3c0d7a5 A |
1 | // © 2016 and later: Unicode, Inc. and others. |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
729e4ab9 A |
3 | /* |
4 | ******************************************************************************* | |
5 | * | |
57a6839d | 6 | * Copyright (C) 1997-2013, International Business Machines |
729e4ab9 A |
7 | * Corporation and others. All Rights Reserved. |
8 | * | |
9 | ******************************************************************************* | |
10 | * file name: locavailable.cpp | |
f3c0d7a5 | 11 | * encoding: UTF-8 |
729e4ab9 A |
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" | |
57a6839d | 28 | #include "uassert.h" |
729e4ab9 A |
29 | #include "umutex.h" |
30 | #include "uresimp.h" | |
31 | ||
32 | // C++ API ----------------------------------------------------------------- *** | |
33 | ||
57a6839d A |
34 | U_NAMESPACE_BEGIN |
35 | ||
4388f060 | 36 | static icu::Locale* availableLocaleList = NULL; |
729e4ab9 | 37 | static int32_t availableLocaleListCount; |
0f5d89e8 | 38 | static icu::UInitOnce gInitOnceLocale = U_INITONCE_INITIALIZER; |
57a6839d A |
39 | |
40 | U_NAMESPACE_END | |
729e4ab9 A |
41 | |
42 | U_CDECL_BEGIN | |
43 | ||
44 | static UBool U_CALLCONV locale_available_cleanup(void) | |
45 | { | |
46 | U_NAMESPACE_USE | |
47 | ||
48 | if (availableLocaleList) { | |
49 | delete []availableLocaleList; | |
50 | availableLocaleList = NULL; | |
51 | } | |
52 | availableLocaleListCount = 0; | |
0f5d89e8 | 53 | gInitOnceLocale.reset(); |
729e4ab9 A |
54 | |
55 | return TRUE; | |
56 | } | |
57 | ||
58 | U_CDECL_END | |
59 | ||
60 | U_NAMESPACE_BEGIN | |
61 | ||
57a6839d A |
62 | void U_CALLCONV locale_available_init() { |
63 | // This function is a friend of class Locale. | |
64 | // This function is only invoked via umtx_initOnce(). | |
65 | ||
66 | // for now, there is a hardcoded list, so just walk through that list and set it up. | |
67 | // Note: this function is a friend of class Locale. | |
68 | availableLocaleListCount = uloc_countAvailable(); | |
69 | if(availableLocaleListCount) { | |
70 | availableLocaleList = new Locale[availableLocaleListCount]; | |
71 | } | |
72 | if (availableLocaleList == NULL) { | |
73 | availableLocaleListCount= 0; | |
74 | } | |
75 | for (int32_t locCount=availableLocaleListCount-1; locCount>=0; --locCount) { | |
76 | availableLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount)); | |
77 | } | |
78 | ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup); | |
79 | } | |
80 | ||
729e4ab9 A |
81 | const Locale* U_EXPORT2 |
82 | Locale::getAvailableLocales(int32_t& count) | |
83 | { | |
0f5d89e8 | 84 | umtx_initOnce(gInitOnceLocale, &locale_available_init); |
729e4ab9 A |
85 | count = availableLocaleListCount; |
86 | return availableLocaleList; | |
87 | } | |
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; | |
57a6839d | 105 | static icu::UInitOnce _installedLocalesInitOnce; |
729e4ab9 A |
106 | |
107 | /* ### Get available **************************************************/ | |
108 | ||
109 | static UBool U_CALLCONV uloc_cleanup(void) { | |
110 | char ** temp; | |
111 | ||
112 | if (_installedLocales) { | |
113 | temp = _installedLocales; | |
114 | _installedLocales = NULL; | |
115 | ||
116 | _installedLocalesCount = 0; | |
57a6839d | 117 | _installedLocalesInitOnce.reset(); |
729e4ab9 A |
118 | |
119 | uprv_free(temp); | |
120 | } | |
121 | return TRUE; | |
122 | } | |
123 | ||
57a6839d A |
124 | // Load Installed Locales. This function will be called exactly once |
125 | // via the initOnce mechanism. | |
729e4ab9 | 126 | |
57a6839d | 127 | static void U_CALLCONV loadInstalledLocales() { |
57a6839d A |
128 | UErrorCode status = U_ZERO_ERROR; |
129 | int32_t i = 0; | |
130 | int32_t localeCount; | |
729e4ab9 | 131 | |
57a6839d A |
132 | U_ASSERT(_installedLocales == NULL); |
133 | U_ASSERT(_installedLocalesCount == 0); | |
134 | ||
135 | _installedLocalesCount = 0; | |
3d1f044b A |
136 | |
137 | icu::LocalUResourceBundlePointer indexLocale(ures_openDirect(NULL, _kIndexLocaleName, &status)); | |
138 | icu::StackUResourceBundle installed; | |
139 | ||
140 | ures_getByKey(indexLocale.getAlias(), _kIndexTag, installed.getAlias(), &status); | |
141 | ||
57a6839d | 142 | if(U_SUCCESS(status)) { |
3d1f044b | 143 | localeCount = ures_getSize(installed.getAlias()); |
57a6839d A |
144 | _installedLocales = (char **) uprv_malloc(sizeof(char*) * (localeCount+1)); |
145 | if (_installedLocales != NULL) { | |
3d1f044b A |
146 | ures_resetIterator(installed.getAlias()); |
147 | while(ures_hasNext(installed.getAlias())) { | |
148 | ures_getNextString(installed.getAlias(), NULL, (const char **)&_installedLocales[i++], &status); | |
729e4ab9 | 149 | } |
57a6839d A |
150 | _installedLocales[i] = NULL; |
151 | _installedLocalesCount = localeCount; | |
152 | ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup); | |
729e4ab9 | 153 | } |
729e4ab9 | 154 | } |
57a6839d A |
155 | } |
156 | ||
157 | static void _load_installedLocales() | |
158 | { | |
159 | umtx_initOnce(_installedLocalesInitOnce, &loadInstalledLocales); | |
729e4ab9 A |
160 | } |
161 | ||
162 | U_CAPI const char* U_EXPORT2 | |
163 | uloc_getAvailable(int32_t offset) | |
164 | { | |
165 | ||
166 | _load_installedLocales(); | |
167 | ||
168 | if (offset > _installedLocalesCount) | |
169 | return NULL; | |
170 | return _installedLocales[offset]; | |
171 | } | |
172 | ||
173 | U_CAPI int32_t U_EXPORT2 | |
174 | uloc_countAvailable() | |
175 | { | |
176 | _load_installedLocales(); | |
177 | return _installedLocalesCount; | |
178 | } | |
57a6839d | 179 |