summaryrefslogtreecommitdiff
path: root/src/corefx/System.Globalization.Native/localeStringData.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corefx/System.Globalization.Native/localeStringData.cpp')
-rw-r--r--src/corefx/System.Globalization.Native/localeStringData.cpp320
1 files changed, 320 insertions, 0 deletions
diff --git a/src/corefx/System.Globalization.Native/localeStringData.cpp b/src/corefx/System.Globalization.Native/localeStringData.cpp
new file mode 100644
index 0000000000..927da67095
--- /dev/null
+++ b/src/corefx/System.Globalization.Native/localeStringData.cpp
@@ -0,0 +1,320 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+#include <assert.h>
+#include <string.h>
+#include <vector>
+
+#include "locale.hpp"
+#include "holders.h"
+
+// Enum that corresponds to managed enum CultureData.LocaleStringData.
+// The numeric values of the enum members match their Win32 counterparts.
+enum LocaleStringData : int32_t
+{
+ LocalizedDisplayName = 0x00000002,
+ EnglishDisplayName = 0x00000072,
+ NativeDisplayName = 0x00000073,
+ LocalizedLanguageName = 0x0000006f,
+ EnglishLanguageName = 0x00001001,
+ NativeLanguageName = 0x00000004,
+ EnglishCountryName = 0x00001002,
+ NativeCountryName = 0x00000008,
+ ListSeparator = 0x0000000C,
+ DecimalSeparator = 0x0000000E,
+ ThousandSeparator = 0x0000000F,
+ Digits = 0x00000013,
+ MonetarySymbol = 0x00000014,
+ Iso4217MonetarySymbol = 0x00000015,
+ MonetaryDecimalSeparator = 0x00000016,
+ MonetaryThousandSeparator = 0x00000017,
+ AMDesignator = 0x00000028,
+ PMDesignator = 0x00000029,
+ PositiveSign = 0x00000050,
+ NegativeSign = 0x00000051,
+ Iso639LanguageName = 0x00000059,
+ Iso3166CountryName = 0x0000005A,
+ NaNSymbol = 0x00000069,
+ PositiveInfinitySymbol = 0x0000006a,
+ ParentName = 0x0000006d,
+ PercentSymbol = 0x00000076,
+ PerMilleSymbol = 0x00000077
+};
+
+/*
+Function:
+GetLocaleInfoDecimalFormatSymbol
+
+Obtains the value of a DecimalFormatSymbols
+*/
+UErrorCode
+GetLocaleInfoDecimalFormatSymbol(const char* locale, UNumberFormatSymbol symbol, UChar* value, int32_t valueLength)
+{
+ UErrorCode status = U_ZERO_ERROR;
+ UNumberFormat* pFormat = unum_open(UNUM_DECIMAL, nullptr, 0, locale, nullptr, &status);
+ UNumberFormatHolder formatHolder(pFormat, status);
+
+ if (U_FAILURE(status))
+ {
+ return status;
+ }
+
+ unum_getSymbol(pFormat, symbol, value, valueLength, &status);
+
+ return status;
+}
+
+/*
+Function:
+GetDigitSymbol
+
+Obtains the value of a Digit DecimalFormatSymbols
+*/
+UErrorCode GetDigitSymbol(const char* locale,
+ UErrorCode previousStatus,
+ UNumberFormatSymbol symbol,
+ int digit,
+ UChar* value,
+ int32_t valueLength)
+{
+ if (U_FAILURE(previousStatus))
+ {
+ return previousStatus;
+ }
+
+ return GetLocaleInfoDecimalFormatSymbol(locale, symbol, value + digit, valueLength - digit);
+}
+
+/*
+Function:
+GetLocaleInfoAmPm
+
+Obtains the value of the AM or PM string for a locale.
+*/
+UErrorCode GetLocaleInfoAmPm(const char* locale, bool am, UChar* value, int32_t valueLength)
+{
+ UErrorCode status = U_ZERO_ERROR;
+ UDateFormat* pFormat = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, locale, nullptr, 0, nullptr, 0, &status);
+ UDateFormatHolder formatHolder(pFormat, status);
+
+ if (U_FAILURE(status))
+ {
+ return status;
+ }
+
+ udat_getSymbols(pFormat, UDAT_AM_PMS, am ? 0 : 1, value, valueLength, &status);
+
+ return status;
+}
+
+/*
+Function:
+GetLocaleIso639LanguageName
+
+Gets the language name for a locale (via uloc_getLanguage) and converts the result to UChars
+*/
+UErrorCode GetLocaleIso639LanguageName(const char* locale, UChar* value, int32_t valueLength)
+{
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t length = uloc_getLanguage(locale, nullptr, 0, &status);
+
+ std::vector<char> buf(length + 1, '\0');
+ status = U_ZERO_ERROR;
+
+ uloc_getLanguage(locale, buf.data(), length + 1, &status);
+
+ if (U_SUCCESS(status))
+ {
+ status = u_charsToUChars_safe(buf.data(), value, valueLength);
+ }
+
+ return status;
+}
+
+/*
+Function:
+GetLocaleIso3166CountryName
+
+Gets the country name for a locale (via uloc_getCountry) and converts the result to UChars
+*/
+UErrorCode GetLocaleIso3166CountryName(const char* locale, UChar* value, int32_t valueLength)
+{
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t length = uloc_getCountry(locale, nullptr, 0, &status);
+
+ std::vector<char> buf(length + 1, '\0');
+ status = U_ZERO_ERROR;
+
+ uloc_getCountry(locale, buf.data(), length + 1, &status);
+
+ if (U_SUCCESS(status))
+ {
+ status = u_charsToUChars_safe(buf.data(), value, valueLength);
+ }
+
+ return status;
+}
+
+/*
+PAL Function:
+GetLocaleInfoString
+
+Obtains string locale information.
+Returns 1 for success, 0 otherwise
+*/
+extern "C" int32_t GlobalizationNative_GetLocaleInfoString(
+ const UChar* localeName, LocaleStringData localeStringData, UChar* value, int32_t valueLength)
+{
+ UErrorCode status = U_ZERO_ERROR;
+ char locale[ULOC_FULLNAME_CAPACITY];
+ GetLocale(localeName, locale, ULOC_FULLNAME_CAPACITY, false, &status);
+
+ if (U_FAILURE(status))
+ {
+ return UErrorCodeToBool(U_ILLEGAL_ARGUMENT_ERROR);
+ }
+
+ switch (localeStringData)
+ {
+ case LocalizedDisplayName:
+ uloc_getDisplayName(locale, DetectDefaultLocaleName(), value, valueLength, &status);
+ break;
+ case EnglishDisplayName:
+ uloc_getDisplayName(locale, ULOC_ENGLISH, value, valueLength, &status);
+ break;
+ case NativeDisplayName:
+ uloc_getDisplayName(locale, locale, value, valueLength, &status);
+ break;
+ case LocalizedLanguageName:
+ uloc_getDisplayLanguage(locale, DetectDefaultLocaleName(), value, valueLength, &status);
+ break;
+ case EnglishLanguageName:
+ uloc_getDisplayLanguage(locale, ULOC_ENGLISH, value, valueLength, &status);
+ break;
+ case NativeLanguageName:
+ uloc_getDisplayLanguage(locale, locale, value, valueLength, &status);
+ break;
+ case EnglishCountryName:
+ uloc_getDisplayCountry(locale, ULOC_ENGLISH, value, valueLength, &status);
+ break;
+ case NativeCountryName:
+ uloc_getDisplayCountry(locale, locale, value, valueLength, &status);
+ break;
+ case ListSeparator:
+ // fall through
+ case ThousandSeparator:
+ status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_GROUPING_SEPARATOR_SYMBOL, value, valueLength);
+ break;
+ case DecimalSeparator:
+ status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_DECIMAL_SEPARATOR_SYMBOL, value, valueLength);
+ break;
+ case Digits:
+ status = GetDigitSymbol(locale, status, UNUM_ZERO_DIGIT_SYMBOL, 0, value, valueLength);
+ // symbols UNUM_ONE_DIGIT to UNUM_NINE_DIGIT are contiguous
+ for (int32_t symbol = UNUM_ONE_DIGIT_SYMBOL; symbol <= UNUM_NINE_DIGIT_SYMBOL; symbol++)
+ {
+ int charIndex = symbol - UNUM_ONE_DIGIT_SYMBOL + 1;
+ status = GetDigitSymbol(
+ locale, status, static_cast<UNumberFormatSymbol>(symbol), charIndex, value, valueLength);
+ }
+ break;
+ case MonetarySymbol:
+ status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_CURRENCY_SYMBOL, value, valueLength);
+ break;
+ case Iso4217MonetarySymbol:
+ status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_INTL_CURRENCY_SYMBOL, value, valueLength);
+ break;
+ case MonetaryDecimalSeparator:
+ status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_MONETARY_SEPARATOR_SYMBOL, value, valueLength);
+ break;
+ case MonetaryThousandSeparator:
+ status =
+ GetLocaleInfoDecimalFormatSymbol(locale, UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL, value, valueLength);
+ break;
+ case AMDesignator:
+ status = GetLocaleInfoAmPm(locale, true, value, valueLength);
+ break;
+ case PMDesignator:
+ status = GetLocaleInfoAmPm(locale, false, value, valueLength);
+ break;
+ case PositiveSign:
+ status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_PLUS_SIGN_SYMBOL, value, valueLength);
+ break;
+ case NegativeSign:
+ status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_MINUS_SIGN_SYMBOL, value, valueLength);
+ break;
+ case Iso639LanguageName:
+ status = GetLocaleIso639LanguageName(locale, value, valueLength);
+ break;
+ case Iso3166CountryName:
+ status = GetLocaleIso3166CountryName(locale, value, valueLength);
+ break;
+ case NaNSymbol:
+ status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_NAN_SYMBOL, value, valueLength);
+ break;
+ case PositiveInfinitySymbol:
+ status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_INFINITY_SYMBOL, value, valueLength);
+ break;
+ case ParentName:
+ {
+ // ICU supports lang[-script][-region][-variant] so up to 4 parents
+ // including invariant locale
+ char localeNameTemp[ULOC_FULLNAME_CAPACITY];
+
+ uloc_getParent(locale, localeNameTemp, ULOC_FULLNAME_CAPACITY, &status);
+ if (U_SUCCESS(status))
+ {
+ status = u_charsToUChars_safe(localeNameTemp, value, valueLength);
+ if (U_SUCCESS(status))
+ {
+ FixupLocaleName(value, valueLength);
+ }
+ }
+ break;
+ }
+ case PercentSymbol:
+ status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_PERCENT_SYMBOL, value, valueLength);
+ break;
+ case PerMilleSymbol:
+ status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_PERMILL_SYMBOL, value, valueLength);
+ break;
+ default:
+ status = U_UNSUPPORTED_ERROR;
+ break;
+ };
+
+ return UErrorCodeToBool(status);
+}
+
+/*
+PAL Function:
+GetLocaleTimeFormat
+
+Obtains time format information (in ICU format, it needs to be coverted to .NET Format).
+Returns 1 for success, 0 otherwise
+*/
+extern "C" int32_t GlobalizationNative_GetLocaleTimeFormat(
+ const UChar* localeName, int shortFormat, UChar* value, int32_t valueLength)
+{
+ UErrorCode err = U_ZERO_ERROR;
+ char locale[ULOC_FULLNAME_CAPACITY];
+ GetLocale(localeName, locale, ULOC_FULLNAME_CAPACITY, false, &err);
+
+ if (U_FAILURE(err))
+ {
+ return UErrorCodeToBool(U_ILLEGAL_ARGUMENT_ERROR);
+ }
+
+ UDateFormatStyle style = (shortFormat != 0) ? UDAT_SHORT : UDAT_MEDIUM;
+ UDateFormat* pFormat = udat_open(style, UDAT_NONE, locale, nullptr, 0, nullptr, 0, &err);
+ UDateFormatHolder formatHolder(pFormat, err);
+
+ if (U_FAILURE(err))
+ return UErrorCodeToBool(err);
+
+ udat_toPattern(pFormat, false, value, valueLength, &err);
+
+ return UErrorCodeToBool(err);
+}