1 // Copyright (C) 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 gInitOnce = U_INITONCE_INITIALIZER;
44 static UBool U_CALLCONV locale_available_cleanup(void)
48 if (availableLocaleList) {
49 delete []availableLocaleList;
50 availableLocaleList = NULL;
52 availableLocaleListCount = 0;
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(gInitOnce, &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 UResourceBundle *indexLocale = NULL;
129 UResourceBundle installed;
130 UErrorCode status = U_ZERO_ERROR;
134 U_ASSERT(_installedLocales == NULL);
135 U_ASSERT(_installedLocalesCount == 0);
137 _installedLocalesCount = 0;
138 ures_initStackObject(&installed);
139 indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status);
140 ures_getByKey(indexLocale, _kIndexTag, &installed, &status);
142 if(U_SUCCESS(status)) {
143 localeCount = ures_getSize(&installed);
144 _installedLocales = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
145 if (_installedLocales != NULL) {
146 ures_resetIterator(&installed);
147 while(ures_hasNext(&installed)) {
148 ures_getNextString(&installed, NULL, (const char **)&_installedLocales[i++], &status);
150 _installedLocales[i] = NULL;
151 _installedLocalesCount = localeCount;
152 ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
155 ures_close(&installed);
156 ures_close(indexLocale);
159 static void _load_installedLocales()
161 umtx_initOnce(_installedLocalesInitOnce, &loadInstalledLocales);
164 U_CAPI const char* U_EXPORT2
165 uloc_getAvailable(int32_t offset)
168 _load_installedLocales();
170 if (offset > _installedLocalesCount)
172 return _installedLocales[offset];
175 U_CAPI int32_t U_EXPORT2
176 uloc_countAvailable()
178 _load_installedLocales();
179 return _installedLocalesCount;