1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
6 * Copyright (C) 1997-2013, International Business Machines
7 * Corporation and others. All Rights Reserved.
9 *******************************************************************************
10 * file name: locavailable.cpp
12 * tab size: 8 (not used)
15 * created on: 2010feb25
16 * created by: Markus W. Scherer
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.
22 #include "unicode/utypes.h"
23 #include "unicode/locid.h"
24 #include "unicode/uloc.h"
25 #include "unicode/ures.h"
32 // C++ API ----------------------------------------------------------------- ***
36 static icu::Locale
* availableLocaleList
= NULL
;
37 static int32_t availableLocaleListCount
;
38 static icu::UInitOnce gInitOnceLocale
= U_INITONCE_INITIALIZER
;
44 static UBool U_CALLCONV
locale_available_cleanup(void)
48 if (availableLocaleList
) {
49 delete []availableLocaleList
;
50 availableLocaleList
= NULL
;
52 availableLocaleListCount
= 0;
53 gInitOnceLocale
.reset();
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().
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
];
72 if (availableLocaleList
== NULL
) {
73 availableLocaleListCount
= 0;
75 for (int32_t locCount
=availableLocaleListCount
-1; locCount
>=0; --locCount
) {
76 availableLocaleList
[locCount
].setFromPOSIXID(uloc_getAvailable(locCount
));
78 ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE
, locale_available_cleanup
);
81 const Locale
* U_EXPORT2
82 Locale::getAvailableLocales(int32_t& count
)
84 umtx_initOnce(gInitOnceLocale
, &locale_available_init
);
85 count
= availableLocaleListCount
;
86 return availableLocaleList
;
92 // C API ------------------------------------------------------------------- ***
96 /* ### Constants **************************************************/
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";
103 static char** _installedLocales
= NULL
;
104 static int32_t _installedLocalesCount
= 0;
105 static icu::UInitOnce _installedLocalesInitOnce
;
107 /* ### Get available **************************************************/
109 static UBool U_CALLCONV
uloc_cleanup(void) {
112 if (_installedLocales
) {
113 temp
= _installedLocales
;
114 _installedLocales
= NULL
;
116 _installedLocalesCount
= 0;
117 _installedLocalesInitOnce
.reset();
124 // Load Installed Locales. This function will be called exactly once
125 // via the initOnce mechanism.
127 static void U_CALLCONV
loadInstalledLocales() {
128 UErrorCode status
= U_ZERO_ERROR
;
132 U_ASSERT(_installedLocales
== NULL
);
133 U_ASSERT(_installedLocalesCount
== 0);
135 _installedLocalesCount
= 0;
137 icu::LocalUResourceBundlePointer
indexLocale(ures_openDirect(NULL
, _kIndexLocaleName
, &status
));
138 icu::StackUResourceBundle installed
;
140 ures_getByKey(indexLocale
.getAlias(), _kIndexTag
, installed
.getAlias(), &status
);
142 if(U_SUCCESS(status
)) {
143 localeCount
= ures_getSize(installed
.getAlias());
144 _installedLocales
= (char **) uprv_malloc(sizeof(char*) * (localeCount
+1));
145 if (_installedLocales
!= NULL
) {
146 ures_resetIterator(installed
.getAlias());
147 while(ures_hasNext(installed
.getAlias())) {
148 ures_getNextString(installed
.getAlias(), NULL
, (const char **)&_installedLocales
[i
++], &status
);
150 _installedLocales
[i
] = NULL
;
151 _installedLocalesCount
= localeCount
;
152 ucln_common_registerCleanup(UCLN_COMMON_ULOC
, uloc_cleanup
);
157 static void _load_installedLocales()
159 umtx_initOnce(_installedLocalesInitOnce
, &loadInstalledLocales
);
162 U_CAPI
const char* U_EXPORT2
163 uloc_getAvailable(int32_t offset
)
166 _load_installedLocales();
168 if (offset
> _installedLocalesCount
)
170 return _installedLocales
[offset
];
173 U_CAPI
int32_t U_EXPORT2
174 uloc_countAvailable()
176 _load_installedLocales();
177 return _installedLocalesCount
;