diff options
Diffstat (limited to 'intl/icu/source/i18n/digitaffixesandpadding.cpp')
-rw-r--r-- | intl/icu/source/i18n/digitaffixesandpadding.cpp | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/intl/icu/source/i18n/digitaffixesandpadding.cpp b/intl/icu/source/i18n/digitaffixesandpadding.cpp new file mode 100644 index 000000000..716ab4a32 --- /dev/null +++ b/intl/icu/source/i18n/digitaffixesandpadding.cpp @@ -0,0 +1,175 @@ +// Copyright (C) 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* + * Copyright (C) 2015, International Business Machines + * Corporation and others. All Rights Reserved. + * + * file name: digitaffixesandpadding.cpp + */ + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING + +#include "unicode/plurrule.h" +#include "charstr.h" +#include "digitaffix.h" +#include "digitaffixesandpadding.h" +#include "digitlst.h" +#include "uassert.h" +#include "valueformatter.h" +#include "visibledigits.h" + +U_NAMESPACE_BEGIN + +UBool +DigitAffixesAndPadding::needsPluralRules() const { + return ( + fPositivePrefix.hasMultipleVariants() || + fPositiveSuffix.hasMultipleVariants() || + fNegativePrefix.hasMultipleVariants() || + fNegativeSuffix.hasMultipleVariants()); +} + +UnicodeString & +DigitAffixesAndPadding::formatInt32( + int32_t value, + const ValueFormatter &formatter, + FieldPositionHandler &handler, + const PluralRules *optPluralRules, + UnicodeString &appendTo, + UErrorCode &status) const { + if (U_FAILURE(status)) { + return appendTo; + } + if (optPluralRules != NULL || fWidth > 0 || !formatter.isFastFormattable(value)) { + VisibleDigitsWithExponent digits; + formatter.toVisibleDigitsWithExponent( + (int64_t) value, digits, status); + return format( + digits, + formatter, + handler, + optPluralRules, + appendTo, + status); + } + UBool bPositive = value >= 0; + const DigitAffix *prefix = bPositive ? &fPositivePrefix.getOtherVariant() : &fNegativePrefix.getOtherVariant(); + const DigitAffix *suffix = bPositive ? &fPositiveSuffix.getOtherVariant() : &fNegativeSuffix.getOtherVariant(); + if (value < 0) { + value = -value; + } + prefix->format(handler, appendTo); + formatter.formatInt32(value, handler, appendTo); + return suffix->format(handler, appendTo); +} + +static UnicodeString & +formatAffix( + const DigitAffix *affix, + FieldPositionHandler &handler, + UnicodeString &appendTo) { + if (affix) { + affix->format(handler, appendTo); + } + return appendTo; +} + +static int32_t +countAffixChar32(const DigitAffix *affix) { + if (affix) { + return affix->countChar32(); + } + return 0; +} + +UnicodeString & +DigitAffixesAndPadding::format( + const VisibleDigitsWithExponent &digits, + const ValueFormatter &formatter, + FieldPositionHandler &handler, + const PluralRules *optPluralRules, + UnicodeString &appendTo, + UErrorCode &status) const { + if (U_FAILURE(status)) { + return appendTo; + } + const DigitAffix *prefix = NULL; + const DigitAffix *suffix = NULL; + if (!digits.isNaN()) { + UBool bPositive = !digits.isNegative(); + const PluralAffix *pluralPrefix = bPositive ? &fPositivePrefix : &fNegativePrefix; + const PluralAffix *pluralSuffix = bPositive ? &fPositiveSuffix : &fNegativeSuffix; + if (optPluralRules == NULL || digits.isInfinite()) { + prefix = &pluralPrefix->getOtherVariant(); + suffix = &pluralSuffix->getOtherVariant(); + } else { + UnicodeString count(optPluralRules->select(digits)); + prefix = &pluralPrefix->getByCategory(count); + suffix = &pluralSuffix->getByCategory(count); + } + } + if (fWidth <= 0) { + formatAffix(prefix, handler, appendTo); + formatter.format(digits, handler, appendTo); + return formatAffix(suffix, handler, appendTo); + } + int32_t codePointCount = countAffixChar32(prefix) + formatter.countChar32(digits) + countAffixChar32(suffix); + int32_t paddingCount = fWidth - codePointCount; + switch (fPadPosition) { + case kPadBeforePrefix: + appendPadding(paddingCount, appendTo); + formatAffix(prefix, handler, appendTo); + formatter.format(digits, handler, appendTo); + return formatAffix(suffix, handler, appendTo); + case kPadAfterPrefix: + formatAffix(prefix, handler, appendTo); + appendPadding(paddingCount, appendTo); + formatter.format(digits, handler, appendTo); + return formatAffix(suffix, handler, appendTo); + case kPadBeforeSuffix: + formatAffix(prefix, handler, appendTo); + formatter.format(digits, handler, appendTo); + appendPadding(paddingCount, appendTo); + return formatAffix(suffix, handler, appendTo); + case kPadAfterSuffix: + formatAffix(prefix, handler, appendTo); + formatter.format(digits, handler, appendTo); + formatAffix(suffix, handler, appendTo); + return appendPadding(paddingCount, appendTo); + default: + U_ASSERT(FALSE); + return appendTo; + } +} + +UnicodeString & +DigitAffixesAndPadding::format( + DigitList &value, + const ValueFormatter &formatter, + FieldPositionHandler &handler, + const PluralRules *optPluralRules, + UnicodeString &appendTo, + UErrorCode &status) const { + VisibleDigitsWithExponent digits; + formatter.toVisibleDigitsWithExponent( + value, digits, status); + if (U_FAILURE(status)) { + return appendTo; + } + return format( + digits, formatter, handler, optPluralRules, appendTo, status); +} + +UnicodeString & +DigitAffixesAndPadding::appendPadding(int32_t paddingCount, UnicodeString &appendTo) const { + for (int32_t i = 0; i < paddingCount; ++i) { + appendTo.append(fPadChar); + } + return appendTo; +} + + +U_NAMESPACE_END +#endif /* #if !UCONFIG_NO_FORMATTING */ |