1// © 2016 and later: Unicode, Inc. and others. 2// License & terms of use: http://www.unicode.org/copyright.html 3/* 4 * Copyright (C) 2015, International Business Machines 5 * Corporation and others. All Rights Reserved. 6 * 7 * file name: digitaffixesandpadding.cpp 8 */ 9 10#include "unicode/utypes.h" 11 12#if !UCONFIG_NO_FORMATTING 13 14#include "unicode/plurrule.h" 15#include "charstr.h" 16#include "digitaffix.h" 17#include "digitaffixesandpadding.h" 18#include "digitlst.h" 19#include "uassert.h" 20#include "valueformatter.h" 21#include "visibledigits.h" 22 23U_NAMESPACE_BEGIN 24 25UBool 26DigitAffixesAndPadding::needsPluralRules() const { 27 return ( 28 fPositivePrefix.hasMultipleVariants() || 29 fPositiveSuffix.hasMultipleVariants() || 30 fNegativePrefix.hasMultipleVariants() || 31 fNegativeSuffix.hasMultipleVariants()); 32} 33 34UnicodeString & 35DigitAffixesAndPadding::formatInt32( 36 int32_t value, 37 const ValueFormatter &formatter, 38 FieldPositionHandler &handler, 39 const PluralRules *optPluralRules, 40 UnicodeString &appendTo, 41 UErrorCode &status) const { 42 if (U_FAILURE(status)) { 43 return appendTo; 44 } 45 if (optPluralRules != NULL || fWidth > 0 || !formatter.isFastFormattable(value)) { 46 VisibleDigitsWithExponent digits; 47 formatter.toVisibleDigitsWithExponent( 48 (int64_t) value, digits, status); 49 return format( 50 digits, 51 formatter, 52 handler, 53 optPluralRules, 54 appendTo, 55 status); 56 } 57 UBool bPositive = value >= 0; 58 const DigitAffix *prefix = bPositive ? &fPositivePrefix.getOtherVariant() : &fNegativePrefix.getOtherVariant(); 59 const DigitAffix *suffix = bPositive ? &fPositiveSuffix.getOtherVariant() : &fNegativeSuffix.getOtherVariant(); 60 if (value < 0) { 61 value = -value; 62 } 63 prefix->format(handler, appendTo); 64 formatter.formatInt32(value, handler, appendTo); 65 return suffix->format(handler, appendTo); 66} 67 68static UnicodeString & 69formatAffix( 70 const DigitAffix *affix, 71 FieldPositionHandler &handler, 72 UnicodeString &appendTo) { 73 if (affix) { 74 affix->format(handler, appendTo); 75 } 76 return appendTo; 77} 78 79static int32_t 80countAffixChar32(const DigitAffix *affix) { 81 if (affix) { 82 return affix->countChar32(); 83 } 84 return 0; 85} 86 87UnicodeString & 88DigitAffixesAndPadding::format( 89 const VisibleDigitsWithExponent &digits, 90 const ValueFormatter &formatter, 91 FieldPositionHandler &handler, 92 const PluralRules *optPluralRules, 93 UnicodeString &appendTo, 94 UErrorCode &status) const { 95 if (U_FAILURE(status)) { 96 return appendTo; 97 } 98 const DigitAffix *prefix = NULL; 99 const DigitAffix *suffix = NULL; 100 if (!digits.isNaN()) { 101 UBool bPositive = !digits.isNegative(); 102 const PluralAffix *pluralPrefix = bPositive ? &fPositivePrefix : &fNegativePrefix; 103 const PluralAffix *pluralSuffix = bPositive ? &fPositiveSuffix : &fNegativeSuffix; 104 if (optPluralRules == NULL || digits.isInfinite()) { 105 prefix = &pluralPrefix->getOtherVariant(); 106 suffix = &pluralSuffix->getOtherVariant(); 107 } else { 108 UnicodeString count(optPluralRules->select(digits)); 109 prefix = &pluralPrefix->getByCategory(count); 110 suffix = &pluralSuffix->getByCategory(count); 111 } 112 } 113 if (fWidth <= 0) { 114 formatAffix(prefix, handler, appendTo); 115 formatter.format(digits, handler, appendTo); 116 return formatAffix(suffix, handler, appendTo); 117 } 118 int32_t codePointCount = countAffixChar32(prefix) + formatter.countChar32(digits) + countAffixChar32(suffix); 119 int32_t paddingCount = fWidth - codePointCount; 120 switch (fPadPosition) { 121 case kPadBeforePrefix: 122 appendPadding(paddingCount, appendTo); 123 formatAffix(prefix, handler, appendTo); 124 formatter.format(digits, handler, appendTo); 125 return formatAffix(suffix, handler, appendTo); 126 case kPadAfterPrefix: 127 formatAffix(prefix, handler, appendTo); 128 appendPadding(paddingCount, appendTo); 129 formatter.format(digits, handler, appendTo); 130 return formatAffix(suffix, handler, appendTo); 131 case kPadBeforeSuffix: 132 formatAffix(prefix, handler, appendTo); 133 formatter.format(digits, handler, appendTo); 134 appendPadding(paddingCount, appendTo); 135 return formatAffix(suffix, handler, appendTo); 136 case kPadAfterSuffix: 137 formatAffix(prefix, handler, appendTo); 138 formatter.format(digits, handler, appendTo); 139 formatAffix(suffix, handler, appendTo); 140 return appendPadding(paddingCount, appendTo); 141 default: 142 U_ASSERT(FALSE); 143 return appendTo; 144 } 145} 146 147UnicodeString & 148DigitAffixesAndPadding::format( 149 DigitList &value, 150 const ValueFormatter &formatter, 151 FieldPositionHandler &handler, 152 const PluralRules *optPluralRules, 153 UnicodeString &appendTo, 154 UErrorCode &status) const { 155 VisibleDigitsWithExponent digits; 156 formatter.toVisibleDigitsWithExponent( 157 value, digits, status); 158 if (U_FAILURE(status)) { 159 return appendTo; 160 } 161 return format( 162 digits, formatter, handler, optPluralRules, appendTo, status); 163} 164 165UnicodeString & 166DigitAffixesAndPadding::appendPadding(int32_t paddingCount, UnicodeString &appendTo) const { 167 for (int32_t i = 0; i < paddingCount; ++i) { 168 appendTo.append(fPadChar); 169 } 170 return appendTo; 171} 172 173 174U_NAMESPACE_END 175#endif /* #if !UCONFIG_NO_FORMATTING */ 176