diff options
author | romankoshelev <[email protected]> | 2023-08-09 20:07:20 +0300 |
---|---|---|
committer | romankoshelev <[email protected]> | 2023-08-09 20:59:13 +0300 |
commit | fd82fb12fb45e71a02c628e45b12c50c0dd0d308 (patch) | |
tree | f582b79f9002ab1d083e9acda600dfb3551c47b6 /contrib/libs/icu/common/loclikely.cpp | |
parent | bf862ddf5c6178e1bb5e4fb3f7c61015deebe284 (diff) |
Update ICU to 70.1
Diffstat (limited to 'contrib/libs/icu/common/loclikely.cpp')
-rw-r--r-- | contrib/libs/icu/common/loclikely.cpp | 143 |
1 files changed, 100 insertions, 43 deletions
diff --git a/contrib/libs/icu/common/loclikely.cpp b/contrib/libs/icu/common/loclikely.cpp index a4a4181cb13..d80096b588e 100644 --- a/contrib/libs/icu/common/loclikely.cpp +++ b/contrib/libs/icu/common/loclikely.cpp @@ -115,7 +115,7 @@ findLikelySubtags(const char* localeID, * @param tag The tag to add. * @param tagLength The length of the tag. * @param buffer The output buffer. - * @param bufferLength The length of the output buffer. This is an input/ouput parameter. + * @param bufferLength The length of the output buffer. This is an input/output parameter. **/ static void U_CALLCONV appendTag( @@ -464,8 +464,7 @@ parseTagString( goto error; } - subtagLength = ulocimp_getLanguage(position, lang, *langLength, &position); - u_terminateChars(lang, *langLength, subtagLength, err); + subtagLength = ulocimp_getLanguage(position, &position, *err).extract(lang, *langLength, *err); /* * Note that we explicit consider U_STRING_NOT_TERMINATED_WARNING @@ -486,8 +485,7 @@ parseTagString( ++position; } - subtagLength = ulocimp_getScript(position, script, *scriptLength, &position); - u_terminateChars(script, *scriptLength, subtagLength, err); + subtagLength = ulocimp_getScript(position, &position, *err).extract(script, *scriptLength, *err); if(U_FAILURE(*err)) { goto error; @@ -511,8 +509,7 @@ parseTagString( } } - subtagLength = ulocimp_getCountry(position, region, *regionLength, &position); - u_terminateChars(region, *regionLength, subtagLength, err); + subtagLength = ulocimp_getCountry(position, &position, *err).extract(region, *regionLength, *err); if(U_FAILURE(*err)) { goto error; @@ -826,7 +823,7 @@ error: } \ } UPRV_BLOCK_MACRO_END -static void +static UBool _uloc_addLikelySubtags(const char* localeID, icu::ByteSink& sink, UErrorCode* err) { @@ -897,15 +894,22 @@ _uloc_addLikelySubtags(const char* localeID, sink.Append(localeID, localIDLength); } - return; + return success; error: if (!U_FAILURE(*err)) { *err = U_ILLEGAL_ARGUMENT_ERROR; } + return FALSE; } +// Add likely subtags to the sink +// return true if the value in the sink is produced by a match during the lookup +// return false if the value in the sink is the same as input because there are +// no match after the lookup. +static UBool _ulocimp_addLikelySubtags(const char*, icu::ByteSink&, UErrorCode*); + static void _uloc_minimizeSubtags(const char* localeID, icu::ByteSink& sink, @@ -921,6 +925,7 @@ _uloc_minimizeSubtags(const char* localeID, const char* trailing = ""; int32_t trailingLength = 0; int32_t trailingIndex = 0; + UBool successGetMax = FALSE; if(U_FAILURE(*err)) { goto error; @@ -961,7 +966,7 @@ _uloc_minimizeSubtags(const char* localeID, { icu::CharString base; { - icu::CharStringByteSink sink(&base); + icu::CharStringByteSink baseSink(&base); createTagString( lang, langLength, @@ -971,7 +976,7 @@ _uloc_minimizeSubtags(const char* localeID, regionLength, NULL, 0, - sink, + baseSink, err); } @@ -980,8 +985,8 @@ _uloc_minimizeSubtags(const char* localeID, * from AddLikelySubtags. **/ { - icu::CharStringByteSink sink(&maximizedTagBuffer); - ulocimp_addLikelySubtags(base.data(), sink, err); + icu::CharStringByteSink maxSink(&maximizedTagBuffer); + successGetMax = _ulocimp_addLikelySubtags(base.data(), maxSink, err); } } @@ -989,13 +994,40 @@ _uloc_minimizeSubtags(const char* localeID, goto error; } + if (!successGetMax) { + /** + * If we got here, return the locale ID parameter unchanged. + **/ + const int32_t localeIDLength = (int32_t)uprv_strlen(localeID); + sink.Append(localeID, localeIDLength); + return; + } + + // In the following, the lang, script, region are referring to those in + // the maximizedTagBuffer, not the one in the localeID. + langLength = sizeof(lang); + scriptLength = sizeof(script); + regionLength = sizeof(region); + parseTagString( + maximizedTagBuffer.data(), + lang, + &langLength, + script, + &scriptLength, + region, + ®ionLength, + err); + if(U_FAILURE(*err)) { + goto error; + } + /** * Start first with just the language. **/ { icu::CharString tagBuffer; { - icu::CharStringByteSink sink(&tagBuffer); + icu::CharStringByteSink tagSink(&tagBuffer); createLikelySubtagsString( lang, langLength, @@ -1005,14 +1037,15 @@ _uloc_minimizeSubtags(const char* localeID, 0, NULL, 0, - sink, + tagSink, err); } if(U_FAILURE(*err)) { goto error; } - else if (!tagBuffer.isEmpty() && uprv_strnicmp( + else if (!tagBuffer.isEmpty() && + uprv_strnicmp( maximizedTagBuffer.data(), tagBuffer.data(), tagBuffer.length()) == 0) { @@ -1039,7 +1072,7 @@ _uloc_minimizeSubtags(const char* localeID, icu::CharString tagBuffer; { - icu::CharStringByteSink sink(&tagBuffer); + icu::CharStringByteSink tagSink(&tagBuffer); createLikelySubtagsString( lang, langLength, @@ -1049,14 +1082,15 @@ _uloc_minimizeSubtags(const char* localeID, regionLength, NULL, 0, - sink, + tagSink, err); } if(U_FAILURE(*err)) { goto error; } - else if (uprv_strnicmp( + else if (!tagBuffer.isEmpty() && + uprv_strnicmp( maximizedTagBuffer.data(), tagBuffer.data(), tagBuffer.length()) == 0) { @@ -1081,10 +1115,10 @@ _uloc_minimizeSubtags(const char* localeID, * since trying with all three subtags would only yield the * maximal version that we already have. **/ - if (scriptLength > 0 && regionLength > 0) { + if (scriptLength > 0) { icu::CharString tagBuffer; { - icu::CharStringByteSink sink(&tagBuffer); + icu::CharStringByteSink tagSink(&tagBuffer); createLikelySubtagsString( lang, langLength, @@ -1094,14 +1128,15 @@ _uloc_minimizeSubtags(const char* localeID, 0, NULL, 0, - sink, + tagSink, err); } if(U_FAILURE(*err)) { goto error; } - else if (uprv_strnicmp( + else if (!tagBuffer.isEmpty() && + uprv_strnicmp( maximizedTagBuffer.data(), tagBuffer.data(), tagBuffer.length()) == 0) { @@ -1123,10 +1158,19 @@ _uloc_minimizeSubtags(const char* localeID, { /** - * If we got here, return the locale ID parameter. + * If we got here, return the max + trail. **/ - const int32_t localeIDLength = (int32_t)uprv_strlen(localeID); - sink.Append(localeID, localeIDLength); + createTagString( + lang, + langLength, + script, + scriptLength, + region, + regionLength, + trailing, + trailingLength, + sink, + err); return; } @@ -1137,13 +1181,13 @@ error: } } -static UBool +static int32_t do_canonicalize(const char* localeID, char* buffer, int32_t bufferCapacity, UErrorCode* err) { - uloc_canonicalize( + int32_t canonicalizedSize = uloc_canonicalize( localeID, buffer, bufferCapacity, @@ -1151,16 +1195,14 @@ do_canonicalize(const char* localeID, if (*err == U_STRING_NOT_TERMINATED_WARNING || *err == U_BUFFER_OVERFLOW_ERROR) { - *err = U_ILLEGAL_ARGUMENT_ERROR; - - return FALSE; + return canonicalizedSize; } else if (U_FAILURE(*err)) { - return FALSE; + return -1; } else { - return TRUE; + return canonicalizedSize; } } @@ -1193,15 +1235,28 @@ uloc_addLikelySubtags(const char* localeID, return reslen; } +static UBool +_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)); + + if (U_SUCCESS(*status)) { + return _uloc_addLikelySubtags(localeBuffer.getBuffer(), sink, status); + } else { + return FALSE; + } +} + U_CAPI void U_EXPORT2 ulocimp_addLikelySubtags(const char* localeID, icu::ByteSink& sink, UErrorCode* status) { - char localeBuffer[ULOC_FULLNAME_CAPACITY]; - - if (do_canonicalize(localeID, localeBuffer, sizeof localeBuffer, status)) { - _uloc_addLikelySubtags(localeBuffer, sink, status); - } + _ulocimp_addLikelySubtags(localeID, sink, status); } U_CAPI int32_t U_EXPORT2 @@ -1237,11 +1292,13 @@ U_CAPI void U_EXPORT2 ulocimp_minimizeSubtags(const char* localeID, icu::ByteSink& sink, UErrorCode* status) { - char localeBuffer[ULOC_FULLNAME_CAPACITY]; - - if (do_canonicalize(localeID, localeBuffer, sizeof localeBuffer, status)) { - _uloc_minimizeSubtags(localeBuffer, sink, status); - } + PreflightingLocaleIDBuffer localeBuffer; + do { + localeBuffer.requestedCapacity = do_canonicalize(localeID, localeBuffer.getBuffer(), + localeBuffer.getCapacity(), status); + } while (localeBuffer.needToTryAgain(status)); + + _uloc_minimizeSubtags(localeBuffer.getBuffer(), sink, status); } // Pairs of (language subtag, + or -) for finding out fast if common languages |