summaryrefslogtreecommitdiffstats
path: root/contrib/libs/icu/common/localematcher.cpp
diff options
context:
space:
mode:
authorromankoshelev <[email protected]>2023-08-09 20:07:20 +0300
committerromankoshelev <[email protected]>2023-08-09 20:59:13 +0300
commitfd82fb12fb45e71a02c628e45b12c50c0dd0d308 (patch)
treef582b79f9002ab1d083e9acda600dfb3551c47b6 /contrib/libs/icu/common/localematcher.cpp
parentbf862ddf5c6178e1bb5e4fb3f7c61015deebe284 (diff)
Update ICU to 70.1
Diffstat (limited to 'contrib/libs/icu/common/localematcher.cpp')
-rw-r--r--contrib/libs/icu/common/localematcher.cpp102
1 files changed, 76 insertions, 26 deletions
diff --git a/contrib/libs/icu/common/localematcher.cpp b/contrib/libs/icu/common/localematcher.cpp
index 85db8c8bf32..3d178dfbaf1 100644
--- a/contrib/libs/icu/common/localematcher.cpp
+++ b/contrib/libs/icu/common/localematcher.cpp
@@ -1,12 +1,9 @@
// © 2019 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html#License
+// License & terms of use: http://www.unicode.org/copyright.html
// localematcher.cpp
// created: 2019may08 Markus W. Scherer
-#ifndef __LOCMATCHER_H__
-#define __LOCMATCHER_H__
-
#include "unicode/utypes.h"
#include "unicode/localebuilder.h"
#include "unicode/localematcher.h"
@@ -131,6 +128,7 @@ LocaleMatcher::Builder::Builder(LocaleMatcher::Builder &&src) U_NOEXCEPT :
thresholdDistance_(src.thresholdDistance_),
demotion_(src.demotion_),
defaultLocale_(src.defaultLocale_),
+ withDefault_(src.withDefault_),
favor_(src.favor_),
direction_(src.direction_) {
src.supportedLocales_ = nullptr;
@@ -140,6 +138,8 @@ LocaleMatcher::Builder::Builder(LocaleMatcher::Builder &&src) U_NOEXCEPT :
LocaleMatcher::Builder::~Builder() {
delete supportedLocales_;
delete defaultLocale_;
+ delete maxDistanceDesired_;
+ delete maxDistanceSupported_;
}
LocaleMatcher::Builder &LocaleMatcher::Builder::operator=(LocaleMatcher::Builder &&src) U_NOEXCEPT {
@@ -150,6 +150,7 @@ LocaleMatcher::Builder &LocaleMatcher::Builder::operator=(LocaleMatcher::Builder
thresholdDistance_ = src.thresholdDistance_;
demotion_ = src.demotion_;
defaultLocale_ = src.defaultLocale_;
+ withDefault_ = src.withDefault_,
favor_ = src.favor_;
direction_ = src.direction_;
@@ -186,7 +187,7 @@ LocaleMatcher::Builder &LocaleMatcher::Builder::setSupportedLocalesFromListStrin
for (int32_t i = 0; i < length; ++i) {
Locale *locale = list.orphanLocaleAt(i);
if (locale == nullptr) { continue; }
- supportedLocales_->addElement(locale, errorCode_);
+ supportedLocales_->addElementX(locale, errorCode_);
if (U_FAILURE(errorCode_)) {
delete locale;
break;
@@ -206,7 +207,7 @@ LocaleMatcher::Builder &LocaleMatcher::Builder::setSupportedLocales(Locale::Iter
errorCode_ = U_MEMORY_ALLOCATION_ERROR;
break;
}
- supportedLocales_->addElement(clone, errorCode_);
+ supportedLocales_->addElementX(clone, errorCode_);
if (U_FAILURE(errorCode_)) {
delete clone;
break;
@@ -222,13 +223,21 @@ LocaleMatcher::Builder &LocaleMatcher::Builder::addSupportedLocale(const Locale
errorCode_ = U_MEMORY_ALLOCATION_ERROR;
return *this;
}
- supportedLocales_->addElement(clone, errorCode_);
+ supportedLocales_->addElementX(clone, errorCode_);
if (U_FAILURE(errorCode_)) {
delete clone;
}
return *this;
}
+LocaleMatcher::Builder &LocaleMatcher::Builder::setNoDefaultLocale() {
+ if (U_FAILURE(errorCode_)) { return *this; }
+ delete defaultLocale_;
+ defaultLocale_ = nullptr;
+ withDefault_ = false;
+ return *this;
+}
+
LocaleMatcher::Builder &LocaleMatcher::Builder::setDefaultLocale(const Locale *defaultLocale) {
if (U_FAILURE(errorCode_)) { return *this; }
Locale *clone = nullptr;
@@ -241,6 +250,7 @@ LocaleMatcher::Builder &LocaleMatcher::Builder::setDefaultLocale(const Locale *d
}
delete defaultLocale_;
defaultLocale_ = clone;
+ withDefault_ = true;
return *this;
}
@@ -256,6 +266,24 @@ LocaleMatcher::Builder &LocaleMatcher::Builder::setDemotionPerDesiredLocale(ULoc
return *this;
}
+LocaleMatcher::Builder &LocaleMatcher::Builder::setMaxDistance(const Locale &desired,
+ const Locale &supported) {
+ if (U_FAILURE(errorCode_)) { return *this; }
+ Locale *desiredClone = desired.clone();
+ Locale *supportedClone = supported.clone();
+ if (desiredClone == nullptr || supportedClone == nullptr) {
+ delete desiredClone; // in case only one could not be allocated
+ delete supportedClone;
+ errorCode_ = U_MEMORY_ALLOCATION_ERROR;
+ return *this;
+ }
+ delete maxDistanceDesired_;
+ delete maxDistanceSupported_;
+ maxDistanceDesired_ = desiredClone;
+ maxDistanceSupported_ = supportedClone;
+ return *this;
+}
+
#if 0
/**
* <i>Internal only!</i>
@@ -317,9 +345,8 @@ UBool compareLSRs(const UHashTok t1, const UHashTok t2) {
int32_t LocaleMatcher::putIfAbsent(const LSR &lsr, int32_t i, int32_t suppLength,
UErrorCode &errorCode) {
if (U_FAILURE(errorCode)) { return suppLength; }
- int32_t index = uhash_geti(supportedLsrToIndex, &lsr);
- if (index == 0) {
- uhash_puti(supportedLsrToIndex, const_cast<LSR *>(&lsr), i + 1, &errorCode);
+ if (!uhash_containsKey(supportedLsrToIndex, &lsr)) {
+ uhash_putiAllowZero(supportedLsrToIndex, const_cast<LSR *>(&lsr), i, &errorCode);
if (U_SUCCESS(errorCode)) {
supportedLSRs[suppLength] = &lsr;
supportedIndexes[suppLength++] = i;
@@ -340,9 +367,6 @@ LocaleMatcher::LocaleMatcher(const Builder &builder, UErrorCode &errorCode) :
supportedLSRs(nullptr), supportedIndexes(nullptr), supportedLSRsLength(0),
ownedDefaultLocale(nullptr), defaultLocale(nullptr) {
if (U_FAILURE(errorCode)) { return; }
- if (thresholdDistance < 0) {
- thresholdDistance = localeDistance.getDefaultScriptDistance();
- }
const Locale *def = builder.defaultLocale_;
LSR builderDefaultLSR;
const LSR *defLSR = nullptr;
@@ -408,22 +432,20 @@ LocaleMatcher::LocaleMatcher(const Builder &builder, UErrorCode &errorCode) :
int32_t suppLength = 0;
// Determine insertion order.
// Add locales immediately that are equivalent to the default.
- MaybeStackArray<int8_t, 100> order(supportedLocalesLength);
- if (order.getAlias() == nullptr) {
- errorCode = U_MEMORY_ALLOCATION_ERROR;
- return;
- }
+ MaybeStackArray<int8_t, 100> order(supportedLocalesLength, errorCode);
+ if (U_FAILURE(errorCode)) { return; }
int32_t numParadigms = 0;
for (int32_t i = 0; i < supportedLocalesLength; ++i) {
const Locale &locale = *supportedLocales[i];
const LSR &lsr = lsrs[i];
- if (defLSR == nullptr) {
+ if (defLSR == nullptr && builder.withDefault_) {
+ // Implicit default locale = first supported locale, if not turned off.
U_ASSERT(i == 0);
def = &locale;
defLSR = &lsr;
order[i] = 1;
suppLength = putIfAbsent(lsr, 0, suppLength, errorCode);
- } else if (lsr.isEquivalentTo(*defLSR)) {
+ } else if (defLSR != nullptr && lsr.isEquivalentTo(*defLSR)) {
order[i] = 1;
suppLength = putIfAbsent(lsr, i, suppLength, errorCode);
} else if (localeDistance.isParadigmLSR(lsr)) {
@@ -458,6 +480,25 @@ LocaleMatcher::LocaleMatcher(const Builder &builder, UErrorCode &errorCode) :
if (builder.demotion_ == ULOCMATCH_DEMOTION_REGION) {
demotionPerDesiredLocale = localeDistance.getDefaultDemotionPerDesiredLocale();
}
+
+ if (thresholdDistance >= 0) {
+ // already copied
+ } else if (builder.maxDistanceDesired_ != nullptr) {
+ LSR suppLSR = getMaximalLsrOrUnd(likelySubtags, *builder.maxDistanceSupported_, errorCode);
+ const LSR *pSuppLSR = &suppLSR;
+ int32_t indexAndDistance = localeDistance.getBestIndexAndDistance(
+ getMaximalLsrOrUnd(likelySubtags, *builder.maxDistanceDesired_, errorCode),
+ &pSuppLSR, 1,
+ LocaleDistance::shiftDistance(100), favorSubtag, direction);
+ if (U_SUCCESS(errorCode)) {
+ // +1 for an exclusive threshold from an inclusive max.
+ thresholdDistance = LocaleDistance::getDistanceFloor(indexAndDistance) + 1;
+ } else {
+ thresholdDistance = 0;
+ }
+ } else {
+ thresholdDistance = localeDistance.getDefaultScriptDistance();
+ }
}
LocaleMatcher::LocaleMatcher(LocaleMatcher &&src) U_NOEXCEPT :
@@ -643,12 +684,11 @@ int32_t LocaleMatcher::getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remai
int32_t bestSupportedLsrIndex = -1;
for (int32_t bestShiftedDistance = LocaleDistance::shiftDistance(thresholdDistance);;) {
// Quick check for exact maximized LSR.
- // Returns suppIndex+1 where 0 means not found.
if (supportedLsrToIndex != nullptr) {
desiredLSR.setHashCode();
- int32_t index = uhash_geti(supportedLsrToIndex, &desiredLSR);
- if (index != 0) {
- int32_t suppIndex = index - 1;
+ UBool found = false;
+ int32_t suppIndex = uhash_getiAndFound(supportedLsrToIndex, &desiredLSR, &found);
+ if (found) {
if (remainingIter != nullptr) {
remainingIter->rememberCurrent(desiredIndex, errorCode);
}
@@ -683,6 +723,18 @@ int32_t LocaleMatcher::getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remai
return supportedIndexes[bestSupportedLsrIndex];
}
+UBool LocaleMatcher::isMatch(const Locale &desired, const Locale &supported,
+ UErrorCode &errorCode) const {
+ LSR suppLSR = getMaximalLsrOrUnd(likelySubtags, supported, errorCode);
+ if (U_FAILURE(errorCode)) { return 0; }
+ const LSR *pSuppLSR = &suppLSR;
+ int32_t indexAndDistance = localeDistance.getBestIndexAndDistance(
+ getMaximalLsrOrUnd(likelySubtags, desired, errorCode),
+ &pSuppLSR, 1,
+ LocaleDistance::shiftDistance(thresholdDistance), favorSubtag, direction);
+ return indexAndDistance >= 0;
+}
+
double LocaleMatcher::internalMatch(const Locale &desired, const Locale &supported, UErrorCode &errorCode) const {
// Returns the inverse of the distance: That is, 1-distance(desired, supported).
LSR suppLSR = getMaximalLsrOrUnd(likelySubtags, supported, errorCode);
@@ -790,5 +842,3 @@ uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable,
return acceptLanguage(*availableLocales, desiredLocales,
result, resultAvailable, outResult, *status);
}
-
-#endif // __LOCMATCHER_H__