]> git.saurik.com Git - apple/icu.git/blame - icuSources/common/locavailable.cpp
ICU-461.12.tar.gz
[apple/icu.git] / icuSources / common / locavailable.cpp
CommitLineData
729e4ab9
A
1/*
2*******************************************************************************
3*
4* Copyright (C) 1997-2010, International Business Machines
5* Corporation and others. All Rights Reserved.
6*
7*******************************************************************************
8* file name: locavailable.cpp
9* encoding: US-ASCII
10* tab size: 8 (not used)
11* indentation:4
12*
13* created on: 2010feb25
14* created by: Markus W. Scherer
15*
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.
18*/
19
20#include "unicode/utypes.h"
21#include "unicode/locid.h"
22#include "unicode/uloc.h"
23#include "unicode/ures.h"
24#include "cmemory.h"
25#include "ucln_cmn.h"
26#include "umutex.h"
27#include "uresimp.h"
28
29// C++ API ----------------------------------------------------------------- ***
30
31static U_NAMESPACE_QUALIFIER Locale* availableLocaleList = NULL;
32static int32_t availableLocaleListCount;
33
34U_CDECL_BEGIN
35
36static UBool U_CALLCONV locale_available_cleanup(void)
37{
38 U_NAMESPACE_USE
39
40 if (availableLocaleList) {
41 delete []availableLocaleList;
42 availableLocaleList = NULL;
43 }
44 availableLocaleListCount = 0;
45
46 return TRUE;
47}
48
49U_CDECL_END
50
51U_NAMESPACE_BEGIN
52
53const Locale* U_EXPORT2
54Locale::getAvailableLocales(int32_t& count)
55{
56 // for now, there is a hardcoded list, so just walk through that list and set it up.
57 UBool needInit;
58 UMTX_CHECK(NULL, availableLocaleList == NULL, needInit);
59
60 if (needInit) {
61 int32_t locCount = uloc_countAvailable();
62 Locale *newLocaleList = 0;
63 if(locCount) {
64 newLocaleList = new Locale[locCount];
65 }
66 if (newLocaleList == NULL) {
67 count = 0;
68 return NULL;
69 }
70
71 count = locCount;
72
73 while(--locCount >= 0) {
74 newLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount));
75 }
76
77 umtx_lock(NULL);
78 if(availableLocaleList == 0) {
79 availableLocaleListCount = count;
80 availableLocaleList = newLocaleList;
81 newLocaleList = NULL;
82 ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup);
83 }
84 umtx_unlock(NULL);
85 delete []newLocaleList;
86 }
87 count = availableLocaleListCount;
88 return availableLocaleList;
89}
90
91
92U_NAMESPACE_END
93
94// C API ------------------------------------------------------------------- ***
95
96U_NAMESPACE_USE
97
98/* ### Constants **************************************************/
99
100/* These strings describe the resources we attempt to load from
101 the locale ResourceBundle data file.*/
102static const char _kIndexLocaleName[] = "res_index";
103static const char _kIndexTag[] = "InstalledLocales";
104
105static char** _installedLocales = NULL;
106static int32_t _installedLocalesCount = 0;
107
108/* ### Get available **************************************************/
109
110static UBool U_CALLCONV uloc_cleanup(void) {
111 char ** temp;
112
113 if (_installedLocales) {
114 temp = _installedLocales;
115 _installedLocales = NULL;
116
117 _installedLocalesCount = 0;
118
119 uprv_free(temp);
120 }
121 return TRUE;
122}
123
124static void _load_installedLocales()
125{
126 UBool localesLoaded;
127
128 UMTX_CHECK(NULL, _installedLocales != NULL, localesLoaded);
129
130 if (localesLoaded == FALSE) {
131 UResourceBundle *indexLocale = NULL;
132 UResourceBundle installed;
133 UErrorCode status = U_ZERO_ERROR;
134 char ** temp;
135 int32_t i = 0;
136 int32_t localeCount;
137
138 ures_initStackObject(&installed);
139 indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status);
140 ures_getByKey(indexLocale, _kIndexTag, &installed, &status);
141
142 if(U_SUCCESS(status)) {
143 localeCount = ures_getSize(&installed);
144 temp = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
145 /* Check for null pointer */
146 if (temp != NULL) {
147 ures_resetIterator(&installed);
148 while(ures_hasNext(&installed)) {
149 ures_getNextString(&installed, NULL, (const char **)&temp[i++], &status);
150 }
151 temp[i] = NULL;
152
153 umtx_lock(NULL);
154 if (_installedLocales == NULL)
155 {
156 _installedLocalesCount = localeCount;
157 _installedLocales = temp;
158 temp = NULL;
159 ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
160 }
161 umtx_unlock(NULL);
162
163 uprv_free(temp);
164 }
165 }
166 ures_close(&installed);
167 ures_close(indexLocale);
168 }
169}
170
171U_CAPI const char* U_EXPORT2
172uloc_getAvailable(int32_t offset)
173{
174
175 _load_installedLocales();
176
177 if (offset > _installedLocalesCount)
178 return NULL;
179 return _installedLocales[offset];
180}
181
182U_CAPI int32_t U_EXPORT2
183uloc_countAvailable()
184{
185 _load_installedLocales();
186 return _installedLocalesCount;
187}