ICU-22520 Switch to using CharString for calling uloc_setKeywordValue().

This commit is contained in:
Fredrik Roubert 2024-01-15 10:30:04 +09:00 committed by Fredrik Roubert
parent 340806bf9a
commit 1b0f5e41c5
3 changed files with 33 additions and 26 deletions

View file

@ -886,6 +886,21 @@ uloc_setKeywordValue(const char* keywordName,
return u_terminateChars(buffer, bufferCapacity, reslen + baseLen, status);
}
U_EXPORT void U_EXPORT2
ulocimp_setKeywordValue(const char* keywordName,
const char* keywordValue,
CharString& localeID,
UErrorCode* status)
{
if (U_FAILURE(*status)) return;
// This is safe because CharString::truncate() doesn't actually erase any
// data, but simply sets the position for where new data will be written.
const char* keywords = locale_getKeywordsStart(localeID.data());
if (keywords != nullptr) localeID.truncate(keywords - localeID.data());
CharStringByteSink sink(&localeID);
ulocimp_setKeywordValue(keywords, keywordName, keywordValue, sink, status);
}
U_EXPORT int32_t U_EXPORT2
ulocimp_setKeywordValue(const char* keywords,
const char* keywordName,
@ -2088,29 +2103,20 @@ uloc_getLCID(const char* localeID)
if (uprv_strchr(localeID, '@')) {
// uprv_convertToLCID does not support keywords other than collation.
// Remove all keywords except collation.
int32_t len;
char tmpLocaleID[ULOC_FULLNAME_CAPACITY];
CharString collVal;
{
CharStringByteSink sink(&collVal);
ulocimp_getKeywordValue(localeID, "collation", sink, &status);
}
if (U_SUCCESS(status) && !collVal.isEmpty()) {
len = uloc_getBaseName(localeID, tmpLocaleID,
UPRV_LENGTHOF(tmpLocaleID) - 1, &status);
if (U_SUCCESS(status) && len > 0) {
tmpLocaleID[len] = 0;
len = uloc_setKeywordValue("collation", collVal.data(), tmpLocaleID,
UPRV_LENGTHOF(tmpLocaleID) - len - 1, &status);
if (U_SUCCESS(status) && len > 0) {
tmpLocaleID[len] = 0;
return uprv_convertToLCID(langID, tmpLocaleID, &status);
}
CharString tmpLocaleID;
{
CharStringByteSink sink(&tmpLocaleID);
ulocimp_getBaseName(localeID, sink, &status);
}
ulocimp_setKeywordValue("collation", collVal.data(), tmpLocaleID, &status);
if (U_SUCCESS(status)) {
return uprv_convertToLCID(langID, tmpLocaleID.data(), &status);
}
}

View file

@ -92,6 +92,12 @@ ulocimp_getKeywordValue(const char* localeID,
icu::ByteSink& sink,
UErrorCode* status);
U_EXPORT void U_EXPORT2
ulocimp_setKeywordValue(const char* keywordName,
const char* keywordValue,
icu::CharString& localeID,
UErrorCode* status);
U_EXPORT int32_t U_EXPORT2
ulocimp_setKeywordValue(const char* keywords,
const char* keywordName,

View file

@ -22,6 +22,7 @@
#include "unicode/ustring.h"
#include "unicode/strenum.h"
#include "unicode/localpointer.h"
#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
#include "iso8601cal.h"
@ -167,21 +168,15 @@ ucal_open( const char16_t* zoneID,
}
if ( caltype == UCAL_GREGORIAN ) {
char localeBuf[ULOC_LOCALE_IDENTIFIER_CAPACITY];
if ( locale == nullptr ) {
locale = uloc_getDefault();
}
int32_t localeLength = static_cast<int32_t>(uprv_strlen(locale));
if (localeLength >= ULOC_LOCALE_IDENTIFIER_CAPACITY) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return nullptr;
}
uprv_strcpy(localeBuf, locale);
uloc_setKeywordValue("calendar", "gregorian", localeBuf, ULOC_LOCALE_IDENTIFIER_CAPACITY, status);
CharString localeBuf(locale, *status);
ulocimp_setKeywordValue("calendar", "gregorian", localeBuf, status);
if (U_FAILURE(*status)) {
return nullptr;
}
return (UCalendar*)Calendar::createInstance(zone.orphan(), Locale(localeBuf), *status);
return (UCalendar*)Calendar::createInstance(zone.orphan(), Locale(localeBuf.data()), *status);
}
return (UCalendar*)Calendar::createInstance(zone.orphan(), Locale(locale), *status);
}