summaryrefslogtreecommitdiff
path: root/Build/source/libs/icu/icu-4.6/common/locavailable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/icu/icu-4.6/common/locavailable.cpp')
-rw-r--r--Build/source/libs/icu/icu-4.6/common/locavailable.cpp187
1 files changed, 187 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-4.6/common/locavailable.cpp b/Build/source/libs/icu/icu-4.6/common/locavailable.cpp
new file mode 100644
index 00000000000..7060a689914
--- /dev/null
+++ b/Build/source/libs/icu/icu-4.6/common/locavailable.cpp
@@ -0,0 +1,187 @@
+/*
+*******************************************************************************
+*
+* Copyright (C) 1997-2010, International Business Machines
+* Corporation and others. All Rights Reserved.
+*
+*******************************************************************************
+* file name: locavailable.cpp
+* encoding: US-ASCII
+* tab size: 8 (not used)
+* indentation:4
+*
+* created on: 2010feb25
+* created by: Markus W. Scherer
+*
+* Code for available locales, separated out from other .cpp files
+* that then do not depend on resource bundle code and res_index bundles.
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/locid.h"
+#include "unicode/uloc.h"
+#include "unicode/ures.h"
+#include "cmemory.h"
+#include "ucln_cmn.h"
+#include "umutex.h"
+#include "uresimp.h"
+
+// C++ API ----------------------------------------------------------------- ***
+
+static U_NAMESPACE_QUALIFIER Locale* availableLocaleList = NULL;
+static int32_t availableLocaleListCount;
+
+U_CDECL_BEGIN
+
+static UBool U_CALLCONV locale_available_cleanup(void)
+{
+ U_NAMESPACE_USE
+
+ if (availableLocaleList) {
+ delete []availableLocaleList;
+ availableLocaleList = NULL;
+ }
+ availableLocaleListCount = 0;
+
+ return TRUE;
+}
+
+U_CDECL_END
+
+U_NAMESPACE_BEGIN
+
+const Locale* U_EXPORT2
+Locale::getAvailableLocales(int32_t& count)
+{
+ // for now, there is a hardcoded list, so just walk through that list and set it up.
+ UBool needInit;
+ UMTX_CHECK(NULL, availableLocaleList == NULL, needInit);
+
+ if (needInit) {
+ int32_t locCount = uloc_countAvailable();
+ Locale *newLocaleList = 0;
+ if(locCount) {
+ newLocaleList = new Locale[locCount];
+ }
+ if (newLocaleList == NULL) {
+ count = 0;
+ return NULL;
+ }
+
+ count = locCount;
+
+ while(--locCount >= 0) {
+ newLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount));
+ }
+
+ umtx_lock(NULL);
+ if(availableLocaleList == 0) {
+ availableLocaleListCount = count;
+ availableLocaleList = newLocaleList;
+ newLocaleList = NULL;
+ ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup);
+ }
+ umtx_unlock(NULL);
+ delete []newLocaleList;
+ }
+ count = availableLocaleListCount;
+ return availableLocaleList;
+}
+
+
+U_NAMESPACE_END
+
+// C API ------------------------------------------------------------------- ***
+
+U_NAMESPACE_USE
+
+/* ### Constants **************************************************/
+
+/* These strings describe the resources we attempt to load from
+ the locale ResourceBundle data file.*/
+static const char _kIndexLocaleName[] = "res_index";
+static const char _kIndexTag[] = "InstalledLocales";
+
+static char** _installedLocales = NULL;
+static int32_t _installedLocalesCount = 0;
+
+/* ### Get available **************************************************/
+
+static UBool U_CALLCONV uloc_cleanup(void) {
+ char ** temp;
+
+ if (_installedLocales) {
+ temp = _installedLocales;
+ _installedLocales = NULL;
+
+ _installedLocalesCount = 0;
+
+ uprv_free(temp);
+ }
+ return TRUE;
+}
+
+static void _load_installedLocales()
+{
+ UBool localesLoaded;
+
+ UMTX_CHECK(NULL, _installedLocales != NULL, localesLoaded);
+
+ if (localesLoaded == FALSE) {
+ UResourceBundle *indexLocale = NULL;
+ UResourceBundle installed;
+ UErrorCode status = U_ZERO_ERROR;
+ char ** temp;
+ int32_t i = 0;
+ int32_t localeCount;
+
+ ures_initStackObject(&installed);
+ indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status);
+ ures_getByKey(indexLocale, _kIndexTag, &installed, &status);
+
+ if(U_SUCCESS(status)) {
+ localeCount = ures_getSize(&installed);
+ temp = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
+ /* Check for null pointer */
+ if (temp != NULL) {
+ ures_resetIterator(&installed);
+ while(ures_hasNext(&installed)) {
+ ures_getNextString(&installed, NULL, (const char **)&temp[i++], &status);
+ }
+ temp[i] = NULL;
+
+ umtx_lock(NULL);
+ if (_installedLocales == NULL)
+ {
+ _installedLocalesCount = localeCount;
+ _installedLocales = temp;
+ temp = NULL;
+ ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
+ }
+ umtx_unlock(NULL);
+
+ uprv_free(temp);
+ }
+ }
+ ures_close(&installed);
+ ures_close(indexLocale);
+ }
+}
+
+U_CAPI const char* U_EXPORT2
+uloc_getAvailable(int32_t offset)
+{
+
+ _load_installedLocales();
+
+ if (offset > _installedLocalesCount)
+ return NULL;
+ return _installedLocales[offset];
+}
+
+U_CAPI int32_t U_EXPORT2
+uloc_countAvailable()
+{
+ _load_installedLocales();
+ return _installedLocalesCount;
+}