16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 1997-2013, International Business Machines 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Corporation and others. All Rights Reserved. 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* file name: locavailable.cpp 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* encoding: US-ASCII 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* tab size: 8 (not used) 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* indentation:4 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created on: 2010feb25 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created by: Markus W. Scherer 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Code for available locales, separated out from other .cpp files 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* that then do not depend on resource bundle code and res_index bundles. 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/locid.h" 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uloc.h" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ures.h" 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucln_cmn.h" 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "umutex.h" 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uresimp.h" 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// C++ API ----------------------------------------------------------------- *** 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::Locale* availableLocaleList = NULL; 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t availableLocaleListCount; 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::UInitOnce gInitOnce = U_INITONCE_INITIALIZER; 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_BEGIN 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool U_CALLCONV locale_available_cleanup(void) 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_NAMESPACE_USE 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (availableLocaleList) { 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete []availableLocaleList; 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org availableLocaleList = NULL; 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org availableLocaleListCount = 0; 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gInitOnce.reset(); 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_END 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid U_CALLCONV locale_available_init() { 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This function is a friend of class Locale. 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This function is only invoked via umtx_initOnce(). 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // for now, there is a hardcoded list, so just walk through that list and set it up. 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Note: this function is a friend of class Locale. 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org availableLocaleListCount = uloc_countAvailable(); 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(availableLocaleListCount) { 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org availableLocaleList = new Locale[availableLocaleListCount]; 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (availableLocaleList == NULL) { 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org availableLocaleListCount= 0; 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t locCount=availableLocaleListCount-1; locCount>=0; --locCount) { 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org availableLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount)); 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup); 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst Locale* U_EXPORT2 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgLocale::getAvailableLocales(int32_t& count) 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_initOnce(gInitOnce, &locale_available_init); 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count = availableLocaleListCount; 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return availableLocaleList; 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// C API ------------------------------------------------------------------- *** 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_USE 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* ### Constants **************************************************/ 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* These strings describe the resources we attempt to load from 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org the locale ResourceBundle data file.*/ 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char _kIndexLocaleName[] = "res_index"; 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char _kIndexTag[] = "InstalledLocales"; 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic char** _installedLocales = NULL; 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t _installedLocalesCount = 0; 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::UInitOnce _installedLocalesInitOnce; 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* ### Get available **************************************************/ 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool U_CALLCONV uloc_cleanup(void) { 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char ** temp; 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (_installedLocales) { 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp = _installedLocales; 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _installedLocales = NULL; 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _installedLocalesCount = 0; 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _installedLocalesInitOnce.reset(); 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(temp); 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Load Installed Locales. This function will be called exactly once 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// via the initOnce mechanism. 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV loadInstalledLocales() { 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle *indexLocale = NULL; 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle installed; 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i = 0; 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t localeCount; 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(_installedLocales == NULL); 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(_installedLocalesCount == 0); 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _installedLocalesCount = 0; 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_initStackObject(&installed); 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status); 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getByKey(indexLocale, _kIndexTag, &installed, &status); 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_SUCCESS(status)) { 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org localeCount = ures_getSize(&installed); 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _installedLocales = (char **) uprv_malloc(sizeof(char*) * (localeCount+1)); 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (_installedLocales != NULL) { 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_resetIterator(&installed); 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(ures_hasNext(&installed)) { 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_getNextString(&installed, NULL, (const char **)&_installedLocales[i++], &status); 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _installedLocales[i] = NULL; 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _installedLocalesCount = localeCount; 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup); 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(&installed); 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(indexLocale); 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void _load_installedLocales() 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_initOnce(_installedLocalesInitOnce, &loadInstalledLocales); 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const char* U_EXPORT2 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguloc_getAvailable(int32_t offset) 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _load_installedLocales(); 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (offset > _installedLocalesCount) 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return _installedLocales[offset]; 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguloc_countAvailable() 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _load_installedLocales(); 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return _installedLocalesCount; 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 180