From 0b3b276ea837e3ae9720e72142fe5c0ae54ad5a3 Mon Sep 17 00:00:00 2001 From: Matt Ellis Date: Tue, 20 Oct 2015 19:30:42 -0700 Subject: [PATCH] Remove use of icu::Locale C++ type Remove all the uses of the icu::Locale type in favor of just using a char* which is the raw locale id (which is exactly what all the ICU C apis use for a locale). The meat of this change si in locale.cpp to actually handle doing the conversion from UChar* to char*. The rest of the places are dealing with the fallout (GetLocale now has a different signiture and the .getName() dance is no longer needed as we have a raw locale name all the time now). --- .../System.Globalization.Native/calendarData.cpp | 61 ++++++----- src/corefx/System.Globalization.Native/locale.cpp | 118 ++++++++++++++------- src/corefx/System.Globalization.Native/locale.hpp | 8 +- .../localeNumberData.cpp | 43 ++++---- .../localeStringData.cpp | 77 +++++++------- 5 files changed, 179 insertions(+), 128 deletions(-) diff --git a/src/corefx/System.Globalization.Native/calendarData.cpp b/src/corefx/System.Globalization.Native/calendarData.cpp index 32f7925..744f452 100644 --- a/src/corefx/System.Globalization.Native/calendarData.cpp +++ b/src/corefx/System.Globalization.Native/calendarData.cpp @@ -209,12 +209,14 @@ Returns the list of CalendarIds that are available for the specified locale. */ extern "C" int32_t GetCalendars(const UChar* localeName, CalendarId* calendars, int32_t calendarsCapacity) { - Locale locale = GetLocale(localeName); - if (locale.isBogus()) + UErrorCode err = U_ZERO_ERROR; + char locale[ULOC_FULLNAME_CAPACITY]; + GetLocale(localeName, locale, ULOC_FULLNAME_CAPACITY, false, &err); + + if (U_FAILURE(err)) return 0; - UErrorCode err = U_ZERO_ERROR; - UEnumeration* pEnum = ucal_getKeywordValuesForLocale("calendar", locale.getName(), TRUE, &err); + UEnumeration* pEnum = ucal_getKeywordValuesForLocale("calendar", locale, TRUE, &err); UEnumerationHolder enumHolder(pEnum, err); if (U_FAILURE(err)) @@ -291,16 +293,19 @@ with the requested value. extern "C" CalendarDataResult GetCalendarInfo( const UChar* localeName, CalendarId calendarId, CalendarDataType dataType, UChar* result, int32_t resultCapacity) { - Locale locale = GetLocale(localeName); - if (locale.isBogus()) + UErrorCode err = U_ZERO_ERROR; + char locale[ULOC_FULLNAME_CAPACITY]; + GetLocale(localeName, locale, ULOC_FULLNAME_CAPACITY, false, &err); + + if (U_FAILURE(err)) return UnknownError; switch (dataType) { case NativeName: - return GetNativeCalendarName(locale.getName(), calendarId, result, resultCapacity); + return GetNativeCalendarName(locale, calendarId, result, resultCapacity); case MonthDay: - return GetMonthDayPattern(locale.getName(), result, resultCapacity); + return GetMonthDayPattern(locale, result, resultCapacity); default: assert(false); return UnknownError; @@ -557,8 +562,11 @@ extern "C" int32_t EnumCalendarInfo(EnumCalendarInfoCallback callback, CalendarDataType dataType, const void* context) { - Locale locale = GetLocale(localeName); - if (locale.isBogus()) + UErrorCode err = U_ZERO_ERROR; + char locale[ULOC_FULLNAME_CAPACITY]; + GetLocale(localeName, locale, ULOC_FULLNAME_CAPACITY, false, &err); + + if (U_FAILURE(err)) return false; switch (dataType) @@ -567,38 +575,37 @@ extern "C" int32_t EnumCalendarInfo(EnumCalendarInfoCallback callback, // ShortDates to map kShort and kMedium in ICU, but also adding the "yMd" // skeleton as well, as this // closely matches what is used on Windows - return InvokeCallbackForDateTimePattern( - locale.getName(), UDAT_YEAR_NUM_MONTH_DAY_UCHAR, callback, context) && - InvokeCallbackForDatePattern(locale.getName(), UDAT_SHORT, callback, context) && - InvokeCallbackForDatePattern(locale.getName(), UDAT_MEDIUM, callback, context); + return InvokeCallbackForDateTimePattern(locale, UDAT_YEAR_NUM_MONTH_DAY_UCHAR, callback, context) && + InvokeCallbackForDatePattern(locale, UDAT_SHORT, callback, context) && + InvokeCallbackForDatePattern(locale, UDAT_MEDIUM, callback, context); case LongDates: // LongDates map to kFull and kLong in ICU. - return InvokeCallbackForDatePattern(locale.getName(), UDAT_FULL, callback, context) && - InvokeCallbackForDatePattern(locale.getName(), UDAT_LONG, callback, context); + return InvokeCallbackForDatePattern(locale, UDAT_FULL, callback, context) && + InvokeCallbackForDatePattern(locale, UDAT_LONG, callback, context); case YearMonths: - return InvokeCallbackForDateTimePattern(locale.getName(), UDAT_YEAR_MONTH_UCHAR, callback, context); + return InvokeCallbackForDateTimePattern(locale, UDAT_YEAR_MONTH_UCHAR, callback, context); case DayNames: - return EnumSymbols(locale.getName(), calendarId, UDAT_STANDALONE_WEEKDAYS, 1, callback, context); + return EnumSymbols(locale, calendarId, UDAT_STANDALONE_WEEKDAYS, 1, callback, context); case AbbrevDayNames: - return EnumSymbols(locale.getName(), calendarId, UDAT_STANDALONE_SHORT_WEEKDAYS, 1, callback, context); + return EnumSymbols(locale, calendarId, UDAT_STANDALONE_SHORT_WEEKDAYS, 1, callback, context); case MonthNames: - return EnumSymbols(locale.getName(), calendarId, UDAT_STANDALONE_MONTHS, 0, callback, context); + return EnumSymbols(locale, calendarId, UDAT_STANDALONE_MONTHS, 0, callback, context); case AbbrevMonthNames: - return EnumSymbols(locale.getName(), calendarId, UDAT_STANDALONE_SHORT_MONTHS, 0, callback, context); + return EnumSymbols(locale, calendarId, UDAT_STANDALONE_SHORT_MONTHS, 0, callback, context); case SuperShortDayNames: #ifdef HAVE_DTWIDTHTYPE_SHORT - return EnumSymbols(locale.getName(), calendarId, UDAT_STANDALONE_SHORTER_WEEKDAYS, 1, callback, context); + return EnumSymbols(locale, calendarId, UDAT_STANDALONE_SHORTER_WEEKDAYS, 1, callback, context); #else - return EnumSymbols(locale.getName(), calendarId, UDAT_STANDALONE_NARROW_WEEKDAYS, 1, callback, context); + return EnumSymbols(locale, calendarId, UDAT_STANDALONE_NARROW_WEEKDAYS, 1, callback, context); #endif case MonthGenitiveNames: - return EnumSymbols(locale.getName(), calendarId, UDAT_MONTHS, 0, callback, context); + return EnumSymbols(locale, calendarId, UDAT_MONTHS, 0, callback, context); case AbbrevMonthGenitiveNames: - return EnumSymbols(locale.getName(), calendarId, UDAT_SHORT_MONTHS, 0, callback, context); + return EnumSymbols(locale, calendarId, UDAT_SHORT_MONTHS, 0, callback, context); case EraNames: - return EnumSymbols(locale.getName(), calendarId, UDAT_ERAS, 0, callback, context); + return EnumSymbols(locale, calendarId, UDAT_ERAS, 0, callback, context); case AbbrevEraNames: - return EnumAbbrevEraNames(locale.getName(), calendarId, callback, context); + return EnumAbbrevEraNames(locale, calendarId, callback, context); default: assert(false); return false; diff --git a/src/corefx/System.Globalization.Native/locale.cpp b/src/corefx/System.Globalization.Native/locale.cpp index f71b68d..c8a78f8 100644 --- a/src/corefx/System.Globalization.Native/locale.cpp +++ b/src/corefx/System.Globalization.Native/locale.cpp @@ -31,45 +31,76 @@ int32_t UErrorCodeToBool(UErrorCode status) return 0; } -Locale GetLocale(const UChar* localeName, bool canonize) +int32_t GetLocale( + const UChar* localeName, char* localeNameResult, int32_t localeNameResultLength, bool canonicalize, UErrorCode* err) { - char localeNameTemp[ULOC_FULLNAME_CAPACITY]; + char localeNameTemp[ULOC_FULLNAME_CAPACITY] = {0}; + int32_t localeLength; - if (localeName != NULL) + // Convert ourselves instead of doing u_UCharsToChars as that function considers '@' a variant and stops. + for (int i = 0; i < ULOC_FULLNAME_CAPACITY - 1; i++) { - // use UnicodeString.extract instead of u_UCharsToChars; u_UCharsToChars - // considers '@' a variant and stops - UnicodeString str(localeName, -1, ULOC_FULLNAME_CAPACITY); - str.extract(0, str.length(), localeNameTemp); + UChar c = localeName[i]; + + if (c > (UChar)0x7F) + { + *err = U_ILLEGAL_ARGUMENT_ERROR; + return ULOC_FULLNAME_CAPACITY; + } + + localeNameTemp[i] = (char)c; + + if (c == (UChar)0x0) + { + break; + } } - Locale loc; - if (canonize) + if (canonicalize) { - loc = Locale::createCanonical(localeName == NULL ? NULL : localeNameTemp); + localeLength = uloc_canonicalize(localeNameTemp, localeNameResult, localeNameResultLength, err); } else { - loc = Locale::createFromName(localeName == NULL ? NULL : localeNameTemp); + localeLength = uloc_getName(localeNameTemp, localeNameResult, localeNameResultLength, err); + } + + if (U_SUCCESS(*err)) + { + // Make sure the "language" part of the locale is reasonable (i.e. we can fetch it and it is within range). + // This mimics how the C++ ICU API determines if a locale is "bogus" or not. + + char language[ULOC_LANG_CAPACITY]; + uloc_getLanguage(localeNameTemp, language, ULOC_LANG_CAPACITY, err); + + if (*err == U_STRING_NOT_TERMINATED_WARNING) + { + // ULOC_LANG_CAPACITY includes the null terminator, so if we couldn't extract the language with the null + // terminator, the language must be invalid. + + *err = U_ILLEGAL_ARGUMENT_ERROR; + } } - return loc; + return localeLength; } UErrorCode u_charsToUChars_safe(const char* str, UChar* value, int32_t valueLength) { int len = strlen(str); + if (len >= valueLength) { return U_BUFFER_OVERFLOW_ERROR; } + u_charsToUChars(str, value, len + 1); return U_ZERO_ERROR; } -int FixupLocaleName(UChar* value, int32_t valueLength) +int32_t FixupLocaleName(UChar* value, int32_t valueLength) { - int i = 0; + int32_t i = 0; for (; i < valueLength; i++) { if (value[i] == (UChar)'\0') @@ -87,20 +118,19 @@ int FixupLocaleName(UChar* value, int32_t valueLength) extern "C" int32_t GetLocaleName(const UChar* localeName, UChar* value, int32_t valueLength) { - Locale locale = GetLocale(localeName, true); - - if (locale.isBogus()) - { - // localeName not properly formatted - return UErrorCodeToBool(U_ILLEGAL_ARGUMENT_ERROR); - } + UErrorCode status = U_ZERO_ERROR; - // other validation done on managed side + char localeNameBuffer[ULOC_FULLNAME_CAPACITY]; + GetLocale(localeName, localeNameBuffer, ULOC_FULLNAME_CAPACITY, true, &status); - UErrorCode status = u_charsToUChars_safe(locale.getName(), value, valueLength); if (U_SUCCESS(status)) { - FixupLocaleName(value, valueLength); + status = u_charsToUChars_safe(localeNameBuffer, value, valueLength); + + if (U_SUCCESS(status)) + { + FixupLocaleName(value, valueLength); + } } return UErrorCodeToBool(status); @@ -108,29 +138,35 @@ extern "C" int32_t GetLocaleName(const UChar* localeName, UChar* value, int32_t extern "C" int32_t GetDefaultLocaleName(UChar* value, int32_t valueLength) { - Locale locale = GetLocale(NULL); - if (locale.isBogus()) - { - // ICU should be able to get default locale - return UErrorCodeToBool(U_INTERNAL_PROGRAM_ERROR); - } + char localeNameBuffer[ULOC_FULLNAME_CAPACITY]; + UErrorCode status = U_ZERO_ERROR; + + const char* defaultLocale = uloc_getDefault(); + + uloc_getBaseName(defaultLocale, localeNameBuffer, ULOC_FULLNAME_CAPACITY, &status); - UErrorCode status = u_charsToUChars_safe(locale.getBaseName(), value, valueLength); if (U_SUCCESS(status)) { - int localeNameLen = FixupLocaleName(value, valueLength); + status = u_charsToUChars_safe(localeNameBuffer, value, valueLength); - // if collation is present, return that to managed side - char collationValueTemp[ULOC_KEYWORDS_CAPACITY]; - if (locale.getKeywordValue("collation", collationValueTemp, ULOC_KEYWORDS_CAPACITY, status) > 0) + if (U_SUCCESS(status)) { - // copy the collation; managed uses a "_" to represent collation (not - // "@collation=") - status = u_charsToUChars_safe("_", &value[localeNameLen], valueLength - localeNameLen); - if (U_SUCCESS(status)) + int localeNameLen = FixupLocaleName(value, valueLength); + + char collationValueTemp[ULOC_KEYWORDS_CAPACITY]; + int32_t collationLen = + uloc_getKeywordValue(defaultLocale, "collation", collationValueTemp, ULOC_KEYWORDS_CAPACITY, &status); + + if (U_SUCCESS(status) && collationLen > 0) { - status = u_charsToUChars_safe( - collationValueTemp, &value[localeNameLen + 1], valueLength - localeNameLen - 1); + // copy the collation; managed uses a "_" to represent collation (not + // "@collation=") + status = u_charsToUChars_safe("_", &value[localeNameLen], valueLength - localeNameLen); + if (U_SUCCESS(status)) + { + status = u_charsToUChars_safe( + collationValueTemp, &value[localeNameLen + 1], valueLength - localeNameLen - 1); + } } } } diff --git a/src/corefx/System.Globalization.Native/locale.hpp b/src/corefx/System.Globalization.Native/locale.hpp index 3ea1707..d6b61b7 100644 --- a/src/corefx/System.Globalization.Native/locale.hpp +++ b/src/corefx/System.Globalization.Native/locale.hpp @@ -27,9 +27,13 @@ int32_t UErrorCodeToBool(UErrorCode code); Function: GetLocale -Returns a locale given the locale name +Converts a managed localeName into something ICU understands and can use as a localeName. */ -Locale GetLocale(const UChar* localeName, bool canonize = false); +int32_t GetLocale(const UChar* localeName, + char* localeNameResult, + int32_t localeNameResultLength, + bool canonicalize, + UErrorCode* err); /* Function: diff --git a/src/corefx/System.Globalization.Native/localeNumberData.cpp b/src/corefx/System.Globalization.Native/localeNumberData.cpp index b73ca1c..842bcff 100644 --- a/src/corefx/System.Globalization.Native/localeNumberData.cpp +++ b/src/corefx/System.Globalization.Native/localeNumberData.cpp @@ -402,25 +402,26 @@ Returns 1 for success, 0 otherwise */ extern "C" int32_t GetLocaleInfoInt(const UChar* localeName, LocaleNumberData localeNumberData, int32_t* value) { - Locale locale = GetLocale(localeName); - if (locale.isBogus()) + 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); } - UErrorCode status = U_ZERO_ERROR; - switch (localeNumberData) { case LanguageId: - *value = uloc_getLCID(locale.getName()); + *value = uloc_getLCID(locale); break; case MeasurementSystem: - status = GetMeasurementSystem(locale.getName(), value); + status = GetMeasurementSystem(locale, value); break; case FractionalDigitsCount: { - UNumberFormat* numformat = unum_open(UNUM_DECIMAL, NULL, 0, locale.getName(), NULL, &status); + UNumberFormat* numformat = unum_open(UNUM_DECIMAL, NULL, 0, locale, NULL, &status); if (U_SUCCESS(status)) { *value = unum_getAttribute(numformat, UNUM_MAX_FRACTION_DIGITS); @@ -429,11 +430,11 @@ extern "C" int32_t GetLocaleInfoInt(const UChar* localeName, LocaleNumberData lo break; } case NegativeNumberFormat: - *value = GetNumberNegativePattern(locale.getName()); + *value = GetNumberNegativePattern(locale); break; case MonetaryFractionalDigitsCount: { - UNumberFormat* numformat = unum_open(UNUM_CURRENCY, NULL, 0, locale.getName(), NULL, &status); + UNumberFormat* numformat = unum_open(UNUM_CURRENCY, NULL, 0, locale, NULL, &status); if (U_SUCCESS(status)) { *value = unum_getAttribute(numformat, UNUM_MAX_FRACTION_DIGITS); @@ -442,15 +443,15 @@ extern "C" int32_t GetLocaleInfoInt(const UChar* localeName, LocaleNumberData lo break; } case PositiveMonetaryNumberFormat: - *value = GetCurrencyPositivePattern(locale.getName()); + *value = GetCurrencyPositivePattern(locale); break; case NegativeMonetaryNumberFormat: - *value = GetCurrencyNegativePattern(locale.getName()); + *value = GetCurrencyNegativePattern(locale); break; case FirstWeekOfYear: { // corresponds to DateTimeFormat.CalendarWeekRule - UCalendar* pCal = ucal_open(nullptr, 0, locale.getName(), UCAL_TRADITIONAL, &status); + UCalendar* pCal = ucal_open(nullptr, 0, locale, UCAL_TRADITIONAL, &status); UCalendarHolder calHolder(pCal, status); if (U_SUCCESS(status)) @@ -482,7 +483,7 @@ extern "C" int32_t GetLocaleInfoInt(const UChar* localeName, LocaleNumberData lo // used in coreclr) // 0 - Left to right (such as en-US) // 1 - Right to left (such as arabic locales) - ULayoutType orientation = uloc_getCharacterOrientation(locale.getName(), &status); + ULayoutType orientation = uloc_getCharacterOrientation(locale, &status); // alternative implementation in ICU 54+ is uloc_isRightToLeft() which // also supports script tags in locale if (U_SUCCESS(status)) @@ -493,7 +494,7 @@ extern "C" int32_t GetLocaleInfoInt(const UChar* localeName, LocaleNumberData lo } case FirstDayofWeek: { - UCalendar* pCal = ucal_open(nullptr, 0, locale.getName(), UCAL_TRADITIONAL, &status); + UCalendar* pCal = ucal_open(nullptr, 0, locale, UCAL_TRADITIONAL, &status); UCalendarHolder calHolder(pCal, status); if (U_SUCCESS(status)) @@ -503,10 +504,10 @@ extern "C" int32_t GetLocaleInfoInt(const UChar* localeName, LocaleNumberData lo break; } case NegativePercentFormat: - *value = GetPercentNegativePattern(locale.getName()); + *value = GetPercentNegativePattern(locale); break; case PositivePercentFormat: - *value = GetPercentPositivePattern(locale.getName()); + *value = GetPercentPositivePattern(locale); break; default: status = U_UNSUPPORTED_ERROR; @@ -529,8 +530,11 @@ extern "C" int32_t GetLocaleInfoGroupingSizes(const UChar* localeName, int32_t* primaryGroupSize, int32_t* secondaryGroupSize) { - Locale locale = GetLocale(localeName); - if (locale.isBogus()) + 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); } @@ -548,8 +552,7 @@ extern "C" int32_t GetLocaleInfoGroupingSizes(const UChar* localeName, return UErrorCodeToBool(U_UNSUPPORTED_ERROR); } - UErrorCode status = U_ZERO_ERROR; - UNumberFormat* numformat = unum_open(style, NULL, 0, locale.getName(), NULL, &status); + UNumberFormat* numformat = unum_open(style, NULL, 0, locale, NULL, &status); if (U_SUCCESS(status)) { *primaryGroupSize = unum_getAttribute(numformat, UNUM_GROUPING_SIZE); diff --git a/src/corefx/System.Globalization.Native/localeStringData.cpp b/src/corefx/System.Globalization.Native/localeStringData.cpp index fb3dff8..6c7942f 100644 --- a/src/corefx/System.Globalization.Native/localeStringData.cpp +++ b/src/corefx/System.Globalization.Native/localeStringData.cpp @@ -173,96 +173,95 @@ Returns 1 for success, 0 otherwise extern "C" int32_t GetLocaleInfoString(const UChar* localeName, LocaleStringData localeStringData, UChar* value, int32_t valueLength) { - Locale locale = GetLocale(localeName); - if (locale.isBogus()) + 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); } - UErrorCode status = U_ZERO_ERROR; switch (localeStringData) { case LocalizedDisplayName: - uloc_getDisplayName(locale.getName(), uloc_getDefault(), value, valueLength, &status); + uloc_getDisplayName(locale, uloc_getDefault(), value, valueLength, &status); break; case EnglishDisplayName: - uloc_getDisplayName(locale.getName(), ULOC_ENGLISH, value, valueLength, &status); + uloc_getDisplayName(locale, ULOC_ENGLISH, value, valueLength, &status); break; case NativeDisplayName: - uloc_getDisplayName(locale.getName(), locale.getName(), value, valueLength, &status); + uloc_getDisplayName(locale, locale, value, valueLength, &status); break; case LocalizedLanguageName: - uloc_getDisplayLanguage(locale.getName(), uloc_getDefault(), value, valueLength, &status); + uloc_getDisplayLanguage(locale, uloc_getDefault(), value, valueLength, &status); break; case EnglishLanguageName: - uloc_getDisplayLanguage(locale.getName(), ULOC_ENGLISH, value, valueLength, &status); + uloc_getDisplayLanguage(locale, ULOC_ENGLISH, value, valueLength, &status); break; case NativeLanguageName: - uloc_getDisplayLanguage(locale.getName(), locale.getName(), value, valueLength, &status); + uloc_getDisplayLanguage(locale, locale, value, valueLength, &status); break; case EnglishCountryName: - uloc_getDisplayCountry(locale.getName(), ULOC_ENGLISH, value, valueLength, &status); + uloc_getDisplayCountry(locale, ULOC_ENGLISH, value, valueLength, &status); break; case NativeCountryName: - uloc_getDisplayCountry(locale.getName(), locale.getName(), value, valueLength, &status); + uloc_getDisplayCountry(locale, locale, value, valueLength, &status); break; case ListSeparator: // fall through case ThousandSeparator: - status = - GetLocaleInfoDecimalFormatSymbol(locale.getName(), UNUM_GROUPING_SEPARATOR_SYMBOL, value, valueLength); + status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_GROUPING_SEPARATOR_SYMBOL, value, valueLength); break; case DecimalSeparator: - status = - GetLocaleInfoDecimalFormatSymbol(locale.getName(), UNUM_DECIMAL_SEPARATOR_SYMBOL, value, valueLength); + status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_DECIMAL_SEPARATOR_SYMBOL, value, valueLength); break; case Digits: - status = GetDigitSymbol(locale.getName(), status, UNUM_ZERO_DIGIT_SYMBOL, 0, value, valueLength); + 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.getName(), status, static_cast(symbol), charIndex, value, valueLength); + locale, status, static_cast(symbol), charIndex, value, valueLength); } break; case MonetarySymbol: - status = GetLocaleInfoDecimalFormatSymbol(locale.getName(), UNUM_CURRENCY_SYMBOL, value, valueLength); + status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_CURRENCY_SYMBOL, value, valueLength); break; case Iso4217MonetarySymbol: - status = GetLocaleInfoDecimalFormatSymbol(locale.getName(), UNUM_INTL_CURRENCY_SYMBOL, value, valueLength); + status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_INTL_CURRENCY_SYMBOL, value, valueLength); break; case MonetaryDecimalSeparator: - status = - GetLocaleInfoDecimalFormatSymbol(locale.getName(), UNUM_MONETARY_SEPARATOR_SYMBOL, value, valueLength); + status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_MONETARY_SEPARATOR_SYMBOL, value, valueLength); break; case MonetaryThousandSeparator: - status = GetLocaleInfoDecimalFormatSymbol( - locale.getName(), UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL, value, valueLength); + status = + GetLocaleInfoDecimalFormatSymbol(locale, UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL, value, valueLength); break; case AMDesignator: - status = GetLocaleInfoAmPm(locale.getName(), true, value, valueLength); + status = GetLocaleInfoAmPm(locale, true, value, valueLength); break; case PMDesignator: - status = GetLocaleInfoAmPm(locale.getName(), false, value, valueLength); + status = GetLocaleInfoAmPm(locale, false, value, valueLength); break; case PositiveSign: - status = GetLocaleInfoDecimalFormatSymbol(locale.getName(), UNUM_PLUS_SIGN_SYMBOL, value, valueLength); + status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_PLUS_SIGN_SYMBOL, value, valueLength); break; case NegativeSign: - status = GetLocaleInfoDecimalFormatSymbol(locale.getName(), UNUM_MINUS_SIGN_SYMBOL, value, valueLength); + status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_MINUS_SIGN_SYMBOL, value, valueLength); break; case Iso639LanguageName: - status = GetLocaleIso639LanguageName(locale.getName(), value, valueLength); + status = GetLocaleIso639LanguageName(locale, value, valueLength); break; case Iso3166CountryName: - status = GetLocaleIso3166CountryName(locale.getName(), value, valueLength); + status = GetLocaleIso3166CountryName(locale, value, valueLength); break; case NaNSymbol: - status = GetLocaleInfoDecimalFormatSymbol(locale.getName(), UNUM_NAN_SYMBOL, value, valueLength); + status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_NAN_SYMBOL, value, valueLength); break; case PositiveInfinitySymbol: - status = GetLocaleInfoDecimalFormatSymbol(locale.getName(), UNUM_INFINITY_SYMBOL, value, valueLength); + status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_INFINITY_SYMBOL, value, valueLength); break; case ParentName: { @@ -270,7 +269,7 @@ GetLocaleInfoString(const UChar* localeName, LocaleStringData localeStringData, // including invariant locale char localeNameTemp[ULOC_FULLNAME_CAPACITY]; - uloc_getParent(locale.getName(), localeNameTemp, ULOC_FULLNAME_CAPACITY, &status); + uloc_getParent(locale, localeNameTemp, ULOC_FULLNAME_CAPACITY, &status); if (U_SUCCESS(status)) { status = u_charsToUChars_safe(localeNameTemp, value, valueLength); @@ -282,10 +281,10 @@ GetLocaleInfoString(const UChar* localeName, LocaleStringData localeStringData, break; } case PercentSymbol: - status = GetLocaleInfoDecimalFormatSymbol(locale.getName(), UNUM_PERCENT_SYMBOL, value, valueLength); + status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_PERCENT_SYMBOL, value, valueLength); break; case PerMilleSymbol: - status = GetLocaleInfoDecimalFormatSymbol(locale.getName(), UNUM_PERMILL_SYMBOL, value, valueLength); + status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_PERMILL_SYMBOL, value, valueLength); break; default: status = U_UNSUPPORTED_ERROR; @@ -304,15 +303,17 @@ Returns 1 for success, 0 otherwise */ extern "C" int32_t GetLocaleTimeFormat(const UChar* localeName, int shortFormat, UChar* value, int32_t valueLength) { - Locale locale = GetLocale(localeName); - if (locale.isBogus()) + 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); } - UErrorCode err = U_ZERO_ERROR; UDateFormatStyle style = (shortFormat != 0) ? UDAT_SHORT : UDAT_MEDIUM; - UDateFormat* pFormat = udat_open(style, UDAT_NONE, locale.getName(), nullptr, 0, nullptr, 0, &err); + UDateFormat* pFormat = udat_open(style, UDAT_NONE, locale, nullptr, 0, nullptr, 0, &err); UDateFormatHolder formatHolder(pFormat, err); if (U_FAILURE(err)) -- 2.7.4