diff options
author | mcheshkov <mcheshkov@yandex-team.ru> | 2022-02-10 16:46:15 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:15 +0300 |
commit | e9d19cec64684c9c1e6b0c98297e5b895cf904fe (patch) | |
tree | 2768b1223e96a8a0610a93d18425d9647c1123c8 /contrib/libs/icu/i18n/measfmt.cpp | |
parent | 60040c91ffe701a84689b2c6310ff845e65cff42 (diff) | |
download | ydb-e9d19cec64684c9c1e6b0c98297e5b895cf904fe.tar.gz |
Restoring authorship annotation for <mcheshkov@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/icu/i18n/measfmt.cpp')
-rw-r--r-- | contrib/libs/icu/i18n/measfmt.cpp | 376 |
1 files changed, 188 insertions, 188 deletions
diff --git a/contrib/libs/icu/i18n/measfmt.cpp b/contrib/libs/icu/i18n/measfmt.cpp index e05d66d413..92dcfb9cf3 100644 --- a/contrib/libs/icu/i18n/measfmt.cpp +++ b/contrib/libs/icu/i18n/measfmt.cpp @@ -1,4 +1,4 @@ -// © 2016 and later: Unicode, Inc. and others. +// © 2016 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html /* ********************************************************************** @@ -26,7 +26,7 @@ #include "unicode/decimfmt.h" #include "uresimp.h" #include "unicode/ures.h" -#include "unicode/ustring.h" +#include "unicode/ustring.h" #include "ureslocs.h" #include "cstring.h" #include "mutex.h" @@ -36,9 +36,9 @@ #include "unicode/putil.h" #include "unicode/smpdtfmt.h" #include "uassert.h" -#include "unicode/numberformatter.h" -#include "number_longnames.h" -#include "number_utypes.h" +#include "unicode/numberformatter.h" +#include "number_longnames.h" +#include "number_utypes.h" #include "sharednumberformat.h" #include "sharedpluralrules.h" @@ -48,33 +48,33 @@ U_NAMESPACE_BEGIN -using number::impl::UFormattedNumberData; - -static constexpr int32_t WIDTH_INDEX_COUNT = UMEASFMT_WIDTH_NARROW + 1; - +using number::impl::UFormattedNumberData; + +static constexpr int32_t WIDTH_INDEX_COUNT = UMEASFMT_WIDTH_NARROW + 1; + UOBJECT_DEFINE_RTTI_IMPLEMENTATION(MeasureFormat) // Used to format durations like 5:47 or 21:35:42. class NumericDateFormatters : public UMemory { public: // Formats like H:mm - UnicodeString hourMinute; + UnicodeString hourMinute; // formats like M:ss - UnicodeString minuteSecond; + UnicodeString minuteSecond; // formats like H:mm:ss - UnicodeString hourMinuteSecond; + UnicodeString hourMinuteSecond; // Constructor that takes the actual patterns for hour-minute, // minute-second, and hour-minute-second respectively. NumericDateFormatters( const UnicodeString &hm, const UnicodeString &ms, - const UnicodeString &hms) : - hourMinute(hm), - minuteSecond(ms), - hourMinuteSecond(hms) { + const UnicodeString &hms) : + hourMinute(hm), + minuteSecond(ms), + hourMinuteSecond(hms) { } private: NumericDateFormatters(const NumericDateFormatters &other); @@ -88,19 +88,19 @@ static UMeasureFormatWidth getRegularWidth(UMeasureFormatWidth width) { return width; } -static UNumberUnitWidth getUnitWidth(UMeasureFormatWidth width) { - switch (width) { - case UMEASFMT_WIDTH_WIDE: - return UNUM_UNIT_WIDTH_FULL_NAME; - case UMEASFMT_WIDTH_NARROW: - case UMEASFMT_WIDTH_NUMERIC: - return UNUM_UNIT_WIDTH_NARROW; - case UMEASFMT_WIDTH_SHORT: - default: - return UNUM_UNIT_WIDTH_SHORT; - } -} - +static UNumberUnitWidth getUnitWidth(UMeasureFormatWidth width) { + switch (width) { + case UMEASFMT_WIDTH_WIDE: + return UNUM_UNIT_WIDTH_FULL_NAME; + case UMEASFMT_WIDTH_NARROW: + case UMEASFMT_WIDTH_NUMERIC: + return UNUM_UNIT_WIDTH_NARROW; + case UMEASFMT_WIDTH_SHORT: + default: + return UNUM_UNIT_WIDTH_SHORT; + } +} + /** * Instances contain all MeasureFormat specific data for a particular locale. * This data is cached. It is never copied, but is shared via shared pointers. @@ -147,20 +147,20 @@ public: } private: - NumberFormat* currencyFormats[WIDTH_INDEX_COUNT]; - NumberFormat* integerFormat; - NumericDateFormatters* numericDateFormatters; - + NumberFormat* currencyFormats[WIDTH_INDEX_COUNT]; + NumberFormat* integerFormat; + NumericDateFormatters* numericDateFormatters; + MeasureFormatCacheData(const MeasureFormatCacheData &other); MeasureFormatCacheData &operator=(const MeasureFormatCacheData &other); }; -MeasureFormatCacheData::MeasureFormatCacheData() - : integerFormat(nullptr), numericDateFormatters(nullptr) { +MeasureFormatCacheData::MeasureFormatCacheData() + : integerFormat(nullptr), numericDateFormatters(nullptr) { for (int32_t i = 0; i < WIDTH_INDEX_COUNT; ++i) { widthFallback[i] = UMEASFMT_WIDTH_COUNT; } - memset(currencyFormats, 0, sizeof(currencyFormats)); + memset(currencyFormats, 0, sizeof(currencyFormats)); } MeasureFormatCacheData::~MeasureFormatCacheData() { @@ -231,7 +231,7 @@ static NumericDateFormatters *loadNumericDateFormatters( NumericDateFormatters *result = new NumericDateFormatters( loadNumericDateFormatterPattern(resource, "hm", status), loadNumericDateFormatterPattern(resource, "ms", status), - loadNumericDateFormatterPattern(resource, "hms", status)); + loadNumericDateFormatterPattern(resource, "hms", status)); if (U_FAILURE(status)) { delete result; return NULL; @@ -355,7 +355,7 @@ MeasureFormat::MeasureFormat( : cache(NULL), numberFormat(NULL), pluralRules(NULL), - fWidth(w), + fWidth(w), listFormatter(NULL) { initMeasureFormat(locale, w, NULL, status); } @@ -368,7 +368,7 @@ MeasureFormat::MeasureFormat( : cache(NULL), numberFormat(NULL), pluralRules(NULL), - fWidth(w), + fWidth(w), listFormatter(NULL) { initMeasureFormat(locale, w, nfToAdopt, status); } @@ -378,7 +378,7 @@ MeasureFormat::MeasureFormat(const MeasureFormat &other) : cache(other.cache), numberFormat(other.numberFormat), pluralRules(other.pluralRules), - fWidth(other.fWidth), + fWidth(other.fWidth), listFormatter(NULL) { cache->addRef(); numberFormat->addRef(); @@ -396,7 +396,7 @@ MeasureFormat &MeasureFormat::operator=(const MeasureFormat &other) { SharedObject::copyPtr(other.cache, cache); SharedObject::copyPtr(other.numberFormat, numberFormat); SharedObject::copyPtr(other.pluralRules, pluralRules); - fWidth = other.fWidth; + fWidth = other.fWidth; delete listFormatter; if (other.listFormatter != NULL) { listFormatter = new ListFormatter(*other.listFormatter); @@ -410,7 +410,7 @@ MeasureFormat::MeasureFormat() : cache(NULL), numberFormat(NULL), pluralRules(NULL), - fWidth(UMEASFMT_WIDTH_SHORT), + fWidth(UMEASFMT_WIDTH_SHORT), listFormatter(NULL) { } @@ -440,7 +440,7 @@ UBool MeasureFormat::operator==(const Format &other) const { // don't have to check it here. // differing widths aren't equivalent - if (fWidth != rhs.fWidth) { + if (fWidth != rhs.fWidth) { return FALSE; } // Width the same check locales. @@ -463,7 +463,7 @@ UBool MeasureFormat::operator==(const Format &other) const { **numberFormat == **rhs.numberFormat); } -MeasureFormat *MeasureFormat::clone() const { +MeasureFormat *MeasureFormat::clone() const { return new MeasureFormat(*this); } @@ -501,22 +501,22 @@ UnicodeString &MeasureFormat::formatMeasurePerUnit( if (U_FAILURE(status)) { return appendTo; } - auto* df = dynamic_cast<const DecimalFormat*>(&getNumberFormatInternal()); - if (df == nullptr) { - // Don't know how to handle other types of NumberFormat - status = U_UNSUPPORTED_ERROR; + auto* df = dynamic_cast<const DecimalFormat*>(&getNumberFormatInternal()); + if (df == nullptr) { + // Don't know how to handle other types of NumberFormat + status = U_UNSUPPORTED_ERROR; return appendTo; } - UFormattedNumberData result; - if (auto* lnf = df->toNumberFormatter(status)) { - result.quantity.setToDouble(measure.getNumber().getDouble(status)); - lnf->unit(measure.getUnit()) - .perUnit(perUnit) - .unitWidth(getUnitWidth(fWidth)) - .formatImpl(&result, status); + UFormattedNumberData result; + if (auto* lnf = df->toNumberFormatter(status)) { + result.quantity.setToDouble(measure.getNumber().getDouble(status)); + lnf->unit(measure.getUnit()) + .perUnit(perUnit) + .unitWidth(getUnitWidth(fWidth)) + .formatImpl(&result, status); } - DecimalFormat::fieldPositionHelper(result, pos, appendTo.length(), status); - appendTo.append(result.toTempString(status)); + DecimalFormat::fieldPositionHelper(result, pos, appendTo.length(), status); + appendTo.append(result.toTempString(status)); return appendTo; } @@ -535,7 +535,7 @@ UnicodeString &MeasureFormat::formatMeasures( if (measureCount == 1) { return formatMeasure(measures[0], **numberFormat, appendTo, pos, status); } - if (fWidth == UMEASFMT_WIDTH_NUMERIC) { + if (fWidth == UMEASFMT_WIDTH_NUMERIC) { Formattable hms[3]; int32_t bitMap = toHMS(measures, measureCount, hms, status); if (bitMap > 0) { @@ -568,12 +568,12 @@ UnicodeString &MeasureFormat::formatMeasures( return appendTo; } -UnicodeString MeasureFormat::getUnitDisplayName(const MeasureUnit& unit, UErrorCode& status) const { - return number::impl::LongNameHandler::getUnitDisplayName( - getLocale(status), - unit, - getUnitWidth(fWidth), - status); +UnicodeString MeasureFormat::getUnitDisplayName(const MeasureUnit& unit, UErrorCode& status) const { + return number::impl::LongNameHandler::getUnitDisplayName( + getLocale(status), + unit, + getUnitWidth(fWidth), + status); } void MeasureFormat::initMeasureFormat( @@ -602,7 +602,7 @@ void MeasureFormat::initMeasureFormat( SharedObject::copyPtr(pr, pluralRules); pr->removeRef(); if (nf.isNull()) { - // TODO: Clean this up + // TODO: Clean this up const SharedNumberFormat *shared = NumberFormat::createSharedInstance( locale, UNUM_DECIMAL, status); if (U_FAILURE(status)) { @@ -616,11 +616,11 @@ void MeasureFormat::initMeasureFormat( return; } } - fWidth = w; + fWidth = w; delete listFormatter; listFormatter = ListFormatter::createInstance( locale, - listStyles[getRegularWidth(fWidth)], + listStyles[getRegularWidth(fWidth)], status); } @@ -643,18 +643,18 @@ UBool MeasureFormat::setMeasureFormatLocale(const Locale &locale, UErrorCode &st if (U_FAILURE(status) || locale == getLocale(status)) { return FALSE; } - initMeasureFormat(locale, fWidth, NULL, status); + initMeasureFormat(locale, fWidth, NULL, status); return U_SUCCESS(status); } -const NumberFormat &MeasureFormat::getNumberFormatInternal() const { +const NumberFormat &MeasureFormat::getNumberFormatInternal() const { return **numberFormat; } -const NumberFormat &MeasureFormat::getCurrencyFormatInternal() const { - return *cache->getCurrencyFormat(UMEASFMT_WIDTH_NARROW); -} - +const NumberFormat &MeasureFormat::getCurrencyFormatInternal() const { + return *cache->getCurrencyFormat(UMEASFMT_WIDTH_NARROW); +} + const PluralRules &MeasureFormat::getPluralRules() const { return **pluralRules; } @@ -681,142 +681,142 @@ UnicodeString &MeasureFormat::formatMeasure( if (isCurrency(amtUnit)) { UChar isoCode[4]; u_charsToUChars(amtUnit.getSubtype(), isoCode, 4); - return cache->getCurrencyFormat(fWidth)->format( + return cache->getCurrencyFormat(fWidth)->format( new CurrencyAmount(amtNumber, isoCode, status), appendTo, pos, status); } - auto* df = dynamic_cast<const DecimalFormat*>(&nf); - if (df == nullptr) { - // Handle other types of NumberFormat using the ICU 63 code, modified to - // get the unitPattern from LongNameHandler and handle fallback to OTHER. - UnicodeString formattedNumber; - StandardPlural::Form pluralForm = QuantityFormatter::selectPlural( - amtNumber, nf, **pluralRules, formattedNumber, pos, status); - UnicodeString pattern = number::impl::LongNameHandler::getUnitPattern(getLocale(status), - amtUnit, getUnitWidth(fWidth), pluralForm, status); - // The above handles fallback from other widths to short, and from other plural forms to OTHER - if (U_FAILURE(status)) { - return appendTo; - } - SimpleFormatter formatter(pattern, 0, 1, status); - return QuantityFormatter::format(formatter, formattedNumber, appendTo, pos, status); - } - UFormattedNumberData result; - if (auto* lnf = df->toNumberFormatter(status)) { - result.quantity.setToDouble(amtNumber.getDouble(status)); - lnf->unit(amtUnit) - .unitWidth(getUnitWidth(fWidth)) - .formatImpl(&result, status); - } - DecimalFormat::fieldPositionHelper(result, pos, appendTo.length(), status); - appendTo.append(result.toTempString(status)); - return appendTo; -} - - -// Formats numeric time duration as 5:00:47 or 3:54. + auto* df = dynamic_cast<const DecimalFormat*>(&nf); + if (df == nullptr) { + // Handle other types of NumberFormat using the ICU 63 code, modified to + // get the unitPattern from LongNameHandler and handle fallback to OTHER. + UnicodeString formattedNumber; + StandardPlural::Form pluralForm = QuantityFormatter::selectPlural( + amtNumber, nf, **pluralRules, formattedNumber, pos, status); + UnicodeString pattern = number::impl::LongNameHandler::getUnitPattern(getLocale(status), + amtUnit, getUnitWidth(fWidth), pluralForm, status); + // The above handles fallback from other widths to short, and from other plural forms to OTHER + if (U_FAILURE(status)) { + return appendTo; + } + SimpleFormatter formatter(pattern, 0, 1, status); + return QuantityFormatter::format(formatter, formattedNumber, appendTo, pos, status); + } + UFormattedNumberData result; + if (auto* lnf = df->toNumberFormatter(status)) { + result.quantity.setToDouble(amtNumber.getDouble(status)); + lnf->unit(amtUnit) + .unitWidth(getUnitWidth(fWidth)) + .formatImpl(&result, status); + } + DecimalFormat::fieldPositionHelper(result, pos, appendTo.length(), status); + appendTo.append(result.toTempString(status)); + return appendTo; +} + + +// Formats numeric time duration as 5:00:47 or 3:54. UnicodeString &MeasureFormat::formatNumeric( const Formattable *hms, // always length 3 - int32_t bitMap, // 1=hour set, 2=minute set, 4=second set + int32_t bitMap, // 1=hour set, 2=minute set, 4=second set UnicodeString &appendTo, UErrorCode &status) const { if (U_FAILURE(status)) { return appendTo; } - UnicodeString pattern; + UnicodeString pattern; - double hours = hms[0].getDouble(status); - double minutes = hms[1].getDouble(status); - double seconds = hms[2].getDouble(status); + double hours = hms[0].getDouble(status); + double minutes = hms[1].getDouble(status); + double seconds = hms[2].getDouble(status); if (U_FAILURE(status)) { return appendTo; } - // All possible combinations: "h", "m", "s", "hm", "hs", "ms", "hms" - if (bitMap == 5 || bitMap == 7) { // "hms" & "hs" (we add minutes if "hs") - pattern = cache->getNumericDateFormatters()->hourMinuteSecond; - hours = uprv_trunc(hours); - minutes = uprv_trunc(minutes); - } else if (bitMap == 3) { // "hm" - pattern = cache->getNumericDateFormatters()->hourMinute; - hours = uprv_trunc(hours); - } else if (bitMap == 6) { // "ms" - pattern = cache->getNumericDateFormatters()->minuteSecond; - minutes = uprv_trunc(minutes); - } else { // h m s, handled outside formatNumeric. No value is also an error. + // All possible combinations: "h", "m", "s", "hm", "hs", "ms", "hms" + if (bitMap == 5 || bitMap == 7) { // "hms" & "hs" (we add minutes if "hs") + pattern = cache->getNumericDateFormatters()->hourMinuteSecond; + hours = uprv_trunc(hours); + minutes = uprv_trunc(minutes); + } else if (bitMap == 3) { // "hm" + pattern = cache->getNumericDateFormatters()->hourMinute; + hours = uprv_trunc(hours); + } else if (bitMap == 6) { // "ms" + pattern = cache->getNumericDateFormatters()->minuteSecond; + minutes = uprv_trunc(minutes); + } else { // h m s, handled outside formatNumeric. No value is also an error. status = U_INTERNAL_PROGRAM_ERROR; return appendTo; } - const DecimalFormat *numberFormatter = dynamic_cast<const DecimalFormat*>(numberFormat->get()); - if (!numberFormatter) { - status = U_INTERNAL_PROGRAM_ERROR; - return appendTo; - } - number::LocalizedNumberFormatter numberFormatter2; - if (auto* lnf = numberFormatter->toNumberFormatter(status)) { - numberFormatter2 = lnf->integerWidth(number::IntegerWidth::zeroFillTo(2)); + const DecimalFormat *numberFormatter = dynamic_cast<const DecimalFormat*>(numberFormat->get()); + if (!numberFormatter) { + status = U_INTERNAL_PROGRAM_ERROR; + return appendTo; + } + number::LocalizedNumberFormatter numberFormatter2; + if (auto* lnf = numberFormatter->toNumberFormatter(status)) { + numberFormatter2 = lnf->integerWidth(number::IntegerWidth::zeroFillTo(2)); } else { - return appendTo; + return appendTo; } - FormattedStringBuilder fsb; + FormattedStringBuilder fsb; - UBool protect = FALSE; - const int32_t patternLength = pattern.length(); - for (int32_t i = 0; i < patternLength; i++) { - char16_t c = pattern[i]; + UBool protect = FALSE; + const int32_t patternLength = pattern.length(); + for (int32_t i = 0; i < patternLength; i++) { + char16_t c = pattern[i]; - // Also set the proper field in this switch - // We don't use DateFormat.Field because this is not a date / time, is a duration. - double value = 0; - switch (c) { - case u'H': value = hours; break; - case u'm': value = minutes; break; - case u's': value = seconds; break; + // Also set the proper field in this switch + // We don't use DateFormat.Field because this is not a date / time, is a duration. + double value = 0; + switch (c) { + case u'H': value = hours; break; + case u'm': value = minutes; break; + case u's': value = seconds; break; } - // There is not enough info to add Field(s) for the unit because all we have are plain - // text patterns. For example in "21:51" there is no text for something like "hour", - // while in something like "21h51" there is ("h"). But we can't really tell... - switch (c) { - case u'H': - case u'm': - case u's': - if (protect) { - fsb.appendChar16(c, kUndefinedField, status); - } else { - UnicodeString tmp; - if ((i + 1 < patternLength) && pattern[i + 1] == c) { // doubled - tmp = numberFormatter2.formatDouble(value, status).toString(status); - i++; - } else { - numberFormatter->format(value, tmp, status); - } - // TODO: Use proper Field - fsb.append(tmp, kUndefinedField, status); - } - break; - case u'\'': - // '' is escaped apostrophe - if ((i + 1 < patternLength) && pattern[i + 1] == c) { - fsb.appendChar16(c, kUndefinedField, status); - i++; - } else { - protect = !protect; - } - break; - default: - fsb.appendChar16(c, kUndefinedField, status); - } - } - - appendTo.append(fsb.toTempUnicodeString()); - - return appendTo; + // There is not enough info to add Field(s) for the unit because all we have are plain + // text patterns. For example in "21:51" there is no text for something like "hour", + // while in something like "21h51" there is ("h"). But we can't really tell... + switch (c) { + case u'H': + case u'm': + case u's': + if (protect) { + fsb.appendChar16(c, kUndefinedField, status); + } else { + UnicodeString tmp; + if ((i + 1 < patternLength) && pattern[i + 1] == c) { // doubled + tmp = numberFormatter2.formatDouble(value, status).toString(status); + i++; + } else { + numberFormatter->format(value, tmp, status); + } + // TODO: Use proper Field + fsb.append(tmp, kUndefinedField, status); + } + break; + case u'\'': + // '' is escaped apostrophe + if ((i + 1 < patternLength) && pattern[i + 1] == c) { + fsb.appendChar16(c, kUndefinedField, status); + i++; + } else { + protect = !protect; + } + break; + default: + fsb.appendChar16(c, kUndefinedField, status); + } + } + + appendTo.append(fsb.toTempUnicodeString()); + + return appendTo; } UnicodeString &MeasureFormat::formatMeasuresSlowTrack( @@ -830,7 +830,7 @@ UnicodeString &MeasureFormat::formatMeasuresSlowTrack( } FieldPosition dontCare(FieldPosition::DONT_CARE); FieldPosition fpos(pos.getField()); - LocalArray<UnicodeString> results(new UnicodeString[measureCount], status); + LocalArray<UnicodeString> results(new UnicodeString[measureCount], status); int32_t fieldPositionFoundIndex = -1; for (int32_t i = 0; i < measureCount; ++i) { const NumberFormat *nf = cache->getIntegerFormat(); @@ -851,7 +851,7 @@ UnicodeString &MeasureFormat::formatMeasuresSlowTrack( } int32_t offset; listFormatter->format( - results.getAlias(), + results.getAlias(), measureCount, appendTo, fieldPositionFoundIndex, @@ -860,7 +860,7 @@ UnicodeString &MeasureFormat::formatMeasuresSlowTrack( if (U_FAILURE(status)) { return appendTo; } - // Fix up FieldPosition indexes if our field is found. + // Fix up FieldPosition indexes if our field is found. if (offset != -1) { pos.setBeginIndex(fpos.getBeginIndex() + offset); pos.setEndIndex(fpos.getEndIndex() + offset); @@ -870,16 +870,16 @@ UnicodeString &MeasureFormat::formatMeasuresSlowTrack( MeasureFormat* U_EXPORT2 MeasureFormat::createCurrencyFormat(const Locale& locale, UErrorCode& ec) { - if (U_FAILURE(ec)) { - return nullptr; + if (U_FAILURE(ec)) { + return nullptr; } - LocalPointer<CurrencyFormat> fmt(new CurrencyFormat(locale, ec), ec); - return fmt.orphan(); + LocalPointer<CurrencyFormat> fmt(new CurrencyFormat(locale, ec), ec); + return fmt.orphan(); } MeasureFormat* U_EXPORT2 MeasureFormat::createCurrencyFormat(UErrorCode& ec) { if (U_FAILURE(ec)) { - return nullptr; + return nullptr; } return MeasureFormat::createCurrencyFormat(Locale::getDefault(), ec); } |