diff --git a/icu4c/source/common/brkiter.cpp b/icu4c/source/common/brkiter.cpp index b452cf2c050..12679c2f474 100644 --- a/icu4c/source/common/brkiter.cpp +++ b/icu4c/source/common/brkiter.cpp @@ -438,17 +438,14 @@ BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status) UTRACE_ENTRY(UTRACE_UBRK_CREATE_LINE); uprv_strcpy(lb_lw, "line"); UErrorCode kvStatus = U_ZERO_ERROR; - CharString value; - CharStringByteSink valueSink(&value); - loc.getKeywordValue("lb", valueSink, kvStatus); + auto value = loc.getKeywordValue("lb", kvStatus); if (U_SUCCESS(kvStatus) && (value == "strict" || value == "normal" || value == "loose")) { uprv_strcat(lb_lw, "_"); uprv_strcat(lb_lw, value.data()); } // lw=phrase is only supported in Japanese and Korean if (uprv_strcmp(loc.getLanguage(), "ja") == 0 || uprv_strcmp(loc.getLanguage(), "ko") == 0) { - value.clear(); - loc.getKeywordValue("lw", valueSink, kvStatus); + value = loc.getKeywordValue("lw", kvStatus); if (U_SUCCESS(kvStatus) && value == "phrase") { uprv_strcat(lb_lw, "_"); uprv_strcat(lb_lw, value.data()); diff --git a/icu4c/source/common/bytesinkutil.h b/icu4c/source/common/bytesinkutil.h index 3161b0d5cea..b3bd487be1d 100644 --- a/icu4c/source/common/bytesinkutil.h +++ b/icu4c/source/common/bytesinkutil.h @@ -43,6 +43,16 @@ private: CharString& dest_; }; +// CharString doesn't provide the public API that StringByteSink requires a +// string class to have so this template specialization replaces the default +// implementation of StringByteSink with CharStringByteSink. +template<> +class StringByteSink : public CharStringByteSink { + public: + StringByteSink(CharString* dest) : CharStringByteSink(dest) { } + StringByteSink(CharString* dest, int32_t /*initialAppendCapacity*/) : CharStringByteSink(dest) { } +}; + class U_COMMON_API ByteSinkUtil { public: ByteSinkUtil() = delete; // all static diff --git a/icu4c/source/common/localebuilder.cpp b/icu4c/source/common/localebuilder.cpp index e6871b2a8c0..e53065a8a60 100644 --- a/icu4c/source/common/localebuilder.cpp +++ b/icu4c/source/common/localebuilder.cpp @@ -3,7 +3,7 @@ #include -#include "bytesinkutil.h" // CharStringByteSink +#include "bytesinkutil.h" // StringByteSink #include "charstr.h" #include "cstring.h" #include "ulocimp.h" @@ -183,9 +183,7 @@ _copyExtensions(const Locale& from, icu::StringEnumeration *keywords, } const char* key; while ((key = keywords->next(nullptr, errorCode)) != nullptr) { - CharString value; - CharStringByteSink sink(&value); - from.getKeywordValue(key, sink, errorCode); + auto value = from.getKeywordValue(key, errorCode); if (U_FAILURE(errorCode)) { return; } if (uprv_strcmp(key, kAttributeKey) == 0) { transform(value.data(), value.length()); @@ -307,10 +305,8 @@ LocaleBuilder& LocaleBuilder::addUnicodeLocaleAttribute( return *this; } - CharString attributes; - CharStringByteSink sink(&attributes); UErrorCode localErrorCode = U_ZERO_ERROR; - extensions_->getKeywordValue(kAttributeKey, sink, localErrorCode); + auto attributes = extensions_->getKeywordValue(kAttributeKey, localErrorCode); if (U_FAILURE(localErrorCode)) { CharString new_attributes(value_str.data(), status_); // No attributes, set the attribute. @@ -362,9 +358,7 @@ LocaleBuilder& LocaleBuilder::removeUnicodeLocaleAttribute( } if (extensions_ == nullptr) { return *this; } UErrorCode localErrorCode = U_ZERO_ERROR; - CharString attributes; - CharStringByteSink sink(&attributes); - extensions_->getKeywordValue(kAttributeKey, sink, localErrorCode); + auto attributes = extensions_->getKeywordValue(kAttributeKey, localErrorCode); // get failure, just return if (U_FAILURE(localErrorCode)) { return *this; } // Do not have any attributes, just return. diff --git a/icu4c/source/common/locdspnm.cpp b/icu4c/source/common/locdspnm.cpp index c836876658f..b2efddf4b40 100644 --- a/icu4c/source/common/locdspnm.cpp +++ b/icu4c/source/common/locdspnm.cpp @@ -634,13 +634,9 @@ LocaleDisplayNamesImpl::localeDisplayName(const Locale& loc, UnicodeString temp2; const char* key; while ((key = e->next((int32_t *)0, status)) != nullptr) { - CharString value; - { - CharStringByteSink sink(&value); - loc.getKeywordValue(key, sink, status); - } - if (U_FAILURE(status)) { - return result; + auto value = loc.getKeywordValue(key, status); + if (U_FAILURE(status)) { + return result; } keyDisplayName(key, temp, true); temp.findAndReplace(formatOpenParen, formatReplaceOpenParen); diff --git a/icu4c/source/common/locid.cpp b/icu4c/source/common/locid.cpp index fcf59b660f5..4a84548b070 100644 --- a/icu4c/source/common/locid.cpp +++ b/icu4c/source/common/locid.cpp @@ -1521,13 +1521,12 @@ AliasReplacer::replaceTransformedExtensions( const char* tkey = ultag_getTKeyStart(str); int32_t tlangLen = (tkey == str) ? 0 : ((tkey == nullptr) ? len : static_cast((tkey - str - 1))); - CharStringByteSink sink(&output); if (tlangLen > 0) { Locale tlang = LocaleBuilder() .setLanguageTag(StringPiece(str, tlangLen)) .build(status); tlang.canonicalize(status); - tlang.toLanguageTag(sink, status); + output = tlang.toLanguageTag(status); if (U_FAILURE(status)) { return false; } @@ -1728,9 +1727,7 @@ AliasReplacer::replace(const Locale& locale, CharString& out, UErrorCode& status while ((key = iter->next(nullptr, status)) != nullptr) { if (uprv_strcmp("sd", key) == 0 || uprv_strcmp("rg", key) == 0 || uprv_strcmp("t", key) == 0) { - CharString value; - CharStringByteSink valueSink(&value); - locale.getKeywordValue(key, valueSink, status); + auto value = locale.getKeywordValue(key, status); if (U_FAILURE(status)) { status = U_ZERO_ERROR; continue; @@ -2628,11 +2625,7 @@ Locale::getUnicodeKeywordValue(StringPiece keywordName, return; } - CharString legacy_value; - { - CharStringByteSink sink(&legacy_value); - getKeywordValue(legacy_key, sink, status); - } + auto legacy_value = getKeywordValue(legacy_key, status); if (U_FAILURE(status)) { return; diff --git a/icu4c/source/i18n/units_data.cpp b/icu4c/source/i18n/units_data.cpp index 22859270b73..5160113d2b5 100644 --- a/icu4c/source/i18n/units_data.cpp +++ b/icu4c/source/i18n/units_data.cpp @@ -403,12 +403,8 @@ U_I18N_API UnitPreferences::UnitPreferences(UErrorCode &status) { } CharString getKeyWordValue(const Locale &locale, StringPiece kw, UErrorCode &status) { - CharString result; - if (U_FAILURE(status)) { return result; } - { - CharStringByteSink sink(&result); - locale.getKeywordValue(kw, sink, status); - } + if (U_FAILURE(status)) { return {}; } + auto result = locale.getKeywordValue(kw, status); if (U_SUCCESS(status) && result.isEmpty()) { status = U_MISSING_RESOURCE_ERROR; }