1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/common/locavailable.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,179 @@ 1.4 +/* 1.5 +******************************************************************************* 1.6 +* 1.7 +* Copyright (C) 1997-2013, International Business Machines 1.8 +* Corporation and others. All Rights Reserved. 1.9 +* 1.10 +******************************************************************************* 1.11 +* file name: locavailable.cpp 1.12 +* encoding: US-ASCII 1.13 +* tab size: 8 (not used) 1.14 +* indentation:4 1.15 +* 1.16 +* created on: 2010feb25 1.17 +* created by: Markus W. Scherer 1.18 +* 1.19 +* Code for available locales, separated out from other .cpp files 1.20 +* that then do not depend on resource bundle code and res_index bundles. 1.21 +*/ 1.22 + 1.23 +#include "unicode/utypes.h" 1.24 +#include "unicode/locid.h" 1.25 +#include "unicode/uloc.h" 1.26 +#include "unicode/ures.h" 1.27 +#include "cmemory.h" 1.28 +#include "ucln_cmn.h" 1.29 +#include "uassert.h" 1.30 +#include "umutex.h" 1.31 +#include "uresimp.h" 1.32 + 1.33 +// C++ API ----------------------------------------------------------------- *** 1.34 + 1.35 +U_NAMESPACE_BEGIN 1.36 + 1.37 +static icu::Locale* availableLocaleList = NULL; 1.38 +static int32_t availableLocaleListCount; 1.39 +static icu::UInitOnce gInitOnce = U_INITONCE_INITIALIZER; 1.40 + 1.41 +U_NAMESPACE_END 1.42 + 1.43 +U_CDECL_BEGIN 1.44 + 1.45 +static UBool U_CALLCONV locale_available_cleanup(void) 1.46 +{ 1.47 + U_NAMESPACE_USE 1.48 + 1.49 + if (availableLocaleList) { 1.50 + delete []availableLocaleList; 1.51 + availableLocaleList = NULL; 1.52 + } 1.53 + availableLocaleListCount = 0; 1.54 + gInitOnce.reset(); 1.55 + 1.56 + return TRUE; 1.57 +} 1.58 + 1.59 +U_CDECL_END 1.60 + 1.61 +U_NAMESPACE_BEGIN 1.62 + 1.63 +void U_CALLCONV locale_available_init() { 1.64 + // This function is a friend of class Locale. 1.65 + // This function is only invoked via umtx_initOnce(). 1.66 + 1.67 + // for now, there is a hardcoded list, so just walk through that list and set it up. 1.68 + // Note: this function is a friend of class Locale. 1.69 + availableLocaleListCount = uloc_countAvailable(); 1.70 + if(availableLocaleListCount) { 1.71 + availableLocaleList = new Locale[availableLocaleListCount]; 1.72 + } 1.73 + if (availableLocaleList == NULL) { 1.74 + availableLocaleListCount= 0; 1.75 + } 1.76 + for (int32_t locCount=availableLocaleListCount-1; locCount>=0; --locCount) { 1.77 + availableLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount)); 1.78 + } 1.79 + ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup); 1.80 +} 1.81 + 1.82 +const Locale* U_EXPORT2 1.83 +Locale::getAvailableLocales(int32_t& count) 1.84 +{ 1.85 + umtx_initOnce(gInitOnce, &locale_available_init); 1.86 + count = availableLocaleListCount; 1.87 + return availableLocaleList; 1.88 +} 1.89 + 1.90 + 1.91 +U_NAMESPACE_END 1.92 + 1.93 +// C API ------------------------------------------------------------------- *** 1.94 + 1.95 +U_NAMESPACE_USE 1.96 + 1.97 +/* ### Constants **************************************************/ 1.98 + 1.99 +/* These strings describe the resources we attempt to load from 1.100 + the locale ResourceBundle data file.*/ 1.101 +static const char _kIndexLocaleName[] = "res_index"; 1.102 +static const char _kIndexTag[] = "InstalledLocales"; 1.103 + 1.104 +static char** _installedLocales = NULL; 1.105 +static int32_t _installedLocalesCount = 0; 1.106 +static icu::UInitOnce _installedLocalesInitOnce; 1.107 + 1.108 +/* ### Get available **************************************************/ 1.109 + 1.110 +static UBool U_CALLCONV uloc_cleanup(void) { 1.111 + char ** temp; 1.112 + 1.113 + if (_installedLocales) { 1.114 + temp = _installedLocales; 1.115 + _installedLocales = NULL; 1.116 + 1.117 + _installedLocalesCount = 0; 1.118 + _installedLocalesInitOnce.reset(); 1.119 + 1.120 + uprv_free(temp); 1.121 + } 1.122 + return TRUE; 1.123 +} 1.124 + 1.125 +// Load Installed Locales. This function will be called exactly once 1.126 +// via the initOnce mechanism. 1.127 + 1.128 +static void U_CALLCONV loadInstalledLocales() { 1.129 + UResourceBundle *indexLocale = NULL; 1.130 + UResourceBundle installed; 1.131 + UErrorCode status = U_ZERO_ERROR; 1.132 + int32_t i = 0; 1.133 + int32_t localeCount; 1.134 + 1.135 + U_ASSERT(_installedLocales == NULL); 1.136 + U_ASSERT(_installedLocalesCount == 0); 1.137 + 1.138 + _installedLocalesCount = 0; 1.139 + ures_initStackObject(&installed); 1.140 + indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status); 1.141 + ures_getByKey(indexLocale, _kIndexTag, &installed, &status); 1.142 + 1.143 + if(U_SUCCESS(status)) { 1.144 + localeCount = ures_getSize(&installed); 1.145 + _installedLocales = (char **) uprv_malloc(sizeof(char*) * (localeCount+1)); 1.146 + if (_installedLocales != NULL) { 1.147 + ures_resetIterator(&installed); 1.148 + while(ures_hasNext(&installed)) { 1.149 + ures_getNextString(&installed, NULL, (const char **)&_installedLocales[i++], &status); 1.150 + } 1.151 + _installedLocales[i] = NULL; 1.152 + _installedLocalesCount = localeCount; 1.153 + ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup); 1.154 + } 1.155 + } 1.156 + ures_close(&installed); 1.157 + ures_close(indexLocale); 1.158 +} 1.159 + 1.160 +static void _load_installedLocales() 1.161 +{ 1.162 + umtx_initOnce(_installedLocalesInitOnce, &loadInstalledLocales); 1.163 +} 1.164 + 1.165 +U_CAPI const char* U_EXPORT2 1.166 +uloc_getAvailable(int32_t offset) 1.167 +{ 1.168 + 1.169 + _load_installedLocales(); 1.170 + 1.171 + if (offset > _installedLocalesCount) 1.172 + return NULL; 1.173 + return _installedLocales[offset]; 1.174 +} 1.175 + 1.176 +U_CAPI int32_t U_EXPORT2 1.177 +uloc_countAvailable() 1.178 +{ 1.179 + _load_installedLocales(); 1.180 + return _installedLocalesCount; 1.181 +} 1.182 +