ICU-22520 Let ulocimp_getRegionForSupplementalData() return CharString.

This commit is contained in:
Fredrik Roubert 2024-02-06 20:02:50 +01:00 committed by Fredrik Roubert
parent 56509e88bf
commit a6efa924ad
8 changed files with 50 additions and 65 deletions

View file

@ -580,11 +580,11 @@ GetRegionFromKey(const char* localeID, const char* key, UErrorCode& status) {
}
} // namespace
U_CAPI int32_t U_EXPORT2
U_EXPORT icu::CharString U_EXPORT2
ulocimp_getRegionForSupplementalData(const char *localeID, UBool inferRegion,
char *region, int32_t regionCapacity, UErrorCode* status) {
UErrorCode* status) {
if (U_FAILURE(*status)) {
return 0;
return {};
}
icu::CharString rgBuf = GetRegionFromKey(localeID, "rg", *status);
if (U_SUCCESS(*status) && rgBuf.isEmpty()) {
@ -608,5 +608,5 @@ ulocimp_getRegionForSupplementalData(const char *localeID, UBool inferRegion,
}
}
return rgBuf.extract(region, regionCapacity, *status);
return rgBuf;
}

View file

@ -349,10 +349,10 @@ _findMetaData(const char16_t* currency, UErrorCode& ec) {
// -------------------------------------
static void
idForLocale(const char* locale, char* countryAndVariant, int capacity, UErrorCode* ec)
static CharString
idForLocale(const char* locale, UErrorCode* ec)
{
ulocimp_getRegionForSupplementalData(locale, false, countryAndVariant, capacity, ec);
return ulocimp_getRegionForSupplementalData(locale, false, ec);
}
// ------------------------------------------
@ -464,9 +464,8 @@ U_CAPI UCurrRegistryKey U_EXPORT2
ucurr_register(const char16_t* isoCode, const char* locale, UErrorCode *status)
{
if (status && U_SUCCESS(*status)) {
char id[ULOC_FULLNAME_CAPACITY];
idForLocale(locale, id, sizeof(id), status);
return CReg::reg(isoCode, id, status);
CharString id = idForLocale(locale, status);
return CReg::reg(isoCode, id.data(), status);
}
return nullptr;
}
@ -540,14 +539,13 @@ ucurr_forLocale(const char* locale,
}
// get country or country_variant in `id'
char id[ULOC_FULLNAME_CAPACITY];
idForLocale(locale, id, UPRV_LENGTHOF(id), ec);
CharString id = idForLocale(locale, ec);
if (U_FAILURE(*ec)) {
return 0;
}
#if !UCONFIG_NO_SERVICE
const char16_t* result = CReg::get(id);
const char16_t* result = CReg::get(id.data());
if (result) {
if(buffCapacity > u_strlen(result)) {
u_strcpy(buff, result);
@ -557,13 +555,13 @@ ucurr_forLocale(const char* locale,
}
#endif
// Remove variants, which is only needed for registration.
char *idDelim = uprv_strchr(id, VAR_DELIM);
char *idDelim = uprv_strchr(id.data(), VAR_DELIM);
if (idDelim) {
idDelim[0] = 0;
id.truncate(idDelim - id.data());
}
const char16_t* s = nullptr; // Currency code from data file.
if (id[0] == 0) {
if (id.isEmpty()) {
// No point looking in the data for an empty string.
// This is what we would get.
localStatus = U_MISSING_RESOURCE_ERROR;
@ -572,7 +570,7 @@ ucurr_forLocale(const char* locale,
localStatus = U_ZERO_ERROR;
UResourceBundle *rb = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &localStatus);
UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
UResourceBundle *countryArray = ures_getByKey(rb, id, cm, &localStatus);
UResourceBundle *countryArray = ures_getByKey(rb, id.data(), cm, &localStatus);
// https://unicode-org.atlassian.net/browse/ICU-21997
// Prefer to use currencies that are legal tender.
if (U_SUCCESS(localStatus)) {
@ -602,7 +600,7 @@ ucurr_forLocale(const char* locale,
ures_close(countryArray);
}
if ((U_FAILURE(localStatus)) && strchr(id, '_') != 0) {
if ((U_FAILURE(localStatus)) && strchr(id.data(), '_') != 0) {
// We don't know about it. Check to see if we support the variant.
CharString parent;
{
@ -2325,10 +2323,9 @@ ucurr_countCurrencies(const char* locale,
{
// local variables
UErrorCode localStatus = U_ZERO_ERROR;
char id[ULOC_FULLNAME_CAPACITY];
// get country or country_variant in `id'
idForLocale(locale, id, sizeof(id), ec);
CharString id = idForLocale(locale, ec);
if (U_FAILURE(*ec))
{
@ -2336,10 +2333,10 @@ ucurr_countCurrencies(const char* locale,
}
// Remove variants, which is only needed for registration.
char *idDelim = strchr(id, VAR_DELIM);
char *idDelim = strchr(id.data(), VAR_DELIM);
if (idDelim)
{
idDelim[0] = 0;
id.truncate(idDelim - id.data());
}
// Look up the CurrencyMap element in the root bundle.
@ -2347,7 +2344,7 @@ ucurr_countCurrencies(const char* locale,
UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
// Using the id derived from the local, get the currency data
UResourceBundle *countryArray = ures_getByKey(rb, id, cm, &localStatus);
UResourceBundle *countryArray = ures_getByKey(rb, id.data(), cm, &localStatus);
// process each currency to see which one is valid for the given date
if (U_SUCCESS(localStatus))
@ -2440,20 +2437,19 @@ ucurr_forLocaleAndDate(const char* locale,
{
// local variables
UErrorCode localStatus = U_ZERO_ERROR;
char id[ULOC_FULLNAME_CAPACITY];
// get country or country_variant in `id'
idForLocale(locale, id, sizeof(id), ec);
CharString id = idForLocale(locale, ec);
if (U_FAILURE(*ec))
{
return 0;
}
// Remove variants, which is only needed for registration.
char *idDelim = strchr(id, VAR_DELIM);
char *idDelim = strchr(id.data(), VAR_DELIM);
if (idDelim)
{
idDelim[0] = 0;
id.truncate(idDelim - id.data());
}
// Look up the CurrencyMap element in the root bundle.
@ -2461,7 +2457,7 @@ ucurr_forLocaleAndDate(const char* locale,
UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus);
// Using the id derived from the local, get the currency data
UResourceBundle *countryArray = ures_getByKey(rb, id, cm, &localStatus);
UResourceBundle *countryArray = ures_getByKey(rb, id.data(), cm, &localStatus);
// process each currency to see which one is valid for the given date
bool matchFound = false;
@ -2587,9 +2583,8 @@ static const UEnumeration defaultKeywordValues = {
U_CAPI UEnumeration *U_EXPORT2 ucurr_getKeywordValuesForLocale(const char *key, const char *locale, UBool commonlyUsed, UErrorCode* status) {
// Resolve region
char prefRegion[ULOC_COUNTRY_CAPACITY];
ulocimp_getRegionForSupplementalData(locale, true, prefRegion, sizeof(prefRegion), status);
CharString prefRegion = ulocimp_getRegionForSupplementalData(locale, true, status);
// Read value from supplementalData
UList *values = ulist_createEmptyList(status);
UList *otherValues = ulist_createEmptyList(status);
@ -2621,7 +2616,7 @@ U_CAPI UEnumeration *U_EXPORT2 ucurr_getKeywordValuesForLocale(const char *key,
break;
}
const char *region = ures_getKey(&bundlekey);
UBool isPrefRegion = uprv_strcmp(region, prefRegion) == 0 ? true : false;
UBool isPrefRegion = prefRegion == region;
if (!isPrefRegion && commonlyUsed) {
// With commonlyUsed=true, we do not put
// currencies for other regions in the

View file

@ -212,28 +212,23 @@ ulocimp_forLanguageTag(const char* langtag,
* (2) any unicode_region_tag in the locale ID; if none then
* (3) if inferRegion is true, the region suggested by
* getLikelySubtags on the localeID.
* If no region is found, returns length 0.
*
* If no region is found, returns an empty string.
*
* @param localeID
* The complete locale ID (with keywords) from which
* to get the region to use for supplemental data.
* @param inferRegion
* If true, will try to infer region from localeID if
* no other region is found.
* @param region
* Buffer in which to put the region ID found; should
* have a capacity at least ULOC_COUNTRY_CAPACITY.
* @param regionCapacity
* The actual capacity of the region buffer.
* @param status
* Pointer to in/out UErrorCode value for latest status.
* @return
* The length of any region code found, or 0 if none.
* The region code found, empty if none found.
* @internal ICU 57
*/
U_CAPI int32_t U_EXPORT2
U_EXPORT icu::CharString U_EXPORT2
ulocimp_getRegionForSupplementalData(const char *localeID, UBool inferRegion,
char *region, int32_t regionCapacity, UErrorCode* status);
UErrorCode* status);
/**
* Add the likely subtags for a provided locale ID, per the algorithm described

View file

@ -283,8 +283,7 @@ static ECalType getCalendarTypeForLocale(const char *locid) {
// when calendar keyword is not available or not supported, read supplementalData
// to get the default calendar type for the locale's region
char region[ULOC_COUNTRY_CAPACITY];
(void)ulocimp_getRegionForSupplementalData(canonicalName.data(), true, region, sizeof(region), &status);
CharString region = ulocimp_getRegionForSupplementalData(canonicalName.data(), true, &status);
if (U_FAILURE(status)) {
return CALTYPE_GREGORIAN;
}
@ -292,7 +291,7 @@ static ECalType getCalendarTypeForLocale(const char *locid) {
// Read preferred calendar values from supplementalData calendarPreference
UResourceBundle *rb = ures_openDirect(nullptr, "supplementalData", &status);
ures_getByKey(rb, "calendarPreferenceData", rb, &status);
UResourceBundle *order = ures_getByKey(rb, region, nullptr, &status);
UResourceBundle *order = ures_getByKey(rb, region.data(), nullptr, &status);
if (status == U_MISSING_RESOURCE_ERROR && rb != nullptr) {
status = U_ZERO_ERROR;
order = ures_getByKey(rb, "001", nullptr, &status);
@ -4027,13 +4026,12 @@ Calendar::setWeekData(const Locale& desiredLocale, const char *type, UErrorCode&
return;
}
char region[ULOC_COUNTRY_CAPACITY];
(void)ulocimp_getRegionForSupplementalData(desiredLocale.getName(), true, region, sizeof(region), &status);
CharString region = ulocimp_getRegionForSupplementalData(desiredLocale.getName(), true, &status);
// Read week data values from supplementalData week data
UResourceBundle *rb = ures_openDirect(nullptr, "supplementalData", &status);
ures_getByKey(rb, "weekData", rb, &status);
UResourceBundle *weekData = ures_getByKey(rb, region, nullptr, &status);
UResourceBundle *weekData = ures_getByKey(rb, region.data(), nullptr, &status);
if (status == U_MISSING_RESOURCE_ERROR && rb != nullptr) {
status = U_ZERO_ERROR;
weekData = ures_getByKey(rb, "001", nullptr, &status);

View file

@ -658,10 +658,9 @@ void DateTimePatternGenerator::getAllowedHourFormats(const Locale &locale, UErro
if (U_FAILURE(status)) { return; }
const char *language = locale.getLanguage();
char baseCountry[8];
ulocimp_getRegionForSupplementalData(locale.getName(), false, baseCountry, 8, &status);
const char* country = baseCountry;
CharString baseCountry = ulocimp_getRegionForSupplementalData(locale.getName(), false, &status);
const char* country = baseCountry.data();
Locale maxLocale; // must be here for correct lifetime
if (*language == '\0' || *country == '\0') {
maxLocale = locale;

View file

@ -716,13 +716,12 @@ static const char * const CAL_TYPES[] = {
U_CAPI UEnumeration* U_EXPORT2
ucal_getKeywordValuesForLocale(const char * /* key */, const char* locale, UBool commonlyUsed, UErrorCode *status) {
// Resolve region
char prefRegion[ULOC_COUNTRY_CAPACITY];
(void)ulocimp_getRegionForSupplementalData(locale, true, prefRegion, sizeof(prefRegion), status);
CharString prefRegion = ulocimp_getRegionForSupplementalData(locale, true, status);
// Read preferred calendar values from supplementalData calendarPreference
UResourceBundle *rb = ures_openDirect(nullptr, "supplementalData", status);
ures_getByKey(rb, "calendarPreferenceData", rb, status);
UResourceBundle *order = ures_getByKey(rb, prefRegion, nullptr, status);
UResourceBundle *order = ures_getByKey(rb, prefRegion.data(), nullptr, status);
if (*status == U_MISSING_RESOURCE_ERROR && rb != nullptr) {
*status = U_ZERO_ERROR;
order = ures_getByKey(rb, "001", nullptr, status);

View file

@ -16,6 +16,7 @@
* created by: Ram Viswanadha,John Emmons
*/
#include "charstr.h"
#include "cmemory.h"
#include "unicode/ustring.h"
#include "unicode/ures.h"
@ -198,16 +199,15 @@ ulocdata_getDelimiter(ULocaleData *uld, ULocaleDataDelimiterType type,
}
static UResourceBundle * measurementTypeBundleForLocale(const char *localeID, const char *measurementType, UErrorCode *status){
char region[ULOC_COUNTRY_CAPACITY];
UResourceBundle *rb;
UResourceBundle *measTypeBundle = nullptr;
ulocimp_getRegionForSupplementalData(localeID, true, region, ULOC_COUNTRY_CAPACITY, status);
icu::CharString region = ulocimp_getRegionForSupplementalData(localeID, true, status);
rb = ures_openDirect(nullptr, "supplementalData", status);
ures_getByKey(rb, "measurementData", rb, status);
if (rb != nullptr) {
UResourceBundle *measDataBundle = ures_getByKey(rb, region, nullptr, status);
UResourceBundle *measDataBundle = ures_getByKey(rb, region.data(), nullptr, status);
if (U_SUCCESS(*status)) {
measTypeBundle = ures_getByKey(measDataBundle, measurementType, nullptr, status);
}

View file

@ -6,6 +6,7 @@
#if !UCONFIG_NO_FORMATTING
#include "bytesinkutil.h"
#include "charstr.h"
#include "cstring.h"
#include "measunit_impl.h"
#include "number_decimalquantity.h"
@ -443,10 +444,8 @@ MaybeStackVector<UnitPreference>
}
}
char regionBuf[8];
ulocimp_getRegionForSupplementalData(locale.getName(), false, regionBuf, 8, &status);
CharString region(regionBuf, status);
CharString region = ulocimp_getRegionForSupplementalData(locale.getName(), false, &status);
// Check the locale system tag, e.g `ms=metric`.
UErrorCode internalMeasureTagStatus = U_ZERO_ERROR;
CharString localeSystem = getKeyWordValue(locale, "measure", internalMeasureTagStatus);