2 *******************************************************************************
4 * Copyright (C) 1997-2013, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * file name: locavailable.cpp
10 * tab size: 8 (not used)
13 * created on: 2010feb25
14 * created by: Markus W. Scherer
16 * Code for available locales, separated out from other .cpp files
17 * that then do not depend on resource bundle code and res_index bundles.
20 #include "unicode/utypes.h"
21 #include "unicode/locid.h"
22 #include "unicode/uloc.h"
23 #include "unicode/ures.h"
30 // C++ API ----------------------------------------------------------------- ***
34 static icu::Locale
* availableLocaleList
= NULL
;
35 static int32_t availableLocaleListCount
;
36 static icu::UInitOnce gInitOnce
= U_INITONCE_INITIALIZER
;
42 static UBool U_CALLCONV
locale_available_cleanup(void)
46 if (availableLocaleList
) {
47 delete []availableLocaleList
;
48 availableLocaleList
= NULL
;
50 availableLocaleListCount
= 0;
60 void U_CALLCONV
locale_available_init() {
61 // This function is a friend of class Locale.
62 // This function is only invoked via umtx_initOnce().
64 // for now, there is a hardcoded list, so just walk through that list and set it up.
65 // Note: this function is a friend of class Locale.
66 availableLocaleListCount
= uloc_countAvailable();
67 if(availableLocaleListCount
) {
68 availableLocaleList
= new Locale
[availableLocaleListCount
];
70 if (availableLocaleList
== NULL
) {
71 availableLocaleListCount
= 0;
73 for (int32_t locCount
=availableLocaleListCount
-1; locCount
>=0; --locCount
) {
74 availableLocaleList
[locCount
].setFromPOSIXID(uloc_getAvailable(locCount
));
76 ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE
, locale_available_cleanup
);
79 const Locale
* U_EXPORT2
80 Locale::getAvailableLocales(int32_t& count
)
82 umtx_initOnce(gInitOnce
, &locale_available_init
);
83 count
= availableLocaleListCount
;
84 return availableLocaleList
;
90 // C API ------------------------------------------------------------------- ***
94 /* ### Constants **************************************************/
96 /* These strings describe the resources we attempt to load from
97 the locale ResourceBundle data file.*/
98 static const char _kIndexLocaleName
[] = "res_index";
99 static const char _kIndexTag
[] = "InstalledLocales";
101 static char** _installedLocales
= NULL
;
102 static int32_t _installedLocalesCount
= 0;
103 static icu::UInitOnce _installedLocalesInitOnce
;
105 /* ### Get available **************************************************/
107 static UBool U_CALLCONV
uloc_cleanup(void) {
110 if (_installedLocales
) {
111 temp
= _installedLocales
;
112 _installedLocales
= NULL
;
114 _installedLocalesCount
= 0;
115 _installedLocalesInitOnce
.reset();
122 // Load Installed Locales. This function will be called exactly once
123 // via the initOnce mechanism.
125 static void U_CALLCONV
loadInstalledLocales() {
126 UResourceBundle
*indexLocale
= NULL
;
127 UResourceBundle installed
;
128 UErrorCode status
= U_ZERO_ERROR
;
132 U_ASSERT(_installedLocales
== NULL
);
133 U_ASSERT(_installedLocalesCount
== 0);
135 _installedLocalesCount
= 0;
136 ures_initStackObject(&installed
);
137 indexLocale
= ures_openDirect(NULL
, _kIndexLocaleName
, &status
);
138 ures_getByKey(indexLocale
, _kIndexTag
, &installed
, &status
);
140 if(U_SUCCESS(status
)) {
141 localeCount
= ures_getSize(&installed
);
142 _installedLocales
= (char **) uprv_malloc(sizeof(char*) * (localeCount
+1));
143 if (_installedLocales
!= NULL
) {
144 ures_resetIterator(&installed
);
145 while(ures_hasNext(&installed
)) {
146 ures_getNextString(&installed
, NULL
, (const char **)&_installedLocales
[i
++], &status
);
148 _installedLocales
[i
] = NULL
;
149 _installedLocalesCount
= localeCount
;
150 ucln_common_registerCleanup(UCLN_COMMON_ULOC
, uloc_cleanup
);
153 ures_close(&installed
);
154 ures_close(indexLocale
);
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
;