summaryrefslogtreecommitdiff
path: root/deps/icu-small/source/i18n/numrange_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'deps/icu-small/source/i18n/numrange_impl.cpp')
-rw-r--r--deps/icu-small/source/i18n/numrange_impl.cpp77
1 files changed, 49 insertions, 28 deletions
diff --git a/deps/icu-small/source/i18n/numrange_impl.cpp b/deps/icu-small/source/i18n/numrange_impl.cpp
index 21365bfc59..05eb2b84de 100644
--- a/deps/icu-small/source/i18n/numrange_impl.cpp
+++ b/deps/icu-small/source/i18n/numrange_impl.cpp
@@ -41,12 +41,12 @@ class NumberRangeDataSink : public ResourceSink {
if (U_FAILURE(status)) { return; }
for (int i = 0; miscTable.getKeyAndValue(i, key, value); i++) {
if (uprv_strcmp(key, "range") == 0) {
- if (fData.rangePattern.getArgumentLimit() != 0) {
+ if (hasRangeData()) {
continue; // have already seen this pattern
}
fData.rangePattern = {value.getUnicodeString(status), status};
} else if (uprv_strcmp(key, "approximately") == 0) {
- if (fData.approximatelyPattern.getArgumentLimit() != 0) {
+ if (hasApproxData()) {
continue; // have already seen this pattern
}
fData.approximatelyPattern = {value.getUnicodeString(status), status};
@@ -54,6 +54,27 @@ class NumberRangeDataSink : public ResourceSink {
}
}
+ bool hasRangeData() {
+ return fData.rangePattern.getArgumentLimit() != 0;
+ }
+
+ bool hasApproxData() {
+ return fData.approximatelyPattern.getArgumentLimit() != 0;
+ }
+
+ bool isComplete() {
+ return hasRangeData() && hasApproxData();
+ }
+
+ void fillInDefaults(UErrorCode& status) {
+ if (!hasRangeData()) {
+ fData.rangePattern = {u"{0}–{1}", status};
+ }
+ if (!hasApproxData()) {
+ fData.approximatelyPattern = {u"~{0}", status};
+ }
+ }
+
private:
NumberRangeData& fData;
};
@@ -68,19 +89,21 @@ void getNumberRangeData(const char* localeName, const char* nsName, NumberRangeD
dataPath.append("NumberElements/", -1, status);
dataPath.append(nsName, -1, status);
dataPath.append("/miscPatterns", -1, status);
- ures_getAllItemsWithFallback(rb.getAlias(), dataPath.data(), sink, status);
if (U_FAILURE(status)) { return; }
- // TODO: Is it necessary to manually fall back to latn, or does the data sink take care of that?
-
- if (data.rangePattern.getArgumentLimit() == 0) {
- // No data!
- data.rangePattern = {u"{0}–{1}", status};
+ UErrorCode localStatus = U_ZERO_ERROR;
+ ures_getAllItemsWithFallback(rb.getAlias(), dataPath.data(), sink, localStatus);
+ if (U_FAILURE(localStatus) && localStatus != U_MISSING_RESOURCE_ERROR) {
+ status = localStatus;
+ return;
}
- if (data.approximatelyPattern.getArgumentLimit() == 0) {
- // No data!
- data.approximatelyPattern = {u"~{0}", status};
+
+ // Fall back to latn if necessary
+ if (!sink.isComplete()) {
+ ures_getAllItemsWithFallback(rb.getAlias(), "NumberElements/latn/miscPatterns", sink, status);
}
+
+ sink.fillInDefaults(status);
}
class PluralRangesDataSink : public ResourceSink {
@@ -177,15 +200,14 @@ NumberRangeFormatterImpl::NumberRangeFormatterImpl(const RangeMacroProps& macros
fCollapse(macros.collapse),
fIdentityFallback(macros.identityFallback) {
- // TODO: As of this writing (ICU 63), there is no locale that has different number miscPatterns
- // based on numbering system. Therefore, data is loaded only from latn. If this changes,
- // this part of the code should be updated to load from the local numbering system.
- // The numbering system could come from the one specified in the NumberFormatter passed to
- // numberFormatterBoth() or similar.
- // See ICU-20144
+ const char* nsName = formatterImpl1.getRawMicroProps().nsName;
+ if (uprv_strcmp(nsName, formatterImpl2.getRawMicroProps().nsName) != 0) {
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
NumberRangeData data;
- getNumberRangeData(macros.locale.getName(), "latn", data, status);
+ getNumberRangeData(macros.locale.getName(), nsName, data, status);
if (U_FAILURE(status)) { return; }
fRangeFormatter = data.rangePattern;
fApproximatelyModifier = {data.approximatelyPattern, UNUM_FIELD_COUNT, false};
@@ -269,8 +291,7 @@ void NumberRangeFormatterImpl::format(UFormattedNumberRangeData& data, bool equa
break;
default:
- U_ASSERT(false);
- break;
+ UPRV_UNREACHABLE;
}
}
@@ -280,8 +301,8 @@ void NumberRangeFormatterImpl::formatSingleValue(UFormattedNumberRangeData& data
UErrorCode& status) const {
if (U_FAILURE(status)) { return; }
if (fSameFormatters) {
- int32_t length = NumberFormatterImpl::writeNumber(micros1, data.quantity1, data.string, 0, status);
- NumberFormatterImpl::writeAffixes(micros1, data.string, 0, length, status);
+ int32_t length = NumberFormatterImpl::writeNumber(micros1, data.quantity1, data.getStringRef(), 0, status);
+ NumberFormatterImpl::writeAffixes(micros1, data.getStringRef(), 0, length, status);
} else {
formatRange(data, micros1, micros2, status);
}
@@ -293,12 +314,12 @@ void NumberRangeFormatterImpl::formatApproximately (UFormattedNumberRangeData& d
UErrorCode& status) const {
if (U_FAILURE(status)) { return; }
if (fSameFormatters) {
- int32_t length = NumberFormatterImpl::writeNumber(micros1, data.quantity1, data.string, 0, status);
+ int32_t length = NumberFormatterImpl::writeNumber(micros1, data.quantity1, data.getStringRef(), 0, status);
// HEURISTIC: Desired modifier order: inner, middle, approximately, outer.
- length += micros1.modInner->apply(data.string, 0, length, status);
- length += micros1.modMiddle->apply(data.string, 0, length, status);
- length += fApproximatelyModifier.apply(data.string, 0, length, status);
- micros1.modOuter->apply(data.string, 0, length, status);
+ length += micros1.modInner->apply(data.getStringRef(), 0, length, status);
+ length += micros1.modMiddle->apply(data.getStringRef(), 0, length, status);
+ length += fApproximatelyModifier.apply(data.getStringRef(), 0, length, status);
+ micros1.modOuter->apply(data.getStringRef(), 0, length, status);
} else {
formatRange(data, micros1, micros2, status);
}
@@ -376,7 +397,7 @@ void NumberRangeFormatterImpl::formatRange(UFormattedNumberRangeData& data,
break;
}
- NumberStringBuilder& string = data.string;
+ NumberStringBuilder& string = data.getStringRef();
int32_t lengthPrefix = 0;
int32_t length1 = 0;
int32_t lengthInfix = 0;