1 /* 2 ******************************************************************************* 3 * Copyright (C) 2015, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ******************************************************************************* 6 */ 7 8 #include "unicode/plurrule.h" 9 #include "unicode/unistr.h" 10 #include "unicode/utypes.h" 11 12 #if !UCONFIG_NO_FORMATTING 13 14 #include "digitformatter.h" 15 #include "digitgrouping.h" 16 #include "digitinterval.h" 17 #include "digitlst.h" 18 #include "precision.h" 19 #include "plurrule_impl.h" 20 #include "smallintformatter.h" 21 #include "uassert.h" 22 #include "valueformatter.h" 23 #include "visibledigits.h" 24 25 U_NAMESPACE_BEGIN 26 27 ValueFormatter::~ValueFormatter() {} 28 29 VisibleDigitsWithExponent & 30 ValueFormatter::toVisibleDigitsWithExponent( 31 int64_t value, 32 VisibleDigitsWithExponent &digits, 33 UErrorCode &status) const { 34 switch (fType) { 35 case kFixedDecimal: 36 return fFixedPrecision->initVisibleDigitsWithExponent( 37 value, digits, status); 38 break; 39 case kScientificNotation: 40 return fScientificPrecision->initVisibleDigitsWithExponent( 41 value, digits, status); 42 break; 43 default: 44 U_ASSERT(FALSE); 45 break; 46 } 47 return digits; 48 } 49 50 VisibleDigitsWithExponent & 51 ValueFormatter::toVisibleDigitsWithExponent( 52 DigitList &value, 53 VisibleDigitsWithExponent &digits, 54 UErrorCode &status) const { 55 switch (fType) { 56 case kFixedDecimal: 57 return fFixedPrecision->initVisibleDigitsWithExponent( 58 value, digits, status); 59 break; 60 case kScientificNotation: 61 return fScientificPrecision->initVisibleDigitsWithExponent( 62 value, digits, status); 63 break; 64 default: 65 U_ASSERT(FALSE); 66 break; 67 } 68 return digits; 69 } 70 71 static UBool isNoGrouping( 72 const DigitGrouping &grouping, 73 int32_t value, 74 const FixedPrecision &precision) { 75 IntDigitCountRange range( 76 precision.fMin.getIntDigitCount(), 77 precision.fMax.getIntDigitCount()); 78 return grouping.isNoGrouping(value, range); 79 } 80 81 UBool 82 ValueFormatter::isFastFormattable(int32_t value) const { 83 switch (fType) { 84 case kFixedDecimal: 85 { 86 if (value == INT32_MIN) { 87 return FALSE; 88 } 89 if (value < 0) { 90 value = -value; 91 } 92 return fFixedPrecision->isFastFormattable() && fFixedOptions->isFastFormattable() && isNoGrouping(*fGrouping, value, *fFixedPrecision); 93 } 94 case kScientificNotation: 95 return FALSE; 96 default: 97 U_ASSERT(FALSE); 98 break; 99 } 100 return FALSE; 101 } 102 103 DigitList & 104 ValueFormatter::round(DigitList &value, UErrorCode &status) const { 105 if (value.isNaN() || value.isInfinite()) { 106 return value; 107 } 108 switch (fType) { 109 case kFixedDecimal: 110 return fFixedPrecision->round(value, 0, status); 111 case kScientificNotation: 112 return fScientificPrecision->round(value, status); 113 default: 114 U_ASSERT(FALSE); 115 break; 116 } 117 return value; 118 } 119 120 UnicodeString & 121 ValueFormatter::formatInt32( 122 int32_t value, 123 FieldPositionHandler &handler, 124 UnicodeString &appendTo) const { 125 switch (fType) { 126 case kFixedDecimal: 127 { 128 IntDigitCountRange range( 129 fFixedPrecision->fMin.getIntDigitCount(), 130 fFixedPrecision->fMax.getIntDigitCount()); 131 return fDigitFormatter->formatPositiveInt32( 132 value, 133 range, 134 handler, 135 appendTo); 136 } 137 break; 138 case kScientificNotation: 139 default: 140 U_ASSERT(FALSE); 141 break; 142 } 143 return appendTo; 144 } 145 146 UnicodeString & 147 ValueFormatter::format( 148 const VisibleDigitsWithExponent &value, 149 FieldPositionHandler &handler, 150 UnicodeString &appendTo) const { 151 switch (fType) { 152 case kFixedDecimal: 153 return fDigitFormatter->format( 154 value.getMantissa(), 155 *fGrouping, 156 *fFixedOptions, 157 handler, 158 appendTo); 159 break; 160 case kScientificNotation: 161 return fDigitFormatter->format( 162 value, 163 *fScientificOptions, 164 handler, 165 appendTo); 166 break; 167 default: 168 U_ASSERT(FALSE); 169 break; 170 } 171 return appendTo; 172 } 173 174 int32_t 175 ValueFormatter::countChar32(const VisibleDigitsWithExponent &value) const { 176 switch (fType) { 177 case kFixedDecimal: 178 return fDigitFormatter->countChar32( 179 value.getMantissa(), 180 *fGrouping, 181 *fFixedOptions); 182 break; 183 case kScientificNotation: 184 return fDigitFormatter->countChar32( 185 value, 186 *fScientificOptions); 187 break; 188 default: 189 U_ASSERT(FALSE); 190 break; 191 } 192 return 0; 193 } 194 195 void 196 ValueFormatter::prepareFixedDecimalFormatting( 197 const DigitFormatter &formatter, 198 const DigitGrouping &grouping, 199 const FixedPrecision &precision, 200 const DigitFormatterOptions &options) { 201 fType = kFixedDecimal; 202 fDigitFormatter = &formatter; 203 fGrouping = &grouping; 204 fFixedPrecision = &precision; 205 fFixedOptions = &options; 206 } 207 208 void 209 ValueFormatter::prepareScientificFormatting( 210 const DigitFormatter &formatter, 211 const ScientificPrecision &precision, 212 const SciFormatterOptions &options) { 213 fType = kScientificNotation; 214 fDigitFormatter = &formatter; 215 fScientificPrecision = &precision; 216 fScientificOptions = &options; 217 } 218 219 U_NAMESPACE_END 220 221 #endif /* !UCONFIG_NO_FORMATTING */ 222