diff options
author | mcheshkov <mcheshkov@yandex-team.ru> | 2022-02-10 16:46:16 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:16 +0300 |
commit | 1312621288956f199a5bd5342b0133d4395fa725 (patch) | |
tree | 1a2c5ffcf89eb53ecd79dbc9bc0a195c27404d0c /contrib/libs/icu/i18n/number_patternmodifier.cpp | |
parent | e9d19cec64684c9c1e6b0c98297e5b895cf904fe (diff) | |
download | ydb-1312621288956f199a5bd5342b0133d4395fa725.tar.gz |
Restoring authorship annotation for <mcheshkov@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/icu/i18n/number_patternmodifier.cpp')
-rw-r--r-- | contrib/libs/icu/i18n/number_patternmodifier.cpp | 660 |
1 files changed, 330 insertions, 330 deletions
diff --git a/contrib/libs/icu/i18n/number_patternmodifier.cpp b/contrib/libs/icu/i18n/number_patternmodifier.cpp index 8a0cd74f7f..45602942ae 100644 --- a/contrib/libs/icu/i18n/number_patternmodifier.cpp +++ b/contrib/libs/icu/i18n/number_patternmodifier.cpp @@ -1,330 +1,330 @@ -// © 2017 and later: Unicode, Inc. and others. -// License & terms of use: http://www.unicode.org/copyright.html - -#include "unicode/utypes.h" - -#if !UCONFIG_NO_FORMATTING - -#include "cstring.h" -#include "number_patternmodifier.h" -#include "unicode/dcfmtsym.h" -#include "unicode/ucurr.h" -#include "unicode/unistr.h" -#include "number_microprops.h" - -using namespace icu; -using namespace icu::number; -using namespace icu::number::impl; - - -AffixPatternProvider::~AffixPatternProvider() = default; - - -MutablePatternModifier::MutablePatternModifier(bool isStrong) - : fStrong(isStrong) {} - -void MutablePatternModifier::setPatternInfo(const AffixPatternProvider* patternInfo, Field field) { - fPatternInfo = patternInfo; - fField = field; -} - -void MutablePatternModifier::setPatternAttributes(UNumberSignDisplay signDisplay, bool perMille) { - fSignDisplay = signDisplay; - fPerMilleReplacesPercent = perMille; -} - -void MutablePatternModifier::setSymbols(const DecimalFormatSymbols* symbols, - const CurrencyUnit& currency, - const UNumberUnitWidth unitWidth, - const PluralRules* rules, - UErrorCode& status) { - U_ASSERT((rules != nullptr) == needsPlurals()); - fSymbols = symbols; - fCurrencySymbols = {currency, symbols->getLocale(), *symbols, status}; - fUnitWidth = unitWidth; - fRules = rules; -} - -void MutablePatternModifier::setNumberProperties(Signum signum, StandardPlural::Form plural) { - fSignum = signum; - fPlural = plural; -} - -bool MutablePatternModifier::needsPlurals() const { - UErrorCode statusLocal = U_ZERO_ERROR; - return fPatternInfo->containsSymbolType(AffixPatternType::TYPE_CURRENCY_TRIPLE, statusLocal); - // Silently ignore any error codes. -} - -ImmutablePatternModifier* MutablePatternModifier::createImmutable(UErrorCode& status) { - // TODO: Move StandardPlural VALUES to standardplural.h - static const StandardPlural::Form STANDARD_PLURAL_VALUES[] = { - StandardPlural::Form::ZERO, - StandardPlural::Form::ONE, - StandardPlural::Form::TWO, - StandardPlural::Form::FEW, - StandardPlural::Form::MANY, - StandardPlural::Form::OTHER}; - - auto pm = new AdoptingModifierStore(); - if (pm == nullptr) { - status = U_MEMORY_ALLOCATION_ERROR; - return nullptr; - } - - if (needsPlurals()) { - // Slower path when we require the plural keyword. - for (StandardPlural::Form plural : STANDARD_PLURAL_VALUES) { - setNumberProperties(SIGNUM_POS, plural); - pm->adoptModifier(SIGNUM_POS, plural, createConstantModifier(status)); - setNumberProperties(SIGNUM_NEG_ZERO, plural); - pm->adoptModifier(SIGNUM_NEG_ZERO, plural, createConstantModifier(status)); - setNumberProperties(SIGNUM_POS_ZERO, plural); - pm->adoptModifier(SIGNUM_POS_ZERO, plural, createConstantModifier(status)); - setNumberProperties(SIGNUM_NEG, plural); - pm->adoptModifier(SIGNUM_NEG, plural, createConstantModifier(status)); - } - if (U_FAILURE(status)) { - delete pm; - return nullptr; - } - return new ImmutablePatternModifier(pm, fRules); // adopts pm - } else { - // Faster path when plural keyword is not needed. - setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT); - pm->adoptModifierWithoutPlural(SIGNUM_POS, createConstantModifier(status)); - setNumberProperties(SIGNUM_NEG_ZERO, StandardPlural::Form::COUNT); - pm->adoptModifierWithoutPlural(SIGNUM_NEG_ZERO, createConstantModifier(status)); - setNumberProperties(SIGNUM_POS_ZERO, StandardPlural::Form::COUNT); - pm->adoptModifierWithoutPlural(SIGNUM_POS_ZERO, createConstantModifier(status)); - setNumberProperties(SIGNUM_NEG, StandardPlural::Form::COUNT); - pm->adoptModifierWithoutPlural(SIGNUM_NEG, createConstantModifier(status)); - if (U_FAILURE(status)) { - delete pm; - return nullptr; - } - return new ImmutablePatternModifier(pm, nullptr); // adopts pm - } -} - -ConstantMultiFieldModifier* MutablePatternModifier::createConstantModifier(UErrorCode& status) { - FormattedStringBuilder a; - FormattedStringBuilder b; - insertPrefix(a, 0, status); - insertSuffix(b, 0, status); - if (fPatternInfo->hasCurrencySign()) { - return new CurrencySpacingEnabledModifier( - a, b, !fPatternInfo->hasBody(), fStrong, *fSymbols, status); - } else { - return new ConstantMultiFieldModifier(a, b, !fPatternInfo->hasBody(), fStrong); - } -} - -ImmutablePatternModifier::ImmutablePatternModifier(AdoptingModifierStore* pm, const PluralRules* rules) - : pm(pm), rules(rules), parent(nullptr) {} - -void ImmutablePatternModifier::processQuantity(DecimalQuantity& quantity, MicroProps& micros, - UErrorCode& status) const { - parent->processQuantity(quantity, micros, status); - micros.rounder.apply(quantity, status); - if (micros.modMiddle != nullptr) { - return; - } - applyToMicros(micros, quantity, status); -} - -void ImmutablePatternModifier::applyToMicros( - MicroProps& micros, const DecimalQuantity& quantity, UErrorCode& status) const { - if (rules == nullptr) { - micros.modMiddle = pm->getModifierWithoutPlural(quantity.signum()); - } else { - StandardPlural::Form pluralForm = utils::getPluralSafe(micros.rounder, rules, quantity, status); - micros.modMiddle = pm->getModifier(quantity.signum(), pluralForm); - } -} - -const Modifier* ImmutablePatternModifier::getModifier(Signum signum, StandardPlural::Form plural) const { - if (rules == nullptr) { - return pm->getModifierWithoutPlural(signum); - } else { - return pm->getModifier(signum, plural); - } -} - -void ImmutablePatternModifier::addToChain(const MicroPropsGenerator* parent) { - this->parent = parent; -} - - -/** Used by the unsafe code path. */ -MicroPropsGenerator& MutablePatternModifier::addToChain(const MicroPropsGenerator* parent) { - fParent = parent; - return *this; -} - -void MutablePatternModifier::processQuantity(DecimalQuantity& fq, MicroProps& micros, - UErrorCode& status) const { - fParent->processQuantity(fq, micros, status); - micros.rounder.apply(fq, status); - if (micros.modMiddle != nullptr) { - return; - } - // The unsafe code path performs self-mutation, so we need a const_cast. - // This method needs to be const because it overrides a const method in the parent class. - auto nonConstThis = const_cast<MutablePatternModifier*>(this); - if (needsPlurals()) { - StandardPlural::Form pluralForm = utils::getPluralSafe(micros.rounder, fRules, fq, status); - nonConstThis->setNumberProperties(fq.signum(), pluralForm); - } else { - nonConstThis->setNumberProperties(fq.signum(), StandardPlural::Form::COUNT); - } - micros.modMiddle = this; -} - -int32_t MutablePatternModifier::apply(FormattedStringBuilder& output, int32_t leftIndex, int32_t rightIndex, - UErrorCode& status) const { - // The unsafe code path performs self-mutation, so we need a const_cast. - // This method needs to be const because it overrides a const method in the parent class. - auto nonConstThis = const_cast<MutablePatternModifier*>(this); - int32_t prefixLen = nonConstThis->insertPrefix(output, leftIndex, status); - int32_t suffixLen = nonConstThis->insertSuffix(output, rightIndex + prefixLen, status); - // If the pattern had no decimal stem body (like #,##0.00), overwrite the value. - int32_t overwriteLen = 0; - if (!fPatternInfo->hasBody()) { - overwriteLen = output.splice( - leftIndex + prefixLen, - rightIndex + prefixLen, - UnicodeString(), - 0, - 0, - kUndefinedField, - status); - } - CurrencySpacingEnabledModifier::applyCurrencySpacing( - output, - leftIndex, - prefixLen, - rightIndex + overwriteLen + prefixLen, - suffixLen, - *fSymbols, - status); - return prefixLen + overwriteLen + suffixLen; -} - -int32_t MutablePatternModifier::getPrefixLength() const { - // The unsafe code path performs self-mutation, so we need a const_cast. - // This method needs to be const because it overrides a const method in the parent class. - auto nonConstThis = const_cast<MutablePatternModifier*>(this); - - // Enter and exit CharSequence Mode to get the length. - UErrorCode status = U_ZERO_ERROR; // status fails only with an iilegal argument exception - nonConstThis->prepareAffix(true); - int result = AffixUtils::unescapedCodePointCount(currentAffix, *this, status); // prefix length - return result; -} - -int32_t MutablePatternModifier::getCodePointCount() const { - // The unsafe code path performs self-mutation, so we need a const_cast. - // This method needs to be const because it overrides a const method in the parent class. - auto nonConstThis = const_cast<MutablePatternModifier*>(this); - - // Render the affixes to get the length - UErrorCode status = U_ZERO_ERROR; // status fails only with an iilegal argument exception - nonConstThis->prepareAffix(true); - int result = AffixUtils::unescapedCodePointCount(currentAffix, *this, status); // prefix length - nonConstThis->prepareAffix(false); - result += AffixUtils::unescapedCodePointCount(currentAffix, *this, status); // suffix length - return result; -} - -bool MutablePatternModifier::isStrong() const { - return fStrong; -} - -bool MutablePatternModifier::containsField(Field field) const { - (void)field; - // This method is not currently used. - UPRV_UNREACHABLE; -} - -void MutablePatternModifier::getParameters(Parameters& output) const { - (void)output; - // This method is not currently used. - UPRV_UNREACHABLE; -} - -bool MutablePatternModifier::semanticallyEquivalent(const Modifier& other) const { - (void)other; - // This method is not currently used. - UPRV_UNREACHABLE; -} - -int32_t MutablePatternModifier::insertPrefix(FormattedStringBuilder& sb, int position, UErrorCode& status) { - prepareAffix(true); - int32_t length = AffixUtils::unescape(currentAffix, sb, position, *this, fField, status); - return length; -} - -int32_t MutablePatternModifier::insertSuffix(FormattedStringBuilder& sb, int position, UErrorCode& status) { - prepareAffix(false); - int32_t length = AffixUtils::unescape(currentAffix, sb, position, *this, fField, status); - return length; -} - -/** This method contains the heart of the logic for rendering LDML affix strings. */ -void MutablePatternModifier::prepareAffix(bool isPrefix) { - PatternStringUtils::patternInfoToStringBuilder( - *fPatternInfo, - isPrefix, - PatternStringUtils::resolveSignDisplay(fSignDisplay, fSignum), - fPlural, - fPerMilleReplacesPercent, - currentAffix); -} - -UnicodeString MutablePatternModifier::getSymbol(AffixPatternType type) const { - UErrorCode localStatus = U_ZERO_ERROR; - switch (type) { - case AffixPatternType::TYPE_MINUS_SIGN: - return fSymbols->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kMinusSignSymbol); - case AffixPatternType::TYPE_PLUS_SIGN: - return fSymbols->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kPlusSignSymbol); - case AffixPatternType::TYPE_PERCENT: - return fSymbols->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kPercentSymbol); - case AffixPatternType::TYPE_PERMILLE: - return fSymbols->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kPerMillSymbol); - case AffixPatternType::TYPE_CURRENCY_SINGLE: { - // UnitWidth ISO and HIDDEN overrides the singular currency symbol. - if (fUnitWidth == UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE) { - return fCurrencySymbols.getIntlCurrencySymbol(localStatus); - } else if (fUnitWidth == UNumberUnitWidth::UNUM_UNIT_WIDTH_HIDDEN) { - return UnicodeString(); - } else if (fUnitWidth == UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW) { - return fCurrencySymbols.getNarrowCurrencySymbol(localStatus); - } else { - return fCurrencySymbols.getCurrencySymbol(localStatus); - } - } - case AffixPatternType::TYPE_CURRENCY_DOUBLE: - return fCurrencySymbols.getIntlCurrencySymbol(localStatus); - case AffixPatternType::TYPE_CURRENCY_TRIPLE: - // NOTE: This is the code path only for patterns containing "¤¤¤". - // Plural currencies set via the API are formatted in LongNameHandler. - // This code path is used by DecimalFormat via CurrencyPluralInfo. - U_ASSERT(fPlural != StandardPlural::Form::COUNT); - return fCurrencySymbols.getPluralName(fPlural, localStatus); - case AffixPatternType::TYPE_CURRENCY_QUAD: - return UnicodeString(u"\uFFFD"); - case AffixPatternType::TYPE_CURRENCY_QUINT: - return UnicodeString(u"\uFFFD"); - default: - UPRV_UNREACHABLE; - } -} - -UnicodeString MutablePatternModifier::toUnicodeString() const { - // Never called by AffixUtils - UPRV_UNREACHABLE; -} - -#endif /* #if !UCONFIG_NO_FORMATTING */ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING + +#include "cstring.h" +#include "number_patternmodifier.h" +#include "unicode/dcfmtsym.h" +#include "unicode/ucurr.h" +#include "unicode/unistr.h" +#include "number_microprops.h" + +using namespace icu; +using namespace icu::number; +using namespace icu::number::impl; + + +AffixPatternProvider::~AffixPatternProvider() = default; + + +MutablePatternModifier::MutablePatternModifier(bool isStrong) + : fStrong(isStrong) {} + +void MutablePatternModifier::setPatternInfo(const AffixPatternProvider* patternInfo, Field field) { + fPatternInfo = patternInfo; + fField = field; +} + +void MutablePatternModifier::setPatternAttributes(UNumberSignDisplay signDisplay, bool perMille) { + fSignDisplay = signDisplay; + fPerMilleReplacesPercent = perMille; +} + +void MutablePatternModifier::setSymbols(const DecimalFormatSymbols* symbols, + const CurrencyUnit& currency, + const UNumberUnitWidth unitWidth, + const PluralRules* rules, + UErrorCode& status) { + U_ASSERT((rules != nullptr) == needsPlurals()); + fSymbols = symbols; + fCurrencySymbols = {currency, symbols->getLocale(), *symbols, status}; + fUnitWidth = unitWidth; + fRules = rules; +} + +void MutablePatternModifier::setNumberProperties(Signum signum, StandardPlural::Form plural) { + fSignum = signum; + fPlural = plural; +} + +bool MutablePatternModifier::needsPlurals() const { + UErrorCode statusLocal = U_ZERO_ERROR; + return fPatternInfo->containsSymbolType(AffixPatternType::TYPE_CURRENCY_TRIPLE, statusLocal); + // Silently ignore any error codes. +} + +ImmutablePatternModifier* MutablePatternModifier::createImmutable(UErrorCode& status) { + // TODO: Move StandardPlural VALUES to standardplural.h + static const StandardPlural::Form STANDARD_PLURAL_VALUES[] = { + StandardPlural::Form::ZERO, + StandardPlural::Form::ONE, + StandardPlural::Form::TWO, + StandardPlural::Form::FEW, + StandardPlural::Form::MANY, + StandardPlural::Form::OTHER}; + + auto pm = new AdoptingModifierStore(); + if (pm == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return nullptr; + } + + if (needsPlurals()) { + // Slower path when we require the plural keyword. + for (StandardPlural::Form plural : STANDARD_PLURAL_VALUES) { + setNumberProperties(SIGNUM_POS, plural); + pm->adoptModifier(SIGNUM_POS, plural, createConstantModifier(status)); + setNumberProperties(SIGNUM_NEG_ZERO, plural); + pm->adoptModifier(SIGNUM_NEG_ZERO, plural, createConstantModifier(status)); + setNumberProperties(SIGNUM_POS_ZERO, plural); + pm->adoptModifier(SIGNUM_POS_ZERO, plural, createConstantModifier(status)); + setNumberProperties(SIGNUM_NEG, plural); + pm->adoptModifier(SIGNUM_NEG, plural, createConstantModifier(status)); + } + if (U_FAILURE(status)) { + delete pm; + return nullptr; + } + return new ImmutablePatternModifier(pm, fRules); // adopts pm + } else { + // Faster path when plural keyword is not needed. + setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT); + pm->adoptModifierWithoutPlural(SIGNUM_POS, createConstantModifier(status)); + setNumberProperties(SIGNUM_NEG_ZERO, StandardPlural::Form::COUNT); + pm->adoptModifierWithoutPlural(SIGNUM_NEG_ZERO, createConstantModifier(status)); + setNumberProperties(SIGNUM_POS_ZERO, StandardPlural::Form::COUNT); + pm->adoptModifierWithoutPlural(SIGNUM_POS_ZERO, createConstantModifier(status)); + setNumberProperties(SIGNUM_NEG, StandardPlural::Form::COUNT); + pm->adoptModifierWithoutPlural(SIGNUM_NEG, createConstantModifier(status)); + if (U_FAILURE(status)) { + delete pm; + return nullptr; + } + return new ImmutablePatternModifier(pm, nullptr); // adopts pm + } +} + +ConstantMultiFieldModifier* MutablePatternModifier::createConstantModifier(UErrorCode& status) { + FormattedStringBuilder a; + FormattedStringBuilder b; + insertPrefix(a, 0, status); + insertSuffix(b, 0, status); + if (fPatternInfo->hasCurrencySign()) { + return new CurrencySpacingEnabledModifier( + a, b, !fPatternInfo->hasBody(), fStrong, *fSymbols, status); + } else { + return new ConstantMultiFieldModifier(a, b, !fPatternInfo->hasBody(), fStrong); + } +} + +ImmutablePatternModifier::ImmutablePatternModifier(AdoptingModifierStore* pm, const PluralRules* rules) + : pm(pm), rules(rules), parent(nullptr) {} + +void ImmutablePatternModifier::processQuantity(DecimalQuantity& quantity, MicroProps& micros, + UErrorCode& status) const { + parent->processQuantity(quantity, micros, status); + micros.rounder.apply(quantity, status); + if (micros.modMiddle != nullptr) { + return; + } + applyToMicros(micros, quantity, status); +} + +void ImmutablePatternModifier::applyToMicros( + MicroProps& micros, const DecimalQuantity& quantity, UErrorCode& status) const { + if (rules == nullptr) { + micros.modMiddle = pm->getModifierWithoutPlural(quantity.signum()); + } else { + StandardPlural::Form pluralForm = utils::getPluralSafe(micros.rounder, rules, quantity, status); + micros.modMiddle = pm->getModifier(quantity.signum(), pluralForm); + } +} + +const Modifier* ImmutablePatternModifier::getModifier(Signum signum, StandardPlural::Form plural) const { + if (rules == nullptr) { + return pm->getModifierWithoutPlural(signum); + } else { + return pm->getModifier(signum, plural); + } +} + +void ImmutablePatternModifier::addToChain(const MicroPropsGenerator* parent) { + this->parent = parent; +} + + +/** Used by the unsafe code path. */ +MicroPropsGenerator& MutablePatternModifier::addToChain(const MicroPropsGenerator* parent) { + fParent = parent; + return *this; +} + +void MutablePatternModifier::processQuantity(DecimalQuantity& fq, MicroProps& micros, + UErrorCode& status) const { + fParent->processQuantity(fq, micros, status); + micros.rounder.apply(fq, status); + if (micros.modMiddle != nullptr) { + return; + } + // The unsafe code path performs self-mutation, so we need a const_cast. + // This method needs to be const because it overrides a const method in the parent class. + auto nonConstThis = const_cast<MutablePatternModifier*>(this); + if (needsPlurals()) { + StandardPlural::Form pluralForm = utils::getPluralSafe(micros.rounder, fRules, fq, status); + nonConstThis->setNumberProperties(fq.signum(), pluralForm); + } else { + nonConstThis->setNumberProperties(fq.signum(), StandardPlural::Form::COUNT); + } + micros.modMiddle = this; +} + +int32_t MutablePatternModifier::apply(FormattedStringBuilder& output, int32_t leftIndex, int32_t rightIndex, + UErrorCode& status) const { + // The unsafe code path performs self-mutation, so we need a const_cast. + // This method needs to be const because it overrides a const method in the parent class. + auto nonConstThis = const_cast<MutablePatternModifier*>(this); + int32_t prefixLen = nonConstThis->insertPrefix(output, leftIndex, status); + int32_t suffixLen = nonConstThis->insertSuffix(output, rightIndex + prefixLen, status); + // If the pattern had no decimal stem body (like #,##0.00), overwrite the value. + int32_t overwriteLen = 0; + if (!fPatternInfo->hasBody()) { + overwriteLen = output.splice( + leftIndex + prefixLen, + rightIndex + prefixLen, + UnicodeString(), + 0, + 0, + kUndefinedField, + status); + } + CurrencySpacingEnabledModifier::applyCurrencySpacing( + output, + leftIndex, + prefixLen, + rightIndex + overwriteLen + prefixLen, + suffixLen, + *fSymbols, + status); + return prefixLen + overwriteLen + suffixLen; +} + +int32_t MutablePatternModifier::getPrefixLength() const { + // The unsafe code path performs self-mutation, so we need a const_cast. + // This method needs to be const because it overrides a const method in the parent class. + auto nonConstThis = const_cast<MutablePatternModifier*>(this); + + // Enter and exit CharSequence Mode to get the length. + UErrorCode status = U_ZERO_ERROR; // status fails only with an iilegal argument exception + nonConstThis->prepareAffix(true); + int result = AffixUtils::unescapedCodePointCount(currentAffix, *this, status); // prefix length + return result; +} + +int32_t MutablePatternModifier::getCodePointCount() const { + // The unsafe code path performs self-mutation, so we need a const_cast. + // This method needs to be const because it overrides a const method in the parent class. + auto nonConstThis = const_cast<MutablePatternModifier*>(this); + + // Render the affixes to get the length + UErrorCode status = U_ZERO_ERROR; // status fails only with an iilegal argument exception + nonConstThis->prepareAffix(true); + int result = AffixUtils::unescapedCodePointCount(currentAffix, *this, status); // prefix length + nonConstThis->prepareAffix(false); + result += AffixUtils::unescapedCodePointCount(currentAffix, *this, status); // suffix length + return result; +} + +bool MutablePatternModifier::isStrong() const { + return fStrong; +} + +bool MutablePatternModifier::containsField(Field field) const { + (void)field; + // This method is not currently used. + UPRV_UNREACHABLE; +} + +void MutablePatternModifier::getParameters(Parameters& output) const { + (void)output; + // This method is not currently used. + UPRV_UNREACHABLE; +} + +bool MutablePatternModifier::semanticallyEquivalent(const Modifier& other) const { + (void)other; + // This method is not currently used. + UPRV_UNREACHABLE; +} + +int32_t MutablePatternModifier::insertPrefix(FormattedStringBuilder& sb, int position, UErrorCode& status) { + prepareAffix(true); + int32_t length = AffixUtils::unescape(currentAffix, sb, position, *this, fField, status); + return length; +} + +int32_t MutablePatternModifier::insertSuffix(FormattedStringBuilder& sb, int position, UErrorCode& status) { + prepareAffix(false); + int32_t length = AffixUtils::unescape(currentAffix, sb, position, *this, fField, status); + return length; +} + +/** This method contains the heart of the logic for rendering LDML affix strings. */ +void MutablePatternModifier::prepareAffix(bool isPrefix) { + PatternStringUtils::patternInfoToStringBuilder( + *fPatternInfo, + isPrefix, + PatternStringUtils::resolveSignDisplay(fSignDisplay, fSignum), + fPlural, + fPerMilleReplacesPercent, + currentAffix); +} + +UnicodeString MutablePatternModifier::getSymbol(AffixPatternType type) const { + UErrorCode localStatus = U_ZERO_ERROR; + switch (type) { + case AffixPatternType::TYPE_MINUS_SIGN: + return fSymbols->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kMinusSignSymbol); + case AffixPatternType::TYPE_PLUS_SIGN: + return fSymbols->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kPlusSignSymbol); + case AffixPatternType::TYPE_PERCENT: + return fSymbols->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kPercentSymbol); + case AffixPatternType::TYPE_PERMILLE: + return fSymbols->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kPerMillSymbol); + case AffixPatternType::TYPE_CURRENCY_SINGLE: { + // UnitWidth ISO and HIDDEN overrides the singular currency symbol. + if (fUnitWidth == UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE) { + return fCurrencySymbols.getIntlCurrencySymbol(localStatus); + } else if (fUnitWidth == UNumberUnitWidth::UNUM_UNIT_WIDTH_HIDDEN) { + return UnicodeString(); + } else if (fUnitWidth == UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW) { + return fCurrencySymbols.getNarrowCurrencySymbol(localStatus); + } else { + return fCurrencySymbols.getCurrencySymbol(localStatus); + } + } + case AffixPatternType::TYPE_CURRENCY_DOUBLE: + return fCurrencySymbols.getIntlCurrencySymbol(localStatus); + case AffixPatternType::TYPE_CURRENCY_TRIPLE: + // NOTE: This is the code path only for patterns containing "¤¤¤". + // Plural currencies set via the API are formatted in LongNameHandler. + // This code path is used by DecimalFormat via CurrencyPluralInfo. + U_ASSERT(fPlural != StandardPlural::Form::COUNT); + return fCurrencySymbols.getPluralName(fPlural, localStatus); + case AffixPatternType::TYPE_CURRENCY_QUAD: + return UnicodeString(u"\uFFFD"); + case AffixPatternType::TYPE_CURRENCY_QUINT: + return UnicodeString(u"\uFFFD"); + default: + UPRV_UNREACHABLE; + } +} + +UnicodeString MutablePatternModifier::toUnicodeString() const { + // Never called by AffixUtils + UPRV_UNREACHABLE; +} + +#endif /* #if !UCONFIG_NO_FORMATTING */ |