ICU-64252.0.1.tar.gz
[apple/icu.git] / icuSources / common / locavailable.cpp
CommitLineData
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
34U_NAMESPACE_BEGIN
35
4388f060 36static icu::Locale* availableLocaleList = NULL;
729e4ab9 37static int32_t availableLocaleListCount;
0f5d89e8 38static icu::UInitOnce gInitOnceLocale = U_INITONCE_INITIALIZER;
57a6839d
A
39
40U_NAMESPACE_END
729e4ab9
A
41
42U_CDECL_BEGIN
43
44static 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
58U_CDECL_END
59
60U_NAMESPACE_BEGIN
61
57a6839d
A
62void 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
81const Locale* U_EXPORT2
82Locale::getAvailableLocales(int32_t& count)
83{
0f5d89e8 84 umtx_initOnce(gInitOnceLocale, &locale_available_init);
729e4ab9
A
85 count = availableLocaleListCount;
86 return availableLocaleList;
87}
88
89
90U_NAMESPACE_END
91
92// C API ------------------------------------------------------------------- ***
93
94U_NAMESPACE_USE
95
96/* ### Constants **************************************************/
97
98/* These strings describe the resources we attempt to load from
99 the locale ResourceBundle data file.*/
100static const char _kIndexLocaleName[] = "res_index";
101static const char _kIndexTag[] = "InstalledLocales";
102
103static char** _installedLocales = NULL;
104static int32_t _installedLocalesCount = 0;
57a6839d 105static icu::UInitOnce _installedLocalesInitOnce;
729e4ab9
A
106
107/* ### Get available **************************************************/
108
109static 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 127static 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
157static void _load_installedLocales()
158{
159 umtx_initOnce(_installedLocalesInitOnce, &loadInstalledLocales);
729e4ab9
A
160}
161
162U_CAPI const char* U_EXPORT2
163uloc_getAvailable(int32_t offset)
164{
165
166 _load_installedLocales();
167
168 if (offset > _installedLocalesCount)
169 return NULL;
170 return _installedLocales[offset];
171}
172
173U_CAPI int32_t U_EXPORT2
174uloc_countAvailable()
175{
176 _load_installedLocales();
177 return _installedLocalesCount;
178}
57a6839d 179