| /* |
| * 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 */ |