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++) {