ICU-21035 Update locale implementation to use ulocimp_getKeywordValue().
diff --git a/icu4c/source/common/locdispnames.cpp b/icu4c/source/common/locdispnames.cpp
index 655c32b..47c0667 100644
--- a/icu4c/source/common/locdispnames.cpp
+++ b/icu4c/source/common/locdispnames.cpp
@@ -26,6 +26,8 @@
#include "unicode/uloc.h"
#include "unicode/ures.h"
#include "unicode/ustring.h"
+#include "bytesinkutil.h"
+#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
#include "putilimp.h"
@@ -811,10 +813,6 @@
UErrorCode* status){
- char keywordValue[ULOC_FULLNAME_CAPACITY*4];
- int32_t capacity = ULOC_FULLNAME_CAPACITY*4;
- int32_t keywordValueLen =0;
-
/* argument checking */
if(status==NULL || U_FAILURE(*status)) {
return 0;
@@ -826,10 +824,11 @@
}
/* get the keyword value */
- keywordValue[0]=0;
- keywordValueLen = uloc_getKeywordValue(locale, keyword, keywordValue, capacity, status);
- if (*status == U_STRING_NOT_TERMINATED_WARNING)
- *status = U_BUFFER_OVERFLOW_ERROR;
+ CharString keywordValue;
+ {
+ CharStringByteSink sink(&keywordValue);
+ ulocimp_getKeywordValue(locale, keyword, sink, status);
+ }
/*
* if the keyword is equal to currency .. then to get the display name
@@ -845,7 +844,7 @@
icu::LocalUResourceBundlePointer currencies(
ures_getByKey(bundle.getAlias(), _kCurrencies, NULL, status));
icu::LocalUResourceBundlePointer currency(
- ures_getByKeyWithFallback(currencies.getAlias(), keywordValue, NULL, status));
+ ures_getByKeyWithFallback(currencies.getAlias(), keywordValue.data(), NULL, status));
dispName = ures_getStringByIndex(currency.getAlias(), UCURRENCY_DISPLAY_NAME_INDEX, &dispNameLen, status);
@@ -869,12 +868,12 @@
}
}else{
/* we have not found the display name for the value .. just copy over */
- if(keywordValueLen <= destCapacity){
- u_charsToUChars(keywordValue, dest, keywordValueLen);
- return u_terminateUChars(dest, destCapacity, keywordValueLen, status);
+ if(keywordValue.length() <= destCapacity){
+ u_charsToUChars(keywordValue.data(), dest, keywordValue.length());
+ return u_terminateUChars(dest, destCapacity, keywordValue.length(), status);
}else{
*status = U_BUFFER_OVERFLOW_ERROR;
- return keywordValueLen;
+ return keywordValue.length();
}
}
@@ -883,8 +882,8 @@
return _getStringOrCopyKey(U_ICUDATA_LANG, displayLocale,
_kTypes, keyword,
- keywordValue,
- keywordValue,
+ keywordValue.data(),
+ keywordValue.data(),
dest, destCapacity,
status);
}
diff --git a/icu4c/source/common/locmap.cpp b/icu4c/source/common/locmap.cpp
index a631134..29a5646 100644
--- a/icu4c/source/common/locmap.cpp
+++ b/icu4c/source/common/locmap.cpp
@@ -28,8 +28,11 @@
*/
#include "locmap.h"
+#include "bytesinkutil.h"
+#include "charstr.h"
#include "cstring.h"
#include "cmemory.h"
+#include "ulocimp.h"
#include "unicode/uloc.h"
#if U_PLATFORM_HAS_WIN32_API && UCONFIG_USE_WINDOWS_LCID_MAPPING_API
@@ -1167,15 +1170,18 @@
// conversion functionality when available.
#if U_PLATFORM_HAS_WIN32_API && UCONFIG_USE_WINDOWS_LCID_MAPPING_API
int32_t len;
- char collVal[ULOC_KEYWORDS_CAPACITY] = {};
char baseName[ULOC_FULLNAME_CAPACITY] = {};
const char * mylocaleID = localeID;
// Check any for keywords.
if (uprv_strchr(localeID, '@'))
{
- len = uloc_getKeywordValue(localeID, "collation", collVal, UPRV_LENGTHOF(collVal) - 1, status);
- if (U_SUCCESS(*status) && len > 0)
+ icu::CharString collVal;
+ {
+ icu::CharStringByteSink sink(&collVal);
+ ulocimp_getKeywordValue(localeID, "collation", sink, status);
+ }
+ if (U_SUCCESS(*status) && !collVal.isEmpty())
{
// If it contains the keyword collation, return 0 so that the LCID lookup table will be used.
return 0;
diff --git a/icu4c/source/common/uloc.cpp b/icu4c/source/common/uloc.cpp
index 07660d7..42cbe4b 100644
--- a/icu4c/source/common/uloc.cpp
+++ b/icu4c/source/common/uloc.cpp
@@ -1995,22 +1995,22 @@
// uprv_convertToLCID does not support keywords other than collation.
// Remove all keywords except collation.
int32_t len;
- char collVal[ULOC_KEYWORDS_CAPACITY];
char tmpLocaleID[ULOC_FULLNAME_CAPACITY];
- len = uloc_getKeywordValue(localeID, "collation", collVal,
- UPRV_LENGTHOF(collVal) - 1, &status);
+ CharString collVal;
+ {
+ CharStringByteSink sink(&collVal);
+ ulocimp_getKeywordValue(localeID, "collation", sink, &status);
+ }
- if (U_SUCCESS(status) && len > 0) {
- collVal[len] = 0;
-
+ 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, tmpLocaleID,
+ len = uloc_setKeywordValue("collation", collVal.data(), tmpLocaleID,
UPRV_LENGTHOF(tmpLocaleID) - len - 1, &status);
if (U_SUCCESS(status) && len > 0) {
diff --git a/icu4c/source/common/uloc_tag.cpp b/icu4c/source/common/uloc_tag.cpp
index 9e93650..b4e3c92 100644
--- a/icu4c/source/common/uloc_tag.cpp
+++ b/icu4c/source/common/uloc_tag.cpp
@@ -15,6 +15,7 @@
#include "unicode/uenum.h"
#include "unicode/uloc.h"
#include "ustr_imp.h"
+#include "bytesinkutil.h"
#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
@@ -1269,35 +1270,17 @@
UBool isBcpUExt;
while (TRUE) {
- icu::CharString buf;
key = uenum_next(keywordEnum.getAlias(), NULL, status);
if (key == NULL) {
break;
}
- char* buffer;
- int32_t resultCapacity = ULOC_KEYWORD_AND_VALUES_CAPACITY;
- for (;;) {
- buffer = buf.getAppendBuffer(
- /*minCapacity=*/resultCapacity,
- /*desiredCapacityHint=*/resultCapacity,
- resultCapacity,
- tmpStatus);
-
- if (U_FAILURE(tmpStatus)) {
- break;
- }
-
- len = uloc_getKeywordValue(
- localeID, key, buffer, resultCapacity, &tmpStatus);
-
- if (tmpStatus != U_BUFFER_OVERFLOW_ERROR) {
- break;
- }
-
- resultCapacity = len;
- tmpStatus = U_ZERO_ERROR;
+ icu::CharString buf;
+ {
+ icu::CharStringByteSink sink(&buf);
+ ulocimp_getKeywordValue(localeID, key, sink, &tmpStatus);
}
+ len = buf.length();
if (U_FAILURE(tmpStatus)) {
if (tmpStatus == U_MEMORY_ALLOCATION_ERROR) {
@@ -1313,11 +1296,6 @@
continue;
}
- buf.append(buffer, len, tmpStatus);
- if (tmpStatus == U_STRING_NOT_TERMINATED_WARNING) {
- tmpStatus = U_ZERO_ERROR; // Terminators provided by CharString.
- }
-
keylen = (int32_t)uprv_strlen(key);
isBcpUExt = (keylen > 1);
@@ -2707,14 +2685,17 @@
key = uenum_next(kwdEnum.getAlias(), &len, &tmpStatus);
if (len == 1 && *key == PRIVATEUSE) {
- char buf[ULOC_KEYWORD_AND_VALUES_CAPACITY];
- buf[0] = PRIVATEUSE;
- buf[1] = SEP;
- len = uloc_getKeywordValue(localeID, key, &buf[2], sizeof(buf) - 2, &tmpStatus);
+ icu::CharString buf;
+ {
+ icu::CharStringByteSink sink(&buf);
+ ulocimp_getKeywordValue(localeID, key, sink, &tmpStatus);
+ }
if (U_SUCCESS(tmpStatus)) {
- if (ultag_isPrivateuseValueSubtags(&buf[2], len)) {
+ if (ultag_isPrivateuseValueSubtags(buf.data(), buf.length())) {
/* return private use only tag */
- sink.Append(buf, len + 2);
+ static const char PREFIX[] = { PRIVATEUSE, SEP };
+ sink.Append(PREFIX, sizeof(PREFIX));
+ sink.Append(buf.data(), buf.length());
done = TRUE;
} else if (strict) {
*status = U_ILLEGAL_ARGUMENT_ERROR;