OLD | NEW |
(Empty) | |
| 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 |
| 31 static U_NAMESPACE_QUALIFIER Locale* availableLocaleList = NULL; |
| 32 static int32_t availableLocaleListCount; |
| 33 |
| 34 U_CDECL_BEGIN |
| 35 |
| 36 static 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 |
| 49 U_CDECL_END |
| 50 |
| 51 U_NAMESPACE_BEGIN |
| 52 |
| 53 const Locale* U_EXPORT2 |
| 54 Locale::getAvailableLocales(int32_t& count) |
| 55 { |
| 56 // for now, there is a hardcoded list, so just walk through that list and se
t 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_ava
ilable_cleanup); |
| 83 } |
| 84 umtx_unlock(NULL); |
| 85 delete []newLocaleList; |
| 86 } |
| 87 count = availableLocaleListCount; |
| 88 return availableLocaleList; |
| 89 } |
| 90 |
| 91 |
| 92 U_NAMESPACE_END |
| 93 |
| 94 // C API ------------------------------------------------------------------- *** |
| 95 |
| 96 U_NAMESPACE_USE |
| 97 |
| 98 /* ### Constants **************************************************/ |
| 99 |
| 100 /* These strings describe the resources we attempt to load from |
| 101 the locale ResourceBundle data file.*/ |
| 102 static const char _kIndexLocaleName[] = "res_index"; |
| 103 static const char _kIndexTag[] = "InstalledLocales"; |
| 104 |
| 105 static char** _installedLocales = NULL; |
| 106 static int32_t _installedLocalesCount = 0; |
| 107 |
| 108 /* ### Get available **************************************************/ |
| 109 |
| 110 static 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 |
| 124 static 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 |
| 171 U_CAPI const char* U_EXPORT2 |
| 172 uloc_getAvailable(int32_t offset) |
| 173 { |
| 174 |
| 175 _load_installedLocales(); |
| 176 |
| 177 if (offset > _installedLocalesCount) |
| 178 return NULL; |
| 179 return _installedLocales[offset]; |
| 180 } |
| 181 |
| 182 U_CAPI int32_t U_EXPORT2 |
| 183 uloc_countAvailable() |
| 184 { |
| 185 _load_installedLocales(); |
| 186 return _installedLocalesCount; |
| 187 } |
OLD | NEW |