ICU-21289 Switch to using CharString for calling uloc_canonicalize().
diff --git a/icu4c/source/common/loclikely.cpp b/icu4c/source/common/loclikely.cpp
index 99551e6..eedfb81 100644
--- a/icu4c/source/common/loclikely.cpp
+++ b/icu4c/source/common/loclikely.cpp
@@ -625,31 +625,6 @@
}
}
-static int32_t
-do_canonicalize(const char* localeID,
- char* buffer,
- int32_t bufferCapacity,
- UErrorCode* err)
-{
- int32_t canonicalizedSize = uloc_canonicalize(
- localeID,
- buffer,
- bufferCapacity,
- err);
-
- if (*err == U_STRING_NOT_TERMINATED_WARNING ||
- *err == U_BUFFER_OVERFLOW_ERROR) {
- return canonicalizedSize;
- }
- else if (U_FAILURE(*err)) {
-
- return -1;
- }
- else {
- return canonicalizedSize;
- }
-}
-
U_CAPI int32_t U_EXPORT2
uloc_addLikelySubtags(const char* localeID,
char* maximizedLocaleID,
@@ -683,14 +658,13 @@
_ulocimp_addLikelySubtags(const char* localeID,
icu::ByteSink& sink,
UErrorCode* status) {
- PreflightingLocaleIDBuffer localeBuffer;
- do {
- localeBuffer.requestedCapacity = do_canonicalize(localeID, localeBuffer.getBuffer(),
- localeBuffer.getCapacity(), status);
- } while (localeBuffer.needToTryAgain(status));
-
+ icu::CharString localeBuffer;
+ {
+ icu::CharStringByteSink localeSink(&localeBuffer);
+ ulocimp_canonicalize(localeID, localeSink, status);
+ }
if (U_SUCCESS(*status)) {
- return _uloc_addLikelySubtags(localeBuffer.getBuffer(), sink, status);
+ return _uloc_addLikelySubtags(localeBuffer.data(), sink, status);
} else {
return false;
}
@@ -737,13 +711,12 @@
icu::ByteSink& sink,
bool favorScript,
UErrorCode* status) {
- PreflightingLocaleIDBuffer localeBuffer;
- do {
- localeBuffer.requestedCapacity = do_canonicalize(localeID, localeBuffer.getBuffer(),
- localeBuffer.getCapacity(), status);
- } while (localeBuffer.needToTryAgain(status));
-
- _uloc_minimizeSubtags(localeBuffer.getBuffer(), sink, favorScript, status);
+ icu::CharString localeBuffer;
+ {
+ icu::CharStringByteSink localeSink(&localeBuffer);
+ ulocimp_canonicalize(localeID, localeSink, status);
+ }
+ _uloc_minimizeSubtags(localeBuffer.data(), sink, favorScript, status);
}
// Pairs of (language subtag, + or -) for finding out fast if common languages
diff --git a/icu4c/source/common/locresdata.cpp b/icu4c/source/common/locresdata.cpp
index 7a0969d..c9d1cdd 100644
--- a/icu4c/source/common/locresdata.cpp
+++ b/icu4c/source/common/locresdata.cpp
@@ -24,6 +24,8 @@
#include "unicode/putil.h"
#include "unicode/uloc.h"
#include "unicode/ures.h"
+#include "bytesinkutil.h"
+#include "charstr.h"
#include "cstring.h"
#include "ulocimp.h"
#include "uresimp.h"
@@ -156,16 +158,18 @@
ULayoutType result = ULOC_LAYOUT_UNKNOWN;
if (!U_FAILURE(*status)) {
- int32_t length = 0;
- char localeBuffer[ULOC_FULLNAME_CAPACITY];
-
- uloc_canonicalize(localeId, localeBuffer, sizeof(localeBuffer), status);
+ icu::CharString localeBuffer;
+ {
+ icu::CharStringByteSink sink(&localeBuffer);
+ ulocimp_canonicalize(localeId, sink, status);
+ }
if (!U_FAILURE(*status)) {
+ int32_t length = 0;
const char16_t* const value =
uloc_getTableStringWithFallback(
nullptr,
- localeBuffer,
+ localeBuffer.data(),
"layout",
nullptr,
key,
diff --git a/icu4c/source/common/uloc_tag.cpp b/icu4c/source/common/uloc_tag.cpp
index 4d5c1f8..fe3261c 100644
--- a/icu4c/source/common/uloc_tag.cpp
+++ b/icu4c/source/common/uloc_tag.cpp
@@ -2625,53 +2625,18 @@
UBool strict,
UErrorCode* status) {
icu::CharString canonical;
- int32_t reslen;
UErrorCode tmpStatus = U_ZERO_ERROR;
UBool hadPosix = false;
const char* pKeywordStart;
/* Note: uloc_canonicalize returns "en_US_POSIX" for input locale ID "". See #6835 */
- int32_t resultCapacity = static_cast<int32_t>(uprv_strlen(localeID));
- if (resultCapacity > 0) {
- char* buffer;
-
- for (;;) {
- buffer = canonical.getAppendBuffer(
- /*minCapacity=*/resultCapacity,
- /*desiredCapacityHint=*/resultCapacity,
- resultCapacity,
- tmpStatus);
-
- if (U_FAILURE(tmpStatus)) {
- *status = tmpStatus;
- return;
- }
-
- reslen =
- uloc_canonicalize(localeID, buffer, resultCapacity, &tmpStatus);
-
- if (tmpStatus != U_BUFFER_OVERFLOW_ERROR) {
- break;
- }
-
- resultCapacity = reslen;
- tmpStatus = U_ZERO_ERROR;
- }
-
- if (U_FAILURE(tmpStatus)) {
- *status = U_ILLEGAL_ARGUMENT_ERROR;
- return;
- }
-
- canonical.append(buffer, reslen, tmpStatus);
- if (tmpStatus == U_STRING_NOT_TERMINATED_WARNING) {
- tmpStatus = U_ZERO_ERROR; // Terminators provided by CharString.
- }
-
- if (U_FAILURE(tmpStatus)) {
- *status = tmpStatus;
- return;
- }
+ {
+ icu::CharStringByteSink canonicalSink(&canonical);
+ ulocimp_canonicalize(localeID, canonicalSink, &tmpStatus);
+ }
+ if (U_FAILURE(tmpStatus)) {
+ *status = tmpStatus;
+ return;
}
/* For handling special case - private use only tag */
diff --git a/icu4c/source/i18n/calendar.cpp b/icu4c/source/i18n/calendar.cpp
index 5612fe9..742891e 100644
--- a/icu4c/source/i18n/calendar.cpp
+++ b/icu4c/source/i18n/calendar.cpp
@@ -255,23 +255,23 @@
UErrorCode status = U_ZERO_ERROR;
ECalType calType = CALTYPE_UNKNOWN;
- //TODO: ULOC_FULL_NAME is out of date and too small..
- char canonicalName[256];
-
// Canonicalize, so that an old-style variant will be transformed to keywords.
// e.g ja_JP_TRADITIONAL -> ja_JP@calendar=japanese
// NOTE: Since ICU-20187, ja_JP_TRADITIONAL no longer canonicalizes, and
// the Gregorian calendar is returned instead.
- int32_t canonicalLen = uloc_canonicalize(locid, canonicalName, sizeof(canonicalName) - 1, &status);
+ CharString canonicalName;
+ {
+ CharStringByteSink sink(&canonicalName);
+ ulocimp_canonicalize(locid, sink, &status);
+ }
if (U_FAILURE(status)) {
return CALTYPE_GREGORIAN;
}
- canonicalName[canonicalLen] = 0; // terminate
CharString calTypeBuf;
{
CharStringByteSink sink(&calTypeBuf);
- ulocimp_getKeywordValue(canonicalName, "calendar", sink, &status);
+ ulocimp_getKeywordValue(canonicalName.data(), "calendar", sink, &status);
}
if (U_SUCCESS(status)) {
calType = getCalendarType(calTypeBuf.data());
@@ -284,7 +284,7 @@
// 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, true, region, sizeof(region), &status);
+ (void)ulocimp_getRegionForSupplementalData(canonicalName.data(), true, region, sizeof(region), &status);
if (U_FAILURE(status)) {
return CALTYPE_GREGORIAN;
}
diff --git a/icu4c/source/i18n/ucol_sit.cpp b/icu4c/source/i18n/ucol_sit.cpp
index 2cbe543..2e5bce2 100644
--- a/icu4c/source/i18n/ucol_sit.cpp
+++ b/icu4c/source/i18n/ucol_sit.cpp
@@ -88,7 +88,6 @@
static const int32_t locElementCount = UCOL_SIT_LOCELEMENT_MAX+1;
static const int32_t locElementCapacity = 32;
static const int32_t loc3066Capacity = 256;
-static const int32_t internalBufferSize = 512;
/* structure containing specification of a collator. Initialized
* from a short string. Also used to construct a short string from a
@@ -452,11 +451,13 @@
ucol_sit_readSpecs(&s, definition, parseError, status);
ucol_sit_calculateWholeLocale(&s, *status);
- char buffer[internalBufferSize];
- uprv_memset(buffer, 0, internalBufferSize);
- uloc_canonicalize(s.locale.data(), buffer, internalBufferSize, status);
+ CharString buffer;
+ {
+ CharStringByteSink sink(&buffer);
+ ulocimp_canonicalize(s.locale.data(), sink, status);
+ }
- UResourceBundle *b = ures_open(U_ICUDATA_COLL, buffer, status);
+ UResourceBundle *b = ures_open(U_ICUDATA_COLL, buffer.data(), status);
/* we try to find stuff from keyword */
UResourceBundle *collations = ures_getByKey(b, "collations", nullptr, status);
UResourceBundle *collElem = nullptr;
@@ -464,7 +465,7 @@
{
// if there is a keyword, we pick it up and try to get elements
CharStringByteSink sink(&keyBuffer);
- ulocimp_getKeywordValue(buffer, "collation", sink, status);
+ ulocimp_getKeywordValue(buffer.data(), "collation", sink, status);
}
if(keyBuffer.isEmpty()) {
// no keyword
@@ -519,14 +520,16 @@
string = ucol_sit_readSpecs(&s, definition, parseError, status);
ucol_sit_calculateWholeLocale(&s, *status);
- char buffer[internalBufferSize];
- uprv_memset(buffer, 0, internalBufferSize);
#ifdef UCOL_TRACE_SIT
fprintf(stderr, "DEF %s, DATA %s, ERR %s\n", definition, s.locale.data(), u_errorName(*status));
#endif
- uloc_canonicalize(s.locale.data(), buffer, internalBufferSize, status);
+ CharString buffer;
+ {
+ CharStringByteSink sink(&buffer);
+ ulocimp_canonicalize(s.locale.data(), sink, status);
+ }
- UCollator *result = ucol_open(buffer, status);
+ UCollator *result = ucol_open(buffer.data(), status);
int32_t i = 0;
for(i = 0; i < UCOL_ATTRIBUTE_COUNT; i++) {