OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (C) 2015, International Business Machines |
| 3 * Corporation and others. All Rights Reserved. |
| 4 * |
| 5 * file name: decimfmtimpl.cpp |
| 6 */ |
| 7 |
| 8 #include "unicode/utypes.h" |
| 9 |
| 10 #if !UCONFIG_NO_FORMATTING |
| 11 |
| 12 #include <math.h> |
| 13 #include "unicode/numfmt.h" |
| 14 #include "unicode/plurrule.h" |
| 15 #include "unicode/ustring.h" |
| 16 #include "decimalformatpattern.h" |
| 17 #include "decimalformatpatternimpl.h" |
| 18 #include "decimfmtimpl.h" |
| 19 #include "fphdlimp.h" |
| 20 #include "plurrule_impl.h" |
| 21 #include "valueformatter.h" |
| 22 #include "visibledigits.h" |
| 23 |
| 24 U_NAMESPACE_BEGIN |
| 25 |
| 26 static const int32_t kMaxScientificIntegerDigits = 8; |
| 27 |
| 28 static const int32_t kFormattingPosPrefix = (1 << 0); |
| 29 static const int32_t kFormattingNegPrefix = (1 << 1); |
| 30 static const int32_t kFormattingPosSuffix = (1 << 2); |
| 31 static const int32_t kFormattingNegSuffix = (1 << 3); |
| 32 static const int32_t kFormattingSymbols = (1 << 4); |
| 33 static const int32_t kFormattingCurrency = (1 << 5); |
| 34 static const int32_t kFormattingUsesCurrency = (1 << 6); |
| 35 static const int32_t kFormattingPluralRules = (1 << 7); |
| 36 static const int32_t kFormattingAffixParser = (1 << 8); |
| 37 static const int32_t kFormattingCurrencyAffixInfo = (1 << 9); |
| 38 static const int32_t kFormattingAll = (1 << 10) - 1; |
| 39 static const int32_t kFormattingAffixes = |
| 40 kFormattingPosPrefix | kFormattingPosSuffix | |
| 41 kFormattingNegPrefix | kFormattingNegSuffix; |
| 42 static const int32_t kFormattingAffixParserWithCurrency = |
| 43 kFormattingAffixParser | kFormattingCurrencyAffixInfo; |
| 44 |
| 45 DecimalFormatImpl::DecimalFormatImpl( |
| 46 NumberFormat *super, |
| 47 const Locale &locale, |
| 48 const UnicodeString &pattern, |
| 49 UErrorCode &status) |
| 50 : fSuper(super), |
| 51 fScale(0), |
| 52 fRoundingMode(DecimalFormat::kRoundHalfEven), |
| 53 fSymbols(NULL), |
| 54 fCurrencyUsage(UCURR_USAGE_STANDARD), |
| 55 fRules(NULL), |
| 56 fMonetary(FALSE) { |
| 57 if (U_FAILURE(status)) { |
| 58 return; |
| 59 } |
| 60 fSymbols = new DecimalFormatSymbols( |
| 61 locale, status); |
| 62 if (fSymbols == NULL) { |
| 63 status = U_MEMORY_ALLOCATION_ERROR; |
| 64 return; |
| 65 } |
| 66 UParseError parseError; |
| 67 applyPattern(pattern, FALSE, parseError, status); |
| 68 updateAll(status); |
| 69 } |
| 70 |
| 71 DecimalFormatImpl::DecimalFormatImpl( |
| 72 NumberFormat *super, |
| 73 const UnicodeString &pattern, |
| 74 DecimalFormatSymbols *symbolsToAdopt, |
| 75 UParseError &parseError, |
| 76 UErrorCode &status) |
| 77 : fSuper(super), |
| 78 fScale(0), |
| 79 fRoundingMode(DecimalFormat::kRoundHalfEven), |
| 80 fSymbols(symbolsToAdopt), |
| 81 fCurrencyUsage(UCURR_USAGE_STANDARD), |
| 82 fRules(NULL), |
| 83 fMonetary(FALSE) { |
| 84 applyPattern(pattern, FALSE, parseError, status); |
| 85 updateAll(status); |
| 86 } |
| 87 |
| 88 DecimalFormatImpl::DecimalFormatImpl( |
| 89 NumberFormat *super, const DecimalFormatImpl &other, UErrorCode &status) : |
| 90 fSuper(super), |
| 91 fMultiplier(other.fMultiplier), |
| 92 fScale(other.fScale), |
| 93 fRoundingMode(other.fRoundingMode), |
| 94 fMinSigDigits(other.fMinSigDigits), |
| 95 fMaxSigDigits(other.fMaxSigDigits), |
| 96 fUseScientific(other.fUseScientific), |
| 97 fUseSigDigits(other.fUseSigDigits), |
| 98 fGrouping(other.fGrouping), |
| 99 fPositivePrefixPattern(other.fPositivePrefixPattern), |
| 100 fNegativePrefixPattern(other.fNegativePrefixPattern), |
| 101 fPositiveSuffixPattern(other.fPositiveSuffixPattern), |
| 102 fNegativeSuffixPattern(other.fNegativeSuffixPattern), |
| 103 fSymbols(other.fSymbols), |
| 104 fCurrencyUsage(other.fCurrencyUsage), |
| 105 fRules(NULL), |
| 106 fMonetary(other.fMonetary), |
| 107 fAffixParser(other.fAffixParser), |
| 108 fCurrencyAffixInfo(other.fCurrencyAffixInfo), |
| 109 fEffPrecision(other.fEffPrecision), |
| 110 fEffGrouping(other.fEffGrouping), |
| 111 fOptions(other.fOptions), |
| 112 fFormatter(other.fFormatter), |
| 113 fAffixes(other.fAffixes) { |
| 114 fSymbols = new DecimalFormatSymbols(*fSymbols); |
| 115 if (fSymbols == NULL && U_SUCCESS(status)) { |
| 116 status = U_MEMORY_ALLOCATION_ERROR; |
| 117 } |
| 118 if (other.fRules != NULL) { |
| 119 fRules = new PluralRules(*other.fRules); |
| 120 if (fRules == NULL && U_SUCCESS(status)) { |
| 121 status = U_MEMORY_ALLOCATION_ERROR; |
| 122 } |
| 123 } |
| 124 } |
| 125 |
| 126 |
| 127 DecimalFormatImpl & |
| 128 DecimalFormatImpl::assign(const DecimalFormatImpl &other, UErrorCode &status) { |
| 129 if (U_FAILURE(status) || this == &other) { |
| 130 return (*this); |
| 131 } |
| 132 UObject::operator=(other); |
| 133 fMultiplier = other.fMultiplier; |
| 134 fScale = other.fScale; |
| 135 fRoundingMode = other.fRoundingMode; |
| 136 fMinSigDigits = other.fMinSigDigits; |
| 137 fMaxSigDigits = other.fMaxSigDigits; |
| 138 fUseScientific = other.fUseScientific; |
| 139 fUseSigDigits = other.fUseSigDigits; |
| 140 fGrouping = other.fGrouping; |
| 141 fPositivePrefixPattern = other.fPositivePrefixPattern; |
| 142 fNegativePrefixPattern = other.fNegativePrefixPattern; |
| 143 fPositiveSuffixPattern = other.fPositiveSuffixPattern; |
| 144 fNegativeSuffixPattern = other.fNegativeSuffixPattern; |
| 145 fCurrencyUsage = other.fCurrencyUsage; |
| 146 fMonetary = other.fMonetary; |
| 147 fAffixParser = other.fAffixParser; |
| 148 fCurrencyAffixInfo = other.fCurrencyAffixInfo; |
| 149 fEffPrecision = other.fEffPrecision; |
| 150 fEffGrouping = other.fEffGrouping; |
| 151 fOptions = other.fOptions; |
| 152 fFormatter = other.fFormatter; |
| 153 fAffixes = other.fAffixes; |
| 154 *fSymbols = *other.fSymbols; |
| 155 if (fRules != NULL && other.fRules != NULL) { |
| 156 *fRules = *other.fRules; |
| 157 } else { |
| 158 delete fRules; |
| 159 fRules = other.fRules; |
| 160 if (fRules != NULL) { |
| 161 fRules = new PluralRules(*fRules); |
| 162 if (fRules == NULL) { |
| 163 status = U_MEMORY_ALLOCATION_ERROR; |
| 164 return *this; |
| 165 } |
| 166 } |
| 167 } |
| 168 return *this; |
| 169 } |
| 170 |
| 171 UBool |
| 172 DecimalFormatImpl::operator==(const DecimalFormatImpl &other) const { |
| 173 if (this == &other) { |
| 174 return TRUE; |
| 175 } |
| 176 return (fMultiplier == other.fMultiplier) |
| 177 && (fScale == other.fScale) |
| 178 && (fRoundingMode == other.fRoundingMode) |
| 179 && (fMinSigDigits == other.fMinSigDigits) |
| 180 && (fMaxSigDigits == other.fMaxSigDigits) |
| 181 && (fUseScientific == other.fUseScientific) |
| 182 && (fUseSigDigits == other.fUseSigDigits) |
| 183 && fGrouping.equals(other.fGrouping) |
| 184 && fPositivePrefixPattern.equals(other.fPositivePrefixPattern) |
| 185 && fNegativePrefixPattern.equals(other.fNegativePrefixPattern) |
| 186 && fPositiveSuffixPattern.equals(other.fPositiveSuffixPattern) |
| 187 && fNegativeSuffixPattern.equals(other.fNegativeSuffixPattern) |
| 188 && fCurrencyUsage == other.fCurrencyUsage |
| 189 && fAffixParser.equals(other.fAffixParser) |
| 190 && fCurrencyAffixInfo.equals(other.fCurrencyAffixInfo) |
| 191 && fEffPrecision.equals(other.fEffPrecision) |
| 192 && fEffGrouping.equals(other.fEffGrouping) |
| 193 && fOptions.equals(other.fOptions) |
| 194 && fFormatter.equals(other.fFormatter) |
| 195 && fAffixes.equals(other.fAffixes) |
| 196 && (*fSymbols == *other.fSymbols) |
| 197 && ((fRules == other.fRules) || ( |
| 198 (fRules != NULL) && (other.fRules != NULL) |
| 199 && (*fRules == *other.fRules))) |
| 200 && (fMonetary == other.fMonetary); |
| 201 } |
| 202 |
| 203 DecimalFormatImpl::~DecimalFormatImpl() { |
| 204 delete fSymbols; |
| 205 delete fRules; |
| 206 } |
| 207 |
| 208 ValueFormatter & |
| 209 DecimalFormatImpl::prepareValueFormatter(ValueFormatter &vf) const { |
| 210 if (fUseScientific) { |
| 211 vf.prepareScientificFormatting( |
| 212 fFormatter, fEffPrecision, fOptions); |
| 213 return vf; |
| 214 } |
| 215 vf.prepareFixedDecimalFormatting( |
| 216 fFormatter, fEffGrouping, fEffPrecision.fMantissa, fOptions.fMantiss
a); |
| 217 return vf; |
| 218 } |
| 219 |
| 220 int32_t |
| 221 DecimalFormatImpl::getPatternScale() const { |
| 222 UBool usesPercent = fPositivePrefixPattern.usesPercent() || |
| 223 fPositiveSuffixPattern.usesPercent() || |
| 224 fNegativePrefixPattern.usesPercent() || |
| 225 fNegativeSuffixPattern.usesPercent(); |
| 226 if (usesPercent) { |
| 227 return 2; |
| 228 } |
| 229 UBool usesPermill = fPositivePrefixPattern.usesPermill() || |
| 230 fPositiveSuffixPattern.usesPermill() || |
| 231 fNegativePrefixPattern.usesPermill() || |
| 232 fNegativeSuffixPattern.usesPermill(); |
| 233 if (usesPermill) { |
| 234 return 3; |
| 235 } |
| 236 return 0; |
| 237 } |
| 238 |
| 239 void |
| 240 DecimalFormatImpl::setMultiplierScale(int32_t scale) { |
| 241 if (scale == 0) { |
| 242 // Needed to preserve equality. fMultiplier == 0 means |
| 243 // multiplier is 1. |
| 244 fMultiplier.set(0); |
| 245 } else { |
| 246 fMultiplier.set(1); |
| 247 fMultiplier.shiftDecimalRight(scale); |
| 248 } |
| 249 } |
| 250 |
| 251 UnicodeString & |
| 252 DecimalFormatImpl::format( |
| 253 int32_t number, |
| 254 UnicodeString &appendTo, |
| 255 FieldPosition &pos, |
| 256 UErrorCode &status) const { |
| 257 FieldPositionOnlyHandler handler(pos); |
| 258 return formatInt32(number, appendTo, handler, status); |
| 259 } |
| 260 |
| 261 UnicodeString & |
| 262 DecimalFormatImpl::format( |
| 263 int32_t number, |
| 264 UnicodeString &appendTo, |
| 265 FieldPositionIterator *posIter, |
| 266 UErrorCode &status) const { |
| 267 FieldPositionIteratorHandler handler(posIter, status); |
| 268 return formatInt32(number, appendTo, handler, status); |
| 269 } |
| 270 |
| 271 template<class T> |
| 272 UBool DecimalFormatImpl::maybeFormatWithDigitList( |
| 273 T number, |
| 274 UnicodeString &appendTo, |
| 275 FieldPositionHandler &handler, |
| 276 UErrorCode &status) const { |
| 277 if (!fMultiplier.isZero()) { |
| 278 DigitList digits; |
| 279 digits.set(number); |
| 280 digits.mult(fMultiplier, status); |
| 281 digits.shiftDecimalRight(fScale); |
| 282 formatAdjustedDigitList(digits, appendTo, handler, status); |
| 283 return TRUE; |
| 284 } |
| 285 if (fScale != 0) { |
| 286 DigitList digits; |
| 287 digits.set(number); |
| 288 digits.shiftDecimalRight(fScale); |
| 289 formatAdjustedDigitList(digits, appendTo, handler, status); |
| 290 return TRUE; |
| 291 } |
| 292 return FALSE; |
| 293 } |
| 294 |
| 295 template<class T> |
| 296 UBool DecimalFormatImpl::maybeInitVisibleDigitsFromDigitList( |
| 297 T number, |
| 298 VisibleDigitsWithExponent &visibleDigits, |
| 299 UErrorCode &status) const { |
| 300 if (!fMultiplier.isZero()) { |
| 301 DigitList digits; |
| 302 digits.set(number); |
| 303 digits.mult(fMultiplier, status); |
| 304 digits.shiftDecimalRight(fScale); |
| 305 initVisibleDigitsFromAdjusted(digits, visibleDigits, status); |
| 306 return TRUE; |
| 307 } |
| 308 if (fScale != 0) { |
| 309 DigitList digits; |
| 310 digits.set(number); |
| 311 digits.shiftDecimalRight(fScale); |
| 312 initVisibleDigitsFromAdjusted(digits, visibleDigits, status); |
| 313 return TRUE; |
| 314 } |
| 315 return FALSE; |
| 316 } |
| 317 |
| 318 UnicodeString & |
| 319 DecimalFormatImpl::formatInt32( |
| 320 int32_t number, |
| 321 UnicodeString &appendTo, |
| 322 FieldPositionHandler &handler, |
| 323 UErrorCode &status) const { |
| 324 if (maybeFormatWithDigitList(number, appendTo, handler, status)) { |
| 325 return appendTo; |
| 326 } |
| 327 ValueFormatter vf; |
| 328 return fAffixes.formatInt32( |
| 329 number, |
| 330 prepareValueFormatter(vf), |
| 331 handler, |
| 332 fRules, |
| 333 appendTo, |
| 334 status); |
| 335 } |
| 336 |
| 337 UnicodeString & |
| 338 DecimalFormatImpl::formatInt64( |
| 339 int64_t number, |
| 340 UnicodeString &appendTo, |
| 341 FieldPositionHandler &handler, |
| 342 UErrorCode &status) const { |
| 343 if (number >= INT32_MIN && number <= INT32_MAX) { |
| 344 return formatInt32((int32_t) number, appendTo, handler, status); |
| 345 } |
| 346 VisibleDigitsWithExponent digits; |
| 347 initVisibleDigitsWithExponent(number, digits, status); |
| 348 return formatVisibleDigitsWithExponent( |
| 349 digits, appendTo, handler, status); |
| 350 } |
| 351 |
| 352 UnicodeString & |
| 353 DecimalFormatImpl::formatDouble( |
| 354 double number, |
| 355 UnicodeString &appendTo, |
| 356 FieldPositionHandler &handler, |
| 357 UErrorCode &status) const { |
| 358 VisibleDigitsWithExponent digits; |
| 359 initVisibleDigitsWithExponent(number, digits, status); |
| 360 return formatVisibleDigitsWithExponent( |
| 361 digits, appendTo, handler, status); |
| 362 } |
| 363 |
| 364 UnicodeString & |
| 365 DecimalFormatImpl::format( |
| 366 double number, |
| 367 UnicodeString &appendTo, |
| 368 FieldPosition &pos, |
| 369 UErrorCode &status) const { |
| 370 FieldPositionOnlyHandler handler(pos); |
| 371 return formatDouble(number, appendTo, handler, status); |
| 372 } |
| 373 |
| 374 UnicodeString & |
| 375 DecimalFormatImpl::format( |
| 376 const DigitList &number, |
| 377 UnicodeString &appendTo, |
| 378 FieldPosition &pos, |
| 379 UErrorCode &status) const { |
| 380 DigitList dl(number); |
| 381 FieldPositionOnlyHandler handler(pos); |
| 382 return formatDigitList(dl, appendTo, handler, status); |
| 383 } |
| 384 |
| 385 UnicodeString & |
| 386 DecimalFormatImpl::format( |
| 387 int64_t number, |
| 388 UnicodeString &appendTo, |
| 389 FieldPosition &pos, |
| 390 UErrorCode &status) const { |
| 391 FieldPositionOnlyHandler handler(pos); |
| 392 return formatInt64(number, appendTo, handler, status); |
| 393 } |
| 394 |
| 395 UnicodeString & |
| 396 DecimalFormatImpl::format( |
| 397 int64_t number, |
| 398 UnicodeString &appendTo, |
| 399 FieldPositionIterator *posIter, |
| 400 UErrorCode &status) const { |
| 401 FieldPositionIteratorHandler handler(posIter, status); |
| 402 return formatInt64(number, appendTo, handler, status); |
| 403 } |
| 404 |
| 405 UnicodeString & |
| 406 DecimalFormatImpl::format( |
| 407 double number, |
| 408 UnicodeString &appendTo, |
| 409 FieldPositionIterator *posIter, |
| 410 UErrorCode &status) const { |
| 411 FieldPositionIteratorHandler handler(posIter, status); |
| 412 return formatDouble(number, appendTo, handler, status); |
| 413 } |
| 414 |
| 415 UnicodeString & |
| 416 DecimalFormatImpl::format( |
| 417 const DigitList &number, |
| 418 UnicodeString &appendTo, |
| 419 FieldPositionIterator *posIter, |
| 420 UErrorCode &status) const { |
| 421 DigitList dl(number); |
| 422 FieldPositionIteratorHandler handler(posIter, status); |
| 423 return formatDigitList(dl, appendTo, handler, status); |
| 424 } |
| 425 |
| 426 UnicodeString & |
| 427 DecimalFormatImpl::format( |
| 428 const StringPiece &number, |
| 429 UnicodeString &appendTo, |
| 430 FieldPositionIterator *posIter, |
| 431 UErrorCode &status) const { |
| 432 DigitList dl; |
| 433 dl.set(number, status); |
| 434 FieldPositionIteratorHandler handler(posIter, status); |
| 435 return formatDigitList(dl, appendTo, handler, status); |
| 436 } |
| 437 |
| 438 UnicodeString & |
| 439 DecimalFormatImpl::format( |
| 440 const VisibleDigitsWithExponent &digits, |
| 441 UnicodeString &appendTo, |
| 442 FieldPosition &pos, |
| 443 UErrorCode &status) const { |
| 444 FieldPositionOnlyHandler handler(pos); |
| 445 return formatVisibleDigitsWithExponent( |
| 446 digits, appendTo, handler, status); |
| 447 } |
| 448 |
| 449 UnicodeString & |
| 450 DecimalFormatImpl::format( |
| 451 const VisibleDigitsWithExponent &digits, |
| 452 UnicodeString &appendTo, |
| 453 FieldPositionIterator *posIter, |
| 454 UErrorCode &status) const { |
| 455 FieldPositionIteratorHandler handler(posIter, status); |
| 456 return formatVisibleDigitsWithExponent( |
| 457 digits, appendTo, handler, status); |
| 458 } |
| 459 |
| 460 DigitList & |
| 461 DecimalFormatImpl::adjustDigitList( |
| 462 DigitList &number, UErrorCode &status) const { |
| 463 number.setRoundingMode(fRoundingMode); |
| 464 if (!fMultiplier.isZero()) { |
| 465 number.mult(fMultiplier, status); |
| 466 } |
| 467 if (fScale != 0) { |
| 468 number.shiftDecimalRight(fScale); |
| 469 } |
| 470 number.reduce(); |
| 471 return number; |
| 472 } |
| 473 |
| 474 UnicodeString & |
| 475 DecimalFormatImpl::formatDigitList( |
| 476 DigitList &number, |
| 477 UnicodeString &appendTo, |
| 478 FieldPositionHandler &handler, |
| 479 UErrorCode &status) const { |
| 480 VisibleDigitsWithExponent digits; |
| 481 initVisibleDigitsWithExponent(number, digits, status); |
| 482 return formatVisibleDigitsWithExponent( |
| 483 digits, appendTo, handler, status); |
| 484 } |
| 485 |
| 486 UnicodeString & |
| 487 DecimalFormatImpl::formatAdjustedDigitList( |
| 488 DigitList &number, |
| 489 UnicodeString &appendTo, |
| 490 FieldPositionHandler &handler, |
| 491 UErrorCode &status) const { |
| 492 ValueFormatter vf; |
| 493 return fAffixes.format( |
| 494 number, |
| 495 prepareValueFormatter(vf), |
| 496 handler, |
| 497 fRules, |
| 498 appendTo, |
| 499 status); |
| 500 } |
| 501 |
| 502 UnicodeString & |
| 503 DecimalFormatImpl::formatVisibleDigitsWithExponent( |
| 504 const VisibleDigitsWithExponent &digits, |
| 505 UnicodeString &appendTo, |
| 506 FieldPositionHandler &handler, |
| 507 UErrorCode &status) const { |
| 508 ValueFormatter vf; |
| 509 return fAffixes.format( |
| 510 digits, |
| 511 prepareValueFormatter(vf), |
| 512 handler, |
| 513 fRules, |
| 514 appendTo, |
| 515 status); |
| 516 } |
| 517 |
| 518 static FixedDecimal &initFixedDecimal( |
| 519 const VisibleDigits &digits, FixedDecimal &result) { |
| 520 result.source = 0.0; |
| 521 result.isNegative = digits.isNegative(); |
| 522 result.isNanOrInfinity = digits.isNaNOrInfinity(); |
| 523 digits.getFixedDecimal( |
| 524 result.source, result.intValue, result.decimalDigits, |
| 525 result.decimalDigitsWithoutTrailingZeros, |
| 526 result.visibleDecimalDigitCount, result.hasIntegerValue); |
| 527 return result; |
| 528 } |
| 529 |
| 530 FixedDecimal & |
| 531 DecimalFormatImpl::getFixedDecimal(double number, FixedDecimal &result, UErrorCo
de &status) const { |
| 532 if (U_FAILURE(status)) { |
| 533 return result; |
| 534 } |
| 535 VisibleDigits digits; |
| 536 fEffPrecision.fMantissa.initVisibleDigits(number, digits, status); |
| 537 return initFixedDecimal(digits, result); |
| 538 } |
| 539 |
| 540 FixedDecimal & |
| 541 DecimalFormatImpl::getFixedDecimal( |
| 542 DigitList &number, FixedDecimal &result, UErrorCode &status) const { |
| 543 if (U_FAILURE(status)) { |
| 544 return result; |
| 545 } |
| 546 VisibleDigits digits; |
| 547 fEffPrecision.fMantissa.initVisibleDigits(number, digits, status); |
| 548 return initFixedDecimal(digits, result); |
| 549 } |
| 550 |
| 551 VisibleDigitsWithExponent & |
| 552 DecimalFormatImpl::initVisibleDigitsWithExponent( |
| 553 int64_t number, |
| 554 VisibleDigitsWithExponent &digits, |
| 555 UErrorCode &status) const { |
| 556 if (maybeInitVisibleDigitsFromDigitList( |
| 557 number, digits, status)) { |
| 558 return digits; |
| 559 } |
| 560 if (fUseScientific) { |
| 561 fEffPrecision.initVisibleDigitsWithExponent( |
| 562 number, digits, status); |
| 563 } else { |
| 564 fEffPrecision.fMantissa.initVisibleDigitsWithExponent( |
| 565 number, digits, status); |
| 566 } |
| 567 return digits; |
| 568 } |
| 569 |
| 570 VisibleDigitsWithExponent & |
| 571 DecimalFormatImpl::initVisibleDigitsWithExponent( |
| 572 double number, |
| 573 VisibleDigitsWithExponent &digits, |
| 574 UErrorCode &status) const { |
| 575 if (maybeInitVisibleDigitsFromDigitList( |
| 576 number, digits, status)) { |
| 577 return digits; |
| 578 } |
| 579 if (fUseScientific) { |
| 580 fEffPrecision.initVisibleDigitsWithExponent( |
| 581 number, digits, status); |
| 582 } else { |
| 583 fEffPrecision.fMantissa.initVisibleDigitsWithExponent( |
| 584 number, digits, status); |
| 585 } |
| 586 return digits; |
| 587 } |
| 588 |
| 589 VisibleDigitsWithExponent & |
| 590 DecimalFormatImpl::initVisibleDigitsWithExponent( |
| 591 DigitList &number, |
| 592 VisibleDigitsWithExponent &digits, |
| 593 UErrorCode &status) const { |
| 594 adjustDigitList(number, status); |
| 595 return initVisibleDigitsFromAdjusted(number, digits, status); |
| 596 } |
| 597 |
| 598 VisibleDigitsWithExponent & |
| 599 DecimalFormatImpl::initVisibleDigitsFromAdjusted( |
| 600 DigitList &number, |
| 601 VisibleDigitsWithExponent &digits, |
| 602 UErrorCode &status) const { |
| 603 if (fUseScientific) { |
| 604 fEffPrecision.initVisibleDigitsWithExponent( |
| 605 number, digits, status); |
| 606 } else { |
| 607 fEffPrecision.fMantissa.initVisibleDigitsWithExponent( |
| 608 number, digits, status); |
| 609 } |
| 610 return digits; |
| 611 } |
| 612 |
| 613 DigitList & |
| 614 DecimalFormatImpl::round( |
| 615 DigitList &number, UErrorCode &status) const { |
| 616 if (number.isNaN() || number.isInfinite()) { |
| 617 return number; |
| 618 } |
| 619 adjustDigitList(number, status); |
| 620 ValueFormatter vf; |
| 621 prepareValueFormatter(vf); |
| 622 return vf.round(number, status); |
| 623 } |
| 624 |
| 625 void |
| 626 DecimalFormatImpl::setMinimumSignificantDigits(int32_t newValue) { |
| 627 fMinSigDigits = newValue; |
| 628 fUseSigDigits = TRUE; // ticket 9936 |
| 629 updatePrecision(); |
| 630 } |
| 631 |
| 632 void |
| 633 DecimalFormatImpl::setMaximumSignificantDigits(int32_t newValue) { |
| 634 fMaxSigDigits = newValue; |
| 635 fUseSigDigits = TRUE; // ticket 9936 |
| 636 updatePrecision(); |
| 637 } |
| 638 |
| 639 void |
| 640 DecimalFormatImpl::setMinMaxSignificantDigits(int32_t min, int32_t max) { |
| 641 fMinSigDigits = min; |
| 642 fMaxSigDigits = max; |
| 643 fUseSigDigits = TRUE; // ticket 9936 |
| 644 updatePrecision(); |
| 645 } |
| 646 |
| 647 void |
| 648 DecimalFormatImpl::setScientificNotation(UBool newValue) { |
| 649 fUseScientific = newValue; |
| 650 updatePrecision(); |
| 651 } |
| 652 |
| 653 void |
| 654 DecimalFormatImpl::setSignificantDigitsUsed(UBool newValue) { |
| 655 fUseSigDigits = newValue; |
| 656 updatePrecision(); |
| 657 } |
| 658 |
| 659 void |
| 660 DecimalFormatImpl::setGroupingSize(int32_t newValue) { |
| 661 fGrouping.fGrouping = newValue; |
| 662 updateGrouping(); |
| 663 } |
| 664 |
| 665 void |
| 666 DecimalFormatImpl::setSecondaryGroupingSize(int32_t newValue) { |
| 667 fGrouping.fGrouping2 = newValue; |
| 668 updateGrouping(); |
| 669 } |
| 670 |
| 671 void |
| 672 DecimalFormatImpl::setMinimumGroupingDigits(int32_t newValue) { |
| 673 fGrouping.fMinGrouping = newValue; |
| 674 updateGrouping(); |
| 675 } |
| 676 |
| 677 void |
| 678 DecimalFormatImpl::setCurrencyUsage( |
| 679 UCurrencyUsage currencyUsage, UErrorCode &status) { |
| 680 fCurrencyUsage = currencyUsage; |
| 681 updateFormatting(kFormattingCurrency, status); |
| 682 } |
| 683 |
| 684 void |
| 685 DecimalFormatImpl::setRoundingIncrement(double d) { |
| 686 if (d > 0.0) { |
| 687 fEffPrecision.fMantissa.fRoundingIncrement.set(d); |
| 688 } else { |
| 689 fEffPrecision.fMantissa.fRoundingIncrement.set(0.0); |
| 690 } |
| 691 } |
| 692 |
| 693 double |
| 694 DecimalFormatImpl::getRoundingIncrement() const { |
| 695 return fEffPrecision.fMantissa.fRoundingIncrement.getDouble(); |
| 696 } |
| 697 |
| 698 int32_t |
| 699 DecimalFormatImpl::getMultiplier() const { |
| 700 if (fMultiplier.isZero()) { |
| 701 return 1; |
| 702 } |
| 703 return (int32_t) fMultiplier.getDouble(); |
| 704 } |
| 705 |
| 706 void |
| 707 DecimalFormatImpl::setMultiplier(int32_t m) { |
| 708 if (m == 0 || m == 1) { |
| 709 fMultiplier.set(0); |
| 710 } else { |
| 711 fMultiplier.set(m); |
| 712 } |
| 713 } |
| 714 |
| 715 void |
| 716 DecimalFormatImpl::setPositivePrefix(const UnicodeString &str) { |
| 717 fPositivePrefixPattern.remove(); |
| 718 fPositivePrefixPattern.addLiteral(str.getBuffer(), 0, str.length()); |
| 719 UErrorCode status = U_ZERO_ERROR; |
| 720 updateFormatting(kFormattingPosPrefix, status); |
| 721 } |
| 722 |
| 723 void |
| 724 DecimalFormatImpl::setPositiveSuffix(const UnicodeString &str) { |
| 725 fPositiveSuffixPattern.remove(); |
| 726 fPositiveSuffixPattern.addLiteral(str.getBuffer(), 0, str.length()); |
| 727 UErrorCode status = U_ZERO_ERROR; |
| 728 updateFormatting(kFormattingPosSuffix, status); |
| 729 } |
| 730 |
| 731 void |
| 732 DecimalFormatImpl::setNegativePrefix(const UnicodeString &str) { |
| 733 fNegativePrefixPattern.remove(); |
| 734 fNegativePrefixPattern.addLiteral(str.getBuffer(), 0, str.length()); |
| 735 UErrorCode status = U_ZERO_ERROR; |
| 736 updateFormatting(kFormattingNegPrefix, status); |
| 737 } |
| 738 |
| 739 void |
| 740 DecimalFormatImpl::setNegativeSuffix(const UnicodeString &str) { |
| 741 fNegativeSuffixPattern.remove(); |
| 742 fNegativeSuffixPattern.addLiteral(str.getBuffer(), 0, str.length()); |
| 743 UErrorCode status = U_ZERO_ERROR; |
| 744 updateFormatting(kFormattingNegSuffix, status); |
| 745 } |
| 746 |
| 747 UnicodeString & |
| 748 DecimalFormatImpl::getPositivePrefix(UnicodeString &result) const { |
| 749 result = fAffixes.fPositivePrefix.getOtherVariant().toString(); |
| 750 return result; |
| 751 } |
| 752 |
| 753 UnicodeString & |
| 754 DecimalFormatImpl::getPositiveSuffix(UnicodeString &result) const { |
| 755 result = fAffixes.fPositiveSuffix.getOtherVariant().toString(); |
| 756 return result; |
| 757 } |
| 758 |
| 759 UnicodeString & |
| 760 DecimalFormatImpl::getNegativePrefix(UnicodeString &result) const { |
| 761 result = fAffixes.fNegativePrefix.getOtherVariant().toString(); |
| 762 return result; |
| 763 } |
| 764 |
| 765 UnicodeString & |
| 766 DecimalFormatImpl::getNegativeSuffix(UnicodeString &result) const { |
| 767 result = fAffixes.fNegativeSuffix.getOtherVariant().toString(); |
| 768 return result; |
| 769 } |
| 770 |
| 771 void |
| 772 DecimalFormatImpl::adoptDecimalFormatSymbols(DecimalFormatSymbols *symbolsToAdop
t) { |
| 773 if (symbolsToAdopt == NULL) { |
| 774 return; |
| 775 } |
| 776 delete fSymbols; |
| 777 fSymbols = symbolsToAdopt; |
| 778 UErrorCode status = U_ZERO_ERROR; |
| 779 updateFormatting(kFormattingSymbols, status); |
| 780 } |
| 781 |
| 782 void |
| 783 DecimalFormatImpl::applyPatternFavorCurrencyPrecision( |
| 784 const UnicodeString &pattern, UErrorCode &status) { |
| 785 UParseError perror; |
| 786 applyPattern(pattern, FALSE, perror, status); |
| 787 updateForApplyPatternFavorCurrencyPrecision(status); |
| 788 } |
| 789 |
| 790 void |
| 791 DecimalFormatImpl::applyPattern( |
| 792 const UnicodeString &pattern, UErrorCode &status) { |
| 793 UParseError perror; |
| 794 applyPattern(pattern, FALSE, perror, status); |
| 795 updateForApplyPattern(status); |
| 796 } |
| 797 |
| 798 void |
| 799 DecimalFormatImpl::applyPattern( |
| 800 const UnicodeString &pattern, |
| 801 UParseError &perror, UErrorCode &status) { |
| 802 applyPattern(pattern, FALSE, perror, status); |
| 803 updateForApplyPattern(status); |
| 804 } |
| 805 |
| 806 void |
| 807 DecimalFormatImpl::applyLocalizedPattern( |
| 808 const UnicodeString &pattern, UErrorCode &status) { |
| 809 UParseError perror; |
| 810 applyPattern(pattern, TRUE, perror, status); |
| 811 updateForApplyPattern(status); |
| 812 } |
| 813 |
| 814 void |
| 815 DecimalFormatImpl::applyLocalizedPattern( |
| 816 const UnicodeString &pattern, |
| 817 UParseError &perror, UErrorCode &status) { |
| 818 applyPattern(pattern, TRUE, perror, status); |
| 819 updateForApplyPattern(status); |
| 820 } |
| 821 |
| 822 void |
| 823 DecimalFormatImpl::applyPattern( |
| 824 const UnicodeString &pattern, |
| 825 UBool localized, UParseError &perror, UErrorCode &status) { |
| 826 if (U_FAILURE(status)) { |
| 827 return; |
| 828 } |
| 829 DecimalFormatPatternParser patternParser; |
| 830 if (localized) { |
| 831 patternParser.useSymbols(*fSymbols); |
| 832 } |
| 833 DecimalFormatPattern out; |
| 834 patternParser.applyPatternWithoutExpandAffix( |
| 835 pattern, out, perror, status); |
| 836 if (U_FAILURE(status)) { |
| 837 return; |
| 838 } |
| 839 fUseScientific = out.fUseExponentialNotation; |
| 840 fUseSigDigits = out.fUseSignificantDigits; |
| 841 fSuper->NumberFormat::setMinimumIntegerDigits(out.fMinimumIntegerDigits); |
| 842 fSuper->NumberFormat::setMaximumIntegerDigits(out.fMaximumIntegerDigits); |
| 843 fSuper->NumberFormat::setMinimumFractionDigits(out.fMinimumFractionDigits); |
| 844 fSuper->NumberFormat::setMaximumFractionDigits(out.fMaximumFractionDigits); |
| 845 fMinSigDigits = out.fMinimumSignificantDigits; |
| 846 fMaxSigDigits = out.fMaximumSignificantDigits; |
| 847 fEffPrecision.fMinExponentDigits = out.fMinExponentDigits; |
| 848 fOptions.fExponent.fAlwaysShowSign = out.fExponentSignAlwaysShown; |
| 849 fSuper->NumberFormat::setGroupingUsed(out.fGroupingUsed); |
| 850 fGrouping.fGrouping = out.fGroupingSize; |
| 851 fGrouping.fGrouping2 = out.fGroupingSize2; |
| 852 fOptions.fMantissa.fAlwaysShowDecimal = out.fDecimalSeparatorAlwaysShown; |
| 853 if (out.fRoundingIncrementUsed) { |
| 854 fEffPrecision.fMantissa.fRoundingIncrement = out.fRoundingIncrement; |
| 855 } else { |
| 856 fEffPrecision.fMantissa.fRoundingIncrement.clear(); |
| 857 } |
| 858 fAffixes.fPadChar = out.fPad; |
| 859 fNegativePrefixPattern = out.fNegPrefixAffix; |
| 860 fNegativeSuffixPattern = out.fNegSuffixAffix; |
| 861 fPositivePrefixPattern = out.fPosPrefixAffix; |
| 862 fPositiveSuffixPattern = out.fPosSuffixAffix; |
| 863 |
| 864 // Work around. Pattern parsing code and DecimalFormat code don't agree |
| 865 // on the definition of field width, so we have to translate from |
| 866 // pattern field width to decimal format field width here. |
| 867 fAffixes.fWidth = out.fFormatWidth == 0 ? 0 : |
| 868 out.fFormatWidth + fPositivePrefixPattern.countChar32() |
| 869 + fPositiveSuffixPattern.countChar32(); |
| 870 switch (out.fPadPosition) { |
| 871 case DecimalFormatPattern::kPadBeforePrefix: |
| 872 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforePrefix; |
| 873 break; |
| 874 case DecimalFormatPattern::kPadAfterPrefix: |
| 875 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterPrefix; |
| 876 break; |
| 877 case DecimalFormatPattern::kPadBeforeSuffix: |
| 878 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforeSuffix; |
| 879 break; |
| 880 case DecimalFormatPattern::kPadAfterSuffix: |
| 881 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterSuffix; |
| 882 break; |
| 883 default: |
| 884 break; |
| 885 } |
| 886 } |
| 887 |
| 888 void |
| 889 DecimalFormatImpl::updatePrecision() { |
| 890 if (fUseScientific) { |
| 891 updatePrecisionForScientific(); |
| 892 } else { |
| 893 updatePrecisionForFixed(); |
| 894 } |
| 895 } |
| 896 |
| 897 static void updatePrecisionForScientificMinMax( |
| 898 const DigitInterval &min, |
| 899 const DigitInterval &max, |
| 900 DigitInterval &resultMin, |
| 901 DigitInterval &resultMax, |
| 902 SignificantDigitInterval &resultSignificant) { |
| 903 resultMin.setIntDigitCount(0); |
| 904 resultMin.setFracDigitCount(0); |
| 905 resultSignificant.clear(); |
| 906 resultMax.clear(); |
| 907 |
| 908 int32_t maxIntDigitCount = max.getIntDigitCount(); |
| 909 int32_t minIntDigitCount = min.getIntDigitCount(); |
| 910 int32_t maxFracDigitCount = max.getFracDigitCount(); |
| 911 int32_t minFracDigitCount = min.getFracDigitCount(); |
| 912 |
| 913 |
| 914 // Not in spec: maxIntDigitCount > 8 assume |
| 915 // maxIntDigitCount = minIntDigitCount. Current DecimalFormat API has |
| 916 // no provision for unsetting maxIntDigitCount which would be useful for |
| 917 // scientific notation. The best we can do is assume that if |
| 918 // maxIntDigitCount is the default of 2000000000 or is "big enough" then |
| 919 // user did not intend to explicitly set it. The 8 was derived emperically |
| 920 // by extensive testing of legacy code. |
| 921 if (maxIntDigitCount > 8) { |
| 922 maxIntDigitCount = minIntDigitCount; |
| 923 } |
| 924 |
| 925 // Per the spec, exponent grouping happens if maxIntDigitCount is more |
| 926 // than 1 and more than minIntDigitCount. |
| 927 UBool bExponentGrouping = maxIntDigitCount > 1 && minIntDigitCount < maxIntD
igitCount; |
| 928 if (bExponentGrouping) { |
| 929 resultMax.setIntDigitCount(maxIntDigitCount); |
| 930 |
| 931 // For exponent grouping minIntDigits is always treated as 1 even |
| 932 // if it wasn't set to 1! |
| 933 resultMin.setIntDigitCount(1); |
| 934 } else { |
| 935 // Fixed digit count left of decimal. minIntDigitCount doesn't have |
| 936 // to equal maxIntDigitCount i.e minIntDigitCount == 0 while |
| 937 // maxIntDigitCount == 1. |
| 938 int32_t fixedIntDigitCount = maxIntDigitCount; |
| 939 |
| 940 // If fixedIntDigitCount is 0 but |
| 941 // min or max fraction count is 0 too then use 1. This way we can get |
| 942 // unlimited precision for X.XXXEX |
| 943 if (fixedIntDigitCount == 0 && (minFracDigitCount == 0 || maxFracDigitCo
unt == 0)) { |
| 944 fixedIntDigitCount = 1; |
| 945 } |
| 946 resultMax.setIntDigitCount(fixedIntDigitCount); |
| 947 resultMin.setIntDigitCount(fixedIntDigitCount); |
| 948 } |
| 949 // Spec says this is how we compute significant digits. 0 means |
| 950 // unlimited significant digits. |
| 951 int32_t maxSigDigits = minIntDigitCount + maxFracDigitCount; |
| 952 if (maxSigDigits > 0) { |
| 953 int32_t minSigDigits = minIntDigitCount + minFracDigitCount; |
| 954 resultSignificant.setMin(minSigDigits); |
| 955 resultSignificant.setMax(maxSigDigits); |
| 956 } |
| 957 } |
| 958 |
| 959 void |
| 960 DecimalFormatImpl::updatePrecisionForScientific() { |
| 961 FixedPrecision *result = &fEffPrecision.fMantissa; |
| 962 if (fUseSigDigits) { |
| 963 result->fMax.setFracDigitCount(-1); |
| 964 result->fMax.setIntDigitCount(1); |
| 965 result->fMin.setFracDigitCount(0); |
| 966 result->fMin.setIntDigitCount(1); |
| 967 result->fSignificant.clear(); |
| 968 extractSigDigits(result->fSignificant); |
| 969 return; |
| 970 } |
| 971 DigitInterval max; |
| 972 DigitInterval min; |
| 973 extractMinMaxDigits(min, max); |
| 974 updatePrecisionForScientificMinMax( |
| 975 min, max, |
| 976 result->fMin, result->fMax, result->fSignificant); |
| 977 } |
| 978 |
| 979 void |
| 980 DecimalFormatImpl::updatePrecisionForFixed() { |
| 981 FixedPrecision *result = &fEffPrecision.fMantissa; |
| 982 if (!fUseSigDigits) { |
| 983 extractMinMaxDigits(result->fMin, result->fMax); |
| 984 result->fSignificant.clear(); |
| 985 } else { |
| 986 extractSigDigits(result->fSignificant); |
| 987 result->fMin.setIntDigitCount(1); |
| 988 result->fMin.setFracDigitCount(0); |
| 989 result->fMax.clear(); |
| 990 } |
| 991 } |
| 992 |
| 993 void |
| 994 DecimalFormatImpl::extractMinMaxDigits( |
| 995 DigitInterval &min, DigitInterval &max) const { |
| 996 min.setIntDigitCount(fSuper->getMinimumIntegerDigits()); |
| 997 max.setIntDigitCount(fSuper->getMaximumIntegerDigits()); |
| 998 min.setFracDigitCount(fSuper->getMinimumFractionDigits()); |
| 999 max.setFracDigitCount(fSuper->getMaximumFractionDigits()); |
| 1000 } |
| 1001 |
| 1002 void |
| 1003 DecimalFormatImpl::extractSigDigits( |
| 1004 SignificantDigitInterval &sig) const { |
| 1005 sig.setMin(fMinSigDigits < 0 ? 0 : fMinSigDigits); |
| 1006 sig.setMax(fMaxSigDigits < 0 ? 0 : fMaxSigDigits); |
| 1007 } |
| 1008 |
| 1009 void |
| 1010 DecimalFormatImpl::updateGrouping() { |
| 1011 if (fSuper->isGroupingUsed()) { |
| 1012 fEffGrouping = fGrouping; |
| 1013 } else { |
| 1014 fEffGrouping.clear(); |
| 1015 } |
| 1016 } |
| 1017 |
| 1018 void |
| 1019 DecimalFormatImpl::updateCurrency(UErrorCode &status) { |
| 1020 updateFormatting(kFormattingCurrency, TRUE, status); |
| 1021 } |
| 1022 |
| 1023 void |
| 1024 DecimalFormatImpl::updateFormatting( |
| 1025 int32_t changedFormattingFields, |
| 1026 UErrorCode &status) { |
| 1027 updateFormatting(changedFormattingFields, TRUE, status); |
| 1028 } |
| 1029 |
| 1030 void |
| 1031 DecimalFormatImpl::updateFormatting( |
| 1032 int32_t changedFormattingFields, |
| 1033 UBool updatePrecisionBasedOnCurrency, |
| 1034 UErrorCode &status) { |
| 1035 if (U_FAILURE(status)) { |
| 1036 return; |
| 1037 } |
| 1038 // Each function updates one field. Order matters. For instance, |
| 1039 // updatePluralRules comes before updateCurrencyAffixInfo because the |
| 1040 // fRules field is needed to update the fCurrencyAffixInfo field. |
| 1041 updateFormattingUsesCurrency(changedFormattingFields); |
| 1042 updateFormattingFixedPointFormatter(changedFormattingFields); |
| 1043 updateFormattingAffixParser(changedFormattingFields); |
| 1044 updateFormattingPluralRules(changedFormattingFields, status); |
| 1045 updateFormattingCurrencyAffixInfo( |
| 1046 changedFormattingFields, |
| 1047 updatePrecisionBasedOnCurrency, |
| 1048 status); |
| 1049 updateFormattingLocalizedPositivePrefix( |
| 1050 changedFormattingFields, status); |
| 1051 updateFormattingLocalizedPositiveSuffix( |
| 1052 changedFormattingFields, status); |
| 1053 updateFormattingLocalizedNegativePrefix( |
| 1054 changedFormattingFields, status); |
| 1055 updateFormattingLocalizedNegativeSuffix( |
| 1056 changedFormattingFields, status); |
| 1057 } |
| 1058 |
| 1059 void |
| 1060 DecimalFormatImpl::updateFormattingUsesCurrency( |
| 1061 int32_t &changedFormattingFields) { |
| 1062 if ((changedFormattingFields & kFormattingAffixes) == 0) { |
| 1063 // If no affixes changed, don't need to do any work |
| 1064 return; |
| 1065 } |
| 1066 UBool newUsesCurrency = |
| 1067 fPositivePrefixPattern.usesCurrency() || |
| 1068 fPositiveSuffixPattern.usesCurrency() || |
| 1069 fNegativePrefixPattern.usesCurrency() || |
| 1070 fNegativeSuffixPattern.usesCurrency(); |
| 1071 if (fMonetary != newUsesCurrency) { |
| 1072 fMonetary = newUsesCurrency; |
| 1073 changedFormattingFields |= kFormattingUsesCurrency; |
| 1074 } |
| 1075 } |
| 1076 |
| 1077 void |
| 1078 DecimalFormatImpl::updateFormattingPluralRules( |
| 1079 int32_t &changedFormattingFields, UErrorCode &status) { |
| 1080 if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency
)) == 0) { |
| 1081 // No work to do if both fSymbols and fMonetary |
| 1082 // fields are unchanged |
| 1083 return; |
| 1084 } |
| 1085 if (U_FAILURE(status)) { |
| 1086 return; |
| 1087 } |
| 1088 PluralRules *newRules = NULL; |
| 1089 if (fMonetary) { |
| 1090 newRules = PluralRules::forLocale(fSymbols->getLocale(), status); |
| 1091 if (U_FAILURE(status)) { |
| 1092 return; |
| 1093 } |
| 1094 } |
| 1095 // Its ok to say a field has changed when it really hasn't but not |
| 1096 // the other way around. Here we assume the field changed unless it |
| 1097 // was NULL before and is still NULL now |
| 1098 if (fRules != newRules) { |
| 1099 delete fRules; |
| 1100 fRules = newRules; |
| 1101 changedFormattingFields |= kFormattingPluralRules; |
| 1102 } |
| 1103 } |
| 1104 |
| 1105 void |
| 1106 DecimalFormatImpl::updateFormattingCurrencyAffixInfo( |
| 1107 int32_t &changedFormattingFields, |
| 1108 UBool updatePrecisionBasedOnCurrency, |
| 1109 UErrorCode &status) { |
| 1110 if ((changedFormattingFields & ( |
| 1111 kFormattingSymbols | kFormattingCurrency | |
| 1112 kFormattingUsesCurrency | kFormattingPluralRules)) == 0) { |
| 1113 // If all these fields are unchanged, no work to do. |
| 1114 return; |
| 1115 } |
| 1116 if (U_FAILURE(status)) { |
| 1117 return; |
| 1118 } |
| 1119 if (!fMonetary) { |
| 1120 if (fCurrencyAffixInfo.isDefault()) { |
| 1121 // In this case don't have to do any work |
| 1122 return; |
| 1123 } |
| 1124 fCurrencyAffixInfo.set(NULL, NULL, NULL, status); |
| 1125 if (U_FAILURE(status)) { |
| 1126 return; |
| 1127 } |
| 1128 changedFormattingFields |= kFormattingCurrencyAffixInfo; |
| 1129 } else { |
| 1130 const UChar *currency = fSuper->getCurrency(); |
| 1131 UChar localeCurr[4]; |
| 1132 if (currency[0] == 0) { |
| 1133 ucurr_forLocale(fSymbols->getLocale().getName(), localeCurr, UPRV_LE
NGTHOF(localeCurr), &status); |
| 1134 if (U_SUCCESS(status)) { |
| 1135 currency = localeCurr; |
| 1136 fSuper->NumberFormat::setCurrency(currency, status); |
| 1137 } else { |
| 1138 currency = NULL; |
| 1139 status = U_ZERO_ERROR; |
| 1140 } |
| 1141 } |
| 1142 fCurrencyAffixInfo.set( |
| 1143 fSymbols->getLocale().getName(), fRules, currency, status); |
| 1144 if (U_FAILURE(status)) { |
| 1145 return; |
| 1146 } |
| 1147 UBool customCurrencySymbol = FALSE; |
| 1148 // If DecimalFormatSymbols has custom currency symbol, prefer |
| 1149 // that over what we just read from the resource bundles |
| 1150 if (fSymbols->isCustomCurrencySymbol()) { |
| 1151 fCurrencyAffixInfo.setSymbol( |
| 1152 fSymbols->getConstSymbol(DecimalFormatSymbols::kCurrencySymb
ol)); |
| 1153 customCurrencySymbol = TRUE; |
| 1154 } |
| 1155 if (fSymbols->isCustomIntlCurrencySymbol()) { |
| 1156 fCurrencyAffixInfo.setISO( |
| 1157 fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrency
Symbol)); |
| 1158 customCurrencySymbol = TRUE; |
| 1159 } |
| 1160 changedFormattingFields |= kFormattingCurrencyAffixInfo; |
| 1161 if (currency && !customCurrencySymbol && updatePrecisionBasedOnCurrency)
{ |
| 1162 FixedPrecision precision; |
| 1163 CurrencyAffixInfo::adjustPrecision( |
| 1164 currency, fCurrencyUsage, precision, status); |
| 1165 if (U_FAILURE(status)) { |
| 1166 return; |
| 1167 } |
| 1168 fSuper->NumberFormat::setMinimumFractionDigits( |
| 1169 precision.fMin.getFracDigitCount()); |
| 1170 fSuper->NumberFormat::setMaximumFractionDigits( |
| 1171 precision.fMax.getFracDigitCount()); |
| 1172 updatePrecision(); |
| 1173 fEffPrecision.fMantissa.fRoundingIncrement = |
| 1174 precision.fRoundingIncrement; |
| 1175 } |
| 1176 |
| 1177 } |
| 1178 } |
| 1179 |
| 1180 void |
| 1181 DecimalFormatImpl::updateFormattingFixedPointFormatter( |
| 1182 int32_t &changedFormattingFields) { |
| 1183 if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency
)) == 0) { |
| 1184 // No work to do if fSymbols is unchanged |
| 1185 return; |
| 1186 } |
| 1187 if (fMonetary) { |
| 1188 fFormatter.setDecimalFormatSymbolsForMonetary(*fSymbols); |
| 1189 } else { |
| 1190 fFormatter.setDecimalFormatSymbols(*fSymbols); |
| 1191 } |
| 1192 } |
| 1193 |
| 1194 void |
| 1195 DecimalFormatImpl::updateFormattingAffixParser( |
| 1196 int32_t &changedFormattingFields) { |
| 1197 if ((changedFormattingFields & kFormattingSymbols) == 0) { |
| 1198 // No work to do if fSymbols is unchanged |
| 1199 return; |
| 1200 } |
| 1201 fAffixParser.setDecimalFormatSymbols(*fSymbols); |
| 1202 changedFormattingFields |= kFormattingAffixParser; |
| 1203 } |
| 1204 |
| 1205 void |
| 1206 DecimalFormatImpl::updateFormattingLocalizedPositivePrefix( |
| 1207 int32_t &changedFormattingFields, UErrorCode &status) { |
| 1208 if (U_FAILURE(status)) { |
| 1209 return; |
| 1210 } |
| 1211 if ((changedFormattingFields & ( |
| 1212 kFormattingPosPrefix | kFormattingAffixParserWithCurrency)) == 0) { |
| 1213 // No work to do |
| 1214 return; |
| 1215 } |
| 1216 fAffixes.fPositivePrefix.remove(); |
| 1217 fAffixParser.parse( |
| 1218 fPositivePrefixPattern, |
| 1219 fCurrencyAffixInfo, |
| 1220 fAffixes.fPositivePrefix, |
| 1221 status); |
| 1222 } |
| 1223 |
| 1224 void |
| 1225 DecimalFormatImpl::updateFormattingLocalizedPositiveSuffix( |
| 1226 int32_t &changedFormattingFields, UErrorCode &status) { |
| 1227 if (U_FAILURE(status)) { |
| 1228 return; |
| 1229 } |
| 1230 if ((changedFormattingFields & ( |
| 1231 kFormattingPosSuffix | kFormattingAffixParserWithCurrency)) == 0) { |
| 1232 // No work to do |
| 1233 return; |
| 1234 } |
| 1235 fAffixes.fPositiveSuffix.remove(); |
| 1236 fAffixParser.parse( |
| 1237 fPositiveSuffixPattern, |
| 1238 fCurrencyAffixInfo, |
| 1239 fAffixes.fPositiveSuffix, |
| 1240 status); |
| 1241 } |
| 1242 |
| 1243 void |
| 1244 DecimalFormatImpl::updateFormattingLocalizedNegativePrefix( |
| 1245 int32_t &changedFormattingFields, UErrorCode &status) { |
| 1246 if (U_FAILURE(status)) { |
| 1247 return; |
| 1248 } |
| 1249 if ((changedFormattingFields & ( |
| 1250 kFormattingNegPrefix | kFormattingAffixParserWithCurrency)) == 0) { |
| 1251 // No work to do |
| 1252 return; |
| 1253 } |
| 1254 fAffixes.fNegativePrefix.remove(); |
| 1255 fAffixParser.parse( |
| 1256 fNegativePrefixPattern, |
| 1257 fCurrencyAffixInfo, |
| 1258 fAffixes.fNegativePrefix, |
| 1259 status); |
| 1260 } |
| 1261 |
| 1262 void |
| 1263 DecimalFormatImpl::updateFormattingLocalizedNegativeSuffix( |
| 1264 int32_t &changedFormattingFields, UErrorCode &status) { |
| 1265 if (U_FAILURE(status)) { |
| 1266 return; |
| 1267 } |
| 1268 if ((changedFormattingFields & ( |
| 1269 kFormattingNegSuffix | kFormattingAffixParserWithCurrency)) == 0) { |
| 1270 // No work to do |
| 1271 return; |
| 1272 } |
| 1273 fAffixes.fNegativeSuffix.remove(); |
| 1274 fAffixParser.parse( |
| 1275 fNegativeSuffixPattern, |
| 1276 fCurrencyAffixInfo, |
| 1277 fAffixes.fNegativeSuffix, |
| 1278 status); |
| 1279 } |
| 1280 |
| 1281 void |
| 1282 DecimalFormatImpl::updateForApplyPatternFavorCurrencyPrecision( |
| 1283 UErrorCode &status) { |
| 1284 updateAll(kFormattingAll & ~kFormattingSymbols, TRUE, status); |
| 1285 } |
| 1286 |
| 1287 void |
| 1288 DecimalFormatImpl::updateForApplyPattern(UErrorCode &status) { |
| 1289 updateAll(kFormattingAll & ~kFormattingSymbols, FALSE, status); |
| 1290 } |
| 1291 |
| 1292 void |
| 1293 DecimalFormatImpl::updateAll(UErrorCode &status) { |
| 1294 updateAll(kFormattingAll, TRUE, status); |
| 1295 } |
| 1296 |
| 1297 void |
| 1298 DecimalFormatImpl::updateAll( |
| 1299 int32_t formattingFlags, |
| 1300 UBool updatePrecisionBasedOnCurrency, |
| 1301 UErrorCode &status) { |
| 1302 if (U_FAILURE(status)) { |
| 1303 return; |
| 1304 } |
| 1305 updatePrecision(); |
| 1306 updateGrouping(); |
| 1307 updateFormatting( |
| 1308 formattingFlags, updatePrecisionBasedOnCurrency, status); |
| 1309 setMultiplierScale(getPatternScale()); |
| 1310 } |
| 1311 |
| 1312 |
| 1313 static int32_t |
| 1314 getMinimumLengthToDescribeGrouping(const DigitGrouping &grouping) { |
| 1315 if (grouping.fGrouping <= 0) { |
| 1316 return 0; |
| 1317 } |
| 1318 if (grouping.fGrouping2 <= 0) { |
| 1319 return grouping.fGrouping + 1; |
| 1320 } |
| 1321 return grouping.fGrouping + grouping.fGrouping2 + 1; |
| 1322 } |
| 1323 |
| 1324 /** |
| 1325 * Given a grouping policy, calculates how many digits are needed left of |
| 1326 * the decimal point to achieve a desired length left of the |
| 1327 * decimal point. |
| 1328 * @param grouping the grouping policy |
| 1329 * @param desiredLength number of characters needed left of decimal point |
| 1330 * @param minLeftDigits at least this many digits is returned |
| 1331 * @param leftDigits the number of digits needed stored here |
| 1332 * which is >= minLeftDigits. |
| 1333 * @return true if a perfect fit or false if having leftDigits would exceed |
| 1334 * desiredLength |
| 1335 */ |
| 1336 static UBool |
| 1337 getLeftDigitsForLeftLength( |
| 1338 const DigitGrouping &grouping, |
| 1339 int32_t desiredLength, |
| 1340 int32_t minLeftDigits, |
| 1341 int32_t &leftDigits) { |
| 1342 leftDigits = minLeftDigits; |
| 1343 int32_t lengthSoFar = leftDigits + grouping.getSeparatorCount(leftDigits); |
| 1344 while (lengthSoFar < desiredLength) { |
| 1345 lengthSoFar += grouping.isSeparatorAt(leftDigits + 1, leftDigits) ? 2 :
1; |
| 1346 ++leftDigits; |
| 1347 } |
| 1348 return (lengthSoFar == desiredLength); |
| 1349 } |
| 1350 |
| 1351 int32_t |
| 1352 DecimalFormatImpl::computeExponentPatternLength() const { |
| 1353 if (fUseScientific) { |
| 1354 return 1 + (fOptions.fExponent.fAlwaysShowSign ? 1 : 0) + fEffPrecision.
fMinExponentDigits; |
| 1355 } |
| 1356 return 0; |
| 1357 } |
| 1358 |
| 1359 int32_t |
| 1360 DecimalFormatImpl::countFractionDigitAndDecimalPatternLength( |
| 1361 int32_t fracDigitCount) const { |
| 1362 if (!fOptions.fMantissa.fAlwaysShowDecimal && fracDigitCount == 0) { |
| 1363 return 0; |
| 1364 } |
| 1365 return fracDigitCount + 1; |
| 1366 } |
| 1367 |
| 1368 UnicodeString& |
| 1369 DecimalFormatImpl::toNumberPattern( |
| 1370 UBool hasPadding, int32_t minimumLength, UnicodeString& result) const { |
| 1371 // Get a grouping policy like the one in this object that does not |
| 1372 // have minimum grouping since toPattern doesn't support it. |
| 1373 DigitGrouping grouping(fEffGrouping); |
| 1374 grouping.fMinGrouping = 0; |
| 1375 |
| 1376 // Only for fixed digits, these are the digits that get 0's. |
| 1377 DigitInterval minInterval; |
| 1378 |
| 1379 // Only for fixed digits, these are the digits that get #'s. |
| 1380 DigitInterval maxInterval; |
| 1381 |
| 1382 // Only for significant digits |
| 1383 int32_t sigMin; |
| 1384 int32_t sigMax; |
| 1385 |
| 1386 // These are all the digits to be displayed. For significant digits, |
| 1387 // this interval always starts at the 1's place an extends left. |
| 1388 DigitInterval fullInterval; |
| 1389 |
| 1390 // Digit range of rounding increment. If rounding increment is .025. |
| 1391 // then roundingIncrementLowerExp = -3 and roundingIncrementUpperExp = -1 |
| 1392 int32_t roundingIncrementLowerExp = 0; |
| 1393 int32_t roundingIncrementUpperExp = 0; |
| 1394 |
| 1395 if (fUseSigDigits) { |
| 1396 SignificantDigitInterval sigInterval; |
| 1397 extractSigDigits(sigInterval); |
| 1398 sigMax = sigInterval.getMax(); |
| 1399 sigMin = sigInterval.getMin(); |
| 1400 fullInterval.setFracDigitCount(0); |
| 1401 fullInterval.setIntDigitCount(sigMax); |
| 1402 } else { |
| 1403 extractMinMaxDigits(minInterval, maxInterval); |
| 1404 if (fUseScientific) { |
| 1405 if (maxInterval.getIntDigitCount() > kMaxScientificIntegerDigits) { |
| 1406 maxInterval.setIntDigitCount(1); |
| 1407 minInterval.shrinkToFitWithin(maxInterval); |
| 1408 } |
| 1409 } else if (hasPadding) { |
| 1410 // Make max int digits match min int digits for now, we |
| 1411 // compute necessary padding later. |
| 1412 maxInterval.setIntDigitCount(minInterval.getIntDigitCount()); |
| 1413 } else { |
| 1414 // For some reason toPattern adds at least one leading '#' |
| 1415 maxInterval.setIntDigitCount(minInterval.getIntDigitCount() + 1); |
| 1416 } |
| 1417 if (!fEffPrecision.fMantissa.fRoundingIncrement.isZero()) { |
| 1418 roundingIncrementLowerExp = |
| 1419 fEffPrecision.fMantissa.fRoundingIncrement.getLowerExponent(
); |
| 1420 roundingIncrementUpperExp = |
| 1421 fEffPrecision.fMantissa.fRoundingIncrement.getUpperExponent(
); |
| 1422 // We have to include the rounding increment in what we display |
| 1423 maxInterval.expandToContainDigit(roundingIncrementLowerExp); |
| 1424 maxInterval.expandToContainDigit(roundingIncrementUpperExp - 1); |
| 1425 } |
| 1426 fullInterval = maxInterval; |
| 1427 } |
| 1428 // We have to include enough digits to show grouping strategy |
| 1429 int32_t minLengthToDescribeGrouping = |
| 1430 getMinimumLengthToDescribeGrouping(grouping); |
| 1431 if (minLengthToDescribeGrouping > 0) { |
| 1432 fullInterval.expandToContainDigit( |
| 1433 getMinimumLengthToDescribeGrouping(grouping) - 1); |
| 1434 } |
| 1435 |
| 1436 // If we have a minimum length, we have to add digits to the left to |
| 1437 // depict padding. |
| 1438 if (hasPadding) { |
| 1439 // For non scientific notation, |
| 1440 // minimumLengthForMantissa = minimumLength |
| 1441 int32_t minimumLengthForMantissa = |
| 1442 minimumLength - computeExponentPatternLength(); |
| 1443 int32_t mininumLengthForMantissaIntPart = |
| 1444 minimumLengthForMantissa |
| 1445 - countFractionDigitAndDecimalPatternLength( |
| 1446 fullInterval.getFracDigitCount()); |
| 1447 // Because of grouping, we may need fewer than expected digits to |
| 1448 // achieve the length we need. |
| 1449 int32_t digitsNeeded; |
| 1450 if (getLeftDigitsForLeftLength( |
| 1451 grouping, |
| 1452 mininumLengthForMantissaIntPart, |
| 1453 fullInterval.getIntDigitCount(), |
| 1454 digitsNeeded)) { |
| 1455 |
| 1456 // In this case, we achieved the exact length that we want. |
| 1457 fullInterval.setIntDigitCount(digitsNeeded); |
| 1458 } else if (digitsNeeded > fullInterval.getIntDigitCount()) { |
| 1459 |
| 1460 // Having digitsNeeded digits goes over desired length which |
| 1461 // means that to have desired length would mean starting on a |
| 1462 // grouping sepearator e.g ,###,### so add a '#' and use one |
| 1463 // less digit. This trick gives ####,### but that is the best |
| 1464 // we can do. |
| 1465 result.append(kPatternDigit); |
| 1466 fullInterval.setIntDigitCount(digitsNeeded - 1); |
| 1467 } |
| 1468 } |
| 1469 int32_t maxDigitPos = fullInterval.getMostSignificantExclusive(); |
| 1470 int32_t minDigitPos = fullInterval.getLeastSignificantInclusive(); |
| 1471 for (int32_t i = maxDigitPos - 1; i >= minDigitPos; --i) { |
| 1472 if (!fOptions.fMantissa.fAlwaysShowDecimal && i == -1) { |
| 1473 result.append(kPatternDecimalSeparator); |
| 1474 } |
| 1475 if (fUseSigDigits) { |
| 1476 // Use digit symbol |
| 1477 if (i >= sigMax || i < sigMax - sigMin) { |
| 1478 result.append(kPatternDigit); |
| 1479 } else { |
| 1480 result.append(kPatternSignificantDigit); |
| 1481 } |
| 1482 } else { |
| 1483 if (i < roundingIncrementUpperExp && i >= roundingIncrementLowerExp)
{ |
| 1484 result.append(fEffPrecision.fMantissa.fRoundingIncrement.getDigi
tByExponent(i) + kPatternZeroDigit); |
| 1485 } else if (minInterval.contains(i)) { |
| 1486 result.append(kPatternZeroDigit); |
| 1487 } else { |
| 1488 result.append(kPatternDigit); |
| 1489 } |
| 1490 } |
| 1491 if (grouping.isSeparatorAt(i + 1, i)) { |
| 1492 result.append(kPatternGroupingSeparator); |
| 1493 } |
| 1494 if (fOptions.fMantissa.fAlwaysShowDecimal && i == 0) { |
| 1495 result.append(kPatternDecimalSeparator); |
| 1496 } |
| 1497 } |
| 1498 if (fUseScientific) { |
| 1499 result.append(kPatternExponent); |
| 1500 if (fOptions.fExponent.fAlwaysShowSign) { |
| 1501 result.append(kPatternPlus); |
| 1502 } |
| 1503 for (int32_t i = 0; i < 1 || i < fEffPrecision.fMinExponentDigits; ++i)
{ |
| 1504 result.append(kPatternZeroDigit); |
| 1505 } |
| 1506 } |
| 1507 return result; |
| 1508 } |
| 1509 |
| 1510 UnicodeString& |
| 1511 DecimalFormatImpl::toPattern(UnicodeString& result) const { |
| 1512 result.remove(); |
| 1513 UnicodeString padSpec; |
| 1514 if (fAffixes.fWidth > 0) { |
| 1515 padSpec.append(kPatternPadEscape); |
| 1516 padSpec.append(fAffixes.fPadChar); |
| 1517 } |
| 1518 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) { |
| 1519 result.append(padSpec); |
| 1520 } |
| 1521 fPositivePrefixPattern.toUserString(result); |
| 1522 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) { |
| 1523 result.append(padSpec); |
| 1524 } |
| 1525 toNumberPattern( |
| 1526 fAffixes.fWidth > 0, |
| 1527 fAffixes.fWidth - fPositivePrefixPattern.countChar32() - fPositiveSu
ffixPattern.countChar32(), |
| 1528 result); |
| 1529 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) { |
| 1530 result.append(padSpec); |
| 1531 } |
| 1532 fPositiveSuffixPattern.toUserString(result); |
| 1533 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) { |
| 1534 result.append(padSpec); |
| 1535 } |
| 1536 AffixPattern withNegative; |
| 1537 withNegative.add(AffixPattern::kNegative); |
| 1538 withNegative.append(fPositivePrefixPattern); |
| 1539 if (!fPositiveSuffixPattern.equals(fNegativeSuffixPattern) || |
| 1540 !withNegative.equals(fNegativePrefixPattern)) { |
| 1541 result.append(kPatternSeparator); |
| 1542 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) { |
| 1543 result.append(padSpec); |
| 1544 } |
| 1545 fNegativePrefixPattern.toUserString(result); |
| 1546 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) { |
| 1547 result.append(padSpec); |
| 1548 } |
| 1549 toNumberPattern( |
| 1550 fAffixes.fWidth > 0, |
| 1551 fAffixes.fWidth - fNegativePrefixPattern.countChar32() - fNegati
veSuffixPattern.countChar32(), |
| 1552 result); |
| 1553 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) { |
| 1554 result.append(padSpec); |
| 1555 } |
| 1556 fNegativeSuffixPattern.toUserString(result); |
| 1557 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) { |
| 1558 result.append(padSpec); |
| 1559 } |
| 1560 } |
| 1561 return result; |
| 1562 } |
| 1563 |
| 1564 int32_t |
| 1565 DecimalFormatImpl::getOldFormatWidth() const { |
| 1566 if (fAffixes.fWidth == 0) { |
| 1567 return 0; |
| 1568 } |
| 1569 return fAffixes.fWidth - fPositiveSuffixPattern.countChar32() - fPositivePre
fixPattern.countChar32(); |
| 1570 } |
| 1571 |
| 1572 const UnicodeString & |
| 1573 DecimalFormatImpl::getConstSymbol( |
| 1574 DecimalFormatSymbols::ENumberFormatSymbol symbol) const { |
| 1575 return fSymbols->getConstSymbol(symbol); |
| 1576 } |
| 1577 |
| 1578 UBool |
| 1579 DecimalFormatImpl::isParseFastpath() const { |
| 1580 AffixPattern negative; |
| 1581 negative.add(AffixPattern::kNegative); |
| 1582 |
| 1583 return fAffixes.fWidth == 0 && |
| 1584 fPositivePrefixPattern.countChar32() == 0 && |
| 1585 fNegativePrefixPattern.equals(negative) && |
| 1586 fPositiveSuffixPattern.countChar32() == 0 && |
| 1587 fNegativeSuffixPattern.countChar32() == 0; |
| 1588 } |
| 1589 |
| 1590 |
| 1591 U_NAMESPACE_END |
| 1592 |
| 1593 #endif /* #if !UCONFIG_NO_FORMATTING */ |
| 1594 |
OLD | NEW |