| OLD | NEW |
| 1 /* | 1 /* |
| 2 ******************************************************************************* | 2 ******************************************************************************* |
| 3 * Copyright (C) 1997-2014, International Business Machines Corporation and * | 3 * Copyright (C) 1997-2015, International Business Machines Corporation and * |
| 4 * others. All Rights Reserved. * | 4 * others. All Rights Reserved. * |
| 5 ******************************************************************************* | 5 ******************************************************************************* |
| 6 * | 6 * |
| 7 * File DECIMFMT.CPP | 7 * File DECIMFMT.CPP |
| 8 * | 8 * |
| 9 * Modification History: | 9 * Modification History: |
| 10 * | 10 * |
| 11 * Date Name Description | 11 * Date Name Description |
| 12 * 02/19/97 aliu Converted from java. | 12 * 02/19/97 aliu Converted from java. |
| 13 * 03/20/97 clhuang Implemented with new APIs. | 13 * 03/20/97 clhuang Implemented with new APIs. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 34 * 06/28/99 stephen Fixed bugs in toPattern(). | 34 * 06/28/99 stephen Fixed bugs in toPattern(). |
| 35 * 06/29/99 stephen Fixed operator= to copy fFormatWidth, fPad, | 35 * 06/29/99 stephen Fixed operator= to copy fFormatWidth, fPad, |
| 36 * fPadPosition | 36 * fPadPosition |
| 37 ******************************************************************************** | 37 ******************************************************************************** |
| 38 */ | 38 */ |
| 39 | 39 |
| 40 #include "unicode/utypes.h" | 40 #include "unicode/utypes.h" |
| 41 | 41 |
| 42 #if !UCONFIG_NO_FORMATTING | 42 #if !UCONFIG_NO_FORMATTING |
| 43 | 43 |
| 44 #include "fphdlimp.h" | |
| 45 #include "unicode/decimfmt.h" | |
| 46 #include "unicode/choicfmt.h" | |
| 47 #include "unicode/ucurr.h" | |
| 48 #include "unicode/ustring.h" | |
| 49 #include "unicode/dcfmtsym.h" | |
| 50 #include "unicode/ures.h" | |
| 51 #include "unicode/uchar.h" | |
| 52 #include "unicode/uniset.h" | 44 #include "unicode/uniset.h" |
| 53 #include "unicode/curramt.h" | |
| 54 #include "unicode/currpinf.h" | 45 #include "unicode/currpinf.h" |
| 55 #include "unicode/plurrule.h" | 46 #include "unicode/plurrule.h" |
| 56 #include "unicode/utf16.h" | 47 #include "unicode/utf16.h" |
| 57 #include "unicode/numsys.h" | 48 #include "unicode/numsys.h" |
| 58 #include "unicode/localpointer.h" | 49 #include "unicode/localpointer.h" |
| 59 #include "uresimp.h" | 50 #include "uresimp.h" |
| 60 #include "ucurrimp.h" | 51 #include "ucurrimp.h" |
| 61 #include "charstr.h" | 52 #include "charstr.h" |
| 62 #include "cmemory.h" | |
| 63 #include "patternprops.h" | 53 #include "patternprops.h" |
| 64 #include "digitlst.h" | |
| 65 #include "cstring.h" | 54 #include "cstring.h" |
| 66 #include "umutex.h" | |
| 67 #include "uassert.h" | 55 #include "uassert.h" |
| 68 #include "putilimp.h" | |
| 69 #include <math.h> | |
| 70 #include "hash.h" | 56 #include "hash.h" |
| 71 #include "decfmtst.h" | 57 #include "decfmtst.h" |
| 72 #include "dcfmtimp.h" | |
| 73 #include "plurrule_impl.h" | 58 #include "plurrule_impl.h" |
| 74 #include "decimalformatpattern.h" | 59 #include "decimalformatpattern.h" |
| 60 #include "fmtableimp.h" |
| 61 #include "decimfmtimpl.h" |
| 62 #include "visibledigits.h" |
| 75 | 63 |
| 76 /* | 64 /* |
| 77 * On certain platforms, round is a macro defined in math.h | 65 * On certain platforms, round is a macro defined in math.h |
| 78 * This undefine is to avoid conflict between the macro and | 66 * This undefine is to avoid conflict between the macro and |
| 79 * the function defined below. | 67 * the function defined below. |
| 80 */ | 68 */ |
| 81 #ifdef round | 69 #ifdef round |
| 82 #undef round | 70 #undef round |
| 83 #endif | 71 #endif |
| 84 | 72 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 95 #define debugout(x) _debugout(__FILE__,__LINE__,x) | 83 #define debugout(x) _debugout(__FILE__,__LINE__,x) |
| 96 #define debug(x) printf("%s:%d: %s\n", __FILE__,__LINE__, x); | 84 #define debug(x) printf("%s:%d: %s\n", __FILE__,__LINE__, x); |
| 97 static const UnicodeString dbg_null("<NULL>",""); | 85 static const UnicodeString dbg_null("<NULL>",""); |
| 98 #define DEREFSTR(x) ((x!=NULL)?(*x):(dbg_null)) | 86 #define DEREFSTR(x) ((x!=NULL)?(*x):(dbg_null)) |
| 99 #else | 87 #else |
| 100 #define debugout(x) | 88 #define debugout(x) |
| 101 #define debug(x) | 89 #define debug(x) |
| 102 #endif | 90 #endif |
| 103 | 91 |
| 104 | 92 |
| 105 | |
| 106 /* == Fastpath calculation. == | |
| 107 */ | |
| 108 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 109 inline DecimalFormatInternal& internalData(uint8_t *reserved) { | |
| 110 return *reinterpret_cast<DecimalFormatInternal*>(reserved); | |
| 111 } | |
| 112 inline const DecimalFormatInternal& internalData(const uint8_t *reserved) { | |
| 113 return *reinterpret_cast<const DecimalFormatInternal*>(reserved); | |
| 114 } | |
| 115 #else | |
| 116 #endif | |
| 117 | |
| 118 /* For currency parsing purose, | 93 /* For currency parsing purose, |
| 119 * Need to remember all prefix patterns and suffix patterns of | 94 * Need to remember all prefix patterns and suffix patterns of |
| 120 * every currency format pattern, | 95 * every currency format pattern, |
| 121 * including the pattern of default currecny style | 96 * including the pattern of default currecny style |
| 122 * and plural currency style. And the patterns are set through applyPattern. | 97 * and plural currency style. And the patterns are set through applyPattern. |
| 123 */ | 98 */ |
| 124 struct AffixPatternsForCurrency : public UMemory { | 99 struct AffixPatternsForCurrency : public UMemory { |
| 125 // negative prefix pattern | 100 // negative prefix pattern |
| 126 UnicodeString negPrefixPatternForCurrency; | 101 UnicodeString negPrefixPatternForCurrency; |
| 127 // negative suffix pattern | 102 // negative suffix pattern |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 posSuffixForCurrency + (UnicodeString)"\" )"); | 163 posSuffixForCurrency + (UnicodeString)"\" )"); |
| 189 } | 164 } |
| 190 #endif | 165 #endif |
| 191 }; | 166 }; |
| 192 | 167 |
| 193 U_CDECL_BEGIN | 168 U_CDECL_BEGIN |
| 194 | 169 |
| 195 /** | 170 /** |
| 196 * @internal ICU 4.2 | 171 * @internal ICU 4.2 |
| 197 */ | 172 */ |
| 198 static UBool U_CALLCONV decimfmtAffixValueComparator(UHashTok val1, UHashTok val
2); | |
| 199 | |
| 200 /** | |
| 201 * @internal ICU 4.2 | |
| 202 */ | |
| 203 static UBool U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHash
Tok val2); | 173 static UBool U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHash
Tok val2); |
| 204 | 174 |
| 205 | 175 |
| 206 static UBool | 176 static UBool |
| 207 U_CALLCONV decimfmtAffixValueComparator(UHashTok val1, UHashTok val2) { | |
| 208 const AffixesForCurrency* affix_1 = | |
| 209 (AffixesForCurrency*)val1.pointer; | |
| 210 const AffixesForCurrency* affix_2 = | |
| 211 (AffixesForCurrency*)val2.pointer; | |
| 212 return affix_1->negPrefixForCurrency == affix_2->negPrefixForCurrency && | |
| 213 affix_1->negSuffixForCurrency == affix_2->negSuffixForCurrency && | |
| 214 affix_1->posPrefixForCurrency == affix_2->posPrefixForCurrency && | |
| 215 affix_1->posSuffixForCurrency == affix_2->posSuffixForCurrency; | |
| 216 } | |
| 217 | |
| 218 | |
| 219 static UBool | |
| 220 U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2) { | 177 U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2) { |
| 221 const AffixPatternsForCurrency* affix_1 = | 178 const AffixPatternsForCurrency* affix_1 = |
| 222 (AffixPatternsForCurrency*)val1.pointer; | 179 (AffixPatternsForCurrency*)val1.pointer; |
| 223 const AffixPatternsForCurrency* affix_2 = | 180 const AffixPatternsForCurrency* affix_2 = |
| 224 (AffixPatternsForCurrency*)val2.pointer; | 181 (AffixPatternsForCurrency*)val2.pointer; |
| 225 return affix_1->negPrefixPatternForCurrency == | 182 return affix_1->negPrefixPatternForCurrency == |
| 226 affix_2->negPrefixPatternForCurrency && | 183 affix_2->negPrefixPatternForCurrency && |
| 227 affix_1->negSuffixPatternForCurrency == | 184 affix_1->negSuffixPatternForCurrency == |
| 228 affix_2->negSuffixPatternForCurrency && | 185 affix_2->negSuffixPatternForCurrency && |
| 229 affix_1->posPrefixPatternForCurrency == | 186 affix_1->posPrefixPatternForCurrency == |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 * These are the tags we expect to see in normal resource bundle files associate
d | 234 * These are the tags we expect to see in normal resource bundle files associate
d |
| 278 * with a locale. | 235 * with a locale. |
| 279 */ | 236 */ |
| 280 const char DecimalFormat::fgNumberPatterns[]="NumberPatterns"; // Deprecated - n
ot used | 237 const char DecimalFormat::fgNumberPatterns[]="NumberPatterns"; // Deprecated - n
ot used |
| 281 static const char fgNumberElements[]="NumberElements"; | 238 static const char fgNumberElements[]="NumberElements"; |
| 282 static const char fgLatn[]="latn"; | 239 static const char fgLatn[]="latn"; |
| 283 static const char fgPatterns[]="patterns"; | 240 static const char fgPatterns[]="patterns"; |
| 284 static const char fgDecimalFormat[]="decimalFormat"; | 241 static const char fgDecimalFormat[]="decimalFormat"; |
| 285 static const char fgCurrencyFormat[]="currencyFormat"; | 242 static const char fgCurrencyFormat[]="currencyFormat"; |
| 286 | 243 |
| 287 static const UChar fgTripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0}; | |
| 288 | |
| 289 inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; } | 244 inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; } |
| 290 inline int32_t _max(int32_t a, int32_t b) { return (a<b) ? b : a; } | 245 inline int32_t _max(int32_t a, int32_t b) { return (a<b) ? b : a; } |
| 291 | 246 |
| 292 static void copyString(const UnicodeString& src, UBool isBogus, UnicodeString *&
dest, UErrorCode &status) { | |
| 293 if (U_FAILURE(status)) { | |
| 294 return; | |
| 295 } | |
| 296 if (isBogus) { | |
| 297 delete dest; | |
| 298 dest = NULL; | |
| 299 } else { | |
| 300 if (dest != NULL) { | |
| 301 *dest = src; | |
| 302 } else { | |
| 303 dest = new UnicodeString(src); | |
| 304 if (dest == NULL) { | |
| 305 status = U_MEMORY_ALLOCATION_ERROR; | |
| 306 return; | |
| 307 } | |
| 308 } | |
| 309 } | |
| 310 } | |
| 311 | |
| 312 | |
| 313 //------------------------------------------------------------------------------ | 247 //------------------------------------------------------------------------------ |
| 314 // Constructs a DecimalFormat instance in the default locale. | 248 // Constructs a DecimalFormat instance in the default locale. |
| 315 | 249 |
| 316 DecimalFormat::DecimalFormat(UErrorCode& status) { | 250 DecimalFormat::DecimalFormat(UErrorCode& status) { |
| 317 init(); | 251 init(); |
| 318 UParseError parseError; | 252 UParseError parseError; |
| 319 construct(status, parseError); | 253 construct(status, parseError); |
| 320 } | 254 } |
| 321 | 255 |
| 322 //------------------------------------------------------------------------------ | 256 //------------------------------------------------------------------------------ |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 } | 318 } |
| 385 | 319 |
| 386 //----------------------------------------------------------------------------- | 320 //----------------------------------------------------------------------------- |
| 387 // Common DecimalFormat initialization. | 321 // Common DecimalFormat initialization. |
| 388 // Put all fields of an uninitialized object into a known state. | 322 // Put all fields of an uninitialized object into a known state. |
| 389 // Common code, shared by all constructors. | 323 // Common code, shared by all constructors. |
| 390 // Can not fail. Leave the object in good enough shape that the destructor | 324 // Can not fail. Leave the object in good enough shape that the destructor |
| 391 // or assignment operator can run successfully. | 325 // or assignment operator can run successfully. |
| 392 void | 326 void |
| 393 DecimalFormat::init() { | 327 DecimalFormat::init() { |
| 394 fPosPrefixPattern = 0; | |
| 395 fPosSuffixPattern = 0; | |
| 396 fNegPrefixPattern = 0; | |
| 397 fNegSuffixPattern = 0; | |
| 398 fCurrencyChoice = 0; | |
| 399 fMultiplier = NULL; | |
| 400 fScale = 0; | |
| 401 fGroupingSize = 0; | |
| 402 fGroupingSize2 = 0; | |
| 403 fDecimalSeparatorAlwaysShown = FALSE; | |
| 404 fSymbols = NULL; | |
| 405 fUseSignificantDigits = FALSE; | |
| 406 fMinSignificantDigits = 1; | |
| 407 fMaxSignificantDigits = 6; | |
| 408 fUseExponentialNotation = FALSE; | |
| 409 fMinExponentDigits = 0; | |
| 410 fExponentSignAlwaysShown = FALSE; | |
| 411 fBoolFlags.clear(); | 328 fBoolFlags.clear(); |
| 412 fRoundingIncrement = 0; | |
| 413 fRoundingMode = kRoundHalfEven; | |
| 414 fPad = 0; | |
| 415 fFormatWidth = 0; | |
| 416 fPadPosition = kPadBeforePrefix; | |
| 417 fStyle = UNUM_DECIMAL; | 329 fStyle = UNUM_DECIMAL; |
| 418 fCurrencySignCount = fgCurrencySignCountZero; | |
| 419 fAffixPatternsForCurrency = NULL; | 330 fAffixPatternsForCurrency = NULL; |
| 420 fAffixesForCurrency = NULL; | |
| 421 fPluralAffixesForCurrency = NULL; | |
| 422 fCurrencyPluralInfo = NULL; | 331 fCurrencyPluralInfo = NULL; |
| 423 fCurrencyUsage = UCURR_USAGE_STANDARD; | |
| 424 #if UCONFIG_HAVE_PARSEALLINPUT | 332 #if UCONFIG_HAVE_PARSEALLINPUT |
| 425 fParseAllInput = UNUM_MAYBE; | 333 fParseAllInput = UNUM_MAYBE; |
| 426 #endif | 334 #endif |
| 427 | 335 |
| 428 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 429 DecimalFormatInternal &data = internalData(fReserved); | |
| 430 data.fFastFormatStatus=kFastpathUNKNOWN; // don't try to calculate the fastp
ath until later. | |
| 431 data.fFastParseStatus=kFastpathUNKNOWN; // don't try to calculate the fastpa
th until later. | |
| 432 #endif | |
| 433 fStaticSets = NULL; | 336 fStaticSets = NULL; |
| 337 fImpl = NULL; |
| 434 } | 338 } |
| 435 | 339 |
| 436 //------------------------------------------------------------------------------ | 340 //------------------------------------------------------------------------------ |
| 437 // Constructs a DecimalFormat instance with the specified number format | 341 // Constructs a DecimalFormat instance with the specified number format |
| 438 // pattern and the number format symbols in the desired locale. The | 342 // pattern and the number format symbols in the desired locale. The |
| 439 // created instance owns the symbols. | 343 // created instance owns the symbols. |
| 440 | 344 |
| 441 void | 345 void |
| 442 DecimalFormat::construct(UErrorCode& status, | 346 DecimalFormat::construct(UErrorCode& status, |
| 443 UParseError& parseErr, | 347 UParseError& parseErr, |
| 444 const UnicodeString* pattern, | 348 const UnicodeString* pattern, |
| 445 DecimalFormatSymbols* symbolsToAdopt) | 349 DecimalFormatSymbols* symbolsToAdopt) |
| 446 { | 350 { |
| 447 fSymbols = symbolsToAdopt; // Do this BEFORE aborting on status failure!!! | 351 LocalPointer<DecimalFormatSymbols> adoptedSymbols(symbolsToAdopt); |
| 448 fRoundingIncrement = NULL; | |
| 449 fRoundingMode = kRoundHalfEven; | |
| 450 fPad = kPatternPadEscape; | |
| 451 fPadPosition = kPadBeforePrefix; | |
| 452 if (U_FAILURE(status)) | 352 if (U_FAILURE(status)) |
| 453 return; | 353 return; |
| 454 | 354 |
| 455 fPosPrefixPattern = fPosSuffixPattern = NULL; | 355 if (adoptedSymbols.isNull()) |
| 456 fNegPrefixPattern = fNegSuffixPattern = NULL; | |
| 457 setMultiplier(1); | |
| 458 fGroupingSize = 3; | |
| 459 fGroupingSize2 = 0; | |
| 460 fDecimalSeparatorAlwaysShown = FALSE; | |
| 461 fUseExponentialNotation = FALSE; | |
| 462 fMinExponentDigits = 0; | |
| 463 | |
| 464 if (fSymbols == NULL) | |
| 465 { | 356 { |
| 466 fSymbols = new DecimalFormatSymbols(Locale::getDefault(), status); | 357 adoptedSymbols.adoptInstead( |
| 467 if (fSymbols == 0) { | 358 new DecimalFormatSymbols(Locale::getDefault(), status)); |
| 359 if (adoptedSymbols.isNull() && U_SUCCESS(status)) { |
| 468 status = U_MEMORY_ALLOCATION_ERROR; | 360 status = U_MEMORY_ALLOCATION_ERROR; |
| 361 } |
| 362 if (U_FAILURE(status)) { |
| 469 return; | 363 return; |
| 470 } | 364 } |
| 471 } | 365 } |
| 472 fStaticSets = DecimalFormatStaticSets::getStaticSets(status); | 366 fStaticSets = DecimalFormatStaticSets::getStaticSets(status); |
| 473 if (U_FAILURE(status)) { | 367 if (U_FAILURE(status)) { |
| 474 return; | 368 return; |
| 475 } | 369 } |
| 476 UErrorCode nsStatus = U_ZERO_ERROR; | |
| 477 NumberingSystem *ns = NumberingSystem::createInstance(nsStatus); | |
| 478 if (U_FAILURE(nsStatus)) { | |
| 479 status = nsStatus; | |
| 480 return; | |
| 481 } | |
| 482 | 370 |
| 483 UnicodeString str; | 371 UnicodeString str; |
| 484 // Uses the default locale's number format pattern if there isn't | 372 // Uses the default locale's number format pattern if there isn't |
| 485 // one specified. | 373 // one specified. |
| 486 if (pattern == NULL) | 374 if (pattern == NULL) |
| 487 { | 375 { |
| 376 UErrorCode nsStatus = U_ZERO_ERROR; |
| 377 LocalPointer<NumberingSystem> ns( |
| 378 NumberingSystem::createInstance(nsStatus)); |
| 379 if (U_FAILURE(nsStatus)) { |
| 380 status = nsStatus; |
| 381 return; |
| 382 } |
| 383 |
| 488 int32_t len = 0; | 384 int32_t len = 0; |
| 489 UResourceBundle *top = ures_open(NULL, Locale::getDefault().getName(), &
status); | 385 UResourceBundle *top = ures_open(NULL, Locale::getDefault().getName(), &
status); |
| 490 | 386 |
| 491 UResourceBundle *resource = ures_getByKeyWithFallback(top, fgNumberEleme
nts, NULL, &status); | 387 UResourceBundle *resource = ures_getByKeyWithFallback(top, fgNumberEleme
nts, NULL, &status); |
| 492 resource = ures_getByKeyWithFallback(resource, ns->getName(), resource,
&status); | 388 resource = ures_getByKeyWithFallback(resource, ns->getName(), resource,
&status); |
| 493 resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &st
atus); | 389 resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &st
atus); |
| 494 const UChar *resStr = ures_getStringByKeyWithFallback(resource, fgDecima
lFormat, &len, &status); | 390 const UChar *resStr = ures_getStringByKeyWithFallback(resource, fgDecima
lFormat, &len, &status); |
| 495 if ( status == U_MISSING_RESOURCE_ERROR && uprv_strcmp(fgLatn,ns->getNam
e())) { | 391 if ( status == U_MISSING_RESOURCE_ERROR && uprv_strcmp(fgLatn,ns->getNam
e())) { |
| 496 status = U_ZERO_ERROR; | 392 status = U_ZERO_ERROR; |
| 497 resource = ures_getByKeyWithFallback(top, fgNumberElements, resource
, &status); | 393 resource = ures_getByKeyWithFallback(top, fgNumberElements, resource
, &status); |
| 498 resource = ures_getByKeyWithFallback(resource, fgLatn, resource, &st
atus); | 394 resource = ures_getByKeyWithFallback(resource, fgLatn, resource, &st
atus); |
| 499 resource = ures_getByKeyWithFallback(resource, fgPatterns, resource,
&status); | 395 resource = ures_getByKeyWithFallback(resource, fgPatterns, resource,
&status); |
| 500 resStr = ures_getStringByKeyWithFallback(resource, fgDecimalFormat,
&len, &status); | 396 resStr = ures_getStringByKeyWithFallback(resource, fgDecimalFormat,
&len, &status); |
| 501 } | 397 } |
| 502 str.setTo(TRUE, resStr, len); | 398 str.setTo(TRUE, resStr, len); |
| 503 pattern = &str; | 399 pattern = &str; |
| 504 ures_close(resource); | 400 ures_close(resource); |
| 505 ures_close(top); | 401 ures_close(top); |
| 506 } | 402 } |
| 507 | 403 |
| 508 delete ns; | 404 fImpl = new DecimalFormatImpl(this, *pattern, adoptedSymbols.getAlias(), par
seErr, status); |
| 405 if (fImpl) { |
| 406 adoptedSymbols.orphan(); |
| 407 } else if (U_SUCCESS(status)) { |
| 408 status = U_MEMORY_ALLOCATION_ERROR; |
| 409 } |
| 410 if (U_FAILURE(status)) { |
| 411 return; |
| 412 } |
| 509 | 413 |
| 510 if (U_FAILURE(status)) | 414 if (U_FAILURE(status)) |
| 511 { | 415 { |
| 512 return; | 416 return; |
| 513 } | 417 } |
| 514 | 418 |
| 515 if (pattern->indexOf((UChar)kCurrencySign) >= 0) { | |
| 516 // If it looks like we are going to use a currency pattern | |
| 517 // then do the time consuming lookup. | |
| 518 setCurrencyForSymbols(); | |
| 519 } else { | |
| 520 setCurrencyInternally(NULL, status); | |
| 521 } | |
| 522 | |
| 523 const UnicodeString* patternUsed; | 419 const UnicodeString* patternUsed; |
| 524 UnicodeString currencyPluralPatternForOther; | 420 UnicodeString currencyPluralPatternForOther; |
| 525 // apply pattern | 421 // apply pattern |
| 526 if (fStyle == UNUM_CURRENCY_PLURAL) { | 422 if (fStyle == UNUM_CURRENCY_PLURAL) { |
| 527 fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), stat
us); | 423 fCurrencyPluralInfo = new CurrencyPluralInfo(fImpl->fSymbols->getLocale(
), status); |
| 528 if (U_FAILURE(status)) { | 424 if (U_FAILURE(status)) { |
| 529 return; | 425 return; |
| 530 } | 426 } |
| 531 | 427 |
| 532 // the pattern used in format is not fixed until formatting, | 428 // the pattern used in format is not fixed until formatting, |
| 533 // in which, the number is known and | 429 // in which, the number is known and |
| 534 // will be used to pick the right pattern based on plural count. | 430 // will be used to pick the right pattern based on plural count. |
| 535 // Here, set the pattern as the pattern of plural count == "other". | 431 // Here, set the pattern as the pattern of plural count == "other". |
| 536 // For most locale, the patterns are probably the same for all | 432 // For most locale, the patterns are probably the same for all |
| 537 // plural count. If not, the right pattern need to be re-applied | 433 // plural count. If not, the right pattern need to be re-applied |
| 538 // during format. | 434 // during format. |
| 539 fCurrencyPluralInfo->getCurrencyPluralPattern(UNICODE_STRING("other", 5)
, currencyPluralPatternForOther); | 435 fCurrencyPluralInfo->getCurrencyPluralPattern(UNICODE_STRING("other", 5)
, currencyPluralPatternForOther); |
| 436 // TODO(refactor): Revisit, we are setting the pattern twice. |
| 437 fImpl->applyPatternFavorCurrencyPrecision( |
| 438 currencyPluralPatternForOther, status); |
| 540 patternUsed = ¤cyPluralPatternForOther; | 439 patternUsed = ¤cyPluralPatternForOther; |
| 541 // TODO: not needed? | |
| 542 setCurrencyForSymbols(); | |
| 543 | 440 |
| 544 } else { | 441 } else { |
| 545 patternUsed = pattern; | 442 patternUsed = pattern; |
| 546 } | 443 } |
| 547 | 444 |
| 548 if (patternUsed->indexOf(kCurrencySign) != -1) { | 445 if (patternUsed->indexOf(kCurrencySign) != -1) { |
| 549 // initialize for currency, not only for plural format, | 446 // initialize for currency, not only for plural format, |
| 550 // but also for mix parsing | 447 // but also for mix parsing |
| 551 if (fCurrencyPluralInfo == NULL) { | 448 if (fCurrencyPluralInfo == NULL) { |
| 552 fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), s
tatus); | 449 fCurrencyPluralInfo = new CurrencyPluralInfo(fImpl->fSymbols->getLoca
le(), status); |
| 553 if (U_FAILURE(status)) { | 450 if (U_FAILURE(status)) { |
| 554 return; | 451 return; |
| 555 } | 452 } |
| 556 } | 453 } |
| 557 // need it for mix parsing | 454 // need it for mix parsing |
| 558 setupCurrencyAffixPatterns(status); | 455 setupCurrencyAffixPatterns(status); |
| 559 // expanded affixes for plural names | |
| 560 if (patternUsed->indexOf(fgTripleCurrencySign, 3, 0) != -1) { | |
| 561 setupCurrencyAffixes(*patternUsed, TRUE, TRUE, status); | |
| 562 } | |
| 563 } | 456 } |
| 564 | |
| 565 applyPatternWithoutExpandAffix(*patternUsed,FALSE, parseErr, status); | |
| 566 | |
| 567 // expand affixes | |
| 568 if (fCurrencySignCount != fgCurrencySignCountInPluralFormat) { | |
| 569 expandAffixAdjustWidth(NULL); | |
| 570 } | |
| 571 | |
| 572 // If it was a currency format, apply the appropriate rounding by | |
| 573 // resetting the currency. NOTE: this copies fCurrency on top of itself. | |
| 574 if (fCurrencySignCount != fgCurrencySignCountZero) { | |
| 575 setCurrencyInternally(getCurrency(), status); | |
| 576 } | |
| 577 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 578 DecimalFormatInternal &data = internalData(fReserved); | |
| 579 data.fFastFormatStatus = kFastpathNO; // allow it to be calculated | |
| 580 data.fFastParseStatus = kFastpathNO; // allow it to be calculated | |
| 581 handleChanged(); | |
| 582 #endif | |
| 583 } | 457 } |
| 584 | 458 |
| 459 static void |
| 460 applyPatternWithNoSideEffects( |
| 461 const UnicodeString& pattern, |
| 462 UParseError& parseError, |
| 463 UnicodeString &negPrefix, |
| 464 UnicodeString &negSuffix, |
| 465 UnicodeString &posPrefix, |
| 466 UnicodeString &posSuffix, |
| 467 UErrorCode& status) { |
| 468 if (U_FAILURE(status)) |
| 469 { |
| 470 return; |
| 471 } |
| 472 DecimalFormatPatternParser patternParser; |
| 473 DecimalFormatPattern out; |
| 474 patternParser.applyPatternWithoutExpandAffix( |
| 475 pattern, |
| 476 out, |
| 477 parseError, |
| 478 status); |
| 479 if (U_FAILURE(status)) { |
| 480 return; |
| 481 } |
| 482 negPrefix = out.fNegPrefixPattern; |
| 483 negSuffix = out.fNegSuffixPattern; |
| 484 posPrefix = out.fPosPrefixPattern; |
| 485 posSuffix = out.fPosSuffixPattern; |
| 486 } |
| 585 | 487 |
| 586 void | 488 void |
| 587 DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) { | 489 DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) { |
| 588 if (U_FAILURE(status)) { | 490 if (U_FAILURE(status)) { |
| 589 return; | 491 return; |
| 590 } | 492 } |
| 591 UParseError parseErr; | 493 UParseError parseErr; |
| 592 fAffixPatternsForCurrency = initHashForAffixPattern(status); | 494 fAffixPatternsForCurrency = initHashForAffixPattern(status); |
| 593 if (U_FAILURE(status)) { | 495 if (U_FAILURE(status)) { |
| 594 return; | 496 return; |
| 595 } | 497 } |
| 596 | 498 |
| 597 NumberingSystem *ns = NumberingSystem::createInstance(fSymbols->getLocale(),
status); | 499 NumberingSystem *ns = NumberingSystem::createInstance(fImpl->fSymbols->getLo
cale(),status); |
| 598 if (U_FAILURE(status)) { | 500 if (U_FAILURE(status)) { |
| 599 return; | 501 return; |
| 600 } | 502 } |
| 601 | 503 |
| 602 // Save the default currency patterns of this locale. | 504 // Save the default currency patterns of this locale. |
| 603 // Here, chose onlyApplyPatternWithoutExpandAffix without | 505 // Here, chose onlyApplyPatternWithoutExpandAffix without |
| 604 // expanding the affix patterns into affixes. | 506 // expanding the affix patterns into affixes. |
| 605 UnicodeString currencyPattern; | 507 UnicodeString currencyPattern; |
| 606 UErrorCode error = U_ZERO_ERROR; | 508 UErrorCode error = U_ZERO_ERROR; |
| 607 | 509 |
| 608 UResourceBundle *resource = ures_open(NULL, fSymbols->getLocale().getName(),
&error); | 510 UResourceBundle *resource = ures_open(NULL, fImpl->fSymbols->getLocale().get
Name(), &error); |
| 609 UResourceBundle *numElements = ures_getByKeyWithFallback(resource, fgNumberE
lements, NULL, &error); | 511 UResourceBundle *numElements = ures_getByKeyWithFallback(resource, fgNumberE
lements, NULL, &error); |
| 610 resource = ures_getByKeyWithFallback(numElements, ns->getName(), resource, &
error); | 512 resource = ures_getByKeyWithFallback(numElements, ns->getName(), resource, &
error); |
| 611 resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &error)
; | 513 resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &error)
; |
| 612 int32_t patLen = 0; | 514 int32_t patLen = 0; |
| 613 const UChar *patResStr = ures_getStringByKeyWithFallback(resource, fgCurrenc
yFormat, &patLen, &error); | 515 const UChar *patResStr = ures_getStringByKeyWithFallback(resource, fgCurrenc
yFormat, &patLen, &error); |
| 614 if ( error == U_MISSING_RESOURCE_ERROR && uprv_strcmp(ns->getName(),fgLatn))
{ | 516 if ( error == U_MISSING_RESOURCE_ERROR && uprv_strcmp(ns->getName(),fgLatn))
{ |
| 615 error = U_ZERO_ERROR; | 517 error = U_ZERO_ERROR; |
| 616 resource = ures_getByKeyWithFallback(numElements, fgLatn, resource, &err
or); | 518 resource = ures_getByKeyWithFallback(numElements, fgLatn, resource, &err
or); |
| 617 resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &er
ror); | 519 resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &er
ror); |
| 618 patResStr = ures_getStringByKeyWithFallback(resource, fgCurrencyFormat,
&patLen, &error); | 520 patResStr = ures_getStringByKeyWithFallback(resource, fgCurrencyFormat,
&patLen, &error); |
| 619 } | 521 } |
| 620 ures_close(numElements); | 522 ures_close(numElements); |
| 621 ures_close(resource); | 523 ures_close(resource); |
| 622 delete ns; | 524 delete ns; |
| 623 | 525 |
| 624 if (U_SUCCESS(error)) { | 526 if (U_SUCCESS(error)) { |
| 625 applyPatternWithoutExpandAffix(UnicodeString(patResStr, patLen), false, | 527 UnicodeString negPrefix; |
| 626 parseErr, status); | 528 UnicodeString negSuffix; |
| 529 UnicodeString posPrefix; |
| 530 UnicodeString posSuffix; |
| 531 applyPatternWithNoSideEffects(UnicodeString(patResStr, patLen), |
| 532 parseErr, |
| 533 negPrefix, negSuffix, posPrefix, posSuffix, status); |
| 627 AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency( | 534 AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency( |
| 628 *fNegPrefixPattern, | 535 negPrefix, |
| 629 *fNegSuffixPattern, | 536 negSuffix, |
| 630 *fPosPrefixPattern, | 537 posPrefix, |
| 631 *fPosSuffixPattern, | 538 posSuffix, |
| 632 UCURR_SYMBOL_NAME); | 539 UCURR_SYMBOL_NAME); |
| 633 fAffixPatternsForCurrency->put(UNICODE_STRING("default", 7), affixPtn, s
tatus); | 540 fAffixPatternsForCurrency->put(UNICODE_STRING("default", 7), affixPtn, s
tatus); |
| 634 } | 541 } |
| 635 | 542 |
| 636 // save the unique currency plural patterns of this locale. | 543 // save the unique currency plural patterns of this locale. |
| 637 Hashtable* pluralPtn = fCurrencyPluralInfo->fPluralCountToCurrencyUnitPatter
n; | 544 Hashtable* pluralPtn = fCurrencyPluralInfo->fPluralCountToCurrencyUnitPatter
n; |
| 638 const UHashElement* element = NULL; | 545 const UHashElement* element = NULL; |
| 639 int32_t pos = -1; | 546 int32_t pos = UHASH_FIRST; |
| 640 Hashtable pluralPatternSet; | 547 Hashtable pluralPatternSet; |
| 641 while ((element = pluralPtn->nextElement(pos)) != NULL) { | 548 while ((element = pluralPtn->nextElement(pos)) != NULL) { |
| 642 const UHashTok valueTok = element->value; | 549 const UHashTok valueTok = element->value; |
| 643 const UnicodeString* value = (UnicodeString*)valueTok.pointer; | 550 const UnicodeString* value = (UnicodeString*)valueTok.pointer; |
| 644 const UHashTok keyTok = element->key; | 551 const UHashTok keyTok = element->key; |
| 645 const UnicodeString* key = (UnicodeString*)keyTok.pointer; | 552 const UnicodeString* key = (UnicodeString*)keyTok.pointer; |
| 646 if (pluralPatternSet.geti(*value) != 1) { | 553 if (pluralPatternSet.geti(*value) != 1) { |
| 554 UnicodeString negPrefix; |
| 555 UnicodeString negSuffix; |
| 556 UnicodeString posPrefix; |
| 557 UnicodeString posSuffix; |
| 647 pluralPatternSet.puti(*value, 1, status); | 558 pluralPatternSet.puti(*value, 1, status); |
| 648 applyPatternWithoutExpandAffix(*value, false, parseErr, status); | 559 applyPatternWithNoSideEffects( |
| 560 *value, parseErr, |
| 561 negPrefix, negSuffix, posPrefix, posSuffix, status); |
| 649 AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency( | 562 AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency( |
| 650 *fNegPrefixPattern, | 563 negPrefix, |
| 651 *fNegSuffixPattern, | 564 negSuffix, |
| 652 *fPosPrefixPattern, | 565 posPrefix, |
| 653 *fPosSuffixPattern, | 566 posSuffix, |
| 654 UCURR_LONG_NAME); | 567 UCURR_LONG_NAME); |
| 655 fAffixPatternsForCurrency->put(*key, affixPtn, status); | 568 fAffixPatternsForCurrency->put(*key, affixPtn, status); |
| 656 } | 569 } |
| 657 } | 570 } |
| 658 } | 571 } |
| 659 | 572 |
| 660 | 573 |
| 661 void | |
| 662 DecimalFormat::setupCurrencyAffixes(const UnicodeString& pattern, | |
| 663 UBool setupForCurrentPattern, | |
| 664 UBool setupForPluralPattern, | |
| 665 UErrorCode& status) { | |
| 666 if (U_FAILURE(status)) { | |
| 667 return; | |
| 668 } | |
| 669 UParseError parseErr; | |
| 670 if (setupForCurrentPattern) { | |
| 671 if (fAffixesForCurrency) { | |
| 672 deleteHashForAffix(fAffixesForCurrency); | |
| 673 } | |
| 674 fAffixesForCurrency = initHashForAffix(status); | |
| 675 if (U_SUCCESS(status)) { | |
| 676 applyPatternWithoutExpandAffix(pattern, false, parseErr, status); | |
| 677 const PluralRules* pluralRules = fCurrencyPluralInfo->getPluralRules
(); | |
| 678 StringEnumeration* keywords = pluralRules->getKeywords(status); | |
| 679 if (U_SUCCESS(status)) { | |
| 680 const UnicodeString* pluralCount; | |
| 681 while ((pluralCount = keywords->snext(status)) != NULL) { | |
| 682 if ( U_SUCCESS(status) ) { | |
| 683 expandAffixAdjustWidth(pluralCount); | |
| 684 AffixesForCurrency* affix = new AffixesForCurrency( | |
| 685 fNegativePrefix, fNegativeSuffix, fPositivePrefix, f
PositiveSuffix); | |
| 686 fAffixesForCurrency->put(*pluralCount, affix, status); | |
| 687 } | |
| 688 } | |
| 689 } | |
| 690 delete keywords; | |
| 691 } | |
| 692 } | |
| 693 | |
| 694 if (U_FAILURE(status)) { | |
| 695 return; | |
| 696 } | |
| 697 | |
| 698 if (setupForPluralPattern) { | |
| 699 if (fPluralAffixesForCurrency) { | |
| 700 deleteHashForAffix(fPluralAffixesForCurrency); | |
| 701 } | |
| 702 fPluralAffixesForCurrency = initHashForAffix(status); | |
| 703 if (U_SUCCESS(status)) { | |
| 704 const PluralRules* pluralRules = fCurrencyPluralInfo->getPluralRules
(); | |
| 705 StringEnumeration* keywords = pluralRules->getKeywords(status); | |
| 706 if (U_SUCCESS(status)) { | |
| 707 const UnicodeString* pluralCount; | |
| 708 while ((pluralCount = keywords->snext(status)) != NULL) { | |
| 709 if ( U_SUCCESS(status) ) { | |
| 710 UnicodeString ptn; | |
| 711 fCurrencyPluralInfo->getCurrencyPluralPattern(*pluralCou
nt, ptn); | |
| 712 applyPatternInternally(*pluralCount, ptn, false, parseEr
r, status); | |
| 713 AffixesForCurrency* affix = new AffixesForCurrency( | |
| 714 fNegativePrefix, fNegativeSuffix, fPositivePrefix, f
PositiveSuffix); | |
| 715 fPluralAffixesForCurrency->put(*pluralCount, affix, stat
us); | |
| 716 } | |
| 717 } | |
| 718 } | |
| 719 delete keywords; | |
| 720 } | |
| 721 } | |
| 722 } | |
| 723 | |
| 724 | |
| 725 //------------------------------------------------------------------------------ | 574 //------------------------------------------------------------------------------ |
| 726 | 575 |
| 727 DecimalFormat::~DecimalFormat() | 576 DecimalFormat::~DecimalFormat() |
| 728 { | 577 { |
| 729 delete fPosPrefixPattern; | |
| 730 delete fPosSuffixPattern; | |
| 731 delete fNegPrefixPattern; | |
| 732 delete fNegSuffixPattern; | |
| 733 delete fCurrencyChoice; | |
| 734 delete fMultiplier; | |
| 735 delete fSymbols; | |
| 736 delete fRoundingIncrement; | |
| 737 deleteHashForAffixPattern(); | 578 deleteHashForAffixPattern(); |
| 738 deleteHashForAffix(fAffixesForCurrency); | |
| 739 deleteHashForAffix(fPluralAffixesForCurrency); | |
| 740 delete fCurrencyPluralInfo; | 579 delete fCurrencyPluralInfo; |
| 580 delete fImpl; |
| 741 } | 581 } |
| 742 | 582 |
| 743 //------------------------------------------------------------------------------ | 583 //------------------------------------------------------------------------------ |
| 744 // copy constructor | 584 // copy constructor |
| 745 | 585 |
| 746 DecimalFormat::DecimalFormat(const DecimalFormat &source) : | 586 DecimalFormat::DecimalFormat(const DecimalFormat &source) : |
| 747 NumberFormat(source) { | 587 NumberFormat(source) { |
| 748 init(); | 588 init(); |
| 749 *this = source; | 589 *this = source; |
| 750 } | 590 } |
| 751 | 591 |
| 752 //------------------------------------------------------------------------------ | 592 //------------------------------------------------------------------------------ |
| 753 // assignment operator | 593 // assignment operator |
| 754 | 594 |
| 755 template <class T> | 595 template <class T> |
| 756 static void _copy_ptr(T** pdest, const T* source) { | |
| 757 if (source == NULL) { | |
| 758 delete *pdest; | |
| 759 *pdest = NULL; | |
| 760 } else if (*pdest == NULL) { | |
| 761 *pdest = new T(*source); | |
| 762 } else { | |
| 763 **pdest = *source; | |
| 764 } | |
| 765 } | |
| 766 | |
| 767 template <class T> | |
| 768 static void _clone_ptr(T** pdest, const T* source) { | 596 static void _clone_ptr(T** pdest, const T* source) { |
| 769 delete *pdest; | 597 delete *pdest; |
| 770 if (source == NULL) { | 598 if (source == NULL) { |
| 771 *pdest = NULL; | 599 *pdest = NULL; |
| 772 } else { | 600 } else { |
| 773 *pdest = static_cast<T*>(source->clone()); | 601 *pdest = static_cast<T*>(source->clone()); |
| 774 } | 602 } |
| 775 } | 603 } |
| 776 | 604 |
| 777 DecimalFormat& | 605 DecimalFormat& |
| 778 DecimalFormat::operator=(const DecimalFormat& rhs) | 606 DecimalFormat::operator=(const DecimalFormat& rhs) |
| 779 { | 607 { |
| 780 if(this != &rhs) { | 608 if(this != &rhs) { |
| 781 UErrorCode status = U_ZERO_ERROR; | 609 UErrorCode status = U_ZERO_ERROR; |
| 782 NumberFormat::operator=(rhs); | 610 NumberFormat::operator=(rhs); |
| 611 if (fImpl == NULL) { |
| 612 fImpl = new DecimalFormatImpl(this, *rhs.fImpl, status); |
| 613 } else { |
| 614 fImpl->assign(*rhs.fImpl, status); |
| 615 } |
| 783 fStaticSets = DecimalFormatStaticSets::getStaticSets(status); | 616 fStaticSets = DecimalFormatStaticSets::getStaticSets(status); |
| 784 fPositivePrefix = rhs.fPositivePrefix; | |
| 785 fPositiveSuffix = rhs.fPositiveSuffix; | |
| 786 fNegativePrefix = rhs.fNegativePrefix; | |
| 787 fNegativeSuffix = rhs.fNegativeSuffix; | |
| 788 _copy_ptr(&fPosPrefixPattern, rhs.fPosPrefixPattern); | |
| 789 _copy_ptr(&fPosSuffixPattern, rhs.fPosSuffixPattern); | |
| 790 _copy_ptr(&fNegPrefixPattern, rhs.fNegPrefixPattern); | |
| 791 _copy_ptr(&fNegSuffixPattern, rhs.fNegSuffixPattern); | |
| 792 _clone_ptr(&fCurrencyChoice, rhs.fCurrencyChoice); | |
| 793 setRoundingIncrement(rhs.getRoundingIncrement()); | |
| 794 fRoundingMode = rhs.fRoundingMode; | |
| 795 setMultiplier(rhs.getMultiplier()); | |
| 796 fGroupingSize = rhs.fGroupingSize; | |
| 797 fGroupingSize2 = rhs.fGroupingSize2; | |
| 798 fDecimalSeparatorAlwaysShown = rhs.fDecimalSeparatorAlwaysShown; | |
| 799 _copy_ptr(&fSymbols, rhs.fSymbols); | |
| 800 fUseExponentialNotation = rhs.fUseExponentialNotation; | |
| 801 fExponentSignAlwaysShown = rhs.fExponentSignAlwaysShown; | |
| 802 fBoolFlags = rhs.fBoolFlags; | |
| 803 /*Bertrand A. D. Update 98.03.17*/ | |
| 804 fCurrencySignCount = rhs.fCurrencySignCount; | |
| 805 /*end of Update*/ | |
| 806 fMinExponentDigits = rhs.fMinExponentDigits; | |
| 807 | |
| 808 /* sfb 990629 */ | |
| 809 fFormatWidth = rhs.fFormatWidth; | |
| 810 fPad = rhs.fPad; | |
| 811 fPadPosition = rhs.fPadPosition; | |
| 812 /* end sfb */ | |
| 813 fMinSignificantDigits = rhs.fMinSignificantDigits; | |
| 814 fMaxSignificantDigits = rhs.fMaxSignificantDigits; | |
| 815 fUseSignificantDigits = rhs.fUseSignificantDigits; | |
| 816 fFormatPattern = rhs.fFormatPattern; | |
| 817 fCurrencyUsage = rhs.fCurrencyUsage; | |
| 818 fStyle = rhs.fStyle; | 617 fStyle = rhs.fStyle; |
| 819 _clone_ptr(&fCurrencyPluralInfo, rhs.fCurrencyPluralInfo); | 618 _clone_ptr(&fCurrencyPluralInfo, rhs.fCurrencyPluralInfo); |
| 820 deleteHashForAffixPattern(); | 619 deleteHashForAffixPattern(); |
| 821 if (rhs.fAffixPatternsForCurrency) { | 620 if (rhs.fAffixPatternsForCurrency) { |
| 822 UErrorCode status = U_ZERO_ERROR; | 621 UErrorCode status = U_ZERO_ERROR; |
| 823 fAffixPatternsForCurrency = initHashForAffixPattern(status); | 622 fAffixPatternsForCurrency = initHashForAffixPattern(status); |
| 824 copyHashForAffixPattern(rhs.fAffixPatternsForCurrency, | 623 copyHashForAffixPattern(rhs.fAffixPatternsForCurrency, |
| 825 fAffixPatternsForCurrency, status); | 624 fAffixPatternsForCurrency, status); |
| 826 } | 625 } |
| 827 deleteHashForAffix(fAffixesForCurrency); | |
| 828 if (rhs.fAffixesForCurrency) { | |
| 829 UErrorCode status = U_ZERO_ERROR; | |
| 830 fAffixesForCurrency = initHashForAffixPattern(status); | |
| 831 copyHashForAffix(rhs.fAffixesForCurrency, fAffixesForCurrency, statu
s); | |
| 832 } | |
| 833 deleteHashForAffix(fPluralAffixesForCurrency); | |
| 834 if (rhs.fPluralAffixesForCurrency) { | |
| 835 UErrorCode status = U_ZERO_ERROR; | |
| 836 fPluralAffixesForCurrency = initHashForAffixPattern(status); | |
| 837 copyHashForAffix(rhs.fPluralAffixesForCurrency, fPluralAffixesForCur
rency, status); | |
| 838 } | |
| 839 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 840 DecimalFormatInternal &data = internalData(fReserved); | |
| 841 const DecimalFormatInternal &rhsData = internalData(rhs.fReserved); | |
| 842 data = rhsData; | |
| 843 #endif | |
| 844 } | 626 } |
| 627 |
| 845 return *this; | 628 return *this; |
| 846 } | 629 } |
| 847 | 630 |
| 848 //------------------------------------------------------------------------------ | 631 //------------------------------------------------------------------------------ |
| 849 | 632 |
| 850 UBool | 633 UBool |
| 851 DecimalFormat::operator==(const Format& that) const | 634 DecimalFormat::operator==(const Format& that) const |
| 852 { | 635 { |
| 853 if (this == &that) | 636 if (this == &that) |
| 854 return TRUE; | 637 return TRUE; |
| 855 | 638 |
| 856 // NumberFormat::operator== guarantees this cast is safe | 639 // NumberFormat::operator== guarantees this cast is safe |
| 857 const DecimalFormat* other = (DecimalFormat*)&that; | 640 const DecimalFormat* other = (DecimalFormat*)&that; |
| 858 | 641 |
| 859 #ifdef FMT_DEBUG | |
| 860 // This code makes it easy to determine why two format objects that should | |
| 861 // be equal aren't. | |
| 862 UBool first = TRUE; | |
| 863 if (!NumberFormat::operator==(that)) { | |
| 864 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 865 debug("NumberFormat::!="); | |
| 866 } else { | |
| 867 if (!((fPosPrefixPattern == other->fPosPrefixPattern && // both null | |
| 868 fPositivePrefix == other->fPositivePrefix) | |
| 869 || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 && | |
| 870 *fPosPrefixPattern == *other->fPosPrefixPattern))) { | |
| 871 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 872 debug("Pos Prefix !="); | |
| 873 } | |
| 874 if (!((fPosSuffixPattern == other->fPosSuffixPattern && // both null | |
| 875 fPositiveSuffix == other->fPositiveSuffix) | |
| 876 || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 && | |
| 877 *fPosSuffixPattern == *other->fPosSuffixPattern))) { | |
| 878 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 879 debug("Pos Suffix !="); | |
| 880 } | |
| 881 if (!((fNegPrefixPattern == other->fNegPrefixPattern && // both null | |
| 882 fNegativePrefix == other->fNegativePrefix) | |
| 883 || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 && | |
| 884 *fNegPrefixPattern == *other->fNegPrefixPattern))) { | |
| 885 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 886 debug("Neg Prefix "); | |
| 887 if (fNegPrefixPattern == NULL) { | |
| 888 debug("NULL("); | |
| 889 debugout(fNegativePrefix); | |
| 890 debug(")"); | |
| 891 } else { | |
| 892 debugout(*fNegPrefixPattern); | |
| 893 } | |
| 894 debug(" != "); | |
| 895 if (other->fNegPrefixPattern == NULL) { | |
| 896 debug("NULL("); | |
| 897 debugout(other->fNegativePrefix); | |
| 898 debug(")"); | |
| 899 } else { | |
| 900 debugout(*other->fNegPrefixPattern); | |
| 901 } | |
| 902 } | |
| 903 if (!((fNegSuffixPattern == other->fNegSuffixPattern && // both null | |
| 904 fNegativeSuffix == other->fNegativeSuffix) | |
| 905 || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 && | |
| 906 *fNegSuffixPattern == *other->fNegSuffixPattern))) { | |
| 907 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 908 debug("Neg Suffix "); | |
| 909 if (fNegSuffixPattern == NULL) { | |
| 910 debug("NULL("); | |
| 911 debugout(fNegativeSuffix); | |
| 912 debug(")"); | |
| 913 } else { | |
| 914 debugout(*fNegSuffixPattern); | |
| 915 } | |
| 916 debug(" != "); | |
| 917 if (other->fNegSuffixPattern == NULL) { | |
| 918 debug("NULL("); | |
| 919 debugout(other->fNegativeSuffix); | |
| 920 debug(")"); | |
| 921 } else { | |
| 922 debugout(*other->fNegSuffixPattern); | |
| 923 } | |
| 924 } | |
| 925 if (!((fRoundingIncrement == other->fRoundingIncrement) // both null | |
| 926 || (fRoundingIncrement != NULL && | |
| 927 other->fRoundingIncrement != NULL && | |
| 928 *fRoundingIncrement == *other->fRoundingIncrement))) { | |
| 929 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 930 debug("Rounding Increment !="); | |
| 931 } | |
| 932 if (fRoundingMode != other->fRoundingMode) { | |
| 933 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 934 printf("Rounding Mode %d != %d", (int)fRoundingMode, (int)other->fRoundi
ngMode); | |
| 935 } | |
| 936 if (getMultiplier() != other->getMultiplier()) { | |
| 937 if (first) { printf("[ "); first = FALSE; } | |
| 938 printf("Multiplier %ld != %ld", getMultiplier(), other->getMultiplier())
; | |
| 939 } | |
| 940 if (fGroupingSize != other->fGroupingSize) { | |
| 941 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 942 printf("Grouping Size %ld != %ld", fGroupingSize, other->fGroupingSize); | |
| 943 } | |
| 944 if (fGroupingSize2 != other->fGroupingSize2) { | |
| 945 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 946 printf("Secondary Grouping Size %ld != %ld", fGroupingSize2, other->fGro
upingSize2); | |
| 947 } | |
| 948 if (fDecimalSeparatorAlwaysShown != other->fDecimalSeparatorAlwaysShown) { | |
| 949 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 950 printf("fDecimalSeparatorAlwaysShown %d != %d", fDecimalSeparatorAlwaysS
hown, other->fDecimalSeparatorAlwaysShown); | |
| 951 } | |
| 952 if (fUseExponentialNotation != other->fUseExponentialNotation) { | |
| 953 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 954 debug("fUseExponentialNotation !="); | |
| 955 } | |
| 956 if (fUseExponentialNotation && | |
| 957 fMinExponentDigits != other->fMinExponentDigits) { | |
| 958 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 959 debug("fMinExponentDigits !="); | |
| 960 } | |
| 961 if (fUseExponentialNotation && | |
| 962 fExponentSignAlwaysShown != other->fExponentSignAlwaysShown) { | |
| 963 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 964 debug("fExponentSignAlwaysShown !="); | |
| 965 } | |
| 966 if (fBoolFlags.getAll() != other->fBoolFlags.getAll()) { | |
| 967 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 968 debug("fBoolFlags !="); | |
| 969 } | |
| 970 if (*fSymbols != *(other->fSymbols)) { | |
| 971 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 972 debug("Symbols !="); | |
| 973 } | |
| 974 // TODO Add debug stuff for significant digits here | |
| 975 if (fUseSignificantDigits != other->fUseSignificantDigits) { | |
| 976 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 977 debug("fUseSignificantDigits !="); | |
| 978 } | |
| 979 if (fUseSignificantDigits && | |
| 980 fMinSignificantDigits != other->fMinSignificantDigits) { | |
| 981 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 982 debug("fMinSignificantDigits !="); | |
| 983 } | |
| 984 if (fUseSignificantDigits && | |
| 985 fMaxSignificantDigits != other->fMaxSignificantDigits) { | |
| 986 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 987 debug("fMaxSignificantDigits !="); | |
| 988 } | |
| 989 if (fFormatWidth != other->fFormatWidth) { | |
| 990 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 991 debug("fFormatWidth !="); | |
| 992 } | |
| 993 if (fPad != other->fPad) { | |
| 994 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 995 debug("fPad !="); | |
| 996 } | |
| 997 if (fPadPosition != other->fPadPosition) { | |
| 998 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 999 debug("fPadPosition !="); | |
| 1000 } | |
| 1001 if (fStyle == UNUM_CURRENCY_PLURAL && | |
| 1002 fStyle != other->fStyle) | |
| 1003 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 1004 debug("fStyle !="); | |
| 1005 } | |
| 1006 if (fStyle == UNUM_CURRENCY_PLURAL && | |
| 1007 fFormatPattern != other->fFormatPattern) { | |
| 1008 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } | |
| 1009 debug("fFormatPattern !="); | |
| 1010 } | |
| 1011 | |
| 1012 if (!first) { printf(" ]"); } | |
| 1013 if (fCurrencySignCount != other->fCurrencySignCount) { | |
| 1014 debug("fCurrencySignCount !="); | |
| 1015 } | |
| 1016 if (fCurrencyPluralInfo == other->fCurrencyPluralInfo) { | |
| 1017 debug("fCurrencyPluralInfo == "); | |
| 1018 if (fCurrencyPluralInfo == NULL) { | |
| 1019 debug("fCurrencyPluralInfo == NULL"); | |
| 1020 } | |
| 1021 } | |
| 1022 if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL && | |
| 1023 *fCurrencyPluralInfo != *(other->fCurrencyPluralInfo)) { | |
| 1024 debug("fCurrencyPluralInfo !="); | |
| 1025 } | |
| 1026 if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo == NULL || | |
| 1027 fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo != NULL) { | |
| 1028 debug("fCurrencyPluralInfo one NULL, the other not"); | |
| 1029 } | |
| 1030 if (fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo == NULL) { | |
| 1031 debug("fCurrencyPluralInfo == "); | |
| 1032 } | |
| 1033 } | |
| 1034 #endif | |
| 1035 | |
| 1036 return ( | 642 return ( |
| 1037 NumberFormat::operator==(that) && | 643 NumberFormat::operator==(that) && |
| 644 fBoolFlags.getAll() == other->fBoolFlags.getAll() && |
| 645 *fImpl == *other->fImpl); |
| 1038 | 646 |
| 1039 ((fCurrencySignCount == fgCurrencySignCountInPluralFormat) ? | |
| 1040 (fAffixPatternsForCurrency->equals(*other->fAffixPatternsForCurrency)) : | |
| 1041 (((fPosPrefixPattern == other->fPosPrefixPattern && // both null | |
| 1042 fPositivePrefix == other->fPositivePrefix) | |
| 1043 || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 && | |
| 1044 *fPosPrefixPattern == *other->fPosPrefixPattern)) && | |
| 1045 ((fPosSuffixPattern == other->fPosSuffixPattern && // both null | |
| 1046 fPositiveSuffix == other->fPositiveSuffix) | |
| 1047 || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 && | |
| 1048 *fPosSuffixPattern == *other->fPosSuffixPattern)) && | |
| 1049 ((fNegPrefixPattern == other->fNegPrefixPattern && // both null | |
| 1050 fNegativePrefix == other->fNegativePrefix) | |
| 1051 || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 && | |
| 1052 *fNegPrefixPattern == *other->fNegPrefixPattern)) && | |
| 1053 ((fNegSuffixPattern == other->fNegSuffixPattern && // both null | |
| 1054 fNegativeSuffix == other->fNegativeSuffix) | |
| 1055 || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 && | |
| 1056 *fNegSuffixPattern == *other->fNegSuffixPattern)))) && | |
| 1057 | |
| 1058 ((fRoundingIncrement == other->fRoundingIncrement) // both null | |
| 1059 || (fRoundingIncrement != NULL && | |
| 1060 other->fRoundingIncrement != NULL && | |
| 1061 *fRoundingIncrement == *other->fRoundingIncrement)) && | |
| 1062 | |
| 1063 fRoundingMode == other->fRoundingMode && | |
| 1064 getMultiplier() == other->getMultiplier() && | |
| 1065 fGroupingSize == other->fGroupingSize && | |
| 1066 fGroupingSize2 == other->fGroupingSize2 && | |
| 1067 fDecimalSeparatorAlwaysShown == other->fDecimalSeparatorAlwaysShown && | |
| 1068 fUseExponentialNotation == other->fUseExponentialNotation && | |
| 1069 | |
| 1070 (!fUseExponentialNotation || | |
| 1071 (fMinExponentDigits == other->fMinExponentDigits && fExponentSignAlw
aysShown == other->fExponentSignAlwaysShown)) && | |
| 1072 | |
| 1073 fBoolFlags.getAll() == other->fBoolFlags.getAll() && | |
| 1074 *fSymbols == *(other->fSymbols) && | |
| 1075 fUseSignificantDigits == other->fUseSignificantDigits && | |
| 1076 | |
| 1077 (!fUseSignificantDigits || | |
| 1078 (fMinSignificantDigits == other->fMinSignificantDigits && fMaxSignif
icantDigits == other->fMaxSignificantDigits)) && | |
| 1079 | |
| 1080 fFormatWidth == other->fFormatWidth && | |
| 1081 fPad == other->fPad && | |
| 1082 fPadPosition == other->fPadPosition && | |
| 1083 | |
| 1084 (fStyle != UNUM_CURRENCY_PLURAL || | |
| 1085 (fStyle == other->fStyle && fFormatPattern == other->fFormatPattern)
) && | |
| 1086 | |
| 1087 fCurrencySignCount == other->fCurrencySignCount && | |
| 1088 | |
| 1089 ((fCurrencyPluralInfo == other->fCurrencyPluralInfo && | |
| 1090 fCurrencyPluralInfo == NULL) || | |
| 1091 (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL && | |
| 1092 *fCurrencyPluralInfo == *(other->fCurrencyPluralInfo))) && | |
| 1093 | |
| 1094 fCurrencyUsage == other->fCurrencyUsage | |
| 1095 | |
| 1096 // depending on other settings we may also need to compare | |
| 1097 // fCurrencyChoice (mostly deprecated?), | |
| 1098 // fAffixesForCurrency & fPluralAffixesForCurrency (only relevant in som
e cases) | |
| 1099 ); | |
| 1100 } | 647 } |
| 1101 | 648 |
| 1102 //------------------------------------------------------------------------------ | 649 //------------------------------------------------------------------------------ |
| 1103 | 650 |
| 1104 Format* | 651 Format* |
| 1105 DecimalFormat::clone() const | 652 DecimalFormat::clone() const |
| 1106 { | 653 { |
| 1107 return new DecimalFormat(*this); | 654 return new DecimalFormat(*this); |
| 1108 } | 655 } |
| 1109 | 656 |
| 1110 | 657 |
| 1111 FixedDecimal | 658 FixedDecimal |
| 1112 DecimalFormat::getFixedDecimal(double number, UErrorCode &status) const { | 659 DecimalFormat::getFixedDecimal(double number, UErrorCode &status) const { |
| 1113 FixedDecimal result; | 660 VisibleDigitsWithExponent digits; |
| 1114 | 661 initVisibleDigitsWithExponent(number, digits, status); |
| 1115 if (U_FAILURE(status)) { | |
| 1116 return result; | |
| 1117 } | |
| 1118 | |
| 1119 if (uprv_isNaN(number) || uprv_isPositiveInfinity(fabs(number))) { | |
| 1120 // For NaN and Infinity the state of the formatter is ignored. | |
| 1121 result.init(number); | |
| 1122 return result; | |
| 1123 } | |
| 1124 | |
| 1125 if (fMultiplier == NULL && fScale == 0 && fRoundingIncrement == 0 && areSign
ificantDigitsUsed() == FALSE && | |
| 1126 result.quickInit(number) && result.visibleDecimalDigitCount <= getMa
ximumFractionDigits()) { | |
| 1127 // Fast Path. Construction of an exact FixedDecimal directly from the do
uble, without passing | |
| 1128 // through a DigitList, was successful, and the formatter is doing not
hing tricky with rounding. | |
| 1129 // printf("getFixedDecimal(%g): taking fast path.\n", number); | |
| 1130 result.adjustForMinFractionDigits(getMinimumFractionDigits()); | |
| 1131 } else { | |
| 1132 // Slow path. Create a DigitList, and have this formatter round it accor
ding to the | |
| 1133 // requirements of the format, and fill the fixedDecimal from that. | |
| 1134 DigitList digits; | |
| 1135 digits.set(number); | |
| 1136 result = getFixedDecimal(digits, status); | |
| 1137 } | |
| 1138 return result; | |
| 1139 } | |
| 1140 | |
| 1141 // MSVC optimizer bug? | |
| 1142 // turn off optimization as it causes different behavior in the int64->double->i
nt64 conversion | |
| 1143 #if defined (_MSC_VER) | |
| 1144 #pragma optimize ( "", off ) | |
| 1145 #endif | |
| 1146 FixedDecimal | |
| 1147 DecimalFormat::getFixedDecimal(const Formattable &number, UErrorCode &status) co
nst { | |
| 1148 if (U_FAILURE(status)) { | 662 if (U_FAILURE(status)) { |
| 1149 return FixedDecimal(); | 663 return FixedDecimal(); |
| 1150 } | 664 } |
| 665 return FixedDecimal(digits.getMantissa()); |
| 666 } |
| 667 |
| 668 VisibleDigitsWithExponent & |
| 669 DecimalFormat::initVisibleDigitsWithExponent( |
| 670 double number, |
| 671 VisibleDigitsWithExponent &digits, |
| 672 UErrorCode &status) const { |
| 673 return fImpl->initVisibleDigitsWithExponent(number, digits, status); |
| 674 } |
| 675 |
| 676 FixedDecimal |
| 677 DecimalFormat::getFixedDecimal(const Formattable &number, UErrorCode &status) co
nst { |
| 678 VisibleDigitsWithExponent digits; |
| 679 initVisibleDigitsWithExponent(number, digits, status); |
| 680 if (U_FAILURE(status)) { |
| 681 return FixedDecimal(); |
| 682 } |
| 683 return FixedDecimal(digits.getMantissa()); |
| 684 } |
| 685 |
| 686 VisibleDigitsWithExponent & |
| 687 DecimalFormat::initVisibleDigitsWithExponent( |
| 688 const Formattable &number, |
| 689 VisibleDigitsWithExponent &digits, |
| 690 UErrorCode &status) const { |
| 691 if (U_FAILURE(status)) { |
| 692 return digits; |
| 693 } |
| 1151 if (!number.isNumeric()) { | 694 if (!number.isNumeric()) { |
| 1152 status = U_ILLEGAL_ARGUMENT_ERROR; | 695 status = U_ILLEGAL_ARGUMENT_ERROR; |
| 1153 return FixedDecimal(); | 696 return digits; |
| 1154 } | 697 } |
| 1155 | 698 |
| 1156 DigitList *dl = number.getDigitList(); | 699 DigitList *dl = number.getDigitList(); |
| 1157 if (dl != NULL) { | 700 if (dl != NULL) { |
| 1158 DigitList clonedDL(*dl); | 701 DigitList dlCopy(*dl); |
| 1159 return getFixedDecimal(clonedDL, status); | 702 return fImpl->initVisibleDigitsWithExponent( |
| 703 dlCopy, digits, status); |
| 1160 } | 704 } |
| 1161 | 705 |
| 1162 Formattable::Type type = number.getType(); | 706 Formattable::Type type = number.getType(); |
| 1163 if (type == Formattable::kDouble || type == Formattable::kLong) { | 707 if (type == Formattable::kDouble || type == Formattable::kLong) { |
| 1164 return getFixedDecimal(number.getDouble(status), status); | 708 return fImpl->initVisibleDigitsWithExponent( |
| 709 number.getDouble(status), digits, status); |
| 1165 } | 710 } |
| 1166 | 711 return fImpl->initVisibleDigitsWithExponent( |
| 1167 if (type == Formattable::kInt64) { | 712 number.getInt64(), digits, status); |
| 1168 // "volatile" here is a workaround to avoid optimization issues. | |
| 1169 volatile double fdv = number.getDouble(status); | |
| 1170 // Note: conversion of int64_t -> double rounds with some compilers to | |
| 1171 // values beyond what can be represented as a 64 bit int. Subseque
nt | |
| 1172 // testing or conversion with int64_t produces bad results. | |
| 1173 // So filter the problematic values, route them to DigitList. | |
| 1174 if (fdv != (double)U_INT64_MAX && fdv != (double)U_INT64_MIN && | |
| 1175 number.getInt64() == (int64_t)fdv) { | |
| 1176 return getFixedDecimal(number.getDouble(status), status); | |
| 1177 } | |
| 1178 } | |
| 1179 | |
| 1180 // The only case left is type==int64_t, with a value with more digits than a
double can represent. | |
| 1181 // Any formattable originating as a big decimal will have had a pre-existing
digit list. | |
| 1182 // Any originating as a double or int32 will have been handled as a double. | |
| 1183 | |
| 1184 U_ASSERT(type == Formattable::kInt64); | |
| 1185 DigitList digits; | |
| 1186 digits.set(number.getInt64()); | |
| 1187 return getFixedDecimal(digits, status); | |
| 1188 } | 713 } |
| 1189 // end workaround MSVC optimizer bug | |
| 1190 #if defined (_MSC_VER) | |
| 1191 #pragma optimize ( "", on ) | |
| 1192 #endif | |
| 1193 | 714 |
| 1194 | 715 |
| 1195 // Create a fixed decimal from a DigitList. | 716 // Create a fixed decimal from a DigitList. |
| 1196 // The digit list may be modified. | 717 // The digit list may be modified. |
| 1197 // Internal function only. | 718 // Internal function only. |
| 1198 FixedDecimal | 719 FixedDecimal |
| 1199 DecimalFormat::getFixedDecimal(DigitList &number, UErrorCode &status) const { | 720 DecimalFormat::getFixedDecimal(DigitList &number, UErrorCode &status) const { |
| 1200 // Round the number according to the requirements of this Format. | 721 VisibleDigitsWithExponent digits; |
| 1201 FixedDecimal result; | 722 initVisibleDigitsWithExponent(number, digits, status); |
| 1202 _round(number, number, result.isNegative, status); | 723 if (U_FAILURE(status)) { |
| 724 return FixedDecimal(); |
| 725 } |
| 726 return FixedDecimal(digits.getMantissa()); |
| 727 } |
| 1203 | 728 |
| 1204 // The int64_t fields in FixedDecimal can easily overflow. | 729 VisibleDigitsWithExponent & |
| 1205 // In deciding what to discard in this event, consider that fixedDecimal | 730 DecimalFormat::initVisibleDigitsWithExponent( |
| 1206 // is being used only with PluralRules, and those rules mostly look at lea
st significant | 731 DigitList &number, |
| 1207 // few digits of the integer part, and whether the fraction part is zero o
r not. | 732 VisibleDigitsWithExponent &digits, |
| 1208 // | 733 UErrorCode &status) const { |
| 1209 // So, in case of overflow when filling in the fields of the FixedDecimal ob
ject, | 734 return fImpl->initVisibleDigitsWithExponent( |
| 1210 // for the integer part, discard the most significant digits. | 735 number, digits, status); |
| 1211 // for the fraction part, discard the least significant digits, | |
| 1212 // don't truncate the fraction value to zero. | |
| 1213 // For simplicity, the int64_t fields are limited to 18 decimal digits, even | |
| 1214 // though they could hold most (but not all) 19 digit values. | |
| 1215 | |
| 1216 // Integer Digits. | |
| 1217 int32_t di = number.getDecimalAt()-18; // Take at most 18 digits. | |
| 1218 if (di < 0) { | |
| 1219 di = 0; | |
| 1220 } | |
| 1221 result.intValue = 0; | |
| 1222 for (; di<number.getDecimalAt(); di++) { | |
| 1223 result.intValue = result.intValue * 10 + (number.getDigit(di) & 0x0f); | |
| 1224 } | |
| 1225 if (result.intValue == 0 && number.getDecimalAt()-18 > 0) { | |
| 1226 // The number is something like 100000000000000000000000. | |
| 1227 // More than 18 digits integer digits, but the least significant 18 are
all zero. | |
| 1228 // We don't want to return zero as the int part, but want to keep zeros | |
| 1229 // for several of the least significant digits. | |
| 1230 result.intValue = 100000000000000000LL; | |
| 1231 } | |
| 1232 | |
| 1233 // Fraction digits. | |
| 1234 result.decimalDigits = result.decimalDigitsWithoutTrailingZeros = result.vis
ibleDecimalDigitCount = 0; | |
| 1235 for (di = number.getDecimalAt(); di < number.getCount(); di++) { | |
| 1236 result.visibleDecimalDigitCount++; | |
| 1237 if (result.decimalDigits < 100000000000000000LL) { | |
| 1238 // 9223372036854775807 Largest 64 bit signed
integer | |
| 1239 int32_t digitVal = number.getDigit(di) & 0x0f; // getDigit() return
s a char, '0'-'9'. | |
| 1240 result.decimalDigits = result.decimalDigits * 10 + digitVal; | |
| 1241 if (digitVal > 0) { | |
| 1242 result.decimalDigitsWithoutTrailingZeros = result.decimalDigits; | |
| 1243 } | |
| 1244 } | |
| 1245 } | |
| 1246 | |
| 1247 result.hasIntegerValue = (result.decimalDigits == 0); | |
| 1248 | |
| 1249 // Trailing fraction zeros. The format specification may require more traili
ng | |
| 1250 // zeros than the numeric value. Add any such on now. | |
| 1251 | |
| 1252 int32_t minFractionDigits; | |
| 1253 if (areSignificantDigitsUsed()) { | |
| 1254 minFractionDigits = getMinimumSignificantDigits() - number.getDecimalAt(
); | |
| 1255 if (minFractionDigits < 0) { | |
| 1256 minFractionDigits = 0; | |
| 1257 } | |
| 1258 } else { | |
| 1259 minFractionDigits = getMinimumFractionDigits(); | |
| 1260 } | |
| 1261 result.adjustForMinFractionDigits(minFractionDigits); | |
| 1262 | |
| 1263 return result; | |
| 1264 } | 736 } |
| 1265 | 737 |
| 1266 | 738 |
| 1267 //------------------------------------------------------------------------------ | 739 //------------------------------------------------------------------------------ |
| 1268 | 740 |
| 1269 UnicodeString& | 741 UnicodeString& |
| 1270 DecimalFormat::format(int32_t number, | 742 DecimalFormat::format(int32_t number, |
| 1271 UnicodeString& appendTo, | 743 UnicodeString& appendTo, |
| 1272 FieldPosition& fieldPosition) const | 744 FieldPosition& fieldPosition) const |
| 1273 { | 745 { |
| 1274 return format((int64_t)number, appendTo, fieldPosition); | 746 UErrorCode status = U_ZERO_ERROR; |
| 747 return fImpl->format(number, appendTo, fieldPosition, status); |
| 1275 } | 748 } |
| 1276 | 749 |
| 1277 UnicodeString& | 750 UnicodeString& |
| 1278 DecimalFormat::format(int32_t number, | 751 DecimalFormat::format(int32_t number, |
| 1279 UnicodeString& appendTo, | 752 UnicodeString& appendTo, |
| 1280 FieldPosition& fieldPosition, | 753 FieldPosition& fieldPosition, |
| 1281 UErrorCode& status) const | 754 UErrorCode& status) const |
| 1282 { | 755 { |
| 1283 return format((int64_t)number, appendTo, fieldPosition, status); | 756 return fImpl->format(number, appendTo, fieldPosition, status); |
| 1284 } | 757 } |
| 1285 | 758 |
| 1286 UnicodeString& | 759 UnicodeString& |
| 1287 DecimalFormat::format(int32_t number, | 760 DecimalFormat::format(int32_t number, |
| 1288 UnicodeString& appendTo, | 761 UnicodeString& appendTo, |
| 1289 FieldPositionIterator* posIter, | 762 FieldPositionIterator* posIter, |
| 1290 UErrorCode& status) const | 763 UErrorCode& status) const |
| 1291 { | 764 { |
| 1292 return format((int64_t)number, appendTo, posIter, status); | 765 return fImpl->format(number, appendTo, posIter, status); |
| 1293 } | 766 } |
| 1294 | 767 |
| 1295 | 768 |
| 1296 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 1297 void DecimalFormat::handleChanged() { | |
| 1298 DecimalFormatInternal &data = internalData(fReserved); | |
| 1299 | |
| 1300 if(data.fFastFormatStatus == kFastpathUNKNOWN || data.fFastParseStatus == kFas
tpathUNKNOWN) { | |
| 1301 return; // still constructing. Wait. | |
| 1302 } | |
| 1303 | |
| 1304 data.fFastParseStatus = data.fFastFormatStatus = kFastpathNO; | |
| 1305 | |
| 1306 #if UCONFIG_HAVE_PARSEALLINPUT | |
| 1307 if(fParseAllInput == UNUM_NO) { | |
| 1308 debug("No Parse fastpath: fParseAllInput==UNUM_NO"); | |
| 1309 } else | |
| 1310 #endif | |
| 1311 if (fFormatWidth!=0) { | |
| 1312 debug("No Parse fastpath: fFormatWidth"); | |
| 1313 } else if(fPositivePrefix.length()>0) { | |
| 1314 debug("No Parse fastpath: positive prefix"); | |
| 1315 } else if(fPositiveSuffix.length()>0) { | |
| 1316 debug("No Parse fastpath: positive suffix"); | |
| 1317 } else if(fNegativePrefix.length()>1 | |
| 1318 || ((fNegativePrefix.length()==1) && (fNegativePrefix.charAt(0)!=0x0
02D))) { | |
| 1319 debug("No Parse fastpath: negative prefix that isn't '-'"); | |
| 1320 } else if(fNegativeSuffix.length()>0) { | |
| 1321 debug("No Parse fastpath: negative suffix"); | |
| 1322 } else { | |
| 1323 data.fFastParseStatus = kFastpathYES; | |
| 1324 debug("parse fastpath: YES"); | |
| 1325 } | |
| 1326 | |
| 1327 if(fUseExponentialNotation) { | |
| 1328 debug("No format fastpath: fUseExponentialNotation"); | |
| 1329 } else if(fFormatWidth!=0) { | |
| 1330 debug("No format fastpath: fFormatWidth!=0"); | |
| 1331 } else if(fMinSignificantDigits!=1) { | |
| 1332 debug("No format fastpath: fMinSignificantDigits!=1"); | |
| 1333 } else if(fMultiplier!=NULL) { | |
| 1334 debug("No format fastpath: fMultiplier!=NULL"); | |
| 1335 } else if(fScale!=0) { | |
| 1336 debug("No format fastpath: fScale!=0"); | |
| 1337 } else if(0x0030 != getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).cha
r32At(0)) { | |
| 1338 debug("No format fastpath: 0x0030 != getConstSymbol(DecimalFormatSymbols::kZ
eroDigitSymbol).char32At(0)"); | |
| 1339 } else if(fDecimalSeparatorAlwaysShown) { | |
| 1340 debug("No format fastpath: fDecimalSeparatorAlwaysShown"); | |
| 1341 } else if(getMinimumFractionDigits()>0) { | |
| 1342 debug("No format fastpath: fMinFractionDigits>0"); | |
| 1343 } else if(fCurrencySignCount != fgCurrencySignCountZero) { | |
| 1344 debug("No format fastpath: fCurrencySignCount != fgCurrencySignCountZero"); | |
| 1345 } else if(fRoundingIncrement!=0) { | |
| 1346 debug("No format fastpath: fRoundingIncrement!=0"); | |
| 1347 } else if (fGroupingSize!=0 && isGroupingUsed()) { | |
| 1348 debug("Maybe format fastpath: fGroupingSize!=0 and grouping is used"); | |
| 1349 #ifdef FMT_DEBUG | |
| 1350 printf("groupingsize=%d\n", fGroupingSize); | |
| 1351 #endif | |
| 1352 | |
| 1353 if (getMinimumIntegerDigits() <= fGroupingSize) { | |
| 1354 data.fFastFormatStatus = kFastpathMAYBE; | |
| 1355 } | |
| 1356 } else if(fGroupingSize2!=0 && isGroupingUsed()) { | |
| 1357 debug("No format fastpath: fGroupingSize2!=0"); | |
| 1358 } else { | |
| 1359 data.fFastFormatStatus = kFastpathYES; | |
| 1360 debug("format:kFastpathYES!"); | |
| 1361 } | |
| 1362 | |
| 1363 | |
| 1364 } | |
| 1365 #endif | |
| 1366 //------------------------------------------------------------------------------ | 769 //------------------------------------------------------------------------------ |
| 1367 | 770 |
| 1368 UnicodeString& | 771 UnicodeString& |
| 1369 DecimalFormat::format(int64_t number, | 772 DecimalFormat::format(int64_t number, |
| 1370 UnicodeString& appendTo, | 773 UnicodeString& appendTo, |
| 1371 FieldPosition& fieldPosition) const | 774 FieldPosition& fieldPosition) const |
| 1372 { | 775 { |
| 1373 UErrorCode status = U_ZERO_ERROR; /* ignored */ | 776 UErrorCode status = U_ZERO_ERROR; /* ignored */ |
| 1374 FieldPositionOnlyHandler handler(fieldPosition); | 777 return fImpl->format(number, appendTo, fieldPosition, status); |
| 1375 return _format(number, appendTo, handler, status); | |
| 1376 } | 778 } |
| 1377 | 779 |
| 1378 UnicodeString& | 780 UnicodeString& |
| 1379 DecimalFormat::format(int64_t number, | 781 DecimalFormat::format(int64_t number, |
| 1380 UnicodeString& appendTo, | 782 UnicodeString& appendTo, |
| 1381 FieldPosition& fieldPosition, | 783 FieldPosition& fieldPosition, |
| 1382 UErrorCode& status) const | 784 UErrorCode& status) const |
| 1383 { | 785 { |
| 1384 FieldPositionOnlyHandler handler(fieldPosition); | 786 return fImpl->format(number, appendTo, fieldPosition, status); |
| 1385 return _format(number, appendTo, handler, status); | |
| 1386 } | 787 } |
| 1387 | 788 |
| 1388 UnicodeString& | 789 UnicodeString& |
| 1389 DecimalFormat::format(int64_t number, | 790 DecimalFormat::format(int64_t number, |
| 1390 UnicodeString& appendTo, | 791 UnicodeString& appendTo, |
| 1391 FieldPositionIterator* posIter, | 792 FieldPositionIterator* posIter, |
| 1392 UErrorCode& status) const | 793 UErrorCode& status) const |
| 1393 { | 794 { |
| 1394 FieldPositionIteratorHandler handler(posIter, status); | 795 return fImpl->format(number, appendTo, posIter, status); |
| 1395 return _format(number, appendTo, handler, status); | |
| 1396 } | |
| 1397 | |
| 1398 UnicodeString& | |
| 1399 DecimalFormat::_format(int64_t number, | |
| 1400 UnicodeString& appendTo, | |
| 1401 FieldPositionHandler& handler, | |
| 1402 UErrorCode &status) const | |
| 1403 { | |
| 1404 // Bottleneck function for formatting int64_t | |
| 1405 if (U_FAILURE(status)) { | |
| 1406 return appendTo; | |
| 1407 } | |
| 1408 | |
| 1409 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 1410 // const UnicodeString *posPrefix = fPosPrefixPattern; | |
| 1411 // const UnicodeString *posSuffix = fPosSuffixPattern; | |
| 1412 // const UnicodeString *negSuffix = fNegSuffixPattern; | |
| 1413 | |
| 1414 const DecimalFormatInternal &data = internalData(fReserved); | |
| 1415 | |
| 1416 #ifdef FMT_DEBUG | |
| 1417 data.dump(); | |
| 1418 printf("fastpath? [%d]\n", number); | |
| 1419 #endif | |
| 1420 | |
| 1421 if( data.fFastFormatStatus==kFastpathYES || | |
| 1422 data.fFastFormatStatus==kFastpathMAYBE) { | |
| 1423 int32_t noGroupingThreshold = 0; | |
| 1424 | |
| 1425 #define kZero 0x0030 | |
| 1426 const int32_t MAX_IDX = MAX_DIGITS+2; | |
| 1427 UChar outputStr[MAX_IDX]; | |
| 1428 int32_t destIdx = MAX_IDX; | |
| 1429 outputStr[--destIdx] = 0; // term | |
| 1430 | |
| 1431 if (data.fFastFormatStatus==kFastpathMAYBE) { | |
| 1432 noGroupingThreshold = destIdx - fGroupingSize; | |
| 1433 } | |
| 1434 int64_t n = number; | |
| 1435 if (number < 1) { | |
| 1436 // Negative numbers are slightly larger than positive | |
| 1437 // output the first digit (or the leading zero) | |
| 1438 outputStr[--destIdx] = (-(n % 10) + kZero); | |
| 1439 n /= -10; | |
| 1440 } | |
| 1441 // get any remaining digits | |
| 1442 while (n > 0) { | |
| 1443 if (destIdx == noGroupingThreshold) { | |
| 1444 goto slowPath; | |
| 1445 } | |
| 1446 outputStr[--destIdx] = (n % 10) + kZero; | |
| 1447 n /= 10; | |
| 1448 } | |
| 1449 | |
| 1450 // Slide the number to the start of the output str | |
| 1451 U_ASSERT(destIdx >= 0); | |
| 1452 int32_t length = MAX_IDX - destIdx -1; | |
| 1453 /*int32_t prefixLen = */ appendAffix(appendTo, static_cast<double>(number),
handler, number<0, TRUE); | |
| 1454 int32_t maxIntDig = getMaximumIntegerDigits(); | |
| 1455 int32_t destlength = length<=maxIntDig?length:maxIntDig; // dest length pinn
ed to max int digits | |
| 1456 | |
| 1457 if(length>maxIntDig && fBoolFlags.contains(UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX
_DIGITS)) { | |
| 1458 status = U_ILLEGAL_ARGUMENT_ERROR; | |
| 1459 } | |
| 1460 | |
| 1461 int32_t prependZero = getMinimumIntegerDigits() - destlength; | |
| 1462 | |
| 1463 #ifdef FMT_DEBUG | |
| 1464 printf("prependZero=%d, length=%d, minintdig=%d maxintdig=%d destlength=%d s
kip=%d\n", prependZero, length, getMinimumIntegerDigits(), maxIntDig, destlength
, length-destlength); | |
| 1465 #endif | |
| 1466 int32_t intBegin = appendTo.length(); | |
| 1467 | |
| 1468 while((prependZero--)>0) { | |
| 1469 appendTo.append((UChar)0x0030); // '0' | |
| 1470 } | |
| 1471 | |
| 1472 appendTo.append(outputStr+destIdx+ | |
| 1473 (length-destlength), // skip any leading digits | |
| 1474 destlength); | |
| 1475 handler.addAttribute(kIntegerField, intBegin, appendTo.length()); | |
| 1476 | |
| 1477 /*int32_t suffixLen =*/ appendAffix(appendTo, static_cast<double>(number), h
andler, number<0, FALSE); | |
| 1478 | |
| 1479 //outputStr[length]=0; | |
| 1480 | |
| 1481 #ifdef FMT_DEBUG | |
| 1482 printf("Writing [%s] length [%d] max %d for [%d]\n", outputStr+destIdx,
length, MAX_IDX, number); | |
| 1483 #endif | |
| 1484 | |
| 1485 #undef kZero | |
| 1486 | |
| 1487 return appendTo; | |
| 1488 } // end fastpath | |
| 1489 #endif | |
| 1490 slowPath: | |
| 1491 | |
| 1492 // Else the slow way - via DigitList | |
| 1493 DigitList digits; | |
| 1494 digits.set(number); | |
| 1495 return _format(digits, appendTo, handler, status); | |
| 1496 } | 796 } |
| 1497 | 797 |
| 1498 //------------------------------------------------------------------------------ | 798 //------------------------------------------------------------------------------ |
| 1499 | 799 |
| 1500 UnicodeString& | 800 UnicodeString& |
| 1501 DecimalFormat::format( double number, | 801 DecimalFormat::format( double number, |
| 1502 UnicodeString& appendTo, | 802 UnicodeString& appendTo, |
| 1503 FieldPosition& fieldPosition) const | 803 FieldPosition& fieldPosition) const |
| 1504 { | 804 { |
| 1505 UErrorCode status = U_ZERO_ERROR; /* ignored */ | 805 UErrorCode status = U_ZERO_ERROR; /* ignored */ |
| 1506 FieldPositionOnlyHandler handler(fieldPosition); | 806 return fImpl->format(number, appendTo, fieldPosition, status); |
| 1507 return _format(number, appendTo, handler, status); | |
| 1508 } | 807 } |
| 1509 | 808 |
| 1510 UnicodeString& | 809 UnicodeString& |
| 1511 DecimalFormat::format( double number, | 810 DecimalFormat::format( double number, |
| 1512 UnicodeString& appendTo, | 811 UnicodeString& appendTo, |
| 1513 FieldPosition& fieldPosition, | 812 FieldPosition& fieldPosition, |
| 1514 UErrorCode& status) const | 813 UErrorCode& status) const |
| 1515 { | 814 { |
| 1516 FieldPositionOnlyHandler handler(fieldPosition); | 815 return fImpl->format(number, appendTo, fieldPosition, status); |
| 1517 return _format(number, appendTo, handler, status); | |
| 1518 } | 816 } |
| 1519 | 817 |
| 1520 UnicodeString& | 818 UnicodeString& |
| 1521 DecimalFormat::format( double number, | 819 DecimalFormat::format( double number, |
| 1522 UnicodeString& appendTo, | 820 UnicodeString& appendTo, |
| 1523 FieldPositionIterator* posIter, | 821 FieldPositionIterator* posIter, |
| 1524 UErrorCode& status) const | 822 UErrorCode& status) const |
| 1525 { | 823 { |
| 1526 FieldPositionIteratorHandler handler(posIter, status); | 824 return fImpl->format(number, appendTo, posIter, status); |
| 1527 return _format(number, appendTo, handler, status); | |
| 1528 } | |
| 1529 | |
| 1530 UnicodeString& | |
| 1531 DecimalFormat::_format( double number, | |
| 1532 UnicodeString& appendTo, | |
| 1533 FieldPositionHandler& handler, | |
| 1534 UErrorCode &status) const | |
| 1535 { | |
| 1536 if (U_FAILURE(status)) { | |
| 1537 return appendTo; | |
| 1538 } | |
| 1539 // Special case for NaN, sets the begin and end index to be the | |
| 1540 // the string length of localized name of NaN. | |
| 1541 // TODO: let NaNs go through DigitList. | |
| 1542 if (uprv_isNaN(number)) | |
| 1543 { | |
| 1544 int begin = appendTo.length(); | |
| 1545 appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol); | |
| 1546 | |
| 1547 handler.addAttribute(kIntegerField, begin, appendTo.length()); | |
| 1548 | |
| 1549 addPadding(appendTo, handler, 0, 0); | |
| 1550 return appendTo; | |
| 1551 } | |
| 1552 | |
| 1553 DigitList digits; | |
| 1554 digits.set(number); | |
| 1555 _format(digits, appendTo, handler, status); | |
| 1556 // No way to return status from here. | |
| 1557 return appendTo; | |
| 1558 } | 825 } |
| 1559 | 826 |
| 1560 //------------------------------------------------------------------------------ | 827 //------------------------------------------------------------------------------ |
| 1561 | 828 |
| 1562 | 829 |
| 1563 UnicodeString& | 830 UnicodeString& |
| 1564 DecimalFormat::format(const StringPiece &number, | 831 DecimalFormat::format(const StringPiece &number, |
| 1565 UnicodeString &toAppendTo, | 832 UnicodeString &toAppendTo, |
| 1566 FieldPositionIterator *posIter, | 833 FieldPositionIterator *posIter, |
| 1567 UErrorCode &status) const | 834 UErrorCode &status) const |
| 1568 { | 835 { |
| 1569 #if UCONFIG_FORMAT_FASTPATHS_49 | 836 return fImpl->format(number, toAppendTo, posIter, status); |
| 1570 // don't bother if the int64 path is not optimized | |
| 1571 int32_t len = number.length(); | |
| 1572 | |
| 1573 if(len>0&&len<10) { /* 10 or more digits may not be an int64 */ | |
| 1574 const char *data = number.data(); | |
| 1575 int64_t num = 0; | |
| 1576 UBool neg = FALSE; | |
| 1577 UBool ok = TRUE; | |
| 1578 | |
| 1579 int32_t start = 0; | |
| 1580 | |
| 1581 if(data[start]=='+') { | |
| 1582 start++; | |
| 1583 } else if(data[start]=='-') { | |
| 1584 neg=TRUE; | |
| 1585 start++; | |
| 1586 } | |
| 1587 | |
| 1588 int32_t place = 1; /* 1, 10, ... */ | |
| 1589 for(int32_t i=len-1;i>=start;i--) { | |
| 1590 if(data[i]>='0'&&data[i]<='9') { | |
| 1591 num+=place*(int64_t)(data[i]-'0'); | |
| 1592 } else { | |
| 1593 ok=FALSE; | |
| 1594 break; | |
| 1595 } | |
| 1596 place *= 10; | |
| 1597 } | |
| 1598 | |
| 1599 if(ok) { | |
| 1600 if(neg) { | |
| 1601 num = -num;// add minus bit | |
| 1602 } | |
| 1603 // format as int64_t | |
| 1604 return format(num, toAppendTo, posIter, status); | |
| 1605 } | |
| 1606 // else fall through | |
| 1607 } | |
| 1608 #endif | |
| 1609 | |
| 1610 DigitList dnum; | |
| 1611 dnum.set(number, status); | |
| 1612 if (U_FAILURE(status)) { | |
| 1613 return toAppendTo; | |
| 1614 } | |
| 1615 FieldPositionIteratorHandler handler(posIter, status); | |
| 1616 _format(dnum, toAppendTo, handler, status); | |
| 1617 return toAppendTo; | |
| 1618 } | 837 } |
| 1619 | 838 |
| 1620 | 839 |
| 1621 UnicodeString& | 840 UnicodeString& |
| 1622 DecimalFormat::format(const DigitList &number, | 841 DecimalFormat::format(const DigitList &number, |
| 1623 UnicodeString &appendTo, | 842 UnicodeString &appendTo, |
| 1624 FieldPositionIterator *posIter, | 843 FieldPositionIterator *posIter, |
| 1625 UErrorCode &status) const { | 844 UErrorCode &status) const { |
| 1626 FieldPositionIteratorHandler handler(posIter, status); | 845 return fImpl->format(number, appendTo, posIter, status); |
| 1627 _format(number, appendTo, handler, status); | |
| 1628 return appendTo; | |
| 1629 } | 846 } |
| 1630 | 847 |
| 1631 | 848 |
| 1632 | |
| 1633 UnicodeString& | 849 UnicodeString& |
| 1634 DecimalFormat::format(const DigitList &number, | 850 DecimalFormat::format(const DigitList &number, |
| 1635 UnicodeString& appendTo, | 851 UnicodeString& appendTo, |
| 1636 FieldPosition& pos, | 852 FieldPosition& pos, |
| 1637 UErrorCode &status) const { | 853 UErrorCode &status) const { |
| 1638 FieldPositionOnlyHandler handler(pos); | 854 return fImpl->format(number, appendTo, pos, status); |
| 1639 _format(number, appendTo, handler, status); | |
| 1640 return appendTo; | |
| 1641 } | |
| 1642 | |
| 1643 DigitList& | |
| 1644 DecimalFormat::_round(const DigitList &number, DigitList &adjustedNum, UBool& is
Negative, UErrorCode &status) const { | |
| 1645 if (U_FAILURE(status)) { | |
| 1646 return adjustedNum; | |
| 1647 } | |
| 1648 | |
| 1649 // note: number and adjustedNum may refer to the same DigitList, in cases wh
ere a copy | |
| 1650 // is not needed by the caller. | |
| 1651 | |
| 1652 adjustedNum = number; | |
| 1653 isNegative = false; | |
| 1654 if (number.isNaN()) { | |
| 1655 return adjustedNum; | |
| 1656 } | |
| 1657 | |
| 1658 // Do this BEFORE checking to see if value is infinite or negative! Sets the | |
| 1659 // begin and end index to be length of the string composed of | |
| 1660 // localized name of Infinite and the positive/negative localized | |
| 1661 // signs. | |
| 1662 | |
| 1663 adjustedNum.setRoundingMode(fRoundingMode); | |
| 1664 if (fMultiplier != NULL) { | |
| 1665 adjustedNum.mult(*fMultiplier, status); | |
| 1666 if (U_FAILURE(status)) { | |
| 1667 return adjustedNum; | |
| 1668 } | |
| 1669 } | |
| 1670 | |
| 1671 if (fScale != 0) { | |
| 1672 DigitList ten; | |
| 1673 ten.set((int32_t)10); | |
| 1674 if (fScale > 0) { | |
| 1675 for (int32_t i = fScale ; i > 0 ; i--) { | |
| 1676 adjustedNum.mult(ten, status); | |
| 1677 if (U_FAILURE(status)) { | |
| 1678 return adjustedNum; | |
| 1679 } | |
| 1680 } | |
| 1681 } else { | |
| 1682 for (int32_t i = fScale ; i < 0 ; i++) { | |
| 1683 adjustedNum.div(ten, status); | |
| 1684 if (U_FAILURE(status)) { | |
| 1685 return adjustedNum; | |
| 1686 } | |
| 1687 } | |
| 1688 } | |
| 1689 } | |
| 1690 | |
| 1691 /* | |
| 1692 * Note: sign is important for zero as well as non-zero numbers. | |
| 1693 * Proper detection of -0.0 is needed to deal with the | |
| 1694 * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98. | |
| 1695 */ | |
| 1696 isNegative = !adjustedNum.isPositive(); | |
| 1697 | |
| 1698 // Apply rounding after multiplier | |
| 1699 | |
| 1700 adjustedNum.fContext.status &= ~DEC_Inexact; | |
| 1701 if (fRoundingIncrement != NULL) { | |
| 1702 adjustedNum.div(*fRoundingIncrement, status); | |
| 1703 adjustedNum.toIntegralValue(); | |
| 1704 adjustedNum.mult(*fRoundingIncrement, status); | |
| 1705 adjustedNum.trim(); | |
| 1706 if (U_FAILURE(status)) { | |
| 1707 return adjustedNum; | |
| 1708 } | |
| 1709 } | |
| 1710 if (fRoundingMode == kRoundUnnecessary && (adjustedNum.fContext.status & DEC
_Inexact)) { | |
| 1711 status = U_FORMAT_INEXACT_ERROR; | |
| 1712 return adjustedNum; | |
| 1713 } | |
| 1714 | |
| 1715 if (adjustedNum.isInfinite()) { | |
| 1716 return adjustedNum; | |
| 1717 } | |
| 1718 | |
| 1719 if (fUseExponentialNotation || areSignificantDigitsUsed()) { | |
| 1720 int32_t sigDigits = precision(); | |
| 1721 if (sigDigits > 0) { | |
| 1722 adjustedNum.round(sigDigits); | |
| 1723 // Travis Keep (21/2/2014): Calling round on a digitList does not ne
cessarily | |
| 1724 // preserve the sign of that digit list. Preserving the sign is espe
cially | |
| 1725 // important when formatting -0.0 for instance. Not preserving the s
ign seems | |
| 1726 // like a bug because I cannot think of any case where the sign woul
d actually | |
| 1727 // have to change when rounding. For now, we preserve the sign by se
tting the | |
| 1728 // positive attribute directly. | |
| 1729 adjustedNum.setPositive(!isNegative); | |
| 1730 } | |
| 1731 } else { | |
| 1732 // Fixed point format. Round to a set number of fraction digits. | |
| 1733 int32_t numFractionDigits = precision(); | |
| 1734 adjustedNum.roundFixedPoint(numFractionDigits); | |
| 1735 } | |
| 1736 if (fRoundingMode == kRoundUnnecessary && (adjustedNum.fContext.status & DEC
_Inexact)) { | |
| 1737 status = U_FORMAT_INEXACT_ERROR; | |
| 1738 return adjustedNum; | |
| 1739 } | |
| 1740 return adjustedNum; | |
| 1741 } | 855 } |
| 1742 | 856 |
| 1743 UnicodeString& | 857 UnicodeString& |
| 1744 DecimalFormat::_format(const DigitList &number, | 858 DecimalFormat::format(const VisibleDigitsWithExponent &number, |
| 1745 UnicodeString& appendTo, | 859 UnicodeString &appendTo, |
| 1746 FieldPositionHandler& handler, | 860 FieldPositionIterator *posIter, |
| 1747 UErrorCode &status) const | 861 UErrorCode &status) const { |
| 1748 { | 862 return fImpl->format(number, appendTo, posIter, status); |
| 1749 if (U_FAILURE(status)) { | |
| 1750 return appendTo; | |
| 1751 } | |
| 1752 | |
| 1753 // Special case for NaN, sets the begin and end index to be the | |
| 1754 // the string length of localized name of NaN. | |
| 1755 if (number.isNaN()) | |
| 1756 { | |
| 1757 int begin = appendTo.length(); | |
| 1758 appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol); | |
| 1759 | |
| 1760 handler.addAttribute(kIntegerField, begin, appendTo.length()); | |
| 1761 | |
| 1762 addPadding(appendTo, handler, 0, 0); | |
| 1763 return appendTo; | |
| 1764 } | |
| 1765 | |
| 1766 DigitList adjustedNum; | |
| 1767 UBool isNegative; | |
| 1768 _round(number, adjustedNum, isNegative, status); | |
| 1769 if (U_FAILURE(status)) { | |
| 1770 return appendTo; | |
| 1771 } | |
| 1772 | |
| 1773 // Special case for INFINITE, | |
| 1774 if (adjustedNum.isInfinite()) { | |
| 1775 int32_t prefixLen = appendAffix(appendTo, adjustedNum.getDouble(), handl
er, isNegative, TRUE); | |
| 1776 | |
| 1777 int begin = appendTo.length(); | |
| 1778 appendTo += getConstSymbol(DecimalFormatSymbols::kInfinitySymbol); | |
| 1779 | |
| 1780 handler.addAttribute(kIntegerField, begin, appendTo.length()); | |
| 1781 | |
| 1782 int32_t suffixLen = appendAffix(appendTo, adjustedNum.getDouble(), handl
er, isNegative, FALSE); | |
| 1783 | |
| 1784 addPadding(appendTo, handler, prefixLen, suffixLen); | |
| 1785 return appendTo; | |
| 1786 } | |
| 1787 return subformat(appendTo, handler, adjustedNum, FALSE, status); | |
| 1788 } | 863 } |
| 1789 | 864 |
| 1790 /** | 865 |
| 1791 * Return true if a grouping separator belongs at the given | 866 UnicodeString& |
| 1792 * position, based on whether grouping is in use and the values of | 867 DecimalFormat::format(const VisibleDigitsWithExponent &number, |
| 1793 * the primary and secondary grouping interval. | 868 UnicodeString& appendTo, |
| 1794 * @param pos the number of integer digits to the right of | 869 FieldPosition& pos, |
| 1795 * the current position. Zero indicates the position after the | 870 UErrorCode &status) const { |
| 1796 * rightmost integer digit. | 871 return fImpl->format(number, appendTo, pos, status); |
| 1797 * @return true if a grouping character belongs at the current | |
| 1798 * position. | |
| 1799 */ | |
| 1800 UBool DecimalFormat::isGroupingPosition(int32_t pos) const { | |
| 1801 UBool result = FALSE; | |
| 1802 if (isGroupingUsed() && (pos > 0) && (fGroupingSize > 0)) { | |
| 1803 if ((fGroupingSize2 > 0) && (pos > fGroupingSize)) { | |
| 1804 result = ((pos - fGroupingSize) % fGroupingSize2) == 0; | |
| 1805 } else { | |
| 1806 result = pos % fGroupingSize == 0; | |
| 1807 } | |
| 1808 } | |
| 1809 return result; | |
| 1810 } | 872 } |
| 1811 | 873 |
| 1812 //------------------------------------------------------------------------------ | 874 DigitList& |
| 1813 | 875 DecimalFormat::_round(const DigitList& number, DigitList& adjustedNum, UBool& is
Negative, UErrorCode& status) const { |
| 1814 /** | 876 adjustedNum = number; |
| 1815 * Complete the formatting of a finite number. On entry, the DigitList must | 877 fImpl->round(adjustedNum, status); |
| 1816 * be filled in with the correct digits. | 878 isNegative = !adjustedNum.isPositive(); |
| 1817 */ | 879 return adjustedNum; |
| 1818 UnicodeString& | |
| 1819 DecimalFormat::subformat(UnicodeString& appendTo, | |
| 1820 FieldPositionHandler& handler, | |
| 1821 DigitList& digits, | |
| 1822 UBool isInteger, | |
| 1823 UErrorCode& status) const | |
| 1824 { | |
| 1825 // char zero = '0'; | |
| 1826 // DigitList returns digits as '0' thru '9', so we will need to | |
| 1827 // always need to subtract the character 0 to get the numeric value to use f
or indexing. | |
| 1828 | |
| 1829 UChar32 localizedDigits[10]; | |
| 1830 localizedDigits[0] = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).
char32At(0); | |
| 1831 localizedDigits[1] = getConstSymbol(DecimalFormatSymbols::kOneDigitSymbol).c
har32At(0); | |
| 1832 localizedDigits[2] = getConstSymbol(DecimalFormatSymbols::kTwoDigitSymbol).c
har32At(0); | |
| 1833 localizedDigits[3] = getConstSymbol(DecimalFormatSymbols::kThreeDigitSymbol)
.char32At(0); | |
| 1834 localizedDigits[4] = getConstSymbol(DecimalFormatSymbols::kFourDigitSymbol).
char32At(0); | |
| 1835 localizedDigits[5] = getConstSymbol(DecimalFormatSymbols::kFiveDigitSymbol).
char32At(0); | |
| 1836 localizedDigits[6] = getConstSymbol(DecimalFormatSymbols::kSixDigitSymbol).c
har32At(0); | |
| 1837 localizedDigits[7] = getConstSymbol(DecimalFormatSymbols::kSevenDigitSymbol)
.char32At(0); | |
| 1838 localizedDigits[8] = getConstSymbol(DecimalFormatSymbols::kEightDigitSymbol)
.char32At(0); | |
| 1839 localizedDigits[9] = getConstSymbol(DecimalFormatSymbols::kNineDigitSymbol).
char32At(0); | |
| 1840 | |
| 1841 const UnicodeString *grouping ; | |
| 1842 if(fCurrencySignCount == fgCurrencySignCountZero) { | |
| 1843 grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbo
l); | |
| 1844 }else{ | |
| 1845 grouping = &getConstSymbol(DecimalFormatSymbols::kMonetaryGroupingSepara
torSymbol); | |
| 1846 } | |
| 1847 const UnicodeString *decimal; | |
| 1848 if(fCurrencySignCount == fgCurrencySignCountZero) { | |
| 1849 decimal = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)
; | |
| 1850 } else { | |
| 1851 decimal = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
); | |
| 1852 } | |
| 1853 UBool useSigDig = areSignificantDigitsUsed(); | |
| 1854 int32_t maxIntDig = getMaximumIntegerDigits(); | |
| 1855 int32_t minIntDig = getMinimumIntegerDigits(); | |
| 1856 | |
| 1857 // Appends the prefix. | |
| 1858 double doubleValue = digits.getDouble(); | |
| 1859 int32_t prefixLen = appendAffix(appendTo, doubleValue, handler, !digits.isPo
sitive(), TRUE); | |
| 1860 | |
| 1861 if (fUseExponentialNotation) | |
| 1862 { | |
| 1863 int currentLength = appendTo.length(); | |
| 1864 int intBegin = currentLength; | |
| 1865 int intEnd = -1; | |
| 1866 int fracBegin = -1; | |
| 1867 | |
| 1868 int32_t minFracDig = 0; | |
| 1869 if (useSigDig) { | |
| 1870 maxIntDig = minIntDig = 1; | |
| 1871 minFracDig = getMinimumSignificantDigits() - 1; | |
| 1872 } else { | |
| 1873 minFracDig = getMinimumFractionDigits(); | |
| 1874 if (maxIntDig > kMaxScientificIntegerDigits) { | |
| 1875 maxIntDig = 1; | |
| 1876 if (maxIntDig < minIntDig) { | |
| 1877 maxIntDig = minIntDig; | |
| 1878 } | |
| 1879 } | |
| 1880 if (maxIntDig > minIntDig) { | |
| 1881 minIntDig = 1; | |
| 1882 } | |
| 1883 } | |
| 1884 | |
| 1885 // Minimum integer digits are handled in exponential format by | |
| 1886 // adjusting the exponent. For example, 0.01234 with 3 minimum | |
| 1887 // integer digits is "123.4E-4". | |
| 1888 | |
| 1889 // Maximum integer digits are interpreted as indicating the | |
| 1890 // repeating range. This is useful for engineering notation, in | |
| 1891 // which the exponent is restricted to a multiple of 3. For | |
| 1892 // example, 0.01234 with 3 maximum integer digits is "12.34e-3". | |
| 1893 // If maximum integer digits are defined and are larger than | |
| 1894 // minimum integer digits, then minimum integer digits are | |
| 1895 // ignored. | |
| 1896 digits.reduce(); // Removes trailing zero digits. | |
| 1897 int32_t exponent = digits.getDecimalAt(); | |
| 1898 if (maxIntDig > 1 && maxIntDig != minIntDig) { | |
| 1899 // A exponent increment is defined; adjust to it. | |
| 1900 exponent = (exponent > 0) ? (exponent - 1) / maxIntDig | |
| 1901 : (exponent / maxIntDig) - 1; | |
| 1902 exponent *= maxIntDig; | |
| 1903 } else { | |
| 1904 // No exponent increment is defined; use minimum integer digits. | |
| 1905 // If none is specified, as in "#E0", generate 1 integer digit. | |
| 1906 exponent -= (minIntDig > 0 || minFracDig > 0) | |
| 1907 ? minIntDig : 1; | |
| 1908 } | |
| 1909 | |
| 1910 // We now output a minimum number of digits, and more if there | |
| 1911 // are more digits, up to the maximum number of digits. We | |
| 1912 // place the decimal point after the "integer" digits, which | |
| 1913 // are the first (decimalAt - exponent) digits. | |
| 1914 int32_t minimumDigits = minIntDig + minFracDig; | |
| 1915 // The number of integer digits is handled specially if the number | |
| 1916 // is zero, since then there may be no digits. | |
| 1917 int32_t integerDigits = digits.isZero() ? minIntDig : | |
| 1918 digits.getDecimalAt() - exponent; | |
| 1919 int32_t totalDigits = digits.getCount(); | |
| 1920 if (minimumDigits > totalDigits) | |
| 1921 totalDigits = minimumDigits; | |
| 1922 if (integerDigits > totalDigits) | |
| 1923 totalDigits = integerDigits; | |
| 1924 | |
| 1925 // totalDigits records total number of digits needs to be processed | |
| 1926 int32_t i; | |
| 1927 for (i=0; i<totalDigits; ++i) | |
| 1928 { | |
| 1929 if (i == integerDigits) | |
| 1930 { | |
| 1931 intEnd = appendTo.length(); | |
| 1932 handler.addAttribute(kIntegerField, intBegin, intEnd); | |
| 1933 | |
| 1934 appendTo += *decimal; | |
| 1935 | |
| 1936 fracBegin = appendTo.length(); | |
| 1937 handler.addAttribute(kDecimalSeparatorField, fracBegin - 1, frac
Begin); | |
| 1938 } | |
| 1939 // Restores the digit character or pads the buffer with zeros. | |
| 1940 UChar32 c = (UChar32)((i < digits.getCount()) ? | |
| 1941 localizedDigits[digits.getDigitValue(i)] : | |
| 1942 localizedDigits[0]); | |
| 1943 appendTo += c; | |
| 1944 } | |
| 1945 | |
| 1946 currentLength = appendTo.length(); | |
| 1947 | |
| 1948 if (intEnd < 0) { | |
| 1949 handler.addAttribute(kIntegerField, intBegin, currentLength); | |
| 1950 } | |
| 1951 if (fracBegin > 0) { | |
| 1952 handler.addAttribute(kFractionField, fracBegin, currentLength); | |
| 1953 } | |
| 1954 | |
| 1955 // The exponent is output using the pattern-specified minimum | |
| 1956 // exponent digits. There is no maximum limit to the exponent | |
| 1957 // digits, since truncating the exponent would appendTo in an | |
| 1958 // unacceptable inaccuracy. | |
| 1959 appendTo += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol); | |
| 1960 | |
| 1961 handler.addAttribute(kExponentSymbolField, currentLength, appendTo.lengt
h()); | |
| 1962 currentLength = appendTo.length(); | |
| 1963 | |
| 1964 // For zero values, we force the exponent to zero. We | |
| 1965 // must do this here, and not earlier, because the value | |
| 1966 // is used to determine integer digit count above. | |
| 1967 if (digits.isZero()) | |
| 1968 exponent = 0; | |
| 1969 | |
| 1970 if (exponent < 0) { | |
| 1971 appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); | |
| 1972 handler.addAttribute(kExponentSignField, currentLength, appendTo.len
gth()); | |
| 1973 } else if (fExponentSignAlwaysShown) { | |
| 1974 appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); | |
| 1975 handler.addAttribute(kExponentSignField, currentLength, appendTo.len
gth()); | |
| 1976 } | |
| 1977 | |
| 1978 currentLength = appendTo.length(); | |
| 1979 | |
| 1980 DigitList expDigits; | |
| 1981 expDigits.set(exponent); | |
| 1982 { | |
| 1983 int expDig = fMinExponentDigits; | |
| 1984 if (fUseExponentialNotation && expDig < 1) { | |
| 1985 expDig = 1; | |
| 1986 } | |
| 1987 for (i=expDigits.getDecimalAt(); i<expDig; ++i) | |
| 1988 appendTo += (localizedDigits[0]); | |
| 1989 } | |
| 1990 for (i=0; i<expDigits.getDecimalAt(); ++i) | |
| 1991 { | |
| 1992 UChar32 c = (UChar32)((i < expDigits.getCount()) ? | |
| 1993 localizedDigits[expDigits.getDigitValue(i)] : | |
| 1994 localizedDigits[0]); | |
| 1995 appendTo += c; | |
| 1996 } | |
| 1997 | |
| 1998 handler.addAttribute(kExponentField, currentLength, appendTo.length()); | |
| 1999 } | |
| 2000 else // Not using exponential notation | |
| 2001 { | |
| 2002 int currentLength = appendTo.length(); | |
| 2003 int intBegin = currentLength; | |
| 2004 | |
| 2005 int32_t sigCount = 0; | |
| 2006 int32_t minSigDig = getMinimumSignificantDigits(); | |
| 2007 int32_t maxSigDig = getMaximumSignificantDigits(); | |
| 2008 if (!useSigDig) { | |
| 2009 minSigDig = 0; | |
| 2010 maxSigDig = INT32_MAX; | |
| 2011 } | |
| 2012 | |
| 2013 // Output the integer portion. Here 'count' is the total | |
| 2014 // number of integer digits we will display, including both | |
| 2015 // leading zeros required to satisfy getMinimumIntegerDigits, | |
| 2016 // and actual digits present in the number. | |
| 2017 int32_t count = useSigDig ? | |
| 2018 _max(1, digits.getDecimalAt()) : minIntDig; | |
| 2019 if (digits.getDecimalAt() > 0 && count < digits.getDecimalAt()) { | |
| 2020 count = digits.getDecimalAt(); | |
| 2021 } | |
| 2022 | |
| 2023 // Handle the case where getMaximumIntegerDigits() is smaller | |
| 2024 // than the real number of integer digits. If this is so, we | |
| 2025 // output the least significant max integer digits. For example, | |
| 2026 // the value 1997 printed with 2 max integer digits is just "97". | |
| 2027 | |
| 2028 int32_t digitIndex = 0; // Index into digitList.fDigits[] | |
| 2029 if (count > maxIntDig && maxIntDig >= 0) { | |
| 2030 count = maxIntDig; | |
| 2031 digitIndex = digits.getDecimalAt() - count; | |
| 2032 if(fBoolFlags.contains(UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS)) { | |
| 2033 status = U_ILLEGAL_ARGUMENT_ERROR; | |
| 2034 } | |
| 2035 } | |
| 2036 | |
| 2037 int32_t sizeBeforeIntegerPart = appendTo.length(); | |
| 2038 | |
| 2039 int32_t i; | |
| 2040 for (i=count-1; i>=0; --i) | |
| 2041 { | |
| 2042 if (i < digits.getDecimalAt() && digitIndex < digits.getCount() && | |
| 2043 sigCount < maxSigDig) { | |
| 2044 // Output a real digit | |
| 2045 appendTo += (UChar32)localizedDigits[digits.getDigitValue(digitI
ndex++)]; | |
| 2046 ++sigCount; | |
| 2047 } | |
| 2048 else | |
| 2049 { | |
| 2050 // Output a zero (leading or trailing) | |
| 2051 appendTo += localizedDigits[0]; | |
| 2052 if (sigCount > 0) { | |
| 2053 ++sigCount; | |
| 2054 } | |
| 2055 } | |
| 2056 | |
| 2057 // Output grouping separator if necessary. | |
| 2058 if (isGroupingPosition(i)) { | |
| 2059 currentLength = appendTo.length(); | |
| 2060 appendTo.append(*grouping); | |
| 2061 handler.addAttribute(kGroupingSeparatorField, currentLength, app
endTo.length()); | |
| 2062 } | |
| 2063 } | |
| 2064 | |
| 2065 // This handles the special case of formatting 0. For zero only, we coun
t the | |
| 2066 // zero to the left of the decimal point as one signficant digit. Ordina
rily we | |
| 2067 // do not count any leading 0's as significant. If the number we are for
matting | |
| 2068 // is not zero, then either sigCount or digits.getCount() will be non-ze
ro. | |
| 2069 if (sigCount == 0 && digits.getCount() == 0) { | |
| 2070 sigCount = 1; | |
| 2071 } | |
| 2072 | |
| 2073 // TODO(dlf): this looks like it was a bug, we marked the int field as e
nding | |
| 2074 // before the zero was generated. | |
| 2075 // Record field information for caller. | |
| 2076 // if (fieldPosition.getField() == NumberFormat::kIntegerField) | |
| 2077 // fieldPosition.setEndIndex(appendTo.length()); | |
| 2078 | |
| 2079 // Determine whether or not there are any printable fractional | |
| 2080 // digits. If we've used up the digits we know there aren't. | |
| 2081 UBool fractionPresent = (!isInteger && digitIndex < digits.getCount()) |
| | |
| 2082 (useSigDig ? (sigCount < minSigDig) : (getMinimumFractionDigits() >
0)); | |
| 2083 | |
| 2084 // If there is no fraction present, and we haven't printed any | |
| 2085 // integer digits, then print a zero. Otherwise we won't print | |
| 2086 // _any_ digits, and we won't be able to parse this string. | |
| 2087 if (!fractionPresent && appendTo.length() == sizeBeforeIntegerPart) | |
| 2088 appendTo += localizedDigits[0]; | |
| 2089 | |
| 2090 currentLength = appendTo.length(); | |
| 2091 handler.addAttribute(kIntegerField, intBegin, currentLength); | |
| 2092 | |
| 2093 // Output the decimal separator if we always do so. | |
| 2094 if (fDecimalSeparatorAlwaysShown || fractionPresent) { | |
| 2095 appendTo += *decimal; | |
| 2096 handler.addAttribute(kDecimalSeparatorField, currentLength, appendTo
.length()); | |
| 2097 currentLength = appendTo.length(); | |
| 2098 } | |
| 2099 | |
| 2100 int fracBegin = currentLength; | |
| 2101 | |
| 2102 count = useSigDig ? INT32_MAX : getMaximumFractionDigits(); | |
| 2103 if (useSigDig && (sigCount == maxSigDig || | |
| 2104 (sigCount >= minSigDig && digitIndex == digits.getCoun
t()))) { | |
| 2105 count = 0; | |
| 2106 } | |
| 2107 | |
| 2108 for (i=0; i < count; ++i) { | |
| 2109 // Here is where we escape from the loop. We escape | |
| 2110 // if we've output the maximum fraction digits | |
| 2111 // (specified in the for expression above). We also | |
| 2112 // stop when we've output the minimum digits and | |
| 2113 // either: we have an integer, so there is no | |
| 2114 // fractional stuff to display, or we're out of | |
| 2115 // significant digits. | |
| 2116 if (!useSigDig && i >= getMinimumFractionDigits() && | |
| 2117 (isInteger || digitIndex >= digits.getCount())) { | |
| 2118 break; | |
| 2119 } | |
| 2120 | |
| 2121 // Output leading fractional zeros. These are zeros | |
| 2122 // that come after the decimal but before any | |
| 2123 // significant digits. These are only output if | |
| 2124 // abs(number being formatted) < 1.0. | |
| 2125 if (-1-i > (digits.getDecimalAt()-1)) { | |
| 2126 appendTo += localizedDigits[0]; | |
| 2127 continue; | |
| 2128 } | |
| 2129 | |
| 2130 // Output a digit, if we have any precision left, or a | |
| 2131 // zero if we don't. We don't want to output noise digits. | |
| 2132 if (!isInteger && digitIndex < digits.getCount()) { | |
| 2133 appendTo += (UChar32)localizedDigits[digits.getDigitValue(digitI
ndex++)]; | |
| 2134 } else { | |
| 2135 appendTo += localizedDigits[0]; | |
| 2136 } | |
| 2137 | |
| 2138 // If we reach the maximum number of significant | |
| 2139 // digits, or if we output all the real digits and | |
| 2140 // reach the minimum, then we are done. | |
| 2141 ++sigCount; | |
| 2142 if (useSigDig && | |
| 2143 (sigCount == maxSigDig || | |
| 2144 (digitIndex == digits.getCount() && sigCount >= minSigDig))) { | |
| 2145 break; | |
| 2146 } | |
| 2147 } | |
| 2148 | |
| 2149 handler.addAttribute(kFractionField, fracBegin, appendTo.length()); | |
| 2150 } | |
| 2151 | |
| 2152 int32_t suffixLen = appendAffix(appendTo, doubleValue, handler, !digits.isPo
sitive(), FALSE); | |
| 2153 | |
| 2154 addPadding(appendTo, handler, prefixLen, suffixLen); | |
| 2155 return appendTo; | |
| 2156 } | 880 } |
| 2157 | 881 |
| 2158 /** | |
| 2159 * Inserts the character fPad as needed to expand result to fFormatWidth. | |
| 2160 * @param result the string to be padded | |
| 2161 */ | |
| 2162 void DecimalFormat::addPadding(UnicodeString& appendTo, | |
| 2163 FieldPositionHandler& handler, | |
| 2164 int32_t prefixLen, | |
| 2165 int32_t suffixLen) const | |
| 2166 { | |
| 2167 if (fFormatWidth > 0) { | |
| 2168 int32_t len = fFormatWidth - appendTo.length(); | |
| 2169 if (len > 0) { | |
| 2170 UnicodeString padding; | |
| 2171 for (int32_t i=0; i<len; ++i) { | |
| 2172 padding += fPad; | |
| 2173 } | |
| 2174 switch (fPadPosition) { | |
| 2175 case kPadAfterPrefix: | |
| 2176 appendTo.insert(prefixLen, padding); | |
| 2177 break; | |
| 2178 case kPadBeforePrefix: | |
| 2179 appendTo.insert(0, padding); | |
| 2180 break; | |
| 2181 case kPadBeforeSuffix: | |
| 2182 appendTo.insert(appendTo.length() - suffixLen, padding); | |
| 2183 break; | |
| 2184 case kPadAfterSuffix: | |
| 2185 appendTo += padding; | |
| 2186 break; | |
| 2187 } | |
| 2188 if (fPadPosition == kPadBeforePrefix || fPadPosition == kPadAfterPre
fix) { | |
| 2189 handler.shiftLast(len); | |
| 2190 } | |
| 2191 } | |
| 2192 } | |
| 2193 } | |
| 2194 | |
| 2195 //------------------------------------------------------------------------------ | |
| 2196 | |
| 2197 void | 882 void |
| 2198 DecimalFormat::parse(const UnicodeString& text, | 883 DecimalFormat::parse(const UnicodeString& text, |
| 2199 Formattable& result, | 884 Formattable& result, |
| 2200 ParsePosition& parsePosition) const { | 885 ParsePosition& parsePosition) const { |
| 2201 parse(text, result, parsePosition, NULL); | 886 parse(text, result, parsePosition, NULL); |
| 2202 } | 887 } |
| 2203 | 888 |
| 2204 CurrencyAmount* DecimalFormat::parseCurrency(const UnicodeString& text, | 889 CurrencyAmount* DecimalFormat::parseCurrency(const UnicodeString& text, |
| 2205 ParsePosition& pos) const { | 890 ParsePosition& pos) const { |
| 2206 Formattable parseResult; | 891 Formattable parseResult; |
| 2207 int32_t start = pos.getIndex(); | 892 int32_t start = pos.getIndex(); |
| 2208 UChar curbuf[4] = {}; | 893 UChar curbuf[4] = {}; |
| 2209 parse(text, parseResult, pos, curbuf); | 894 parse(text, parseResult, pos, curbuf); |
| 2210 if (pos.getIndex() != start) { | 895 if (pos.getIndex() != start) { |
| 2211 UErrorCode ec = U_ZERO_ERROR; | 896 UErrorCode ec = U_ZERO_ERROR; |
| 2212 LocalPointer<CurrencyAmount> currAmt(new CurrencyAmount(parseResult, cur
buf, ec)); | 897 LocalPointer<CurrencyAmount> currAmt(new CurrencyAmount(parseResult, cur
buf, ec), ec); |
| 2213 if (U_FAILURE(ec)) { | 898 if (U_FAILURE(ec)) { |
| 2214 pos.setIndex(start); // indicate failure | 899 pos.setIndex(start); // indicate failure |
| 2215 } else { | 900 } else { |
| 2216 return currAmt.orphan(); | 901 return currAmt.orphan(); |
| 2217 } | 902 } |
| 2218 } | 903 } |
| 2219 return NULL; | 904 return NULL; |
| 2220 } | 905 } |
| 2221 | 906 |
| 2222 /** | 907 /** |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2243 // clear any old contents in the result. In particular, clears any DigitLis
t | 928 // clear any old contents in the result. In particular, clears any DigitLis
t |
| 2244 // that it may be holding. | 929 // that it may be holding. |
| 2245 result.setLong(0); | 930 result.setLong(0); |
| 2246 if (currency != NULL) { | 931 if (currency != NULL) { |
| 2247 for (int32_t ci=0; ci<4; ci++) { | 932 for (int32_t ci=0; ci<4; ci++) { |
| 2248 currency[ci] = 0; | 933 currency[ci] = 0; |
| 2249 } | 934 } |
| 2250 } | 935 } |
| 2251 | 936 |
| 2252 // Handle NaN as a special case: | 937 // Handle NaN as a special case: |
| 938 int32_t formatWidth = fImpl->getOldFormatWidth(); |
| 2253 | 939 |
| 2254 // Skip padding characters, if around prefix | 940 // Skip padding characters, if around prefix |
| 2255 if (fFormatWidth > 0 && (fPadPosition == kPadBeforePrefix || | 941 if (formatWidth > 0 && ( |
| 2256 fPadPosition == kPadAfterPrefix)) { | 942 fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePr
efix || |
| 943 fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPre
fix)) { |
| 2257 i = skipPadding(text, i); | 944 i = skipPadding(text, i); |
| 2258 } | 945 } |
| 2259 | 946 |
| 2260 if (isLenient()) { | 947 if (isLenient()) { |
| 2261 // skip any leading whitespace | 948 // skip any leading whitespace |
| 2262 i = backup = skipUWhiteSpace(text, i); | 949 i = backup = skipUWhiteSpace(text, i); |
| 2263 } | 950 } |
| 2264 | 951 |
| 2265 // If the text is composed of the representation of NaN, returns NaN.length | 952 // If the text is composed of the representation of NaN, returns NaN.length |
| 2266 const UnicodeString *nan = &getConstSymbol(DecimalFormatSymbols::kNaNSymbol)
; | 953 const UnicodeString *nan = &fImpl->getConstSymbol(DecimalFormatSymbols::kNaN
Symbol); |
| 2267 int32_t nanLen = (text.compare(i, nan->length(), *nan) | 954 int32_t nanLen = (text.compare(i, nan->length(), *nan) |
| 2268 ? 0 : nan->length()); | 955 ? 0 : nan->length()); |
| 2269 if (nanLen) { | 956 if (nanLen) { |
| 2270 i += nanLen; | 957 i += nanLen; |
| 2271 if (fFormatWidth > 0 && (fPadPosition == kPadBeforeSuffix || | 958 if (formatWidth > 0 && (fImpl->fAffixes.fPadPosition == DigitAffixesAndP
adding::kPadBeforeSuffix || fImpl->fAffixes.fPadPosition == DigitAffixesAndPaddi
ng::kPadAfterSuffix)) { |
| 2272 fPadPosition == kPadAfterSuffix)) { | |
| 2273 i = skipPadding(text, i); | 959 i = skipPadding(text, i); |
| 2274 } | 960 } |
| 2275 parsePosition.setIndex(i); | 961 parsePosition.setIndex(i); |
| 2276 result.setDouble(uprv_getNaN()); | 962 result.setDouble(uprv_getNaN()); |
| 2277 return; | 963 return; |
| 2278 } | 964 } |
| 2279 | 965 |
| 2280 // NaN parse failed; start over | 966 // NaN parse failed; start over |
| 2281 i = backup; | 967 i = backup; |
| 2282 parsePosition.setIndex(i); | 968 parsePosition.setIndex(i); |
| 2283 | 969 |
| 2284 // status is used to record whether a number is infinite. | 970 // status is used to record whether a number is infinite. |
| 2285 UBool status[fgStatusLength]; | 971 UBool status[fgStatusLength]; |
| 2286 | 972 |
| 2287 DigitList *digits = result.getInternalDigitList(); // get one from the stack
buffer | 973 DigitList *digits = result.getInternalDigitList(); // get one from the stack
buffer |
| 2288 if (digits == NULL) { | 974 if (digits == NULL) { |
| 2289 return; // no way to report error from here. | 975 return; // no way to report error from here. |
| 2290 } | 976 } |
| 2291 | 977 |
| 2292 if (fCurrencySignCount != fgCurrencySignCountZero) { | 978 if (fImpl->fMonetary) { |
| 2293 if (!parseForCurrency(text, parsePosition, *digits, | 979 if (!parseForCurrency(text, parsePosition, *digits, |
| 2294 status, currency)) { | 980 status, currency)) { |
| 2295 return; | 981 return; |
| 2296 } | 982 } |
| 2297 } else { | 983 } else { |
| 2298 if (!subparse(text, | 984 if (!subparse(text, |
| 2299 fNegPrefixPattern, fNegSuffixPattern, | 985 &fImpl->fAffixes.fNegativePrefix.getOtherVariant().toStrin
g(), |
| 2300 fPosPrefixPattern, fPosSuffixPattern, | 986 &fImpl->fAffixes.fNegativeSuffix.getOtherVariant().toStrin
g(), |
| 987 &fImpl->fAffixes.fPositivePrefix.getOtherVariant().toStrin
g(), |
| 988 &fImpl->fAffixes.fPositiveSuffix.getOtherVariant().toStrin
g(), |
| 2301 FALSE, UCURR_SYMBOL_NAME, | 989 FALSE, UCURR_SYMBOL_NAME, |
| 2302 parsePosition, *digits, status, currency)) { | 990 parsePosition, *digits, status, currency)) { |
| 2303 debug("!subparse(...) - rewind"); | 991 debug("!subparse(...) - rewind"); |
| 2304 parsePosition.setIndex(startIdx); | 992 parsePosition.setIndex(startIdx); |
| 2305 return; | 993 return; |
| 2306 } | 994 } |
| 2307 } | 995 } |
| 2308 | 996 |
| 2309 // Handle infinity | 997 // Handle infinity |
| 2310 if (status[fgStatusInfinite]) { | 998 if (status[fgStatusInfinite]) { |
| 2311 double inf = uprv_getInfinity(); | 999 double inf = uprv_getInfinity(); |
| 2312 result.setDouble(digits->isPositive() ? inf : -inf); | 1000 result.setDouble(digits->isPositive() ? inf : -inf); |
| 2313 // TODO: set the dl to infinity, and let it fall into the code below. | 1001 // TODO: set the dl to infinity, and let it fall into the code below. |
| 2314 } | 1002 } |
| 2315 | 1003 |
| 2316 else { | 1004 else { |
| 2317 | 1005 |
| 2318 if (fMultiplier != NULL) { | 1006 if (!fImpl->fMultiplier.isZero()) { |
| 2319 UErrorCode ec = U_ZERO_ERROR; | 1007 UErrorCode ec = U_ZERO_ERROR; |
| 2320 digits->div(*fMultiplier, ec); | 1008 digits->div(fImpl->fMultiplier, ec); |
| 2321 } | 1009 } |
| 2322 | 1010 |
| 2323 if (fScale != 0) { | 1011 if (fImpl->fScale != 0) { |
| 2324 DigitList ten; | 1012 DigitList ten; |
| 2325 ten.set((int32_t)10); | 1013 ten.set((int32_t)10); |
| 2326 if (fScale > 0) { | 1014 if (fImpl->fScale > 0) { |
| 2327 for (int32_t i = fScale; i > 0; i--) { | 1015 for (int32_t i = fImpl->fScale; i > 0; i--) { |
| 2328 UErrorCode ec = U_ZERO_ERROR; | 1016 UErrorCode ec = U_ZERO_ERROR; |
| 2329 digits->div(ten,ec); | 1017 digits->div(ten,ec); |
| 2330 } | 1018 } |
| 2331 } else { | 1019 } else { |
| 2332 for (int32_t i = fScale; i < 0; i++) { | 1020 for (int32_t i = fImpl->fScale; i < 0; i++) { |
| 2333 UErrorCode ec = U_ZERO_ERROR; | 1021 UErrorCode ec = U_ZERO_ERROR; |
| 2334 digits->mult(ten,ec); | 1022 digits->mult(ten,ec); |
| 2335 } | 1023 } |
| 2336 } | 1024 } |
| 2337 } | 1025 } |
| 2338 | 1026 |
| 2339 // Negative zero special case: | 1027 // Negative zero special case: |
| 2340 // if parsing integerOnly, change to +0, which goes into an int32 in
a Formattable. | 1028 // if parsing integerOnly, change to +0, which goes into an int32 in
a Formattable. |
| 2341 // if not parsing integerOnly, leave as -0, which a double can repres
ent. | 1029 // if not parsing integerOnly, leave as -0, which a double can repres
ent. |
| 2342 if (digits->isZero() && !digits->isPositive() && isParseIntegerOnly()) { | 1030 if (digits->isZero() && !digits->isPositive() && isParseIntegerOnly()) { |
| 2343 digits->setPositive(TRUE); | 1031 digits->setPositive(TRUE); |
| 2344 } | 1032 } |
| 2345 result.adoptDigitList(digits); | 1033 result.adoptDigitList(digits); |
| 2346 } | 1034 } |
| 2347 } | 1035 } |
| 2348 | 1036 |
| 2349 | 1037 |
| 2350 | 1038 |
| 2351 UBool | 1039 UBool |
| 2352 DecimalFormat::parseForCurrency(const UnicodeString& text, | 1040 DecimalFormat::parseForCurrency(const UnicodeString& text, |
| 2353 ParsePosition& parsePosition, | 1041 ParsePosition& parsePosition, |
| 2354 DigitList& digits, | 1042 DigitList& digits, |
| 2355 UBool* status, | 1043 UBool* status, |
| 2356 UChar* currency) const { | 1044 UChar* currency) const { |
| 1045 UnicodeString positivePrefix; |
| 1046 UnicodeString positiveSuffix; |
| 1047 UnicodeString negativePrefix; |
| 1048 UnicodeString negativeSuffix; |
| 1049 fImpl->fPositivePrefixPattern.toString(positivePrefix); |
| 1050 fImpl->fPositiveSuffixPattern.toString(positiveSuffix); |
| 1051 fImpl->fNegativePrefixPattern.toString(negativePrefix); |
| 1052 fImpl->fNegativeSuffixPattern.toString(negativeSuffix); |
| 1053 |
| 2357 int origPos = parsePosition.getIndex(); | 1054 int origPos = parsePosition.getIndex(); |
| 2358 int maxPosIndex = origPos; | 1055 int maxPosIndex = origPos; |
| 2359 int maxErrorPos = -1; | 1056 int maxErrorPos = -1; |
| 2360 // First, parse against current pattern. | 1057 // First, parse against current pattern. |
| 2361 // Since current pattern could be set by applyPattern(), | 1058 // Since current pattern could be set by applyPattern(), |
| 2362 // it could be an arbitrary pattern, and it may not be the one | 1059 // it could be an arbitrary pattern, and it may not be the one |
| 2363 // defined in current locale. | 1060 // defined in current locale. |
| 2364 UBool tmpStatus[fgStatusLength]; | 1061 UBool tmpStatus[fgStatusLength]; |
| 2365 ParsePosition tmpPos(origPos); | 1062 ParsePosition tmpPos(origPos); |
| 2366 DigitList tmpDigitList; | 1063 DigitList tmpDigitList; |
| 2367 UBool found; | 1064 UBool found; |
| 2368 if (fStyle == UNUM_CURRENCY_PLURAL) { | 1065 if (fStyle == UNUM_CURRENCY_PLURAL) { |
| 2369 found = subparse(text, | 1066 found = subparse(text, |
| 2370 fNegPrefixPattern, fNegSuffixPattern, | 1067 &negativePrefix, &negativeSuffix, |
| 2371 fPosPrefixPattern, fPosSuffixPattern, | 1068 &positivePrefix, &positiveSuffix, |
| 2372 TRUE, UCURR_LONG_NAME, | 1069 TRUE, UCURR_LONG_NAME, |
| 2373 tmpPos, tmpDigitList, tmpStatus, currency); | 1070 tmpPos, tmpDigitList, tmpStatus, currency); |
| 2374 } else { | 1071 } else { |
| 2375 found = subparse(text, | 1072 found = subparse(text, |
| 2376 fNegPrefixPattern, fNegSuffixPattern, | 1073 &negativePrefix, &negativeSuffix, |
| 2377 fPosPrefixPattern, fPosSuffixPattern, | 1074 &positivePrefix, &positiveSuffix, |
| 2378 TRUE, UCURR_SYMBOL_NAME, | 1075 TRUE, UCURR_SYMBOL_NAME, |
| 2379 tmpPos, tmpDigitList, tmpStatus, currency); | 1076 tmpPos, tmpDigitList, tmpStatus, currency); |
| 2380 } | 1077 } |
| 2381 if (found) { | 1078 if (found) { |
| 2382 if (tmpPos.getIndex() > maxPosIndex) { | 1079 if (tmpPos.getIndex() > maxPosIndex) { |
| 2383 maxPosIndex = tmpPos.getIndex(); | 1080 maxPosIndex = tmpPos.getIndex(); |
| 2384 for (int32_t i = 0; i < fgStatusLength; ++i) { | 1081 for (int32_t i = 0; i < fgStatusLength; ++i) { |
| 2385 status[i] = tmpStatus[i]; | 1082 status[i] = tmpStatus[i]; |
| 2386 } | 1083 } |
| 2387 digits = tmpDigitList; | 1084 digits = tmpDigitList; |
| 2388 } | 1085 } |
| 2389 } else { | 1086 } else { |
| 2390 maxErrorPos = tmpPos.getErrorIndex(); | 1087 maxErrorPos = tmpPos.getErrorIndex(); |
| 2391 } | 1088 } |
| 2392 // Then, parse against affix patterns. | 1089 // Then, parse against affix patterns. |
| 2393 // Those are currency patterns and currency plural patterns. | 1090 // Those are currency patterns and currency plural patterns. |
| 2394 int32_t pos = -1; | 1091 int32_t pos = UHASH_FIRST; |
| 2395 const UHashElement* element = NULL; | 1092 const UHashElement* element = NULL; |
| 2396 while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) { | 1093 while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) { |
| 2397 const UHashTok valueTok = element->value; | 1094 const UHashTok valueTok = element->value; |
| 2398 const AffixPatternsForCurrency* affixPtn = (AffixPatternsForCurrency*)va
lueTok.pointer; | 1095 const AffixPatternsForCurrency* affixPtn = (AffixPatternsForCurrency*)va
lueTok.pointer; |
| 2399 UBool tmpStatus[fgStatusLength]; | 1096 UBool tmpStatus[fgStatusLength]; |
| 2400 ParsePosition tmpPos(origPos); | 1097 ParsePosition tmpPos(origPos); |
| 2401 DigitList tmpDigitList; | 1098 DigitList tmpDigitList; |
| 2402 | 1099 |
| 2403 #ifdef FMT_DEBUG | 1100 #ifdef FMT_DEBUG |
| 2404 debug("trying affix for currency.."); | 1101 debug("trying affix for currency.."); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2439 // output currency is not requested. After the complex currency | 1136 // output currency is not requested. After the complex currency |
| 2440 // parsing implementation was introduced, the default currency | 1137 // parsing implementation was introduced, the default currency |
| 2441 // instance parsing slowed down because of the new code flow. | 1138 // instance parsing slowed down because of the new code flow. |
| 2442 // I filed #10312 - Yoshito | 1139 // I filed #10312 - Yoshito |
| 2443 UBool tmpStatus_2[fgStatusLength]; | 1140 UBool tmpStatus_2[fgStatusLength]; |
| 2444 ParsePosition tmpPos_2(origPos); | 1141 ParsePosition tmpPos_2(origPos); |
| 2445 DigitList tmpDigitList_2; | 1142 DigitList tmpDigitList_2; |
| 2446 | 1143 |
| 2447 // Disable complex currency parsing and try it again. | 1144 // Disable complex currency parsing and try it again. |
| 2448 UBool result = subparse(text, | 1145 UBool result = subparse(text, |
| 2449 &fNegativePrefix, &fNegativeSuffix, | 1146 &fImpl->fAffixes.fNegativePrefix.getOtherVariant().t
oString(), |
| 2450 &fPositivePrefix, &fPositiveSuffix, | 1147 &fImpl->fAffixes.fNegativeSuffix.getOtherVariant().t
oString(), |
| 1148 &fImpl->fAffixes.fPositivePrefix.getOtherVariant().t
oString(), |
| 1149 &fImpl->fAffixes.fPositiveSuffix.getOtherVariant().t
oString(), |
| 2451 FALSE /* disable complex currency parsing */, UCURR_
SYMBOL_NAME, | 1150 FALSE /* disable complex currency parsing */, UCURR_
SYMBOL_NAME, |
| 2452 tmpPos_2, tmpDigitList_2, tmpStatus_2, | 1151 tmpPos_2, tmpDigitList_2, tmpStatus_2, |
| 2453 currency); | 1152 currency); |
| 2454 if (result) { | 1153 if (result) { |
| 2455 if (tmpPos_2.getIndex() > maxPosIndex) { | 1154 if (tmpPos_2.getIndex() > maxPosIndex) { |
| 2456 maxPosIndex = tmpPos_2.getIndex(); | 1155 maxPosIndex = tmpPos_2.getIndex(); |
| 2457 for (int32_t i = 0; i < fgStatusLength; ++i) { | 1156 for (int32_t i = 0; i < fgStatusLength; ++i) { |
| 2458 status[i] = tmpStatus_2[i]; | 1157 status[i] = tmpStatus_2[i]; |
| 2459 } | 1158 } |
| 2460 digits = tmpDigitList_2; | 1159 digits = tmpDigitList_2; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2511 // will be acceptable to the decNumber library, then at the end passes that
string | 1210 // will be acceptable to the decNumber library, then at the end passes that
string |
| 2512 // off for conversion to a decNumber. | 1211 // off for conversion to a decNumber. |
| 2513 UErrorCode err = U_ZERO_ERROR; | 1212 UErrorCode err = U_ZERO_ERROR; |
| 2514 CharString parsedNum; | 1213 CharString parsedNum; |
| 2515 digits.setToZero(); | 1214 digits.setToZero(); |
| 2516 | 1215 |
| 2517 int32_t position = parsePosition.getIndex(); | 1216 int32_t position = parsePosition.getIndex(); |
| 2518 int32_t oldStart = position; | 1217 int32_t oldStart = position; |
| 2519 int32_t textLength = text.length(); // One less pointer to follow | 1218 int32_t textLength = text.length(); // One less pointer to follow |
| 2520 UBool strictParse = !isLenient(); | 1219 UBool strictParse = !isLenient(); |
| 2521 UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32
At(0); | 1220 UChar32 zero = fImpl->getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol)
.char32At(0); |
| 2522 const UnicodeString *groupingString = &getConstSymbol(fCurrencySignCount ==
fgCurrencySignCountZero ? | 1221 const UnicodeString *groupingString = &fImpl->getConstSymbol( |
| 2523 DecimalFormatSymbols::kGroupingSeparatorSymbol : DecimalFormatSymbols::k
MonetaryGroupingSeparatorSymbol); | 1222 !fImpl->fMonetary ? |
| 1223 DecimalFormatSymbols::kGroupingSeparatorSymbol : DecimalFormatSymbol
s::kMonetaryGroupingSeparatorSymbol); |
| 2524 UChar32 groupingChar = groupingString->char32At(0); | 1224 UChar32 groupingChar = groupingString->char32At(0); |
| 2525 int32_t groupingStringLength = groupingString->length(); | 1225 int32_t groupingStringLength = groupingString->length(); |
| 2526 int32_t groupingCharLength = U16_LENGTH(groupingChar); | 1226 int32_t groupingCharLength = U16_LENGTH(groupingChar); |
| 2527 UBool groupingUsed = isGroupingUsed(); | 1227 UBool groupingUsed = isGroupingUsed(); |
| 2528 #ifdef FMT_DEBUG | 1228 #ifdef FMT_DEBUG |
| 2529 UChar dbgbuf[300]; | 1229 UChar dbgbuf[300]; |
| 2530 UnicodeString s(dbgbuf,0,300);; | 1230 UnicodeString s(dbgbuf,0,300);; |
| 2531 s.append((UnicodeString)"PARSE \"").append(text.tempSubString(position)).app
end((UnicodeString)"\" " ); | 1231 s.append((UnicodeString)"PARSE \"").append(text.tempSubString(position)).app
end((UnicodeString)"\" " ); |
| 2532 #define DBGAPPD(x) if(x) { s.append(UnicodeString(#x "=")); if(x->isEmpty()) {
s.append(UnicodeString("<empty>")); } else { s.append(*x); } s.append(UnicodeStr
ing(" ")); } else { s.append(UnicodeString(#x "=NULL ")); } | 1232 #define DBGAPPD(x) if(x) { s.append(UnicodeString(#x "=")); if(x->isEmpty()) {
s.append(UnicodeString("<empty>")); } else { s.append(*x); } s.append(UnicodeStr
ing(" ")); } else { s.append(UnicodeString(#x "=NULL ")); } |
| 2533 DBGAPPD(negPrefix); | 1233 DBGAPPD(negPrefix); |
| 2534 DBGAPPD(negSuffix); | 1234 DBGAPPD(negSuffix); |
| 2535 DBGAPPD(posPrefix); | 1235 DBGAPPD(posPrefix); |
| 2536 DBGAPPD(posSuffix); | 1236 DBGAPPD(posSuffix); |
| 2537 debugout(s); | 1237 debugout(s); |
| 2538 printf("currencyParsing=%d, fFormatWidth=%d, isParseIntegerOnly=%c text.leng
th=%d negPrefLen=%d\n", currencyParsing, fFormatWidth, (isParseIntegerOnly())?'Y
':'N', text.length(), negPrefix!=NULL?negPrefix->length():-1); | |
| 2539 #endif | 1238 #endif |
| 2540 | 1239 |
| 2541 UBool fastParseOk = false; /* TRUE iff fast parse is OK */ | 1240 UBool fastParseOk = false; /* TRUE iff fast parse is OK */ |
| 2542 // UBool fastParseHadDecimal = FALSE; /* true if fast parse saw a decimal po
int. */ | 1241 // UBool fastParseHadDecimal = FALSE; /* true if fast parse saw a decimal po
int. */ |
| 2543 const DecimalFormatInternal &data = internalData(fReserved); | 1242 if((fImpl->isParseFastpath()) && !fImpl->fMonetary && |
| 2544 if((data.fFastParseStatus==kFastpathYES) && | |
| 2545 fCurrencySignCount == fgCurrencySignCountZero && | |
| 2546 // (negPrefix!=NULL&&negPrefix->isEmpty()) || | |
| 2547 text.length()>0 && | 1243 text.length()>0 && |
| 2548 text.length()<32 && | 1244 text.length()<32 && |
| 2549 (posPrefix==NULL||posPrefix->isEmpty()) && | 1245 (posPrefix==NULL||posPrefix->isEmpty()) && |
| 2550 (posSuffix==NULL||posSuffix->isEmpty()) && | 1246 (posSuffix==NULL||posSuffix->isEmpty()) && |
| 2551 // (negPrefix==NULL||negPrefix->isEmpty()) && | 1247 // (negPrefix==NULL||negPrefix->isEmpty()) && |
| 2552 // (negSuffix==NULL||(negSuffix->isEmpty()) ) && | 1248 // (negSuffix==NULL||(negSuffix->isEmpty()) ) && |
| 2553 TRUE) { // optimized path | 1249 TRUE) { // optimized path |
| 2554 int j=position; | 1250 int j=position; |
| 2555 int l=text.length(); | 1251 int l=text.length(); |
| 2556 int digitCount=0; | 1252 int digitCount=0; |
| 2557 UChar32 ch = text.char32At(j); | 1253 UChar32 ch = text.char32At(j); |
| 2558 const UnicodeString *decimalString = &getConstSymbol(DecimalFormatSymbols:
:kDecimalSeparatorSymbol); | 1254 const UnicodeString *decimalString = &fImpl->getConstSymbol(DecimalFormatS
ymbols::kDecimalSeparatorSymbol); |
| 2559 UChar32 decimalChar = 0; | 1255 UChar32 decimalChar = 0; |
| 2560 UBool intOnly = FALSE; | 1256 UBool intOnly = FALSE; |
| 2561 UChar32 lookForGroup = (groupingUsed&&intOnly&&strictParse)?groupingChar:0
; | 1257 UChar32 lookForGroup = (groupingUsed&&intOnly&&strictParse)?groupingChar:0
; |
| 2562 | 1258 |
| 2563 int32_t decimalCount = decimalString->countChar32(0,3); | 1259 int32_t decimalCount = decimalString->countChar32(0,3); |
| 2564 if(isParseIntegerOnly()) { | 1260 if(isParseIntegerOnly()) { |
| 2565 decimalChar = 0; // not allowed | 1261 decimalChar = 0; // not allowed |
| 2566 intOnly = TRUE; // Don't look for decimals. | 1262 intOnly = TRUE; // Don't look for decimals. |
| 2567 } else if(decimalCount==1) { | 1263 } else if(decimalCount==1) { |
| 2568 decimalChar = decimalString->char32At(0); // Look for this decimal | 1264 decimalChar = decimalString->char32At(0); // Look for this decimal |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2610 } else { | 1306 } else { |
| 2611 digitCount=-1; // fail - fall through to slow parse | 1307 digitCount=-1; // fail - fall through to slow parse |
| 2612 break; | 1308 break; |
| 2613 } | 1309 } |
| 2614 j+=U16_LENGTH(ch); | 1310 j+=U16_LENGTH(ch); |
| 2615 ch = text.char32At(j); // for next | 1311 ch = text.char32At(j); // for next |
| 2616 } | 1312 } |
| 2617 if( | 1313 if( |
| 2618 ((j==l)||intOnly) // end OR only parsing integer | 1314 ((j==l)||intOnly) // end OR only parsing integer |
| 2619 && (digitCount>0)) { // and have at least one digit | 1315 && (digitCount>0)) { // and have at least one digit |
| 2620 #ifdef FMT_DEBUG | |
| 2621 printf("PP -> %d, good = [%s] digitcount=%d, fGroupingSize=%d fGrouping
Size2=%d!\n", j, parsedNum.data(), digitCount, fGroupingSize, fGroupingSize2); | |
| 2622 #endif | |
| 2623 fastParseOk=true; // Fast parse OK! | 1316 fastParseOk=true; // Fast parse OK! |
| 2624 | 1317 |
| 2625 #ifdef SKIP_OPT | 1318 #ifdef SKIP_OPT |
| 2626 debug("SKIP_OPT"); | 1319 debug("SKIP_OPT"); |
| 2627 /* for testing, try it the slow way. also */ | 1320 /* for testing, try it the slow way. also */ |
| 2628 fastParseOk=false; | 1321 fastParseOk=false; |
| 2629 parsedNum.clear(); | 1322 parsedNum.clear(); |
| 2630 #else | 1323 #else |
| 2631 parsePosition.setIndex(position=j); | 1324 parsePosition.setIndex(position=j); |
| 2632 status[fgStatusInfinite]=false; | 1325 status[fgStatusInfinite]=false; |
| 2633 #endif | 1326 #endif |
| 2634 } else { | 1327 } else { |
| 2635 // was not OK. reset, retry | 1328 // was not OK. reset, retry |
| 2636 #ifdef FMT_DEBUG | 1329 #ifdef FMT_DEBUG |
| 2637 printf("Fall through: j=%d, l=%d, digitCount=%d\n", j, l, digitCount); | 1330 printf("Fall through: j=%d, l=%d, digitCount=%d\n", j, l, digitCount); |
| 2638 #endif | 1331 #endif |
| 2639 parsedNum.clear(); | 1332 parsedNum.clear(); |
| 2640 } | 1333 } |
| 2641 } else { | 1334 } else { |
| 2642 #ifdef FMT_DEBUG | 1335 #ifdef FMT_DEBUG |
| 2643 printf("Could not fastpath parse. "); | 1336 printf("Could not fastpath parse. "); |
| 2644 printf("fFormatWidth=%d ", fFormatWidth); | |
| 2645 printf("text.length()=%d ", text.length()); | 1337 printf("text.length()=%d ", text.length()); |
| 2646 printf("posPrefix=%p posSuffix=%p ", posPrefix, posSuffix); | 1338 printf("posPrefix=%p posSuffix=%p ", posPrefix, posSuffix); |
| 2647 | 1339 |
| 2648 printf("\n"); | 1340 printf("\n"); |
| 2649 #endif | 1341 #endif |
| 2650 } | 1342 } |
| 2651 | 1343 |
| 1344 UnicodeString formatPattern; |
| 1345 toPattern(formatPattern); |
| 1346 |
| 2652 if(!fastParseOk | 1347 if(!fastParseOk |
| 2653 #if UCONFIG_HAVE_PARSEALLINPUT | 1348 #if UCONFIG_HAVE_PARSEALLINPUT |
| 2654 && fParseAllInput!=UNUM_YES | 1349 && fParseAllInput!=UNUM_YES |
| 2655 #endif | 1350 #endif |
| 2656 ) | 1351 ) |
| 2657 { | 1352 { |
| 1353 int32_t formatWidth = fImpl->getOldFormatWidth(); |
| 2658 // Match padding before prefix | 1354 // Match padding before prefix |
| 2659 if (fFormatWidth > 0 && fPadPosition == kPadBeforePrefix) { | 1355 if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPaddin
g::kPadBeforePrefix) { |
| 2660 position = skipPadding(text, position); | 1356 position = skipPadding(text, position); |
| 2661 } | 1357 } |
| 2662 | 1358 |
| 2663 // Match positive and negative prefixes; prefer longest match. | 1359 // Match positive and negative prefixes; prefer longest match. |
| 2664 int32_t posMatch = compareAffix(text, position, FALSE, TRUE, posPrefix, comp
lexCurrencyParsing, type, currency); | 1360 int32_t posMatch = compareAffix(text, position, FALSE, TRUE, posPrefix, comp
lexCurrencyParsing, type, currency); |
| 2665 int32_t negMatch = compareAffix(text, position, TRUE, TRUE, negPrefix, comp
lexCurrencyParsing, type, currency); | 1361 int32_t negMatch = compareAffix(text, position, TRUE, TRUE, negPrefix, comp
lexCurrencyParsing, type, currency); |
| 2666 if (posMatch >= 0 && negMatch >= 0) { | 1362 if (posMatch >= 0 && negMatch >= 0) { |
| 2667 if (posMatch > negMatch) { | 1363 if (posMatch > negMatch) { |
| 2668 negMatch = -1; | 1364 negMatch = -1; |
| 2669 } else if (negMatch > posMatch) { | 1365 } else if (negMatch > posMatch) { |
| 2670 posMatch = -1; | 1366 posMatch = -1; |
| 2671 } | 1367 } |
| 2672 } | 1368 } |
| 2673 if (posMatch >= 0) { | 1369 if (posMatch >= 0) { |
| 2674 position += posMatch; | 1370 position += posMatch; |
| 2675 parsedNum.append('+', err); | 1371 parsedNum.append('+', err); |
| 2676 } else if (negMatch >= 0) { | 1372 } else if (negMatch >= 0) { |
| 2677 position += negMatch; | 1373 position += negMatch; |
| 2678 parsedNum.append('-', err); | 1374 parsedNum.append('-', err); |
| 2679 } else if (strictParse){ | 1375 } else if (strictParse){ |
| 2680 parsePosition.setErrorIndex(position); | 1376 parsePosition.setErrorIndex(position); |
| 2681 return FALSE; | 1377 return FALSE; |
| 2682 } else { | 1378 } else { |
| 2683 // Temporary set positive. This might be changed after checking suffix | 1379 // Temporary set positive. This might be changed after checking suffix |
| 2684 parsedNum.append('+', err); | 1380 parsedNum.append('+', err); |
| 2685 } | 1381 } |
| 2686 | 1382 |
| 2687 // Match padding before prefix | 1383 // Match padding before prefix |
| 2688 if (fFormatWidth > 0 && fPadPosition == kPadAfterPrefix) { | 1384 if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPaddin
g::kPadAfterPrefix) { |
| 2689 position = skipPadding(text, position); | 1385 position = skipPadding(text, position); |
| 2690 } | 1386 } |
| 2691 | 1387 |
| 2692 if (! strictParse) { | 1388 if (! strictParse) { |
| 2693 position = skipUWhiteSpace(text, position); | 1389 position = skipUWhiteSpace(text, position); |
| 2694 } | 1390 } |
| 2695 | 1391 |
| 2696 // process digits or Inf, find decimal position | 1392 // process digits or Inf, find decimal position |
| 2697 const UnicodeString *inf = &getConstSymbol(DecimalFormatSymbols::kInfinitySy
mbol); | 1393 const UnicodeString *inf = &fImpl->getConstSymbol(DecimalFormatSymbols::kInf
initySymbol); |
| 2698 int32_t infLen = (text.compare(position, inf->length(), *inf) | 1394 int32_t infLen = (text.compare(position, inf->length(), *inf) |
| 2699 ? 0 : inf->length()); | 1395 ? 0 : inf->length()); |
| 2700 position += infLen; // infLen is non-zero when it does equal to infinity | 1396 position += infLen; // infLen is non-zero when it does equal to infinity |
| 2701 status[fgStatusInfinite] = infLen != 0; | 1397 status[fgStatusInfinite] = infLen != 0; |
| 2702 | 1398 |
| 2703 if (infLen != 0) { | 1399 if (infLen != 0) { |
| 2704 parsedNum.append("Infinity", err); | 1400 parsedNum.append("Infinity", err); |
| 2705 } else { | 1401 } else { |
| 2706 // We now have a string of digits, possibly with grouping symbols, | 1402 // We now have a string of digits, possibly with grouping symbols, |
| 2707 // and decimal points. We want to process these into a DigitList. | 1403 // and decimal points. We want to process these into a DigitList. |
| 2708 // We don't want to put a bunch of leading zeros into the DigitList | 1404 // We don't want to put a bunch of leading zeros into the DigitList |
| 2709 // though, so we keep track of the location of the decimal point, | 1405 // though, so we keep track of the location of the decimal point, |
| 2710 // put only significant digits into the DigitList, and adjust the | 1406 // put only significant digits into the DigitList, and adjust the |
| 2711 // exponent as needed. | 1407 // exponent as needed. |
| 2712 | 1408 |
| 2713 | 1409 |
| 2714 UBool strictFail = FALSE; // did we exit with a strict parse failure? | 1410 UBool strictFail = FALSE; // did we exit with a strict parse failure? |
| 2715 int32_t lastGroup = -1; // where did we last see a grouping separator? | 1411 int32_t lastGroup = -1; // where did we last see a grouping separator? |
| 2716 int32_t digitStart = position; | 1412 int32_t digitStart = position; |
| 2717 int32_t gs2 = fGroupingSize2 == 0 ? fGroupingSize : fGroupingSize2; | 1413 int32_t gs2 = fImpl->fEffGrouping.fGrouping2 == 0 ? fImpl->fEffGrouping.
fGrouping : fImpl->fEffGrouping.fGrouping2; |
| 2718 | 1414 |
| 2719 const UnicodeString *decimalString; | 1415 const UnicodeString *decimalString; |
| 2720 if (fCurrencySignCount != fgCurrencySignCountZero) { | 1416 if (fImpl->fMonetary) { |
| 2721 decimalString = &getConstSymbol(DecimalFormatSymbols::kMonetarySepar
atorSymbol); | 1417 decimalString = &fImpl->getConstSymbol(DecimalFormatSymbols::kMoneta
rySeparatorSymbol); |
| 2722 } else { | 1418 } else { |
| 2723 decimalString = &getConstSymbol(DecimalFormatSymbols::kDecimalSepara
torSymbol); | 1419 decimalString = &fImpl->getConstSymbol(DecimalFormatSymbols::kDecima
lSeparatorSymbol); |
| 2724 } | 1420 } |
| 2725 UChar32 decimalChar = decimalString->char32At(0); | 1421 UChar32 decimalChar = decimalString->char32At(0); |
| 2726 int32_t decimalStringLength = decimalString->length(); | 1422 int32_t decimalStringLength = decimalString->length(); |
| 2727 int32_t decimalCharLength = U16_LENGTH(decimalChar); | 1423 int32_t decimalCharLength = U16_LENGTH(decimalChar); |
| 2728 | 1424 |
| 2729 UBool sawDecimal = FALSE; | 1425 UBool sawDecimal = FALSE; |
| 2730 UChar32 sawDecimalChar = 0xFFFF; | 1426 UChar32 sawDecimalChar = 0xFFFF; |
| 2731 UBool sawGrouping = FALSE; | 1427 UBool sawGrouping = FALSE; |
| 2732 UChar32 sawGroupingChar = 0xFFFF; | 1428 UChar32 sawGroupingChar = 0xFFFF; |
| 2733 UBool sawDigit = FALSE; | 1429 UBool sawDigit = FALSE; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2777 digit = ch - zero; | 1473 digit = ch - zero; |
| 2778 if (digit < 0 || digit > 9) | 1474 if (digit < 0 || digit > 9) |
| 2779 { | 1475 { |
| 2780 digit = u_charDigitValue(ch); | 1476 digit = u_charDigitValue(ch); |
| 2781 } | 1477 } |
| 2782 | 1478 |
| 2783 // As a last resort, look through the localized digits if the zero d
igit | 1479 // As a last resort, look through the localized digits if the zero d
igit |
| 2784 // is not a "standard" Unicode digit. | 1480 // is not a "standard" Unicode digit. |
| 2785 if ( (digit < 0 || digit > 9) && u_charDigitValue(zero) != 0) { | 1481 if ( (digit < 0 || digit > 9) && u_charDigitValue(zero) != 0) { |
| 2786 digit = 0; | 1482 digit = 0; |
| 2787 if ( getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(
DecimalFormatSymbols::kZeroDigitSymbol)).char32At(0) == ch ) { | 1483 if ( fImpl->getConstSymbol((DecimalFormatSymbols::ENumberFormatS
ymbol)(DecimalFormatSymbols::kZeroDigitSymbol)).char32At(0) == ch ) { |
| 2788 break; | 1484 break; |
| 2789 } | 1485 } |
| 2790 for (digit = 1 ; digit < 10 ; digit++ ) { | 1486 for (digit = 1 ; digit < 10 ; digit++ ) { |
| 2791 if ( getConstSymbol((DecimalFormatSymbols::ENumberFormatSymb
ol)(DecimalFormatSymbols::kOneDigitSymbol+digit-1)).char32At(0) == ch ) { | 1487 if ( fImpl->getConstSymbol((DecimalFormatSymbols::ENumberFor
matSymbol)(DecimalFormatSymbols::kOneDigitSymbol+digit-1)).char32At(0) == ch ) { |
| 2792 break; | 1488 break; |
| 2793 } | 1489 } |
| 2794 } | 1490 } |
| 2795 } | 1491 } |
| 2796 | 1492 |
| 2797 if (digit >= 0 && digit <= 9) | 1493 if (digit >= 0 && digit <= 9) |
| 2798 { | 1494 { |
| 2799 if (strictParse && backup != -1) { | 1495 if (strictParse && backup != -1) { |
| 2800 // comma followed by digit, so group before comma is a | 1496 // comma followed by digit, so group before comma is a |
| 2801 // secondary group. If there was a group separator | 1497 // secondary group. If there was a group separator |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2853 backup = position; | 1549 backup = position; |
| 2854 position += groupingStringLength; | 1550 position += groupingStringLength; |
| 2855 sawGrouping=TRUE; | 1551 sawGrouping=TRUE; |
| 2856 // Once we see a grouping character, we only accept that groupin
g character from then on. | 1552 // Once we see a grouping character, we only accept that groupin
g character from then on. |
| 2857 sawGroupingChar=ch; | 1553 sawGroupingChar=ch; |
| 2858 } | 1554 } |
| 2859 else if (matchDecimal(decimalChar,sawDecimal,sawDecimalChar, decimal
Set, ch)) | 1555 else if (matchDecimal(decimalChar,sawDecimal,sawDecimalChar, decimal
Set, ch)) |
| 2860 { | 1556 { |
| 2861 if (strictParse) { | 1557 if (strictParse) { |
| 2862 if (backup != -1 || | 1558 if (backup != -1 || |
| 2863 (lastGroup != -1 && position - lastGroup != fGroupingSiz
e + 1)) { | 1559 (lastGroup != -1 && position - lastGroup != fImpl->fEffG
rouping.fGrouping + 1)) { |
| 2864 strictFail = TRUE; | 1560 strictFail = TRUE; |
| 2865 break; | 1561 break; |
| 2866 } | 1562 } |
| 2867 } | 1563 } |
| 2868 | 1564 |
| 2869 // If we're only parsing integers, or if we ALREADY saw the | 1565 // If we're only parsing integers, or if we ALREADY saw the |
| 2870 // decimal, then don't parse this one. | 1566 // decimal, then don't parse this one. |
| 2871 if (isParseIntegerOnly() || sawDecimal) { | 1567 if (isParseIntegerOnly() || sawDecimal) { |
| 2872 break; | 1568 break; |
| 2873 } | 1569 } |
| 2874 | 1570 |
| 2875 parsedNum.append('.', err); | 1571 parsedNum.append('.', err); |
| 2876 position += decimalStringLength; | 1572 position += decimalStringLength; |
| 2877 sawDecimal = TRUE; | 1573 sawDecimal = TRUE; |
| 2878 // Once we see a decimal character, we only accept that decimal
character from then on. | 1574 // Once we see a decimal character, we only accept that decimal
character from then on. |
| 2879 sawDecimalChar=ch; | 1575 sawDecimalChar=ch; |
| 2880 // decimalSet is considered to consist of (ch,ch) | 1576 // decimalSet is considered to consist of (ch,ch) |
| 2881 } | 1577 } |
| 2882 else { | 1578 else { |
| 2883 | 1579 |
| 2884 if(!fBoolFlags.contains(UNUM_PARSE_NO_EXPONENT) || // don't pars
e if this is set unless.. | 1580 if(!fBoolFlags.contains(UNUM_PARSE_NO_EXPONENT) || // don't pars
e if this is set unless.. |
| 2885 isScientificNotation()) { // .. it's an exponent format - ign
ore setting and parse anyways | 1581 isScientificNotation()) { // .. it's an exponent format - ign
ore setting and parse anyways |
| 2886 const UnicodeString *tmp; | 1582 const UnicodeString *tmp; |
| 2887 tmp = &getConstSymbol(DecimalFormatSymbols::kExponentialSymb
ol); | 1583 tmp = &fImpl->getConstSymbol(DecimalFormatSymbols::kExponent
ialSymbol); |
| 2888 // TODO: CASE | 1584 // TODO: CASE |
| 2889 if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_
CASE_DEFAULT)) // error code is set below if !sawDigit | 1585 if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_
CASE_DEFAULT)) // error code is set below if !sawDigit |
| 2890 { | 1586 { |
| 2891 // Parse sign, if present | 1587 // Parse sign, if present |
| 2892 int32_t pos = position + tmp->length(); | 1588 int32_t pos = position + tmp->length(); |
| 2893 char exponentSign = '+'; | 1589 char exponentSign = '+'; |
| 2894 | 1590 |
| 2895 if (pos < textLength) | 1591 if (pos < textLength) |
| 2896 { | 1592 { |
| 2897 tmp = &getConstSymbol(DecimalFormatSymbols::kPlusSig
nSymbol); | 1593 tmp = &fImpl->getConstSymbol(DecimalFormatSymbols::k
PlusSignSymbol); |
| 2898 if (!text.compare(pos, tmp->length(), *tmp)) | 1594 if (!text.compare(pos, tmp->length(), *tmp)) |
| 2899 { | 1595 { |
| 2900 pos += tmp->length(); | 1596 pos += tmp->length(); |
| 2901 } | 1597 } |
| 2902 else { | 1598 else { |
| 2903 tmp = &getConstSymbol(DecimalFormatSymbols::kMin
usSignSymbol); | 1599 tmp = &fImpl->getConstSymbol(DecimalFormatSymbol
s::kMinusSignSymbol); |
| 2904 if (!text.compare(pos, tmp->length(), *tmp)) | 1600 if (!text.compare(pos, tmp->length(), *tmp)) |
| 2905 { | 1601 { |
| 2906 exponentSign = '-'; | 1602 exponentSign = '-'; |
| 2907 pos += tmp->length(); | 1603 pos += tmp->length(); |
| 2908 } | 1604 } |
| 2909 } | 1605 } |
| 2910 } | 1606 } |
| 2911 | 1607 |
| 2912 UBool sawExponentDigit = FALSE; | 1608 UBool sawExponentDigit = FALSE; |
| 2913 while (pos < textLength) { | 1609 while (pos < textLength) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2940 } | 1636 } |
| 2941 } else { // not parsing exponent | 1637 } else { // not parsing exponent |
| 2942 break; | 1638 break; |
| 2943 } | 1639 } |
| 2944 } | 1640 } |
| 2945 } | 1641 } |
| 2946 | 1642 |
| 2947 // if we didn't see a decimal and it is required, check to see if the pa
ttern had one | 1643 // if we didn't see a decimal and it is required, check to see if the pa
ttern had one |
| 2948 if(!sawDecimal && isDecimalPatternMatchRequired()) | 1644 if(!sawDecimal && isDecimalPatternMatchRequired()) |
| 2949 { | 1645 { |
| 2950 if(fFormatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSym
bol) != 0) | 1646 if(formatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSymb
ol) != 0) |
| 2951 { | 1647 { |
| 2952 parsePosition.setIndex(oldStart); | 1648 parsePosition.setIndex(oldStart); |
| 2953 parsePosition.setErrorIndex(position); | 1649 parsePosition.setErrorIndex(position); |
| 2954 debug("decimal point match required fail!"); | 1650 debug("decimal point match required fail!"); |
| 2955 return FALSE; | 1651 return FALSE; |
| 2956 } | 1652 } |
| 2957 } | 1653 } |
| 2958 | 1654 |
| 2959 if (backup != -1) | 1655 if (backup != -1) |
| 2960 { | 1656 { |
| 2961 position = backup; | 1657 position = backup; |
| 2962 } | 1658 } |
| 2963 | 1659 |
| 2964 if (strictParse && !sawDecimal) { | 1660 if (strictParse && !sawDecimal) { |
| 2965 if (lastGroup != -1 && position - lastGroup != fGroupingSize + 1) { | 1661 if (lastGroup != -1 && position - lastGroup != fImpl->fEffGrouping.f
Grouping + 1) { |
| 2966 strictFail = TRUE; | 1662 strictFail = TRUE; |
| 2967 } | 1663 } |
| 2968 } | 1664 } |
| 2969 | 1665 |
| 2970 if (strictFail) { | 1666 if (strictFail) { |
| 2971 // only set with strictParse and a grouping separator error | 1667 // only set with strictParse and a grouping separator error |
| 2972 | 1668 |
| 2973 parsePosition.setIndex(oldStart); | 1669 parsePosition.setIndex(oldStart); |
| 2974 parsePosition.setErrorIndex(position); | 1670 parsePosition.setErrorIndex(position); |
| 2975 debug("strictFail!"); | 1671 debug("strictFail!"); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2987 debug("none of text rec"); | 1683 debug("none of text rec"); |
| 2988 printf("position=%d\n",position); | 1684 printf("position=%d\n",position); |
| 2989 #endif | 1685 #endif |
| 2990 parsePosition.setIndex(oldStart); | 1686 parsePosition.setIndex(oldStart); |
| 2991 parsePosition.setErrorIndex(oldStart); | 1687 parsePosition.setErrorIndex(oldStart); |
| 2992 return FALSE; | 1688 return FALSE; |
| 2993 } | 1689 } |
| 2994 } | 1690 } |
| 2995 | 1691 |
| 2996 // Match padding before suffix | 1692 // Match padding before suffix |
| 2997 if (fFormatWidth > 0 && fPadPosition == kPadBeforeSuffix) { | 1693 if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPaddin
g::kPadBeforeSuffix) { |
| 2998 position = skipPadding(text, position); | 1694 position = skipPadding(text, position); |
| 2999 } | 1695 } |
| 3000 | 1696 |
| 3001 int32_t posSuffixMatch = -1, negSuffixMatch = -1; | 1697 int32_t posSuffixMatch = -1, negSuffixMatch = -1; |
| 3002 | 1698 |
| 3003 // Match positive and negative suffixes; prefer longest match. | 1699 // Match positive and negative suffixes; prefer longest match. |
| 3004 if (posMatch >= 0 || (!strictParse && negMatch < 0)) { | 1700 if (posMatch >= 0 || (!strictParse && negMatch < 0)) { |
| 3005 posSuffixMatch = compareAffix(text, position, FALSE, FALSE, posSuffix, c
omplexCurrencyParsing, type, currency); | 1701 posSuffixMatch = compareAffix(text, position, FALSE, FALSE, posSuffix, c
omplexCurrencyParsing, type, currency); |
| 3006 } | 1702 } |
| 3007 if (negMatch >= 0) { | 1703 if (negMatch >= 0) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3018 // Fail if neither or both | 1714 // Fail if neither or both |
| 3019 if (strictParse && ((posSuffixMatch >= 0) == (negSuffixMatch >= 0))) { | 1715 if (strictParse && ((posSuffixMatch >= 0) == (negSuffixMatch >= 0))) { |
| 3020 parsePosition.setErrorIndex(position); | 1716 parsePosition.setErrorIndex(position); |
| 3021 debug("neither or both"); | 1717 debug("neither or both"); |
| 3022 return FALSE; | 1718 return FALSE; |
| 3023 } | 1719 } |
| 3024 | 1720 |
| 3025 position += (posSuffixMatch >= 0 ? posSuffixMatch : (negSuffixMatch >= 0 ? n
egSuffixMatch : 0)); | 1721 position += (posSuffixMatch >= 0 ? posSuffixMatch : (negSuffixMatch >= 0 ? n
egSuffixMatch : 0)); |
| 3026 | 1722 |
| 3027 // Match padding before suffix | 1723 // Match padding before suffix |
| 3028 if (fFormatWidth > 0 && fPadPosition == kPadAfterSuffix) { | 1724 if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPaddin
g::kPadAfterSuffix) { |
| 3029 position = skipPadding(text, position); | 1725 position = skipPadding(text, position); |
| 3030 } | 1726 } |
| 3031 | 1727 |
| 3032 parsePosition.setIndex(position); | 1728 parsePosition.setIndex(position); |
| 3033 | 1729 |
| 3034 parsedNum.data()[0] = (posSuffixMatch >= 0 || (!strictParse && negMatch < 0
&& negSuffixMatch < 0)) ? '+' : '-'; | 1730 parsedNum.data()[0] = (posSuffixMatch >= 0 || (!strictParse && negMatch < 0
&& negSuffixMatch < 0)) ? '+' : '-'; |
| 3035 #ifdef FMT_DEBUG | 1731 #ifdef FMT_DEBUG |
| 3036 printf("PP -> %d, SLOW = [%s]! pp=%d, os=%d, err=%s\n", position, parsedNum.d
ata(), parsePosition.getIndex(),oldStart,u_errorName(err)); | 1732 printf("PP -> %d, SLOW = [%s]! pp=%d, os=%d, err=%s\n", position, parsedNum.d
ata(), parsePosition.getIndex(),oldStart,u_errorName(err)); |
| 3037 #endif | 1733 #endif |
| 3038 } /* end SLOW parse */ | 1734 } /* end SLOW parse */ |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3066 #ifdef FMT_DEBUG | 1762 #ifdef FMT_DEBUG |
| 3067 printf(" err setting %s\n", u_errorName(err)); | 1763 printf(" err setting %s\n", u_errorName(err)); |
| 3068 #endif | 1764 #endif |
| 3069 parsePosition.setErrorIndex(position); | 1765 parsePosition.setErrorIndex(position); |
| 3070 return FALSE; | 1766 return FALSE; |
| 3071 } | 1767 } |
| 3072 | 1768 |
| 3073 // check if we missed a required decimal point | 1769 // check if we missed a required decimal point |
| 3074 if(fastParseOk && isDecimalPatternMatchRequired()) | 1770 if(fastParseOk && isDecimalPatternMatchRequired()) |
| 3075 { | 1771 { |
| 3076 if(fFormatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSymbol)
!= 0) | 1772 if(formatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSymbol)
!= 0) |
| 3077 { | 1773 { |
| 3078 parsePosition.setIndex(oldStart); | 1774 parsePosition.setIndex(oldStart); |
| 3079 parsePosition.setErrorIndex(position); | 1775 parsePosition.setErrorIndex(position); |
| 3080 debug("decimal point match required fail!"); | 1776 debug("decimal point match required fail!"); |
| 3081 return FALSE; | 1777 return FALSE; |
| 3082 } | 1778 } |
| 3083 } | 1779 } |
| 3084 | 1780 |
| 3085 | 1781 |
| 3086 return TRUE; | 1782 return TRUE; |
| 3087 } | 1783 } |
| 3088 | 1784 |
| 3089 /** | 1785 /** |
| 3090 * Starting at position, advance past a run of pad characters, if any. | 1786 * Starting at position, advance past a run of pad characters, if any. |
| 3091 * Return the index of the first character after position that is not a pad | 1787 * Return the index of the first character after position that is not a pad |
| 3092 * character. Result is >= position. | 1788 * character. Result is >= position. |
| 3093 */ | 1789 */ |
| 3094 int32_t DecimalFormat::skipPadding(const UnicodeString& text, int32_t position)
const { | 1790 int32_t DecimalFormat::skipPadding(const UnicodeString& text, int32_t position)
const { |
| 3095 int32_t padLen = U16_LENGTH(fPad); | 1791 int32_t padLen = U16_LENGTH(fImpl->fAffixes.fPadChar); |
| 3096 while (position < text.length() && | 1792 while (position < text.length() && |
| 3097 text.char32At(position) == fPad) { | 1793 text.char32At(position) == fImpl->fAffixes.fPadChar) { |
| 3098 position += padLen; | 1794 position += padLen; |
| 3099 } | 1795 } |
| 3100 return position; | 1796 return position; |
| 3101 } | 1797 } |
| 3102 | 1798 |
| 3103 /** | 1799 /** |
| 3104 * Return the length matched by the given affix, or -1 if none. | 1800 * Return the length matched by the given affix, or -1 if none. |
| 3105 * Runs of white space in the affix, match runs of white space in | 1801 * Runs of white space in the affix, match runs of white space in |
| 3106 * the input. Pattern white space and input white space are | 1802 * the input. Pattern white space and input white space are |
| 3107 * determined differently; see code. | 1803 * determined differently; see code. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3121 int32_t DecimalFormat::compareAffix(const UnicodeString& text, | 1817 int32_t DecimalFormat::compareAffix(const UnicodeString& text, |
| 3122 int32_t pos, | 1818 int32_t pos, |
| 3123 UBool isNegative, | 1819 UBool isNegative, |
| 3124 UBool isPrefix, | 1820 UBool isPrefix, |
| 3125 const UnicodeString* affixPat, | 1821 const UnicodeString* affixPat, |
| 3126 UBool complexCurrencyParsing, | 1822 UBool complexCurrencyParsing, |
| 3127 int8_t type, | 1823 int8_t type, |
| 3128 UChar* currency) const | 1824 UChar* currency) const |
| 3129 { | 1825 { |
| 3130 const UnicodeString *patternToCompare; | 1826 const UnicodeString *patternToCompare; |
| 3131 if (fCurrencyChoice != NULL || currency != NULL || | 1827 if (currency != NULL || |
| 3132 (fCurrencySignCount != fgCurrencySignCountZero && complexCurrencyParsing
)) { | 1828 (fImpl->fMonetary && complexCurrencyParsing)) { |
| 3133 | 1829 |
| 3134 if (affixPat != NULL) { | 1830 if (affixPat != NULL) { |
| 3135 return compareComplexAffix(*affixPat, text, pos, type, currency); | 1831 return compareComplexAffix(*affixPat, text, pos, type, currency); |
| 3136 } | 1832 } |
| 3137 } | 1833 } |
| 3138 | 1834 |
| 3139 if (isNegative) { | 1835 if (isNegative) { |
| 3140 if (isPrefix) { | 1836 if (isPrefix) { |
| 3141 patternToCompare = &fNegativePrefix; | 1837 patternToCompare = &fImpl->fAffixes.fNegativePrefix.getOtherVariant(
).toString(); |
| 3142 } | 1838 } |
| 3143 else { | 1839 else { |
| 3144 patternToCompare = &fNegativeSuffix; | 1840 patternToCompare = &fImpl->fAffixes.fNegativeSuffix.getOtherVariant(
).toString(); |
| 3145 } | 1841 } |
| 3146 } | 1842 } |
| 3147 else { | 1843 else { |
| 3148 if (isPrefix) { | 1844 if (isPrefix) { |
| 3149 patternToCompare = &fPositivePrefix; | 1845 patternToCompare = &fImpl->fAffixes.fPositivePrefix.getOtherVariant(
).toString(); |
| 3150 } | 1846 } |
| 3151 else { | 1847 else { |
| 3152 patternToCompare = &fPositiveSuffix; | 1848 patternToCompare = &fImpl->fAffixes.fPositiveSuffix.getOtherVariant(
).toString(); |
| 3153 } | 1849 } |
| 3154 } | 1850 } |
| 3155 return compareSimpleAffix(*patternToCompare, text, pos, isLenient()); | 1851 return compareSimpleAffix(*patternToCompare, text, pos, isLenient()); |
| 3156 } | 1852 } |
| 3157 | 1853 |
| 3158 UBool DecimalFormat::equalWithSignCompatibility(UChar32 lhs, UChar32 rhs) const
{ | 1854 UBool DecimalFormat::equalWithSignCompatibility(UChar32 lhs, UChar32 rhs) const
{ |
| 3159 if (lhs == rhs) { | 1855 if (lhs == rhs) { |
| 3160 return TRUE; | 1856 return TRUE; |
| 3161 } | 1857 } |
| 3162 U_ASSERT(fStaticSets != NULL); // should already be loaded | 1858 U_ASSERT(fStaticSets != NULL); // should already be loaded |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3413 * currency that this formatter is set to. | 2109 * currency that this formatter is set to. |
| 3414 * @return length of input that matches, or -1 if match failure | 2110 * @return length of input that matches, or -1 if match failure |
| 3415 */ | 2111 */ |
| 3416 int32_t DecimalFormat::compareComplexAffix(const UnicodeString& affixPat, | 2112 int32_t DecimalFormat::compareComplexAffix(const UnicodeString& affixPat, |
| 3417 const UnicodeString& text, | 2113 const UnicodeString& text, |
| 3418 int32_t pos, | 2114 int32_t pos, |
| 3419 int8_t type, | 2115 int8_t type, |
| 3420 UChar* currency) const | 2116 UChar* currency) const |
| 3421 { | 2117 { |
| 3422 int32_t start = pos; | 2118 int32_t start = pos; |
| 3423 U_ASSERT(currency != NULL || | 2119 U_ASSERT(currency != NULL || fImpl->fMonetary); |
| 3424 (fCurrencyChoice != NULL && *getCurrency() != 0) || | |
| 3425 fCurrencySignCount != fgCurrencySignCountZero); | |
| 3426 | 2120 |
| 3427 for (int32_t i=0; | 2121 for (int32_t i=0; |
| 3428 i<affixPat.length() && pos >= 0; ) { | 2122 i<affixPat.length() && pos >= 0; ) { |
| 3429 UChar32 c = affixPat.char32At(i); | 2123 UChar32 c = affixPat.char32At(i); |
| 3430 i += U16_LENGTH(c); | 2124 i += U16_LENGTH(c); |
| 3431 | 2125 |
| 3432 if (c == kQuote) { | 2126 if (c == kQuote) { |
| 3433 U_ASSERT(i <= affixPat.length()); | 2127 U_ASSERT(i <= affixPat.length()); |
| 3434 c = affixPat.char32At(i); | 2128 c = affixPat.char32At(i); |
| 3435 i += U16_LENGTH(c); | 2129 i += U16_LENGTH(c); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3480 continue; | 2174 continue; |
| 3481 } | 2175 } |
| 3482 } | 2176 } |
| 3483 pos = ppos.getIndex(); | 2177 pos = ppos.getIndex(); |
| 3484 } else if (!isLenient()){ | 2178 } else if (!isLenient()){ |
| 3485 pos = -1; | 2179 pos = -1; |
| 3486 } | 2180 } |
| 3487 continue; | 2181 continue; |
| 3488 } | 2182 } |
| 3489 case kPatternPercent: | 2183 case kPatternPercent: |
| 3490 affix = &getConstSymbol(DecimalFormatSymbols::kPercentSymbol); | 2184 affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kPercentSym
bol); |
| 3491 break; | 2185 break; |
| 3492 case kPatternPerMill: | 2186 case kPatternPerMill: |
| 3493 affix = &getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); | 2187 affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kPerMillSym
bol); |
| 3494 break; | 2188 break; |
| 3495 case kPatternPlus: | 2189 case kPatternPlus: |
| 3496 affix = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); | 2190 affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kPlusSignSy
mbol); |
| 3497 break; | 2191 break; |
| 3498 case kPatternMinus: | 2192 case kPatternMinus: |
| 3499 affix = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); | 2193 affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kMinusSignS
ymbol); |
| 3500 break; | 2194 break; |
| 3501 default: | 2195 default: |
| 3502 // fall through to affix!=0 test, which will fail | 2196 // fall through to affix!=0 test, which will fail |
| 3503 break; | 2197 break; |
| 3504 } | 2198 } |
| 3505 | 2199 |
| 3506 if (affix != NULL) { | 2200 if (affix != NULL) { |
| 3507 pos = match(text, pos, *affix); | 2201 pos = match(text, pos, *affix); |
| 3508 continue; | 2202 continue; |
| 3509 } | 2203 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3596 } | 2290 } |
| 3597 | 2291 |
| 3598 | 2292 |
| 3599 | 2293 |
| 3600 //------------------------------------------------------------------------------ | 2294 //------------------------------------------------------------------------------ |
| 3601 // Gets the pointer to the localized decimal format symbols | 2295 // Gets the pointer to the localized decimal format symbols |
| 3602 | 2296 |
| 3603 const DecimalFormatSymbols* | 2297 const DecimalFormatSymbols* |
| 3604 DecimalFormat::getDecimalFormatSymbols() const | 2298 DecimalFormat::getDecimalFormatSymbols() const |
| 3605 { | 2299 { |
| 3606 return fSymbols; | 2300 return &fImpl->getDecimalFormatSymbols(); |
| 3607 } | 2301 } |
| 3608 | 2302 |
| 3609 //------------------------------------------------------------------------------ | 2303 //------------------------------------------------------------------------------ |
| 3610 // De-owning the current localized symbols and adopt the new symbols. | 2304 // De-owning the current localized symbols and adopt the new symbols. |
| 3611 | 2305 |
| 3612 void | 2306 void |
| 3613 DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt) | 2307 DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt) |
| 3614 { | 2308 { |
| 3615 if (symbolsToAdopt == NULL) { | 2309 if (symbolsToAdopt == NULL) { |
| 3616 return; // do not allow caller to set fSymbols to NULL | 2310 return; // do not allow caller to set fSymbols to NULL |
| 3617 } | 2311 } |
| 3618 | 2312 fImpl->adoptDecimalFormatSymbols(symbolsToAdopt); |
| 3619 UBool sameSymbols = FALSE; | |
| 3620 if (fSymbols != NULL) { | |
| 3621 sameSymbols = (UBool)(getConstSymbol(DecimalFormatSymbols::kCurrencySymb
ol) == | |
| 3622 symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
) && | |
| 3623 getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) == | |
| 3624 symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySy
mbol)); | |
| 3625 delete fSymbols; | |
| 3626 } | |
| 3627 | |
| 3628 fSymbols = symbolsToAdopt; | |
| 3629 if (!sameSymbols) { | |
| 3630 // If the currency symbols are the same, there is no need to recalculate
. | |
| 3631 setCurrencyForSymbols(); | |
| 3632 } | |
| 3633 expandAffixes(NULL); | |
| 3634 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 3635 handleChanged(); | |
| 3636 #endif | |
| 3637 } | 2313 } |
| 3638 //------------------------------------------------------------------------------ | 2314 //------------------------------------------------------------------------------ |
| 3639 // Setting the symbols is equlivalent to adopting a newly created localized | 2315 // Setting the symbols is equlivalent to adopting a newly created localized |
| 3640 // symbols. | 2316 // symbols. |
| 3641 | 2317 |
| 3642 void | 2318 void |
| 3643 DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols) | 2319 DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols) |
| 3644 { | 2320 { |
| 3645 adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols)); | 2321 adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols)); |
| 3646 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 3647 handleChanged(); | |
| 3648 #endif | |
| 3649 } | 2322 } |
| 3650 | 2323 |
| 3651 | 2324 |
| 3652 const CurrencyPluralInfo* | 2325 const CurrencyPluralInfo* |
| 3653 DecimalFormat::getCurrencyPluralInfo(void) const | 2326 DecimalFormat::getCurrencyPluralInfo(void) const |
| 3654 { | 2327 { |
| 3655 return fCurrencyPluralInfo; | 2328 return fCurrencyPluralInfo; |
| 3656 } | 2329 } |
| 3657 | 2330 |
| 3658 | 2331 |
| 3659 void | 2332 void |
| 3660 DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt) | 2333 DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt) |
| 3661 { | 2334 { |
| 3662 if (toAdopt != NULL) { | 2335 if (toAdopt != NULL) { |
| 3663 delete fCurrencyPluralInfo; | 2336 delete fCurrencyPluralInfo; |
| 3664 fCurrencyPluralInfo = toAdopt; | 2337 fCurrencyPluralInfo = toAdopt; |
| 3665 // re-set currency affix patterns and currency affixes. | 2338 // re-set currency affix patterns and currency affixes. |
| 3666 if (fCurrencySignCount != fgCurrencySignCountZero) { | 2339 if (fImpl->fMonetary) { |
| 3667 UErrorCode status = U_ZERO_ERROR; | 2340 UErrorCode status = U_ZERO_ERROR; |
| 3668 if (fAffixPatternsForCurrency) { | 2341 if (fAffixPatternsForCurrency) { |
| 3669 deleteHashForAffixPattern(); | 2342 deleteHashForAffixPattern(); |
| 3670 } | 2343 } |
| 3671 setupCurrencyAffixPatterns(status); | 2344 setupCurrencyAffixPatterns(status); |
| 3672 if (fCurrencySignCount == fgCurrencySignCountInPluralFormat) { | |
| 3673 // only setup the affixes of the plural pattern. | |
| 3674 setupCurrencyAffixes(fFormatPattern, FALSE, TRUE, status); | |
| 3675 } | |
| 3676 } | 2345 } |
| 3677 } | 2346 } |
| 3678 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 3679 handleChanged(); | |
| 3680 #endif | |
| 3681 } | 2347 } |
| 3682 | 2348 |
| 3683 void | 2349 void |
| 3684 DecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo& info) | 2350 DecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo& info) |
| 3685 { | 2351 { |
| 3686 adoptCurrencyPluralInfo(info.clone()); | 2352 adoptCurrencyPluralInfo(info.clone()); |
| 3687 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 3688 handleChanged(); | |
| 3689 #endif | |
| 3690 } | 2353 } |
| 3691 | 2354 |
| 3692 | 2355 |
| 3693 /** | |
| 3694 * Update the currency object to match the symbols. This method | |
| 3695 * is used only when the caller has passed in a symbols object | |
| 3696 * that may not be the default object for its locale. | |
| 3697 */ | |
| 3698 void | |
| 3699 DecimalFormat::setCurrencyForSymbols() { | |
| 3700 /*Bug 4212072 | |
| 3701 Update the affix strings accroding to symbols in order to keep | |
| 3702 the affix strings up to date. | |
| 3703 [Richard/GCL] | |
| 3704 */ | |
| 3705 | |
| 3706 // With the introduction of the Currency object, the currency | |
| 3707 // symbols in the DFS object are ignored. For backward | |
| 3708 // compatibility, we check any explicitly set DFS object. If it | |
| 3709 // is a default symbols object for its locale, we change the | |
| 3710 // currency object to one for that locale. If it is custom, | |
| 3711 // we set the currency to null. | |
| 3712 UErrorCode ec = U_ZERO_ERROR; | |
| 3713 const UChar* c = NULL; | |
| 3714 const char* loc = fSymbols->getLocale().getName(); | |
| 3715 UChar intlCurrencySymbol[4]; | |
| 3716 ucurr_forLocale(loc, intlCurrencySymbol, 4, &ec); | |
| 3717 UnicodeString currencySymbol; | |
| 3718 | |
| 3719 uprv_getStaticCurrencyName(intlCurrencySymbol, loc, currencySymbol, ec); | |
| 3720 if (U_SUCCESS(ec) | |
| 3721 && getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) == currencySymb
ol | |
| 3722 && getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) == UnicodeS
tring(intlCurrencySymbol)) | |
| 3723 { | |
| 3724 // Trap an error in mapping locale to currency. If we can't | |
| 3725 // map, then don't fail and set the currency to "". | |
| 3726 c = intlCurrencySymbol; | |
| 3727 } | |
| 3728 ec = U_ZERO_ERROR; // reset local error code! | |
| 3729 setCurrencyInternally(c, ec); | |
| 3730 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 3731 handleChanged(); | |
| 3732 #endif | |
| 3733 } | |
| 3734 | |
| 3735 | |
| 3736 //------------------------------------------------------------------------------ | 2356 //------------------------------------------------------------------------------ |
| 3737 // Gets the positive prefix of the number pattern. | 2357 // Gets the positive prefix of the number pattern. |
| 3738 | 2358 |
| 3739 UnicodeString& | 2359 UnicodeString& |
| 3740 DecimalFormat::getPositivePrefix(UnicodeString& result) const | 2360 DecimalFormat::getPositivePrefix(UnicodeString& result) const |
| 3741 { | 2361 { |
| 3742 result = fPositivePrefix; | 2362 return fImpl->getPositivePrefix(result); |
| 3743 return result; | |
| 3744 } | 2363 } |
| 3745 | 2364 |
| 3746 //------------------------------------------------------------------------------ | 2365 //------------------------------------------------------------------------------ |
| 3747 // Sets the positive prefix of the number pattern. | 2366 // Sets the positive prefix of the number pattern. |
| 3748 | 2367 |
| 3749 void | 2368 void |
| 3750 DecimalFormat::setPositivePrefix(const UnicodeString& newValue) | 2369 DecimalFormat::setPositivePrefix(const UnicodeString& newValue) |
| 3751 { | 2370 { |
| 3752 fPositivePrefix = newValue; | 2371 fImpl->setPositivePrefix(newValue); |
| 3753 delete fPosPrefixPattern; | |
| 3754 fPosPrefixPattern = 0; | |
| 3755 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 3756 handleChanged(); | |
| 3757 #endif | |
| 3758 } | 2372 } |
| 3759 | 2373 |
| 3760 //------------------------------------------------------------------------------ | 2374 //------------------------------------------------------------------------------ |
| 3761 // Gets the negative prefix of the number pattern. | 2375 // Gets the negative prefix of the number pattern. |
| 3762 | 2376 |
| 3763 UnicodeString& | 2377 UnicodeString& |
| 3764 DecimalFormat::getNegativePrefix(UnicodeString& result) const | 2378 DecimalFormat::getNegativePrefix(UnicodeString& result) const |
| 3765 { | 2379 { |
| 3766 result = fNegativePrefix; | 2380 return fImpl->getNegativePrefix(result); |
| 3767 return result; | |
| 3768 } | 2381 } |
| 3769 | 2382 |
| 3770 //------------------------------------------------------------------------------ | 2383 //------------------------------------------------------------------------------ |
| 3771 // Gets the negative prefix of the number pattern. | 2384 // Gets the negative prefix of the number pattern. |
| 3772 | 2385 |
| 3773 void | 2386 void |
| 3774 DecimalFormat::setNegativePrefix(const UnicodeString& newValue) | 2387 DecimalFormat::setNegativePrefix(const UnicodeString& newValue) |
| 3775 { | 2388 { |
| 3776 fNegativePrefix = newValue; | 2389 fImpl->setNegativePrefix(newValue); |
| 3777 delete fNegPrefixPattern; | |
| 3778 fNegPrefixPattern = 0; | |
| 3779 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 3780 handleChanged(); | |
| 3781 #endif | |
| 3782 } | 2390 } |
| 3783 | 2391 |
| 3784 //------------------------------------------------------------------------------ | 2392 //------------------------------------------------------------------------------ |
| 3785 // Gets the positive suffix of the number pattern. | 2393 // Gets the positive suffix of the number pattern. |
| 3786 | 2394 |
| 3787 UnicodeString& | 2395 UnicodeString& |
| 3788 DecimalFormat::getPositiveSuffix(UnicodeString& result) const | 2396 DecimalFormat::getPositiveSuffix(UnicodeString& result) const |
| 3789 { | 2397 { |
| 3790 result = fPositiveSuffix; | 2398 return fImpl->getPositiveSuffix(result); |
| 3791 return result; | |
| 3792 } | 2399 } |
| 3793 | 2400 |
| 3794 //------------------------------------------------------------------------------ | 2401 //------------------------------------------------------------------------------ |
| 3795 // Sets the positive suffix of the number pattern. | 2402 // Sets the positive suffix of the number pattern. |
| 3796 | 2403 |
| 3797 void | 2404 void |
| 3798 DecimalFormat::setPositiveSuffix(const UnicodeString& newValue) | 2405 DecimalFormat::setPositiveSuffix(const UnicodeString& newValue) |
| 3799 { | 2406 { |
| 3800 fPositiveSuffix = newValue; | 2407 fImpl->setPositiveSuffix(newValue); |
| 3801 delete fPosSuffixPattern; | |
| 3802 fPosSuffixPattern = 0; | |
| 3803 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 3804 handleChanged(); | |
| 3805 #endif | |
| 3806 } | 2408 } |
| 3807 | 2409 |
| 3808 //------------------------------------------------------------------------------ | 2410 //------------------------------------------------------------------------------ |
| 3809 // Gets the negative suffix of the number pattern. | 2411 // Gets the negative suffix of the number pattern. |
| 3810 | 2412 |
| 3811 UnicodeString& | 2413 UnicodeString& |
| 3812 DecimalFormat::getNegativeSuffix(UnicodeString& result) const | 2414 DecimalFormat::getNegativeSuffix(UnicodeString& result) const |
| 3813 { | 2415 { |
| 3814 result = fNegativeSuffix; | 2416 return fImpl->getNegativeSuffix(result); |
| 3815 return result; | |
| 3816 } | 2417 } |
| 3817 | 2418 |
| 3818 //------------------------------------------------------------------------------ | 2419 //------------------------------------------------------------------------------ |
| 3819 // Sets the negative suffix of the number pattern. | 2420 // Sets the negative suffix of the number pattern. |
| 3820 | 2421 |
| 3821 void | 2422 void |
| 3822 DecimalFormat::setNegativeSuffix(const UnicodeString& newValue) | 2423 DecimalFormat::setNegativeSuffix(const UnicodeString& newValue) |
| 3823 { | 2424 { |
| 3824 fNegativeSuffix = newValue; | 2425 fImpl->setNegativeSuffix(newValue); |
| 3825 delete fNegSuffixPattern; | |
| 3826 fNegSuffixPattern = 0; | |
| 3827 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 3828 handleChanged(); | |
| 3829 #endif | |
| 3830 } | 2426 } |
| 3831 | 2427 |
| 3832 //------------------------------------------------------------------------------ | 2428 //------------------------------------------------------------------------------ |
| 3833 // Gets the multiplier of the number pattern. | 2429 // Gets the multiplier of the number pattern. |
| 3834 // Multipliers are stored as decimal numbers (DigitLists) because that | 2430 // Multipliers are stored as decimal numbers (DigitLists) because that |
| 3835 // is the most convenient for muliplying or dividing the numbers to be form
atted. | 2431 // is the most convenient for muliplying or dividing the numbers to be form
atted. |
| 3836 // A NULL multiplier implies one, and the scaling operations are skipped. | 2432 // A NULL multiplier implies one, and the scaling operations are skipped. |
| 3837 | 2433 |
| 3838 int32_t | 2434 int32_t |
| 3839 DecimalFormat::getMultiplier() const | 2435 DecimalFormat::getMultiplier() const |
| 3840 { | 2436 { |
| 3841 if (fMultiplier == NULL) { | 2437 return fImpl->getMultiplier(); |
| 3842 return 1; | |
| 3843 } else { | |
| 3844 return fMultiplier->getLong(); | |
| 3845 } | |
| 3846 } | 2438 } |
| 3847 | 2439 |
| 3848 //------------------------------------------------------------------------------ | 2440 //------------------------------------------------------------------------------ |
| 3849 // Sets the multiplier of the number pattern. | 2441 // Sets the multiplier of the number pattern. |
| 3850 void | 2442 void |
| 3851 DecimalFormat::setMultiplier(int32_t newValue) | 2443 DecimalFormat::setMultiplier(int32_t newValue) |
| 3852 { | 2444 { |
| 3853 // if (newValue == 0) { | 2445 fImpl->setMultiplier(newValue); |
| 3854 // throw new IllegalArgumentException("Bad multiplier: " + newValue); | |
| 3855 // } | |
| 3856 if (newValue == 0) { | |
| 3857 newValue = 1; // one being the benign default value for a multiplier
. | |
| 3858 } | |
| 3859 if (newValue == 1) { | |
| 3860 delete fMultiplier; | |
| 3861 fMultiplier = NULL; | |
| 3862 } else { | |
| 3863 if (fMultiplier == NULL) { | |
| 3864 fMultiplier = new DigitList; | |
| 3865 } | |
| 3866 if (fMultiplier != NULL) { | |
| 3867 fMultiplier->set(newValue); | |
| 3868 } | |
| 3869 } | |
| 3870 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 3871 handleChanged(); | |
| 3872 #endif | |
| 3873 } | 2446 } |
| 3874 | 2447 |
| 3875 /** | 2448 /** |
| 3876 * Get the rounding increment. | 2449 * Get the rounding increment. |
| 3877 * @return A positive rounding increment, or 0.0 if rounding | 2450 * @return A positive rounding increment, or 0.0 if rounding |
| 3878 * is not in effect. | 2451 * is not in effect. |
| 3879 * @see #setRoundingIncrement | 2452 * @see #setRoundingIncrement |
| 3880 * @see #getRoundingMode | 2453 * @see #getRoundingMode |
| 3881 * @see #setRoundingMode | 2454 * @see #setRoundingMode |
| 3882 */ | 2455 */ |
| 3883 double DecimalFormat::getRoundingIncrement() const { | 2456 double DecimalFormat::getRoundingIncrement() const { |
| 3884 if (fRoundingIncrement == NULL) { | 2457 return fImpl->getRoundingIncrement(); |
| 3885 return 0.0; | |
| 3886 } else { | |
| 3887 return fRoundingIncrement->getDouble(); | |
| 3888 } | |
| 3889 } | 2458 } |
| 3890 | 2459 |
| 3891 /** | 2460 /** |
| 3892 * Set the rounding increment. This method also controls whether | 2461 * Set the rounding increment. This method also controls whether |
| 3893 * rounding is enabled. | 2462 * rounding is enabled. |
| 3894 * @param newValue A positive rounding increment, or 0.0 to disable rounding. | 2463 * @param newValue A positive rounding increment, or 0.0 to disable rounding. |
| 3895 * Negative increments are equivalent to 0.0. | 2464 * Negative increments are equivalent to 0.0. |
| 3896 * @see #getRoundingIncrement | 2465 * @see #getRoundingIncrement |
| 3897 * @see #getRoundingMode | 2466 * @see #getRoundingMode |
| 3898 * @see #setRoundingMode | 2467 * @see #setRoundingMode |
| 3899 */ | 2468 */ |
| 3900 void DecimalFormat::setRoundingIncrement(double newValue) { | 2469 void DecimalFormat::setRoundingIncrement(double newValue) { |
| 3901 if (newValue > 0.0) { | 2470 fImpl->setRoundingIncrement(newValue); |
| 3902 if (fRoundingIncrement == NULL) { | |
| 3903 fRoundingIncrement = new DigitList(); | |
| 3904 } | |
| 3905 if (fRoundingIncrement != NULL) { | |
| 3906 fRoundingIncrement->set(newValue); | |
| 3907 return; | |
| 3908 } | |
| 3909 } | |
| 3910 // These statements are executed if newValue is less than 0.0 | |
| 3911 // or fRoundingIncrement could not be created. | |
| 3912 delete fRoundingIncrement; | |
| 3913 fRoundingIncrement = NULL; | |
| 3914 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 3915 handleChanged(); | |
| 3916 #endif | |
| 3917 } | 2471 } |
| 3918 | 2472 |
| 3919 /** | 2473 /** |
| 3920 * Get the rounding mode. | 2474 * Get the rounding mode. |
| 3921 * @return A rounding mode | 2475 * @return A rounding mode |
| 3922 * @see #setRoundingIncrement | 2476 * @see #setRoundingIncrement |
| 3923 * @see #getRoundingIncrement | 2477 * @see #getRoundingIncrement |
| 3924 * @see #setRoundingMode | 2478 * @see #setRoundingMode |
| 3925 */ | 2479 */ |
| 3926 DecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() const { | 2480 DecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() const { |
| 3927 return fRoundingMode; | 2481 return fImpl->getRoundingMode(); |
| 3928 } | 2482 } |
| 3929 | 2483 |
| 3930 /** | 2484 /** |
| 3931 * Set the rounding mode. This has no effect unless the rounding | 2485 * Set the rounding mode. This has no effect unless the rounding |
| 3932 * increment is greater than zero. | 2486 * increment is greater than zero. |
| 3933 * @param roundingMode A rounding mode | 2487 * @param roundingMode A rounding mode |
| 3934 * @see #setRoundingIncrement | 2488 * @see #setRoundingIncrement |
| 3935 * @see #getRoundingIncrement | 2489 * @see #getRoundingIncrement |
| 3936 * @see #getRoundingMode | 2490 * @see #getRoundingMode |
| 3937 */ | 2491 */ |
| 3938 void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) { | 2492 void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) { |
| 3939 fRoundingMode = roundingMode; | 2493 fImpl->setRoundingMode(roundingMode); |
| 3940 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 3941 handleChanged(); | |
| 3942 #endif | |
| 3943 } | 2494 } |
| 3944 | 2495 |
| 3945 /** | 2496 /** |
| 3946 * Get the width to which the output of <code>format()</code> is padded. | 2497 * Get the width to which the output of <code>format()</code> is padded. |
| 3947 * @return the format width, or zero if no padding is in effect | 2498 * @return the format width, or zero if no padding is in effect |
| 3948 * @see #setFormatWidth | 2499 * @see #setFormatWidth |
| 3949 * @see #getPadCharacter | 2500 * @see #getPadCharacter |
| 3950 * @see #setPadCharacter | 2501 * @see #setPadCharacter |
| 3951 * @see #getPadPosition | 2502 * @see #getPadPosition |
| 3952 * @see #setPadPosition | 2503 * @see #setPadPosition |
| 3953 */ | 2504 */ |
| 3954 int32_t DecimalFormat::getFormatWidth() const { | 2505 int32_t DecimalFormat::getFormatWidth() const { |
| 3955 return fFormatWidth; | 2506 return fImpl->getFormatWidth(); |
| 3956 } | 2507 } |
| 3957 | 2508 |
| 3958 /** | 2509 /** |
| 3959 * Set the width to which the output of <code>format()</code> is padded. | 2510 * Set the width to which the output of <code>format()</code> is padded. |
| 3960 * This method also controls whether padding is enabled. | 2511 * This method also controls whether padding is enabled. |
| 3961 * @param width the width to which to pad the result of | 2512 * @param width the width to which to pad the result of |
| 3962 * <code>format()</code>, or zero to disable padding. A negative | 2513 * <code>format()</code>, or zero to disable padding. A negative |
| 3963 * width is equivalent to 0. | 2514 * width is equivalent to 0. |
| 3964 * @see #getFormatWidth | 2515 * @see #getFormatWidth |
| 3965 * @see #getPadCharacter | 2516 * @see #getPadCharacter |
| 3966 * @see #setPadCharacter | 2517 * @see #setPadCharacter |
| 3967 * @see #getPadPosition | 2518 * @see #getPadPosition |
| 3968 * @see #setPadPosition | 2519 * @see #setPadPosition |
| 3969 */ | 2520 */ |
| 3970 void DecimalFormat::setFormatWidth(int32_t width) { | 2521 void DecimalFormat::setFormatWidth(int32_t width) { |
| 3971 fFormatWidth = (width > 0) ? width : 0; | 2522 int32_t formatWidth = (width > 0) ? width : 0; |
| 3972 #if UCONFIG_FORMAT_FASTPATHS_49 | 2523 fImpl->setFormatWidth(formatWidth); |
| 3973 handleChanged(); | |
| 3974 #endif | |
| 3975 } | 2524 } |
| 3976 | 2525 |
| 3977 UnicodeString DecimalFormat::getPadCharacterString() const { | 2526 UnicodeString DecimalFormat::getPadCharacterString() const { |
| 3978 return UnicodeString(fPad); | 2527 return UnicodeString(fImpl->getPadCharacter()); |
| 3979 } | 2528 } |
| 3980 | 2529 |
| 3981 void DecimalFormat::setPadCharacter(const UnicodeString &padChar) { | 2530 void DecimalFormat::setPadCharacter(const UnicodeString &padChar) { |
| 2531 UChar pad; |
| 3982 if (padChar.length() > 0) { | 2532 if (padChar.length() > 0) { |
| 3983 fPad = padChar.char32At(0); | 2533 pad = padChar.char32At(0); |
| 3984 } | 2534 } |
| 3985 else { | 2535 else { |
| 3986 fPad = kDefaultPad; | 2536 pad = kDefaultPad; |
| 3987 } | 2537 } |
| 3988 #if UCONFIG_FORMAT_FASTPATHS_49 | 2538 fImpl->setPadCharacter(pad); |
| 3989 handleChanged(); | 2539 } |
| 3990 #endif | 2540 |
| 2541 static DecimalFormat::EPadPosition fromPadPosition(DigitAffixesAndPadding::EPadP
osition padPos) { |
| 2542 switch (padPos) { |
| 2543 case DigitAffixesAndPadding::kPadBeforePrefix: |
| 2544 return DecimalFormat::kPadBeforePrefix; |
| 2545 case DigitAffixesAndPadding::kPadAfterPrefix: |
| 2546 return DecimalFormat::kPadAfterPrefix; |
| 2547 case DigitAffixesAndPadding::kPadBeforeSuffix: |
| 2548 return DecimalFormat::kPadBeforeSuffix; |
| 2549 case DigitAffixesAndPadding::kPadAfterSuffix: |
| 2550 return DecimalFormat::kPadAfterSuffix; |
| 2551 default: |
| 2552 U_ASSERT(FALSE); |
| 2553 break; |
| 2554 } |
| 2555 return DecimalFormat::kPadBeforePrefix; |
| 3991 } | 2556 } |
| 3992 | 2557 |
| 3993 /** | 2558 /** |
| 3994 * Get the position at which padding will take place. This is the location | 2559 * Get the position at which padding will take place. This is the location |
| 3995 * at which padding will be inserted if the result of <code>format()</code> | 2560 * at which padding will be inserted if the result of <code>format()</code> |
| 3996 * is shorter than the format width. | 2561 * is shorter than the format width. |
| 3997 * @return the pad position, one of <code>kPadBeforePrefix</code>, | 2562 * @return the pad position, one of <code>kPadBeforePrefix</code>, |
| 3998 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or | 2563 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or |
| 3999 * <code>kPadAfterSuffix</code>. | 2564 * <code>kPadAfterSuffix</code>. |
| 4000 * @see #setFormatWidth | 2565 * @see #setFormatWidth |
| 4001 * @see #getFormatWidth | 2566 * @see #getFormatWidth |
| 4002 * @see #setPadCharacter | 2567 * @see #setPadCharacter |
| 4003 * @see #getPadCharacter | 2568 * @see #getPadCharacter |
| 4004 * @see #setPadPosition | 2569 * @see #setPadPosition |
| 4005 * @see #kPadBeforePrefix | 2570 * @see #kPadBeforePrefix |
| 4006 * @see #kPadAfterPrefix | 2571 * @see #kPadAfterPrefix |
| 4007 * @see #kPadBeforeSuffix | 2572 * @see #kPadBeforeSuffix |
| 4008 * @see #kPadAfterSuffix | 2573 * @see #kPadAfterSuffix |
| 4009 */ | 2574 */ |
| 4010 DecimalFormat::EPadPosition DecimalFormat::getPadPosition() const { | 2575 DecimalFormat::EPadPosition DecimalFormat::getPadPosition() const { |
| 4011 return fPadPosition; | 2576 return fromPadPosition(fImpl->getPadPosition()); |
| 2577 } |
| 2578 |
| 2579 static DigitAffixesAndPadding::EPadPosition toPadPosition(DecimalFormat::EPadPos
ition padPos) { |
| 2580 switch (padPos) { |
| 2581 case DecimalFormat::kPadBeforePrefix: |
| 2582 return DigitAffixesAndPadding::kPadBeforePrefix; |
| 2583 case DecimalFormat::kPadAfterPrefix: |
| 2584 return DigitAffixesAndPadding::kPadAfterPrefix; |
| 2585 case DecimalFormat::kPadBeforeSuffix: |
| 2586 return DigitAffixesAndPadding::kPadBeforeSuffix; |
| 2587 case DecimalFormat::kPadAfterSuffix: |
| 2588 return DigitAffixesAndPadding::kPadAfterSuffix; |
| 2589 default: |
| 2590 U_ASSERT(FALSE); |
| 2591 break; |
| 2592 } |
| 2593 return DigitAffixesAndPadding::kPadBeforePrefix; |
| 4012 } | 2594 } |
| 4013 | 2595 |
| 4014 /** | 2596 /** |
| 4015 * <strong><font face=helvetica color=red>NEW</font></strong> | 2597 * <strong><font face=helvetica color=red>NEW</font></strong> |
| 4016 * Set the position at which padding will take place. This is the location | 2598 * Set the position at which padding will take place. This is the location |
| 4017 * at which padding will be inserted if the result of <code>format()</code> | 2599 * at which padding will be inserted if the result of <code>format()</code> |
| 4018 * is shorter than the format width. This has no effect unless padding is | 2600 * is shorter than the format width. This has no effect unless padding is |
| 4019 * enabled. | 2601 * enabled. |
| 4020 * @param padPos the pad position, one of <code>kPadBeforePrefix</code>, | 2602 * @param padPos the pad position, one of <code>kPadBeforePrefix</code>, |
| 4021 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or | 2603 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or |
| 4022 * <code>kPadAfterSuffix</code>. | 2604 * <code>kPadAfterSuffix</code>. |
| 4023 * @see #setFormatWidth | 2605 * @see #setFormatWidth |
| 4024 * @see #getFormatWidth | 2606 * @see #getFormatWidth |
| 4025 * @see #setPadCharacter | 2607 * @see #setPadCharacter |
| 4026 * @see #getPadCharacter | 2608 * @see #getPadCharacter |
| 4027 * @see #getPadPosition | 2609 * @see #getPadPosition |
| 4028 * @see #kPadBeforePrefix | 2610 * @see #kPadBeforePrefix |
| 4029 * @see #kPadAfterPrefix | 2611 * @see #kPadAfterPrefix |
| 4030 * @see #kPadBeforeSuffix | 2612 * @see #kPadBeforeSuffix |
| 4031 * @see #kPadAfterSuffix | 2613 * @see #kPadAfterSuffix |
| 4032 */ | 2614 */ |
| 4033 void DecimalFormat::setPadPosition(EPadPosition padPos) { | 2615 void DecimalFormat::setPadPosition(EPadPosition padPos) { |
| 4034 fPadPosition = padPos; | 2616 fImpl->setPadPosition(toPadPosition(padPos)); |
| 4035 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 4036 handleChanged(); | |
| 4037 #endif | |
| 4038 } | 2617 } |
| 4039 | 2618 |
| 4040 /** | 2619 /** |
| 4041 * Return whether or not scientific notation is used. | 2620 * Return whether or not scientific notation is used. |
| 4042 * @return TRUE if this object formats and parses scientific notation | 2621 * @return TRUE if this object formats and parses scientific notation |
| 4043 * @see #setScientificNotation | 2622 * @see #setScientificNotation |
| 4044 * @see #getMinimumExponentDigits | 2623 * @see #getMinimumExponentDigits |
| 4045 * @see #setMinimumExponentDigits | 2624 * @see #setMinimumExponentDigits |
| 4046 * @see #isExponentSignAlwaysShown | 2625 * @see #isExponentSignAlwaysShown |
| 4047 * @see #setExponentSignAlwaysShown | 2626 * @see #setExponentSignAlwaysShown |
| 4048 */ | 2627 */ |
| 4049 UBool DecimalFormat::isScientificNotation() const { | 2628 UBool DecimalFormat::isScientificNotation() const { |
| 4050 return fUseExponentialNotation; | 2629 return fImpl->isScientificNotation(); |
| 4051 } | 2630 } |
| 4052 | 2631 |
| 4053 /** | 2632 /** |
| 4054 * Set whether or not scientific notation is used. | 2633 * Set whether or not scientific notation is used. |
| 4055 * @param useScientific TRUE if this object formats and parses scientific | 2634 * @param useScientific TRUE if this object formats and parses scientific |
| 4056 * notation | 2635 * notation |
| 4057 * @see #isScientificNotation | 2636 * @see #isScientificNotation |
| 4058 * @see #getMinimumExponentDigits | 2637 * @see #getMinimumExponentDigits |
| 4059 * @see #setMinimumExponentDigits | 2638 * @see #setMinimumExponentDigits |
| 4060 * @see #isExponentSignAlwaysShown | 2639 * @see #isExponentSignAlwaysShown |
| 4061 * @see #setExponentSignAlwaysShown | 2640 * @see #setExponentSignAlwaysShown |
| 4062 */ | 2641 */ |
| 4063 void DecimalFormat::setScientificNotation(UBool useScientific) { | 2642 void DecimalFormat::setScientificNotation(UBool useScientific) { |
| 4064 fUseExponentialNotation = useScientific; | 2643 fImpl->setScientificNotation(useScientific); |
| 4065 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 4066 handleChanged(); | |
| 4067 #endif | |
| 4068 } | 2644 } |
| 4069 | 2645 |
| 4070 /** | 2646 /** |
| 4071 * Return the minimum exponent digits that will be shown. | 2647 * Return the minimum exponent digits that will be shown. |
| 4072 * @return the minimum exponent digits that will be shown | 2648 * @return the minimum exponent digits that will be shown |
| 4073 * @see #setScientificNotation | 2649 * @see #setScientificNotation |
| 4074 * @see #isScientificNotation | 2650 * @see #isScientificNotation |
| 4075 * @see #setMinimumExponentDigits | 2651 * @see #setMinimumExponentDigits |
| 4076 * @see #isExponentSignAlwaysShown | 2652 * @see #isExponentSignAlwaysShown |
| 4077 * @see #setExponentSignAlwaysShown | 2653 * @see #setExponentSignAlwaysShown |
| 4078 */ | 2654 */ |
| 4079 int8_t DecimalFormat::getMinimumExponentDigits() const { | 2655 int8_t DecimalFormat::getMinimumExponentDigits() const { |
| 4080 return fMinExponentDigits; | 2656 return fImpl->getMinimumExponentDigits(); |
| 4081 } | 2657 } |
| 4082 | 2658 |
| 4083 /** | 2659 /** |
| 4084 * Set the minimum exponent digits that will be shown. This has no | 2660 * Set the minimum exponent digits that will be shown. This has no |
| 4085 * effect unless scientific notation is in use. | 2661 * effect unless scientific notation is in use. |
| 4086 * @param minExpDig a value >= 1 indicating the fewest exponent digits | 2662 * @param minExpDig a value >= 1 indicating the fewest exponent digits |
| 4087 * that will be shown. Values less than 1 will be treated as 1. | 2663 * that will be shown. Values less than 1 will be treated as 1. |
| 4088 * @see #setScientificNotation | 2664 * @see #setScientificNotation |
| 4089 * @see #isScientificNotation | 2665 * @see #isScientificNotation |
| 4090 * @see #getMinimumExponentDigits | 2666 * @see #getMinimumExponentDigits |
| 4091 * @see #isExponentSignAlwaysShown | 2667 * @see #isExponentSignAlwaysShown |
| 4092 * @see #setExponentSignAlwaysShown | 2668 * @see #setExponentSignAlwaysShown |
| 4093 */ | 2669 */ |
| 4094 void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) { | 2670 void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) { |
| 4095 fMinExponentDigits = (int8_t)((minExpDig > 0) ? minExpDig : 1); | 2671 int32_t minExponentDigits = (int8_t)((minExpDig > 0) ? minExpDig : 1); |
| 4096 #if UCONFIG_FORMAT_FASTPATHS_49 | 2672 fImpl->setMinimumExponentDigits(minExponentDigits); |
| 4097 handleChanged(); | |
| 4098 #endif | |
| 4099 } | 2673 } |
| 4100 | 2674 |
| 4101 /** | 2675 /** |
| 4102 * Return whether the exponent sign is always shown. | 2676 * Return whether the exponent sign is always shown. |
| 4103 * @return TRUE if the exponent is always prefixed with either the | 2677 * @return TRUE if the exponent is always prefixed with either the |
| 4104 * localized minus sign or the localized plus sign, false if only negative | 2678 * localized minus sign or the localized plus sign, false if only negative |
| 4105 * exponents are prefixed with the localized minus sign. | 2679 * exponents are prefixed with the localized minus sign. |
| 4106 * @see #setScientificNotation | 2680 * @see #setScientificNotation |
| 4107 * @see #isScientificNotation | 2681 * @see #isScientificNotation |
| 4108 * @see #setMinimumExponentDigits | 2682 * @see #setMinimumExponentDigits |
| 4109 * @see #getMinimumExponentDigits | 2683 * @see #getMinimumExponentDigits |
| 4110 * @see #setExponentSignAlwaysShown | 2684 * @see #setExponentSignAlwaysShown |
| 4111 */ | 2685 */ |
| 4112 UBool DecimalFormat::isExponentSignAlwaysShown() const { | 2686 UBool DecimalFormat::isExponentSignAlwaysShown() const { |
| 4113 return fExponentSignAlwaysShown; | 2687 return fImpl->isExponentSignAlwaysShown(); |
| 4114 } | 2688 } |
| 4115 | 2689 |
| 4116 /** | 2690 /** |
| 4117 * Set whether the exponent sign is always shown. This has no effect | 2691 * Set whether the exponent sign is always shown. This has no effect |
| 4118 * unless scientific notation is in use. | 2692 * unless scientific notation is in use. |
| 4119 * @param expSignAlways TRUE if the exponent is always prefixed with either | 2693 * @param expSignAlways TRUE if the exponent is always prefixed with either |
| 4120 * the localized minus sign or the localized plus sign, false if only | 2694 * the localized minus sign or the localized plus sign, false if only |
| 4121 * negative exponents are prefixed with the localized minus sign. | 2695 * negative exponents are prefixed with the localized minus sign. |
| 4122 * @see #setScientificNotation | 2696 * @see #setScientificNotation |
| 4123 * @see #isScientificNotation | 2697 * @see #isScientificNotation |
| 4124 * @see #setMinimumExponentDigits | 2698 * @see #setMinimumExponentDigits |
| 4125 * @see #getMinimumExponentDigits | 2699 * @see #getMinimumExponentDigits |
| 4126 * @see #isExponentSignAlwaysShown | 2700 * @see #isExponentSignAlwaysShown |
| 4127 */ | 2701 */ |
| 4128 void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) { | 2702 void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) { |
| 4129 fExponentSignAlwaysShown = expSignAlways; | 2703 fImpl->setExponentSignAlwaysShown(expSignAlways); |
| 4130 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 4131 handleChanged(); | |
| 4132 #endif | |
| 4133 } | 2704 } |
| 4134 | 2705 |
| 4135 //------------------------------------------------------------------------------ | 2706 //------------------------------------------------------------------------------ |
| 4136 // Gets the grouping size of the number pattern. For example, thousand or 10 | 2707 // Gets the grouping size of the number pattern. For example, thousand or 10 |
| 4137 // thousand groupings. | 2708 // thousand groupings. |
| 4138 | 2709 |
| 4139 int32_t | 2710 int32_t |
| 4140 DecimalFormat::getGroupingSize() const | 2711 DecimalFormat::getGroupingSize() const |
| 4141 { | 2712 { |
| 4142 return isGroupingUsed() ? fGroupingSize : 0; | 2713 return fImpl->getGroupingSize(); |
| 4143 } | 2714 } |
| 4144 | 2715 |
| 4145 //------------------------------------------------------------------------------ | 2716 //------------------------------------------------------------------------------ |
| 4146 // Gets the grouping size of the number pattern. | 2717 // Gets the grouping size of the number pattern. |
| 4147 | 2718 |
| 4148 void | 2719 void |
| 4149 DecimalFormat::setGroupingSize(int32_t newValue) | 2720 DecimalFormat::setGroupingSize(int32_t newValue) |
| 4150 { | 2721 { |
| 4151 fGroupingSize = newValue; | 2722 fImpl->setGroupingSize(newValue); |
| 4152 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 4153 handleChanged(); | |
| 4154 #endif | |
| 4155 } | 2723 } |
| 4156 | 2724 |
| 4157 //------------------------------------------------------------------------------ | 2725 //------------------------------------------------------------------------------ |
| 4158 | 2726 |
| 4159 int32_t | 2727 int32_t |
| 4160 DecimalFormat::getSecondaryGroupingSize() const | 2728 DecimalFormat::getSecondaryGroupingSize() const |
| 4161 { | 2729 { |
| 4162 return fGroupingSize2; | 2730 return fImpl->getSecondaryGroupingSize(); |
| 4163 } | 2731 } |
| 4164 | 2732 |
| 4165 //------------------------------------------------------------------------------ | 2733 //------------------------------------------------------------------------------ |
| 4166 | 2734 |
| 4167 void | 2735 void |
| 4168 DecimalFormat::setSecondaryGroupingSize(int32_t newValue) | 2736 DecimalFormat::setSecondaryGroupingSize(int32_t newValue) |
| 4169 { | 2737 { |
| 4170 fGroupingSize2 = newValue; | 2738 fImpl->setSecondaryGroupingSize(newValue); |
| 4171 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 4172 handleChanged(); | |
| 4173 #endif | |
| 4174 } | 2739 } |
| 4175 | 2740 |
| 4176 //------------------------------------------------------------------------------ | 2741 //------------------------------------------------------------------------------ |
| 2742 |
| 2743 int32_t |
| 2744 DecimalFormat::getMinimumGroupingDigits() const |
| 2745 { |
| 2746 return fImpl->getMinimumGroupingDigits(); |
| 2747 } |
| 2748 |
| 2749 //------------------------------------------------------------------------------ |
| 2750 |
| 2751 void |
| 2752 DecimalFormat::setMinimumGroupingDigits(int32_t newValue) |
| 2753 { |
| 2754 fImpl->setMinimumGroupingDigits(newValue); |
| 2755 } |
| 2756 |
| 2757 //------------------------------------------------------------------------------ |
| 4177 // Checks if to show the decimal separator. | 2758 // Checks if to show the decimal separator. |
| 4178 | 2759 |
| 4179 UBool | 2760 UBool |
| 4180 DecimalFormat::isDecimalSeparatorAlwaysShown() const | 2761 DecimalFormat::isDecimalSeparatorAlwaysShown() const |
| 4181 { | 2762 { |
| 4182 return fDecimalSeparatorAlwaysShown; | 2763 return fImpl->isDecimalSeparatorAlwaysShown(); |
| 4183 } | 2764 } |
| 4184 | 2765 |
| 4185 //------------------------------------------------------------------------------ | 2766 //------------------------------------------------------------------------------ |
| 4186 // Sets to always show the decimal separator. | 2767 // Sets to always show the decimal separator. |
| 4187 | 2768 |
| 4188 void | 2769 void |
| 4189 DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue) | 2770 DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue) |
| 4190 { | 2771 { |
| 4191 fDecimalSeparatorAlwaysShown = newValue; | 2772 fImpl->setDecimalSeparatorAlwaysShown(newValue); |
| 4192 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 4193 handleChanged(); | |
| 4194 #endif | |
| 4195 } | 2773 } |
| 4196 | 2774 |
| 4197 //------------------------------------------------------------------------------ | 2775 //------------------------------------------------------------------------------ |
| 4198 // Checks if decimal point pattern match is required | 2776 // Checks if decimal point pattern match is required |
| 4199 UBool | 2777 UBool |
| 4200 DecimalFormat::isDecimalPatternMatchRequired(void) const | 2778 DecimalFormat::isDecimalPatternMatchRequired(void) const |
| 4201 { | 2779 { |
| 4202 return fBoolFlags.contains(UNUM_PARSE_DECIMAL_MARK_REQUIRED); | 2780 return fBoolFlags.contains(UNUM_PARSE_DECIMAL_MARK_REQUIRED); |
| 4203 } | 2781 } |
| 4204 | 2782 |
| 4205 //------------------------------------------------------------------------------ | 2783 //------------------------------------------------------------------------------ |
| 4206 // Checks if decimal point pattern match is required | 2784 // Checks if decimal point pattern match is required |
| 4207 | 2785 |
| 4208 void | 2786 void |
| 4209 DecimalFormat::setDecimalPatternMatchRequired(UBool newValue) | 2787 DecimalFormat::setDecimalPatternMatchRequired(UBool newValue) |
| 4210 { | 2788 { |
| 4211 fBoolFlags.set(UNUM_PARSE_DECIMAL_MARK_REQUIRED, newValue); | 2789 fBoolFlags.set(UNUM_PARSE_DECIMAL_MARK_REQUIRED, newValue); |
| 4212 } | 2790 } |
| 4213 | 2791 |
| 4214 | 2792 |
| 4215 //------------------------------------------------------------------------------ | 2793 //------------------------------------------------------------------------------ |
| 4216 // Emits the pattern of this DecimalFormat instance. | 2794 // Emits the pattern of this DecimalFormat instance. |
| 4217 | 2795 |
| 4218 UnicodeString& | 2796 UnicodeString& |
| 4219 DecimalFormat::toPattern(UnicodeString& result) const | 2797 DecimalFormat::toPattern(UnicodeString& result) const |
| 4220 { | 2798 { |
| 4221 return toPattern(result, FALSE); | 2799 return fImpl->toPattern(result); |
| 4222 } | 2800 } |
| 4223 | 2801 |
| 4224 //------------------------------------------------------------------------------ | 2802 //------------------------------------------------------------------------------ |
| 4225 // Emits the localized pattern this DecimalFormat instance. | 2803 // Emits the localized pattern this DecimalFormat instance. |
| 4226 | 2804 |
| 4227 UnicodeString& | 2805 UnicodeString& |
| 4228 DecimalFormat::toLocalizedPattern(UnicodeString& result) const | 2806 DecimalFormat::toLocalizedPattern(UnicodeString& result) const |
| 4229 { | 2807 { |
| 4230 return toPattern(result, TRUE); | 2808 // toLocalizedPattern is deprecated, so we just make it the same as |
| 2809 // toPattern. |
| 2810 return fImpl->toPattern(result); |
| 4231 } | 2811 } |
| 4232 | 2812 |
| 4233 //------------------------------------------------------------------------------ | 2813 //------------------------------------------------------------------------------ |
| 4234 /** | |
| 4235 * Expand the affix pattern strings into the expanded affix strings. If any | |
| 4236 * affix pattern string is null, do not expand it. This method should be | |
| 4237 * called any time the symbols or the affix patterns change in order to keep | |
| 4238 * the expanded affix strings up to date. | |
| 4239 * This method also will be called before formatting if format currency | |
| 4240 * plural names, since the plural name is not a static one, it is | |
| 4241 * based on the currency plural count, the affix will be known only | |
| 4242 * after the currency plural count is know. | |
| 4243 * In which case, the parameter | |
| 4244 * 'pluralCount' will be a non-null currency plural count. | |
| 4245 * In all other cases, the 'pluralCount' is null, which means it is not needed. | |
| 4246 */ | |
| 4247 void DecimalFormat::expandAffixes(const UnicodeString* pluralCount) { | |
| 4248 FieldPositionHandler none; | |
| 4249 if (fPosPrefixPattern != 0) { | |
| 4250 expandAffix(*fPosPrefixPattern, fPositivePrefix, 0, none, FALSE, pluralCou
nt); | |
| 4251 } | |
| 4252 if (fPosSuffixPattern != 0) { | |
| 4253 expandAffix(*fPosSuffixPattern, fPositiveSuffix, 0, none, FALSE, pluralCou
nt); | |
| 4254 } | |
| 4255 if (fNegPrefixPattern != 0) { | |
| 4256 expandAffix(*fNegPrefixPattern, fNegativePrefix, 0, none, FALSE, pluralCou
nt); | |
| 4257 } | |
| 4258 if (fNegSuffixPattern != 0) { | |
| 4259 expandAffix(*fNegSuffixPattern, fNegativeSuffix, 0, none, FALSE, pluralCou
nt); | |
| 4260 } | |
| 4261 #ifdef FMT_DEBUG | |
| 4262 UnicodeString s; | |
| 4263 s.append(UnicodeString("[")) | |
| 4264 .append(DEREFSTR(fPosPrefixPattern)).append((UnicodeString)"|").append(DER
EFSTR(fPosSuffixPattern)) | |
| 4265 .append((UnicodeString)";") .append(DEREFSTR(fNegPrefixPattern)).append((U
nicodeString)"|").append(DEREFSTR(fNegSuffixPattern)) | |
| 4266 .append((UnicodeString)"]->[") | |
| 4267 .append(fPositivePrefix).append((UnicodeString)"|").append(fPositiveSuff
ix) | |
| 4268 .append((UnicodeString)";") .append(fNegativePrefix).append((UnicodeStri
ng)"|").append(fNegativeSuffix) | |
| 4269 .append((UnicodeString)"]\n"); | |
| 4270 debugout(s); | |
| 4271 #endif | |
| 4272 } | |
| 4273 | |
| 4274 /** | |
| 4275 * Expand an affix pattern into an affix string. All characters in the | |
| 4276 * pattern are literal unless prefixed by kQuote. The following characters | |
| 4277 * after kQuote are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE, | |
| 4278 * PATTERN_MINUS, and kCurrencySign. If kCurrencySign is doubled (kQuote + | |
| 4279 * kCurrencySign + kCurrencySign), it is interpreted as an international | |
| 4280 * currency sign. If CURRENCY_SIGN is tripled, it is interpreted as | |
| 4281 * currency plural long names, such as "US Dollars". | |
| 4282 * Any other character after a kQuote represents itself. | |
| 4283 * kQuote must be followed by another character; kQuote may not occur by | |
| 4284 * itself at the end of the pattern. | |
| 4285 * | |
| 4286 * This method is used in two distinct ways. First, it is used to expand | |
| 4287 * the stored affix patterns into actual affixes. For this usage, doFormat | |
| 4288 * must be false. Second, it is used to expand the stored affix patterns | |
| 4289 * given a specific number (doFormat == true), for those rare cases in | |
| 4290 * which a currency format references a ChoiceFormat (e.g., en_IN display | |
| 4291 * name for INR). The number itself is taken from digitList. | |
| 4292 * | |
| 4293 * When used in the first way, this method has a side effect: It sets | |
| 4294 * currencyChoice to a ChoiceFormat object, if the currency's display name | |
| 4295 * in this locale is a ChoiceFormat pattern (very rare). It only does this | |
| 4296 * if currencyChoice is null to start with. | |
| 4297 * | |
| 4298 * @param pattern the non-null, fPossibly empty pattern | |
| 4299 * @param affix string to receive the expanded equivalent of pattern. | |
| 4300 * Previous contents are deleted. | |
| 4301 * @param doFormat if false, then the pattern will be expanded, and if a | |
| 4302 * currency symbol is encountered that expands to a ChoiceFormat, the | |
| 4303 * currencyChoice member variable will be initialized if it is null. If | |
| 4304 * doFormat is true, then it is assumed that the currencyChoice has been | |
| 4305 * created, and it will be used to format the value in digitList. | |
| 4306 * @param pluralCount the plural count. It is only used for currency | |
| 4307 * plural format. In which case, it is the plural | |
| 4308 * count of the currency amount. For example, | |
| 4309 * in en_US, it is the singular "one", or the plural | |
| 4310 * "other". For all other cases, it is null, and | |
| 4311 * is not being used. | |
| 4312 */ | |
| 4313 void DecimalFormat::expandAffix(const UnicodeString& pattern, | |
| 4314 UnicodeString& affix, | |
| 4315 double number, | |
| 4316 FieldPositionHandler& handler, | |
| 4317 UBool doFormat, | |
| 4318 const UnicodeString* pluralCount) const { | |
| 4319 affix.remove(); | |
| 4320 for (int i=0; i<pattern.length(); ) { | |
| 4321 UChar32 c = pattern.char32At(i); | |
| 4322 i += U16_LENGTH(c); | |
| 4323 if (c == kQuote) { | |
| 4324 c = pattern.char32At(i); | |
| 4325 i += U16_LENGTH(c); | |
| 4326 int beginIdx = affix.length(); | |
| 4327 switch (c) { | |
| 4328 case kCurrencySign: { | |
| 4329 // As of ICU 2.2 we use the currency object, and | |
| 4330 // ignore the currency symbols in the DFS, unless | |
| 4331 // we have a null currency object. This occurs if | |
| 4332 // resurrecting a pre-2.2 object or if the user | |
| 4333 // sets a custom DFS. | |
| 4334 UBool intl = i<pattern.length() && | |
| 4335 pattern.char32At(i) == kCurrencySign; | |
| 4336 UBool plural = FALSE; | |
| 4337 if (intl) { | |
| 4338 ++i; | |
| 4339 plural = i<pattern.length() && | |
| 4340 pattern.char32At(i) == kCurrencySign; | |
| 4341 if (plural) { | |
| 4342 intl = FALSE; | |
| 4343 ++i; | |
| 4344 } | |
| 4345 } | |
| 4346 const UChar* currencyUChars = getCurrency(); | |
| 4347 if (currencyUChars[0] != 0) { | |
| 4348 UErrorCode ec = U_ZERO_ERROR; | |
| 4349 if (plural && pluralCount != NULL) { | |
| 4350 // plural name is only needed when pluralCount != null, | |
| 4351 // which means when formatting currency plural names. | |
| 4352 // For other cases, pluralCount == null, | |
| 4353 // and plural names are not needed. | |
| 4354 int32_t len; | |
| 4355 CharString pluralCountChar; | |
| 4356 pluralCountChar.appendInvariantChars(*pluralCount, ec); | |
| 4357 UBool isChoiceFormat; | |
| 4358 const UChar* s = ucurr_getPluralName(currencyUChars, | |
| 4359 fSymbols != NULL ? fSymbols->getLocale().getName() : | |
| 4360 Locale::getDefault().getName(), &isChoiceFormat, | |
| 4361 pluralCountChar.data(), &len, &ec); | |
| 4362 affix += UnicodeString(s, len); | |
| 4363 handler.addAttribute(kCurrencyField, beginIdx, affix.len
gth()); | |
| 4364 } else if(intl) { | |
| 4365 affix.append(currencyUChars, -1); | |
| 4366 handler.addAttribute(kCurrencyField, beginIdx, affix.len
gth()); | |
| 4367 } else { | |
| 4368 int32_t len; | |
| 4369 UBool isChoiceFormat; | |
| 4370 // If fSymbols is NULL, use default locale | |
| 4371 const UChar* s = ucurr_getName(currencyUChars, | |
| 4372 fSymbols != NULL ? fSymbols->getLocale().getName() :
Locale::getDefault().getName(), | |
| 4373 UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &ec); | |
| 4374 if (isChoiceFormat) { | |
| 4375 // Two modes here: If doFormat is false, we set up | |
| 4376 // currencyChoice. If doFormat is true, we use the | |
| 4377 // previously created currencyChoice to format the | |
| 4378 // value in digitList. | |
| 4379 if (!doFormat) { | |
| 4380 // If the currency is handled by a ChoiceFormat, | |
| 4381 // then we're not going to use the expanded | |
| 4382 // patterns. Instantiate the ChoiceFormat and | |
| 4383 // return. | |
| 4384 if (fCurrencyChoice == NULL) { | |
| 4385 // TODO Replace double-check with proper thr
ead-safe code | |
| 4386 ChoiceFormat* fmt = new ChoiceFormat(Unicode
String(s), ec); | |
| 4387 if (U_SUCCESS(ec)) { | |
| 4388 umtx_lock(NULL); | |
| 4389 if (fCurrencyChoice == NULL) { | |
| 4390 // Cast away const | |
| 4391 ((DecimalFormat*)this)->fCurrencyCho
ice = fmt; | |
| 4392 fmt = NULL; | |
| 4393 } | |
| 4394 umtx_unlock(NULL); | |
| 4395 delete fmt; | |
| 4396 } | |
| 4397 } | |
| 4398 // We could almost return null or "" here, since
the | |
| 4399 // expanded affixes are almost not used at all | |
| 4400 // in this situation. However, one method -- | |
| 4401 // toPattern() -- still does use the expanded | |
| 4402 // affixes, in order to set up a padding | |
| 4403 // pattern. We use the CURRENCY_SIGN as a | |
| 4404 // placeholder. | |
| 4405 affix.append(kCurrencySign); | |
| 4406 } else { | |
| 4407 if (fCurrencyChoice != NULL) { | |
| 4408 FieldPosition pos(0); // ignored | |
| 4409 if (number < 0) { | |
| 4410 number = -number; | |
| 4411 } | |
| 4412 fCurrencyChoice->format(number, affix, pos); | |
| 4413 } else { | |
| 4414 // We only arrive here if the currency choic
e | |
| 4415 // format in the locale data is INVALID. | |
| 4416 affix.append(currencyUChars, -1); | |
| 4417 handler.addAttribute(kCurrencyField, beginId
x, affix.length()); | |
| 4418 } | |
| 4419 } | |
| 4420 continue; | |
| 4421 } | |
| 4422 affix += UnicodeString(s, len); | |
| 4423 handler.addAttribute(kCurrencyField, beginIdx, affix.len
gth()); | |
| 4424 } | |
| 4425 } else { | |
| 4426 if(intl) { | |
| 4427 affix += getConstSymbol(DecimalFormatSymbols::kIntlCurre
ncySymbol); | |
| 4428 } else { | |
| 4429 affix += getConstSymbol(DecimalFormatSymbols::kCurrencyS
ymbol); | |
| 4430 } | |
| 4431 handler.addAttribute(kCurrencyField, beginIdx, affix.length(
)); | |
| 4432 } | |
| 4433 break; | |
| 4434 } | |
| 4435 case kPatternPercent: | |
| 4436 affix += getConstSymbol(DecimalFormatSymbols::kPercentSymbol); | |
| 4437 handler.addAttribute(kPercentField, beginIdx, affix.length()); | |
| 4438 break; | |
| 4439 case kPatternPerMill: | |
| 4440 affix += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); | |
| 4441 handler.addAttribute(kPermillField, beginIdx, affix.length()); | |
| 4442 break; | |
| 4443 case kPatternPlus: | |
| 4444 affix += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); | |
| 4445 handler.addAttribute(kSignField, beginIdx, affix.length()); | |
| 4446 break; | |
| 4447 case kPatternMinus: | |
| 4448 affix += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); | |
| 4449 handler.addAttribute(kSignField, beginIdx, affix.length()); | |
| 4450 break; | |
| 4451 default: | |
| 4452 affix.append(c); | |
| 4453 break; | |
| 4454 } | |
| 4455 } | |
| 4456 else { | |
| 4457 affix.append(c); | |
| 4458 } | |
| 4459 } | |
| 4460 } | |
| 4461 | |
| 4462 /** | |
| 4463 * Append an affix to the given StringBuffer. | |
| 4464 * @param buf buffer to append to | |
| 4465 * @param isNegative | |
| 4466 * @param isPrefix | |
| 4467 */ | |
| 4468 int32_t DecimalFormat::appendAffix(UnicodeString& buf, double number, | |
| 4469 FieldPositionHandler& handler, | |
| 4470 UBool isNegative, UBool isPrefix) const { | |
| 4471 // plural format precedes choice format | |
| 4472 if (fCurrencyChoice != 0 && | |
| 4473 fCurrencySignCount != fgCurrencySignCountInPluralFormat) { | |
| 4474 const UnicodeString* affixPat; | |
| 4475 if (isPrefix) { | |
| 4476 affixPat = isNegative ? fNegPrefixPattern : fPosPrefixPattern; | |
| 4477 } else { | |
| 4478 affixPat = isNegative ? fNegSuffixPattern : fPosSuffixPattern; | |
| 4479 } | |
| 4480 if (affixPat) { | |
| 4481 UnicodeString affixBuf; | |
| 4482 expandAffix(*affixPat, affixBuf, number, handler, TRUE, NULL); | |
| 4483 buf.append(affixBuf); | |
| 4484 return affixBuf.length(); | |
| 4485 } | |
| 4486 // else someone called a function that reset the pattern. | |
| 4487 } | |
| 4488 | |
| 4489 const UnicodeString* affix; | |
| 4490 if (fCurrencySignCount == fgCurrencySignCountInPluralFormat) { | |
| 4491 // TODO: get an accurate count of visible fraction digits. | |
| 4492 UnicodeString pluralCount; | |
| 4493 int32_t minFractionDigits = this->getMinimumFractionDigits(); | |
| 4494 if (minFractionDigits > 0) { | |
| 4495 FixedDecimal ni(number, this->getMinimumFractionDigits()); | |
| 4496 pluralCount = fCurrencyPluralInfo->getPluralRules()->select(ni); | |
| 4497 } else { | |
| 4498 pluralCount = fCurrencyPluralInfo->getPluralRules()->select(number); | |
| 4499 } | |
| 4500 AffixesForCurrency* oneSet; | |
| 4501 if (fStyle == UNUM_CURRENCY_PLURAL) { | |
| 4502 oneSet = (AffixesForCurrency*)fPluralAffixesForCurrency->get(pluralC
ount); | |
| 4503 } else { | |
| 4504 oneSet = (AffixesForCurrency*)fAffixesForCurrency->get(pluralCount); | |
| 4505 } | |
| 4506 if (isPrefix) { | |
| 4507 affix = isNegative ? &oneSet->negPrefixForCurrency : | |
| 4508 &oneSet->posPrefixForCurrency; | |
| 4509 } else { | |
| 4510 affix = isNegative ? &oneSet->negSuffixForCurrency : | |
| 4511 &oneSet->posSuffixForCurrency; | |
| 4512 } | |
| 4513 } else { | |
| 4514 if (isPrefix) { | |
| 4515 affix = isNegative ? &fNegativePrefix : &fPositivePrefix; | |
| 4516 } else { | |
| 4517 affix = isNegative ? &fNegativeSuffix : &fPositiveSuffix; | |
| 4518 } | |
| 4519 } | |
| 4520 | |
| 4521 int32_t begin = (int) buf.length(); | |
| 4522 | |
| 4523 buf.append(*affix); | |
| 4524 | |
| 4525 if (handler.isRecording()) { | |
| 4526 int32_t offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbol
s::kCurrencySymbol)); | |
| 4527 if (offset > -1) { | |
| 4528 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
); | |
| 4529 handler.addAttribute(kCurrencyField, begin + offset, begin + offset + af
f.length()); | |
| 4530 } | |
| 4531 | |
| 4532 offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kIntl
CurrencySymbol)); | |
| 4533 if (offset > -1) { | |
| 4534 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kIntlCurrencySy
mbol); | |
| 4535 handler.addAttribute(kCurrencyField, begin + offset, begin + offset + af
f.length()); | |
| 4536 } | |
| 4537 | |
| 4538 offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kMinu
sSignSymbol)); | |
| 4539 if (offset > -1) { | |
| 4540 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kMinusSignSymbo
l); | |
| 4541 handler.addAttribute(kSignField, begin + offset, begin + offset + aff.le
ngth()); | |
| 4542 } | |
| 4543 | |
| 4544 offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPerc
entSymbol)); | |
| 4545 if (offset > -1) { | |
| 4546 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPercentSymbol)
; | |
| 4547 handler.addAttribute(kPercentField, begin + offset, begin + offset + aff
.length()); | |
| 4548 } | |
| 4549 | |
| 4550 offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPerM
illSymbol)); | |
| 4551 if (offset > -1) { | |
| 4552 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPerMillSymbol)
; | |
| 4553 handler.addAttribute(kPermillField, begin + offset, begin + offset + aff
.length()); | |
| 4554 } | |
| 4555 } | |
| 4556 return affix->length(); | |
| 4557 } | |
| 4558 | |
| 4559 /** | |
| 4560 * Appends an affix pattern to the given StringBuffer, quoting special | |
| 4561 * characters as needed. Uses the internal affix pattern, if that exists, | |
| 4562 * or the literal affix, if the internal affix pattern is null. The | |
| 4563 * appended string will generate the same affix pattern (or literal affix) | |
| 4564 * when passed to toPattern(). | |
| 4565 * | |
| 4566 * @param appendTo the affix string is appended to this | |
| 4567 * @param affixPattern a pattern such as fPosPrefixPattern; may be null | |
| 4568 * @param expAffix a corresponding expanded affix, such as fPositivePrefix. | |
| 4569 * Ignored unless affixPattern is null. If affixPattern is null, then | |
| 4570 * expAffix is appended as a literal affix. | |
| 4571 * @param localized true if the appended pattern should contain localized | |
| 4572 * pattern characters; otherwise, non-localized pattern chars are appended | |
| 4573 */ | |
| 4574 void DecimalFormat::appendAffixPattern(UnicodeString& appendTo, | |
| 4575 const UnicodeString* affixPattern, | |
| 4576 const UnicodeString& expAffix, | |
| 4577 UBool localized) const { | |
| 4578 if (affixPattern == 0) { | |
| 4579 appendAffixPattern(appendTo, expAffix, localized); | |
| 4580 } else { | |
| 4581 int i; | |
| 4582 for (int pos=0; pos<affixPattern->length(); pos=i) { | |
| 4583 i = affixPattern->indexOf(kQuote, pos); | |
| 4584 if (i < 0) { | |
| 4585 UnicodeString s; | |
| 4586 affixPattern->extractBetween(pos, affixPattern->length(), s); | |
| 4587 appendAffixPattern(appendTo, s, localized); | |
| 4588 break; | |
| 4589 } | |
| 4590 if (i > pos) { | |
| 4591 UnicodeString s; | |
| 4592 affixPattern->extractBetween(pos, i, s); | |
| 4593 appendAffixPattern(appendTo, s, localized); | |
| 4594 } | |
| 4595 UChar32 c = affixPattern->char32At(++i); | |
| 4596 ++i; | |
| 4597 if (c == kQuote) { | |
| 4598 appendTo.append(c).append(c); | |
| 4599 // Fall through and append another kQuote below | |
| 4600 } else if (c == kCurrencySign && | |
| 4601 i<affixPattern->length() && | |
| 4602 affixPattern->char32At(i) == kCurrencySign) { | |
| 4603 ++i; | |
| 4604 appendTo.append(c).append(c); | |
| 4605 } else if (localized) { | |
| 4606 switch (c) { | |
| 4607 case kPatternPercent: | |
| 4608 appendTo += getConstSymbol(DecimalFormatSymbols::kPercentSym
bol); | |
| 4609 break; | |
| 4610 case kPatternPerMill: | |
| 4611 appendTo += getConstSymbol(DecimalFormatSymbols::kPerMillSym
bol); | |
| 4612 break; | |
| 4613 case kPatternPlus: | |
| 4614 appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSy
mbol); | |
| 4615 break; | |
| 4616 case kPatternMinus: | |
| 4617 appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignS
ymbol); | |
| 4618 break; | |
| 4619 default: | |
| 4620 appendTo.append(c); | |
| 4621 } | |
| 4622 } else { | |
| 4623 appendTo.append(c); | |
| 4624 } | |
| 4625 } | |
| 4626 } | |
| 4627 } | |
| 4628 | |
| 4629 /** | |
| 4630 * Append an affix to the given StringBuffer, using quotes if | |
| 4631 * there are special characters. Single quotes themselves must be | |
| 4632 * escaped in either case. | |
| 4633 */ | |
| 4634 void | |
| 4635 DecimalFormat::appendAffixPattern(UnicodeString& appendTo, | |
| 4636 const UnicodeString& affix, | |
| 4637 UBool localized) const { | |
| 4638 UBool needQuote; | |
| 4639 if(localized) { | |
| 4640 needQuote = affix.indexOf(getConstSymbol(DecimalFormatSymbols::kZeroDigi
tSymbol)) >= 0 | |
| 4641 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kGroupingSepar
atorSymbol)) >= 0 | |
| 4642 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDecimalSepara
torSymbol)) >= 0 | |
| 4643 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol
)) >= 0 | |
| 4644 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
)) >= 0 | |
| 4645 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDigitSymbol))
>= 0 | |
| 4646 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPatternSepara
torSymbol)) >= 0 | |
| 4647 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbo
l)) >= 0 | |
| 4648 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymb
ol)) >= 0 | |
| 4649 || affix.indexOf(kCurrencySign) >= 0; | |
| 4650 } | |
| 4651 else { | |
| 4652 needQuote = affix.indexOf(kPatternZeroDigit) >= 0 | |
| 4653 || affix.indexOf(kPatternGroupingSeparator) >= 0 | |
| 4654 || affix.indexOf(kPatternDecimalSeparator) >= 0 | |
| 4655 || affix.indexOf(kPatternPercent) >= 0 | |
| 4656 || affix.indexOf(kPatternPerMill) >= 0 | |
| 4657 || affix.indexOf(kPatternDigit) >= 0 | |
| 4658 || affix.indexOf(kPatternSeparator) >= 0 | |
| 4659 || affix.indexOf(kPatternExponent) >= 0 | |
| 4660 || affix.indexOf(kPatternPlus) >= 0 | |
| 4661 || affix.indexOf(kPatternMinus) >= 0 | |
| 4662 || affix.indexOf(kCurrencySign) >= 0; | |
| 4663 } | |
| 4664 if (needQuote) | |
| 4665 appendTo += (UChar)0x0027 /*'\''*/; | |
| 4666 if (affix.indexOf((UChar)0x0027 /*'\''*/) < 0) | |
| 4667 appendTo += affix; | |
| 4668 else { | |
| 4669 for (int32_t j = 0; j < affix.length(); ) { | |
| 4670 UChar32 c = affix.char32At(j); | |
| 4671 j += U16_LENGTH(c); | |
| 4672 appendTo += c; | |
| 4673 if (c == 0x0027 /*'\''*/) | |
| 4674 appendTo += c; | |
| 4675 } | |
| 4676 } | |
| 4677 if (needQuote) | |
| 4678 appendTo += (UChar)0x0027 /*'\''*/; | |
| 4679 } | |
| 4680 | |
| 4681 //------------------------------------------------------------------------------ | |
| 4682 | |
| 4683 UnicodeString& | |
| 4684 DecimalFormat::toPattern(UnicodeString& result, UBool localized) const | |
| 4685 { | |
| 4686 if (fStyle == UNUM_CURRENCY_PLURAL) { | |
| 4687 // the prefix or suffix pattern might not be defined yet, | |
| 4688 // so they can not be synthesized, | |
| 4689 // instead, get them directly. | |
| 4690 // but it might not be the actual pattern used in formatting. | |
| 4691 // the actual pattern used in formatting depends on the | |
| 4692 // formatted number's plural count. | |
| 4693 result = fFormatPattern; | |
| 4694 return result; | |
| 4695 } | |
| 4696 result.remove(); | |
| 4697 UChar32 zero, sigDigit = kPatternSignificantDigit; | |
| 4698 UnicodeString digit, group; | |
| 4699 int32_t i; | |
| 4700 int32_t roundingDecimalPos = 0; // Pos of decimal in roundingDigits | |
| 4701 UnicodeString roundingDigits; | |
| 4702 int32_t padPos = (fFormatWidth > 0) ? fPadPosition : -1; | |
| 4703 UnicodeString padSpec; | |
| 4704 UBool useSigDig = areSignificantDigitsUsed(); | |
| 4705 | |
| 4706 if (localized) { | |
| 4707 digit.append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol)); | |
| 4708 group.append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymb
ol)); | |
| 4709 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0
); | |
| 4710 if (useSigDig) { | |
| 4711 sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSym
bol).char32At(0); | |
| 4712 } | |
| 4713 } | |
| 4714 else { | |
| 4715 digit.append((UChar)kPatternDigit); | |
| 4716 group.append((UChar)kPatternGroupingSeparator); | |
| 4717 zero = (UChar32)kPatternZeroDigit; | |
| 4718 } | |
| 4719 if (fFormatWidth > 0) { | |
| 4720 if (localized) { | |
| 4721 padSpec.append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol
)); | |
| 4722 } | |
| 4723 else { | |
| 4724 padSpec.append((UChar)kPatternPadEscape); | |
| 4725 } | |
| 4726 padSpec.append(fPad); | |
| 4727 } | |
| 4728 if (fRoundingIncrement != NULL) { | |
| 4729 for(i=0; i<fRoundingIncrement->getCount(); ++i) { | |
| 4730 roundingDigits.append(zero+(fRoundingIncrement->getDigitValue(i))); //
Convert to Unicode digit | |
| 4731 } | |
| 4732 roundingDecimalPos = fRoundingIncrement->getDecimalAt(); | |
| 4733 } | |
| 4734 for (int32_t part=0; part<2; ++part) { | |
| 4735 if (padPos == kPadBeforePrefix) { | |
| 4736 result.append(padSpec); | |
| 4737 } | |
| 4738 appendAffixPattern(result, | |
| 4739 (part==0 ? fPosPrefixPattern : fNegPrefixPattern), | |
| 4740 (part==0 ? fPositivePrefix : fNegativePrefix), | |
| 4741 localized); | |
| 4742 if (padPos == kPadAfterPrefix && ! padSpec.isEmpty()) { | |
| 4743 result.append(padSpec); | |
| 4744 } | |
| 4745 int32_t sub0Start = result.length(); | |
| 4746 int32_t g = isGroupingUsed() ? _max(0, fGroupingSize) : 0; | |
| 4747 if (g > 0 && fGroupingSize2 > 0 && fGroupingSize2 != fGroupingSize) { | |
| 4748 g += fGroupingSize2; | |
| 4749 } | |
| 4750 int32_t maxDig = 0, minDig = 0, maxSigDig = 0; | |
| 4751 if (useSigDig) { | |
| 4752 minDig = getMinimumSignificantDigits(); | |
| 4753 maxDig = maxSigDig = getMaximumSignificantDigits(); | |
| 4754 } else { | |
| 4755 minDig = getMinimumIntegerDigits(); | |
| 4756 maxDig = getMaximumIntegerDigits(); | |
| 4757 } | |
| 4758 if (fUseExponentialNotation) { | |
| 4759 if (maxDig > kMaxScientificIntegerDigits) { | |
| 4760 maxDig = 1; | |
| 4761 } | |
| 4762 } else if (useSigDig) { | |
| 4763 maxDig = _max(maxDig, g+1); | |
| 4764 } else { | |
| 4765 maxDig = _max(_max(g, getMinimumIntegerDigits()), | |
| 4766 roundingDecimalPos) + 1; | |
| 4767 } | |
| 4768 for (i = maxDig; i > 0; --i) { | |
| 4769 if (!fUseExponentialNotation && i<maxDig && | |
| 4770 isGroupingPosition(i)) { | |
| 4771 result.append(group); | |
| 4772 } | |
| 4773 if (useSigDig) { | |
| 4774 // #@,@### (maxSigDig == 5, minSigDig == 2) | |
| 4775 // 65 4321 (1-based pos, count from the right) | |
| 4776 // Use # if pos > maxSigDig or 1 <= pos <= (maxSigDig - minSigDi
g) | |
| 4777 // Use @ if (maxSigDig - minSigDig) < pos <= maxSigDig | |
| 4778 if (maxSigDig >= i && i > (maxSigDig - minDig)) { | |
| 4779 result.append(sigDigit); | |
| 4780 } else { | |
| 4781 result.append(digit); | |
| 4782 } | |
| 4783 } else { | |
| 4784 if (! roundingDigits.isEmpty()) { | |
| 4785 int32_t pos = roundingDecimalPos - i; | |
| 4786 if (pos >= 0 && pos < roundingDigits.length()) { | |
| 4787 result.append((UChar) (roundingDigits.char32At(pos) - kP
atternZeroDigit + zero)); | |
| 4788 continue; | |
| 4789 } | |
| 4790 } | |
| 4791 if (i<=minDig) { | |
| 4792 result.append(zero); | |
| 4793 } else { | |
| 4794 result.append(digit); | |
| 4795 } | |
| 4796 } | |
| 4797 } | |
| 4798 if (!useSigDig) { | |
| 4799 if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown)
{ | |
| 4800 if (localized) { | |
| 4801 result += getConstSymbol(DecimalFormatSymbols::kDecimalSepar
atorSymbol); | |
| 4802 } | |
| 4803 else { | |
| 4804 result.append((UChar)kPatternDecimalSeparator); | |
| 4805 } | |
| 4806 } | |
| 4807 int32_t pos = roundingDecimalPos; | |
| 4808 for (i = 0; i < getMaximumFractionDigits(); ++i) { | |
| 4809 if (! roundingDigits.isEmpty() && pos < roundingDigits.length())
{ | |
| 4810 if (pos < 0) { | |
| 4811 result.append(zero); | |
| 4812 } | |
| 4813 else { | |
| 4814 result.append((UChar)(roundingDigits.char32At(pos) - kPa
tternZeroDigit + zero)); | |
| 4815 } | |
| 4816 ++pos; | |
| 4817 continue; | |
| 4818 } | |
| 4819 if (i<getMinimumFractionDigits()) { | |
| 4820 result.append(zero); | |
| 4821 } | |
| 4822 else { | |
| 4823 result.append(digit); | |
| 4824 } | |
| 4825 } | |
| 4826 } | |
| 4827 if (fUseExponentialNotation) { | |
| 4828 if (localized) { | |
| 4829 result += getConstSymbol(DecimalFormatSymbols::kExponentialSymbo
l); | |
| 4830 } | |
| 4831 else { | |
| 4832 result.append((UChar)kPatternExponent); | |
| 4833 } | |
| 4834 if (fExponentSignAlwaysShown) { | |
| 4835 if (localized) { | |
| 4836 result += getConstSymbol(DecimalFormatSymbols::kPlusSignSymb
ol); | |
| 4837 } | |
| 4838 else { | |
| 4839 result.append((UChar)kPatternPlus); | |
| 4840 } | |
| 4841 } | |
| 4842 for (i=0; i<fMinExponentDigits; ++i) { | |
| 4843 result.append(zero); | |
| 4844 } | |
| 4845 } | |
| 4846 if (! padSpec.isEmpty() && !fUseExponentialNotation) { | |
| 4847 int32_t add = fFormatWidth - result.length() + sub0Start | |
| 4848 - ((part == 0) | |
| 4849 ? fPositivePrefix.length() + fPositiveSuffix.length() | |
| 4850 : fNegativePrefix.length() + fNegativeSuffix.length()); | |
| 4851 while (add > 0) { | |
| 4852 result.insert(sub0Start, digit); | |
| 4853 ++maxDig; | |
| 4854 --add; | |
| 4855 // Only add a grouping separator if we have at least | |
| 4856 // 2 additional characters to be added, so we don't | |
| 4857 // end up with ",###". | |
| 4858 if (add>1 && isGroupingPosition(maxDig)) { | |
| 4859 result.insert(sub0Start, group); | |
| 4860 --add; | |
| 4861 } | |
| 4862 } | |
| 4863 } | |
| 4864 if (fPadPosition == kPadBeforeSuffix && ! padSpec.isEmpty()) { | |
| 4865 result.append(padSpec); | |
| 4866 } | |
| 4867 if (part == 0) { | |
| 4868 appendAffixPattern(result, fPosSuffixPattern, fPositiveSuffix, local
ized); | |
| 4869 if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) { | |
| 4870 result.append(padSpec); | |
| 4871 } | |
| 4872 UBool isDefault = FALSE; | |
| 4873 if ((fNegSuffixPattern == fPosSuffixPattern && // both null | |
| 4874 fNegativeSuffix == fPositiveSuffix) | |
| 4875 || (fNegSuffixPattern != 0 && fPosSuffixPattern != 0 && | |
| 4876 *fNegSuffixPattern == *fPosSuffixPattern)) | |
| 4877 { | |
| 4878 if (fNegPrefixPattern != NULL && fPosPrefixPattern != NULL) | |
| 4879 { | |
| 4880 int32_t length = fPosPrefixPattern->length(); | |
| 4881 isDefault = fNegPrefixPattern->length() == (length+2) && | |
| 4882 (*fNegPrefixPattern)[(int32_t)0] == kQuote && | |
| 4883 (*fNegPrefixPattern)[(int32_t)1] == kPatternMinus && | |
| 4884 fNegPrefixPattern->compare(2, length, *fPosPrefixPattern
, 0, length) == 0; | |
| 4885 } | |
| 4886 if (!isDefault && | |
| 4887 fNegPrefixPattern == NULL && fPosPrefixPattern == NULL) | |
| 4888 { | |
| 4889 int32_t length = fPositivePrefix.length(); | |
| 4890 isDefault = fNegativePrefix.length() == (length+1) && | |
| 4891 fNegativePrefix.compare(getConstSymbol(DecimalFormatSymb
ols::kMinusSignSymbol)) == 0 && | |
| 4892 fNegativePrefix.compare(1, length, fPositivePrefix, 0, l
ength) == 0; | |
| 4893 } | |
| 4894 } | |
| 4895 if (isDefault) { | |
| 4896 break; // Don't output default negative subpattern | |
| 4897 } else { | |
| 4898 if (localized) { | |
| 4899 result += getConstSymbol(DecimalFormatSymbols::kPatternSepar
atorSymbol); | |
| 4900 } | |
| 4901 else { | |
| 4902 result.append((UChar)kPatternSeparator); | |
| 4903 } | |
| 4904 } | |
| 4905 } else { | |
| 4906 appendAffixPattern(result, fNegSuffixPattern, fNegativeSuffix, local
ized); | |
| 4907 if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) { | |
| 4908 result.append(padSpec); | |
| 4909 } | |
| 4910 } | |
| 4911 } | |
| 4912 | |
| 4913 return result; | |
| 4914 } | |
| 4915 | |
| 4916 //------------------------------------------------------------------------------ | |
| 4917 | 2814 |
| 4918 void | 2815 void |
| 4919 DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status) | 2816 DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status) |
| 4920 { | 2817 { |
| 4921 UParseError parseError; | 2818 fImpl->applyPattern(pattern, status); |
| 4922 applyPattern(pattern, FALSE, parseError, status); | |
| 4923 } | 2819 } |
| 4924 | 2820 |
| 4925 //------------------------------------------------------------------------------ | 2821 //------------------------------------------------------------------------------ |
| 4926 | 2822 |
| 4927 void | 2823 void |
| 4928 DecimalFormat::applyPattern(const UnicodeString& pattern, | 2824 DecimalFormat::applyPattern(const UnicodeString& pattern, |
| 4929 UParseError& parseError, | 2825 UParseError& parseError, |
| 4930 UErrorCode& status) | 2826 UErrorCode& status) |
| 4931 { | 2827 { |
| 4932 applyPattern(pattern, FALSE, parseError, status); | 2828 fImpl->applyPattern(pattern, parseError, status); |
| 4933 } | 2829 } |
| 4934 //------------------------------------------------------------------------------ | 2830 //------------------------------------------------------------------------------ |
| 4935 | 2831 |
| 4936 void | 2832 void |
| 4937 DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& s
tatus) | 2833 DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& s
tatus) |
| 4938 { | 2834 { |
| 4939 UParseError parseError; | 2835 fImpl->applyLocalizedPattern(pattern, status); |
| 4940 applyPattern(pattern, TRUE,parseError,status); | |
| 4941 } | 2836 } |
| 4942 | 2837 |
| 4943 //------------------------------------------------------------------------------ | 2838 //------------------------------------------------------------------------------ |
| 4944 | 2839 |
| 4945 void | 2840 void |
| 4946 DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, | 2841 DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, |
| 4947 UParseError& parseError, | 2842 UParseError& parseError, |
| 4948 UErrorCode& status) | 2843 UErrorCode& status) |
| 4949 { | 2844 { |
| 4950 applyPattern(pattern, TRUE,parseError,status); | 2845 fImpl->applyLocalizedPattern(pattern, parseError, status); |
| 4951 } | 2846 } |
| 4952 | 2847 |
| 4953 //------------------------------------------------------------------------------ | 2848 //------------------------------------------------------------------------------ |
| 4954 | 2849 |
| 4955 void | |
| 4956 DecimalFormat::applyPatternWithoutExpandAffix(const UnicodeString& pattern, | |
| 4957 UBool localized, | |
| 4958 UParseError& parseError, | |
| 4959 UErrorCode& status) | |
| 4960 { | |
| 4961 if (U_FAILURE(status)) | |
| 4962 { | |
| 4963 return; | |
| 4964 } | |
| 4965 DecimalFormatPatternParser patternParser; | |
| 4966 if (localized) { | |
| 4967 patternParser.useSymbols(*fSymbols); | |
| 4968 } | |
| 4969 fFormatPattern = pattern; | |
| 4970 DecimalFormatPattern out; | |
| 4971 patternParser.applyPatternWithoutExpandAffix( | |
| 4972 pattern, | |
| 4973 out, | |
| 4974 parseError, | |
| 4975 status); | |
| 4976 if (U_FAILURE(status)) { | |
| 4977 return; | |
| 4978 } | |
| 4979 | |
| 4980 setMinimumIntegerDigits(out.fMinimumIntegerDigits); | |
| 4981 setMaximumIntegerDigits(out.fMaximumIntegerDigits); | |
| 4982 setMinimumFractionDigits(out.fMinimumFractionDigits); | |
| 4983 setMaximumFractionDigits(out.fMaximumFractionDigits); | |
| 4984 setSignificantDigitsUsed(out.fUseSignificantDigits); | |
| 4985 if (out.fUseSignificantDigits) { | |
| 4986 setMinimumSignificantDigits(out.fMinimumSignificantDigits); | |
| 4987 setMaximumSignificantDigits(out.fMaximumSignificantDigits); | |
| 4988 } | |
| 4989 fUseExponentialNotation = out.fUseExponentialNotation; | |
| 4990 if (out.fUseExponentialNotation) { | |
| 4991 fMinExponentDigits = out.fMinExponentDigits; | |
| 4992 } | |
| 4993 fExponentSignAlwaysShown = out.fExponentSignAlwaysShown; | |
| 4994 fCurrencySignCount = out.fCurrencySignCount; | |
| 4995 setGroupingUsed(out.fGroupingUsed); | |
| 4996 if (out.fGroupingUsed) { | |
| 4997 fGroupingSize = out.fGroupingSize; | |
| 4998 fGroupingSize2 = out.fGroupingSize2; | |
| 4999 } | |
| 5000 setMultiplier(out.fMultiplier); | |
| 5001 fDecimalSeparatorAlwaysShown = out.fDecimalSeparatorAlwaysShown; | |
| 5002 fFormatWidth = out.fFormatWidth; | |
| 5003 if (out.fRoundingIncrementUsed) { | |
| 5004 if (fRoundingIncrement != NULL) { | |
| 5005 *fRoundingIncrement = out.fRoundingIncrement; | |
| 5006 } else { | |
| 5007 fRoundingIncrement = new DigitList(out.fRoundingIncrement); | |
| 5008 /* test for NULL */ | |
| 5009 if (fRoundingIncrement == NULL) { | |
| 5010 status = U_MEMORY_ALLOCATION_ERROR; | |
| 5011 return; | |
| 5012 } | |
| 5013 } | |
| 5014 } else { | |
| 5015 setRoundingIncrement(0.0); | |
| 5016 } | |
| 5017 fPad = out.fPad; | |
| 5018 switch (out.fPadPosition) { | |
| 5019 case DecimalFormatPattern::kPadBeforePrefix: | |
| 5020 fPadPosition = kPadBeforePrefix; | |
| 5021 break; | |
| 5022 case DecimalFormatPattern::kPadAfterPrefix: | |
| 5023 fPadPosition = kPadAfterPrefix; | |
| 5024 break; | |
| 5025 case DecimalFormatPattern::kPadBeforeSuffix: | |
| 5026 fPadPosition = kPadBeforeSuffix; | |
| 5027 break; | |
| 5028 case DecimalFormatPattern::kPadAfterSuffix: | |
| 5029 fPadPosition = kPadAfterSuffix; | |
| 5030 break; | |
| 5031 } | |
| 5032 copyString(out.fNegPrefixPattern, out.fNegPatternsBogus, fNegPrefixPattern,
status); | |
| 5033 copyString(out.fNegSuffixPattern, out.fNegPatternsBogus, fNegSuffixPattern,
status); | |
| 5034 copyString(out.fPosPrefixPattern, out.fPosPatternsBogus, fPosPrefixPattern,
status); | |
| 5035 copyString(out.fPosSuffixPattern, out.fPosPatternsBogus, fPosSuffixPattern,
status); | |
| 5036 } | |
| 5037 | |
| 5038 | |
| 5039 void | |
| 5040 DecimalFormat::expandAffixAdjustWidth(const UnicodeString* pluralCount) { | |
| 5041 expandAffixes(pluralCount); | |
| 5042 if (fFormatWidth > 0) { | |
| 5043 // Finish computing format width (see above) | |
| 5044 // TODO: how to handle fFormatWidth, | |
| 5045 // need to save in f(Plural)AffixesForCurrecy? | |
| 5046 fFormatWidth += fPositivePrefix.length() + fPositiveSuffix.length(); | |
| 5047 } | |
| 5048 } | |
| 5049 | |
| 5050 | |
| 5051 void | |
| 5052 DecimalFormat::applyPattern(const UnicodeString& pattern, | |
| 5053 UBool localized, | |
| 5054 UParseError& parseError, | |
| 5055 UErrorCode& status) | |
| 5056 { | |
| 5057 // do the following re-set first. since they change private data by | |
| 5058 // apply pattern again. | |
| 5059 if (pattern.indexOf(kCurrencySign) != -1) { | |
| 5060 if (fCurrencyPluralInfo == NULL) { | |
| 5061 // initialize currencyPluralInfo if needed | |
| 5062 fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(),
status); | |
| 5063 } | |
| 5064 if (fAffixPatternsForCurrency == NULL) { | |
| 5065 setupCurrencyAffixPatterns(status); | |
| 5066 } | |
| 5067 if (pattern.indexOf(fgTripleCurrencySign, 3, 0) != -1) { | |
| 5068 // only setup the affixes of the current pattern. | |
| 5069 setupCurrencyAffixes(pattern, TRUE, FALSE, status); | |
| 5070 } | |
| 5071 } | |
| 5072 applyPatternWithoutExpandAffix(pattern, localized, parseError, status); | |
| 5073 expandAffixAdjustWidth(NULL); | |
| 5074 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 5075 handleChanged(); | |
| 5076 #endif | |
| 5077 } | |
| 5078 | |
| 5079 | |
| 5080 void | |
| 5081 DecimalFormat::applyPatternInternally(const UnicodeString& pluralCount, | |
| 5082 const UnicodeString& pattern, | |
| 5083 UBool localized, | |
| 5084 UParseError& parseError, | |
| 5085 UErrorCode& status) { | |
| 5086 applyPatternWithoutExpandAffix(pattern, localized, parseError, status); | |
| 5087 expandAffixAdjustWidth(&pluralCount); | |
| 5088 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 5089 handleChanged(); | |
| 5090 #endif | |
| 5091 } | |
| 5092 | |
| 5093 | |
| 5094 /** | 2850 /** |
| 5095 * Sets the maximum number of digits allowed in the integer portion of a | 2851 * Sets the maximum number of digits allowed in the integer portion of a |
| 5096 * number. | 2852 * number. |
| 5097 * @see NumberFormat#setMaximumIntegerDigits | 2853 * @see NumberFormat#setMaximumIntegerDigits |
| 5098 */ | 2854 */ |
| 5099 void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) { | 2855 void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) { |
| 5100 NumberFormat::setMaximumIntegerDigits(_min(newValue, gDefaultMaxIntegerDigit
s)); | 2856 newValue = _min(newValue, gDefaultMaxIntegerDigits); |
| 5101 #if UCONFIG_FORMAT_FASTPATHS_49 | 2857 NumberFormat::setMaximumIntegerDigits(newValue); |
| 5102 handleChanged(); | 2858 fImpl->updatePrecision(); |
| 5103 #endif | |
| 5104 } | 2859 } |
| 5105 | 2860 |
| 5106 /** | 2861 /** |
| 5107 * Sets the minimum number of digits allowed in the integer portion of a | 2862 * Sets the minimum number of digits allowed in the integer portion of a |
| 5108 * number. This override limits the integer digit count to 309. | 2863 * number. This override limits the integer digit count to 309. |
| 5109 * @see NumberFormat#setMinimumIntegerDigits | 2864 * @see NumberFormat#setMinimumIntegerDigits |
| 5110 */ | 2865 */ |
| 5111 void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) { | 2866 void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) { |
| 5112 NumberFormat::setMinimumIntegerDigits(_min(newValue, kDoubleIntegerDigits)); | 2867 newValue = _min(newValue, kDoubleIntegerDigits); |
| 5113 #if UCONFIG_FORMAT_FASTPATHS_49 | 2868 NumberFormat::setMinimumIntegerDigits(newValue); |
| 5114 handleChanged(); | 2869 fImpl->updatePrecision(); |
| 5115 #endif | |
| 5116 } | 2870 } |
| 5117 | 2871 |
| 5118 /** | 2872 /** |
| 5119 * Sets the maximum number of digits allowed in the fraction portion of a | 2873 * Sets the maximum number of digits allowed in the fraction portion of a |
| 5120 * number. This override limits the fraction digit count to 340. | 2874 * number. This override limits the fraction digit count to 340. |
| 5121 * @see NumberFormat#setMaximumFractionDigits | 2875 * @see NumberFormat#setMaximumFractionDigits |
| 5122 */ | 2876 */ |
| 5123 void DecimalFormat::setMaximumFractionDigits(int32_t newValue) { | 2877 void DecimalFormat::setMaximumFractionDigits(int32_t newValue) { |
| 5124 NumberFormat::setMaximumFractionDigits(_min(newValue, kDoubleFractionDigits)
); | 2878 newValue = _min(newValue, kDoubleFractionDigits); |
| 5125 #if UCONFIG_FORMAT_FASTPATHS_49 | 2879 NumberFormat::setMaximumFractionDigits(newValue); |
| 5126 handleChanged(); | 2880 fImpl->updatePrecision(); |
| 5127 #endif | |
| 5128 } | 2881 } |
| 5129 | 2882 |
| 5130 /** | 2883 /** |
| 5131 * Sets the minimum number of digits allowed in the fraction portion of a | 2884 * Sets the minimum number of digits allowed in the fraction portion of a |
| 5132 * number. This override limits the fraction digit count to 340. | 2885 * number. This override limits the fraction digit count to 340. |
| 5133 * @see NumberFormat#setMinimumFractionDigits | 2886 * @see NumberFormat#setMinimumFractionDigits |
| 5134 */ | 2887 */ |
| 5135 void DecimalFormat::setMinimumFractionDigits(int32_t newValue) { | 2888 void DecimalFormat::setMinimumFractionDigits(int32_t newValue) { |
| 5136 NumberFormat::setMinimumFractionDigits(_min(newValue, kDoubleFractionDigits)
); | 2889 newValue = _min(newValue, kDoubleFractionDigits); |
| 5137 #if UCONFIG_FORMAT_FASTPATHS_49 | 2890 NumberFormat::setMinimumFractionDigits(newValue); |
| 5138 handleChanged(); | 2891 fImpl->updatePrecision(); |
| 5139 #endif | |
| 5140 } | 2892 } |
| 5141 | 2893 |
| 5142 int32_t DecimalFormat::getMinimumSignificantDigits() const { | 2894 int32_t DecimalFormat::getMinimumSignificantDigits() const { |
| 5143 return fMinSignificantDigits; | 2895 return fImpl->getMinimumSignificantDigits(); |
| 5144 } | 2896 } |
| 5145 | 2897 |
| 5146 int32_t DecimalFormat::getMaximumSignificantDigits() const { | 2898 int32_t DecimalFormat::getMaximumSignificantDigits() const { |
| 5147 return fMaxSignificantDigits; | 2899 return fImpl->getMaximumSignificantDigits(); |
| 5148 } | 2900 } |
| 5149 | 2901 |
| 5150 void DecimalFormat::setMinimumSignificantDigits(int32_t min) { | 2902 void DecimalFormat::setMinimumSignificantDigits(int32_t min) { |
| 5151 if (min < 1) { | 2903 if (min < 1) { |
| 5152 min = 1; | 2904 min = 1; |
| 5153 } | 2905 } |
| 5154 // pin max sig dig to >= min | 2906 // pin max sig dig to >= min |
| 5155 int32_t max = _max(fMaxSignificantDigits, min); | 2907 int32_t max = _max(fImpl->fMaxSigDigits, min); |
| 5156 fMinSignificantDigits = min; | 2908 fImpl->setMinMaxSignificantDigits(min, max); |
| 5157 fMaxSignificantDigits = max; | |
| 5158 fUseSignificantDigits = TRUE; | |
| 5159 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 5160 handleChanged(); | |
| 5161 #endif | |
| 5162 } | 2909 } |
| 5163 | 2910 |
| 5164 void DecimalFormat::setMaximumSignificantDigits(int32_t max) { | 2911 void DecimalFormat::setMaximumSignificantDigits(int32_t max) { |
| 5165 if (max < 1) { | 2912 if (max < 1) { |
| 5166 max = 1; | 2913 max = 1; |
| 5167 } | 2914 } |
| 5168 // pin min sig dig to 1..max | 2915 // pin min sig dig to 1..max |
| 5169 U_ASSERT(fMinSignificantDigits >= 1); | 2916 U_ASSERT(fImpl->fMinSigDigits >= 1); |
| 5170 int32_t min = _min(fMinSignificantDigits, max); | 2917 int32_t min = _min(fImpl->fMinSigDigits, max); |
| 5171 fMinSignificantDigits = min; | 2918 fImpl->setMinMaxSignificantDigits(min, max); |
| 5172 fMaxSignificantDigits = max; | |
| 5173 fUseSignificantDigits = TRUE; | |
| 5174 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 5175 handleChanged(); | |
| 5176 #endif | |
| 5177 } | 2919 } |
| 5178 | 2920 |
| 5179 UBool DecimalFormat::areSignificantDigitsUsed() const { | 2921 UBool DecimalFormat::areSignificantDigitsUsed() const { |
| 5180 return fUseSignificantDigits; | 2922 return fImpl->areSignificantDigitsUsed(); |
| 5181 } | 2923 } |
| 5182 | 2924 |
| 5183 void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) { | 2925 void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) { |
| 5184 fUseSignificantDigits = useSignificantDigits; | 2926 fImpl->setSignificantDigitsUsed(useSignificantDigits); |
| 5185 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 5186 handleChanged(); | |
| 5187 #endif | |
| 5188 } | |
| 5189 | |
| 5190 void DecimalFormat::setCurrencyInternally(const UChar* theCurrency, | |
| 5191 UErrorCode& ec) { | |
| 5192 // If we are a currency format, then modify our affixes to | |
| 5193 // encode the currency symbol for the given currency in our | |
| 5194 // locale, and adjust the decimal digits and rounding for the | |
| 5195 // given currency. | |
| 5196 | |
| 5197 // Note: The code is ordered so that this object is *not changed* | |
| 5198 // until we are sure we are going to succeed. | |
| 5199 | |
| 5200 // NULL or empty currency is *legal* and indicates no currency. | |
| 5201 UBool isCurr = (theCurrency && *theCurrency); | |
| 5202 | |
| 5203 double rounding = 0.0; | |
| 5204 int32_t frac = 0; | |
| 5205 if (fCurrencySignCount != fgCurrencySignCountZero && isCurr) { | |
| 5206 rounding = ucurr_getRoundingIncrementForUsage(theCurrency, fCurrencyUsag
e, &ec); | |
| 5207 frac = ucurr_getDefaultFractionDigitsForUsage(theCurrency, fCurrencyUsag
e, &ec); | |
| 5208 } | |
| 5209 | |
| 5210 NumberFormat::setCurrency(theCurrency, ec); | |
| 5211 if (U_FAILURE(ec)) return; | |
| 5212 | |
| 5213 if (fCurrencySignCount != fgCurrencySignCountZero) { | |
| 5214 // NULL or empty currency is *legal* and indicates no currency. | |
| 5215 if (isCurr) { | |
| 5216 setRoundingIncrement(rounding); | |
| 5217 setMinimumFractionDigits(frac); | |
| 5218 setMaximumFractionDigits(frac); | |
| 5219 } | |
| 5220 expandAffixes(NULL); | |
| 5221 } | |
| 5222 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 5223 handleChanged(); | |
| 5224 #endif | |
| 5225 } | 2927 } |
| 5226 | 2928 |
| 5227 void DecimalFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) { | 2929 void DecimalFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) { |
| 5228 // set the currency before compute affixes to get the right currency names | 2930 // set the currency before compute affixes to get the right currency names |
| 5229 NumberFormat::setCurrency(theCurrency, ec); | 2931 NumberFormat::setCurrency(theCurrency, ec); |
| 5230 if (fFormatPattern.indexOf(fgTripleCurrencySign, 3, 0) != -1) { | 2932 fImpl->updateCurrency(ec); |
| 5231 UnicodeString savedPtn = fFormatPattern; | |
| 5232 setupCurrencyAffixes(fFormatPattern, TRUE, TRUE, ec); | |
| 5233 UParseError parseErr; | |
| 5234 applyPattern(savedPtn, FALSE, parseErr, ec); | |
| 5235 } | |
| 5236 // set the currency after apply pattern to get the correct rounding/fraction | |
| 5237 setCurrencyInternally(theCurrency, ec); | |
| 5238 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 5239 handleChanged(); | |
| 5240 #endif | |
| 5241 } | 2933 } |
| 5242 | 2934 |
| 5243 void DecimalFormat::setCurrencyUsage(UCurrencyUsage newContext, UErrorCode* ec){ | 2935 void DecimalFormat::setCurrencyUsage(UCurrencyUsage newContext, UErrorCode* ec){ |
| 5244 fCurrencyUsage = newContext; | 2936 fImpl->setCurrencyUsage(newContext, *ec); |
| 5245 | |
| 5246 const UChar* theCurrency = getCurrency(); | |
| 5247 | |
| 5248 // We set rounding/digit based on currency context | |
| 5249 if(theCurrency){ | |
| 5250 double rounding = ucurr_getRoundingIncrementForUsage(theCurrency, fCurre
ncyUsage, ec); | |
| 5251 int32_t frac = ucurr_getDefaultFractionDigitsForUsage(theCurrency, fCurr
encyUsage, ec); | |
| 5252 | |
| 5253 if (U_SUCCESS(*ec)) { | |
| 5254 setRoundingIncrement(rounding); | |
| 5255 setMinimumFractionDigits(frac); | |
| 5256 setMaximumFractionDigits(frac); | |
| 5257 } | |
| 5258 } | |
| 5259 } | 2937 } |
| 5260 | 2938 |
| 5261 UCurrencyUsage DecimalFormat::getCurrencyUsage() const { | 2939 UCurrencyUsage DecimalFormat::getCurrencyUsage() const { |
| 5262 return fCurrencyUsage; | 2940 return fImpl->getCurrencyUsage(); |
| 5263 } | 2941 } |
| 5264 | 2942 |
| 5265 // Deprecated variant with no UErrorCode parameter | 2943 // Deprecated variant with no UErrorCode parameter |
| 5266 void DecimalFormat::setCurrency(const UChar* theCurrency) { | 2944 void DecimalFormat::setCurrency(const UChar* theCurrency) { |
| 5267 UErrorCode ec = U_ZERO_ERROR; | 2945 UErrorCode ec = U_ZERO_ERROR; |
| 5268 setCurrency(theCurrency, ec); | 2946 setCurrency(theCurrency, ec); |
| 5269 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 5270 handleChanged(); | |
| 5271 #endif | |
| 5272 } | 2947 } |
| 5273 | 2948 |
| 5274 void DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const { | 2949 void DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const { |
| 5275 if (fSymbols == NULL) { | 2950 if (fImpl->fSymbols == NULL) { |
| 5276 ec = U_MEMORY_ALLOCATION_ERROR; | 2951 ec = U_MEMORY_ALLOCATION_ERROR; |
| 5277 return; | 2952 return; |
| 5278 } | 2953 } |
| 5279 ec = U_ZERO_ERROR; | 2954 ec = U_ZERO_ERROR; |
| 5280 const UChar* c = getCurrency(); | 2955 const UChar* c = getCurrency(); |
| 5281 if (*c == 0) { | 2956 if (*c == 0) { |
| 5282 const UnicodeString &intl = | 2957 const UnicodeString &intl = |
| 5283 fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); | 2958 fImpl->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); |
| 5284 c = intl.getBuffer(); // ok for intl to go out of scope | 2959 c = intl.getBuffer(); // ok for intl to go out of scope |
| 5285 } | 2960 } |
| 5286 u_strncpy(result, c, 3); | 2961 u_strncpy(result, c, 3); |
| 5287 result[3] = 0; | 2962 result[3] = 0; |
| 5288 } | 2963 } |
| 5289 | 2964 |
| 5290 /** | |
| 5291 * Return the number of fraction digits to display, or the total | |
| 5292 * number of digits for significant digit formats and exponential | |
| 5293 * formats. | |
| 5294 */ | |
| 5295 int32_t | |
| 5296 DecimalFormat::precision() const { | |
| 5297 if (areSignificantDigitsUsed()) { | |
| 5298 return getMaximumSignificantDigits(); | |
| 5299 } else if (fUseExponentialNotation) { | |
| 5300 return getMinimumIntegerDigits() + getMaximumFractionDigits(); | |
| 5301 } else { | |
| 5302 return getMaximumFractionDigits(); | |
| 5303 } | |
| 5304 } | |
| 5305 | |
| 5306 | |
| 5307 // TODO: template algorithm | |
| 5308 Hashtable* | |
| 5309 DecimalFormat::initHashForAffix(UErrorCode& status) { | |
| 5310 if ( U_FAILURE(status) ) { | |
| 5311 return NULL; | |
| 5312 } | |
| 5313 Hashtable* hTable; | |
| 5314 if ( (hTable = new Hashtable(TRUE, status)) == NULL ) { | |
| 5315 status = U_MEMORY_ALLOCATION_ERROR; | |
| 5316 return NULL; | |
| 5317 } | |
| 5318 if ( U_FAILURE(status) ) { | |
| 5319 delete hTable; | |
| 5320 return NULL; | |
| 5321 } | |
| 5322 hTable->setValueComparator(decimfmtAffixValueComparator); | |
| 5323 return hTable; | |
| 5324 } | |
| 5325 | |
| 5326 Hashtable* | 2965 Hashtable* |
| 5327 DecimalFormat::initHashForAffixPattern(UErrorCode& status) { | 2966 DecimalFormat::initHashForAffixPattern(UErrorCode& status) { |
| 5328 if ( U_FAILURE(status) ) { | 2967 if ( U_FAILURE(status) ) { |
| 5329 return NULL; | 2968 return NULL; |
| 5330 } | 2969 } |
| 5331 Hashtable* hTable; | 2970 Hashtable* hTable; |
| 5332 if ( (hTable = new Hashtable(TRUE, status)) == NULL ) { | 2971 if ( (hTable = new Hashtable(TRUE, status)) == NULL ) { |
| 5333 status = U_MEMORY_ALLOCATION_ERROR; | 2972 status = U_MEMORY_ALLOCATION_ERROR; |
| 5334 return NULL; | 2973 return NULL; |
| 5335 } | 2974 } |
| 5336 if ( U_FAILURE(status) ) { | 2975 if ( U_FAILURE(status) ) { |
| 5337 delete hTable; | 2976 delete hTable; |
| 5338 return NULL; | 2977 return NULL; |
| 5339 } | 2978 } |
| 5340 hTable->setValueComparator(decimfmtAffixPatternValueComparator); | 2979 hTable->setValueComparator(decimfmtAffixPatternValueComparator); |
| 5341 return hTable; | 2980 return hTable; |
| 5342 } | 2981 } |
| 5343 | 2982 |
| 5344 void | 2983 void |
| 5345 DecimalFormat::deleteHashForAffix(Hashtable*& table) | |
| 5346 { | |
| 5347 if ( table == NULL ) { | |
| 5348 return; | |
| 5349 } | |
| 5350 int32_t pos = -1; | |
| 5351 const UHashElement* element = NULL; | |
| 5352 while ( (element = table->nextElement(pos)) != NULL ) { | |
| 5353 const UHashTok valueTok = element->value; | |
| 5354 const AffixesForCurrency* value = (AffixesForCurrency*)valueTok.pointer; | |
| 5355 delete value; | |
| 5356 } | |
| 5357 delete table; | |
| 5358 table = NULL; | |
| 5359 } | |
| 5360 | |
| 5361 | |
| 5362 | |
| 5363 void | |
| 5364 DecimalFormat::deleteHashForAffixPattern() | 2984 DecimalFormat::deleteHashForAffixPattern() |
| 5365 { | 2985 { |
| 5366 if ( fAffixPatternsForCurrency == NULL ) { | 2986 if ( fAffixPatternsForCurrency == NULL ) { |
| 5367 return; | 2987 return; |
| 5368 } | 2988 } |
| 5369 int32_t pos = -1; | 2989 int32_t pos = UHASH_FIRST; |
| 5370 const UHashElement* element = NULL; | 2990 const UHashElement* element = NULL; |
| 5371 while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) { | 2991 while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) { |
| 5372 const UHashTok valueTok = element->value; | 2992 const UHashTok valueTok = element->value; |
| 5373 const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)value
Tok.pointer; | 2993 const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)value
Tok.pointer; |
| 5374 delete value; | 2994 delete value; |
| 5375 } | 2995 } |
| 5376 delete fAffixPatternsForCurrency; | 2996 delete fAffixPatternsForCurrency; |
| 5377 fAffixPatternsForCurrency = NULL; | 2997 fAffixPatternsForCurrency = NULL; |
| 5378 } | 2998 } |
| 5379 | 2999 |
| 5380 | 3000 |
| 5381 void | 3001 void |
| 5382 DecimalFormat::copyHashForAffixPattern(const Hashtable* source, | 3002 DecimalFormat::copyHashForAffixPattern(const Hashtable* source, |
| 5383 Hashtable* target, | 3003 Hashtable* target, |
| 5384 UErrorCode& status) { | 3004 UErrorCode& status) { |
| 5385 if ( U_FAILURE(status) ) { | 3005 if ( U_FAILURE(status) ) { |
| 5386 return; | 3006 return; |
| 5387 } | 3007 } |
| 5388 int32_t pos = -1; | 3008 int32_t pos = UHASH_FIRST; |
| 5389 const UHashElement* element = NULL; | 3009 const UHashElement* element = NULL; |
| 5390 if ( source ) { | 3010 if ( source ) { |
| 5391 while ( (element = source->nextElement(pos)) != NULL ) { | 3011 while ( (element = source->nextElement(pos)) != NULL ) { |
| 5392 const UHashTok keyTok = element->key; | 3012 const UHashTok keyTok = element->key; |
| 5393 const UnicodeString* key = (UnicodeString*)keyTok.pointer; | 3013 const UnicodeString* key = (UnicodeString*)keyTok.pointer; |
| 5394 const UHashTok valueTok = element->value; | 3014 const UHashTok valueTok = element->value; |
| 5395 const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)v
alueTok.pointer; | 3015 const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)v
alueTok.pointer; |
| 5396 AffixPatternsForCurrency* copy = new AffixPatternsForCurrency( | 3016 AffixPatternsForCurrency* copy = new AffixPatternsForCurrency( |
| 5397 value->negPrefixPatternForCurrency, | 3017 value->negPrefixPatternForCurrency, |
| 5398 value->negSuffixPatternForCurrency, | 3018 value->negSuffixPatternForCurrency, |
| 5399 value->posPrefixPatternForCurrency, | 3019 value->posPrefixPatternForCurrency, |
| 5400 value->posSuffixPatternForCurrency, | 3020 value->posSuffixPatternForCurrency, |
| 5401 value->patternType); | 3021 value->patternType); |
| 5402 target->put(UnicodeString(*key), copy, status); | 3022 target->put(UnicodeString(*key), copy, status); |
| 5403 if ( U_FAILURE(status) ) { | 3023 if ( U_FAILURE(status) ) { |
| 5404 return; | 3024 return; |
| 5405 } | 3025 } |
| 5406 } | 3026 } |
| 5407 } | 3027 } |
| 5408 } | 3028 } |
| 5409 | 3029 |
| 5410 // this is only overridden to call handleChanged() for fastpath purposes. | |
| 5411 void | 3030 void |
| 5412 DecimalFormat::setGroupingUsed(UBool newValue) { | 3031 DecimalFormat::setGroupingUsed(UBool newValue) { |
| 5413 NumberFormat::setGroupingUsed(newValue); | 3032 NumberFormat::setGroupingUsed(newValue); |
| 5414 handleChanged(); | 3033 fImpl->updateGrouping(); |
| 5415 } | 3034 } |
| 5416 | 3035 |
| 5417 // this is only overridden to call handleChanged() for fastpath purposes. | |
| 5418 void | 3036 void |
| 5419 DecimalFormat::setParseIntegerOnly(UBool newValue) { | 3037 DecimalFormat::setParseIntegerOnly(UBool newValue) { |
| 5420 NumberFormat::setParseIntegerOnly(newValue); | 3038 NumberFormat::setParseIntegerOnly(newValue); |
| 5421 handleChanged(); | |
| 5422 } | 3039 } |
| 5423 | 3040 |
| 5424 // this is only overridden to call handleChanged() for fastpath purposes. | |
| 5425 // setContext doesn't affect the fastPath right now, but this is called for comp
leteness | |
| 5426 void | 3041 void |
| 5427 DecimalFormat::setContext(UDisplayContext value, UErrorCode& status) { | 3042 DecimalFormat::setContext(UDisplayContext value, UErrorCode& status) { |
| 5428 NumberFormat::setContext(value, status); | 3043 NumberFormat::setContext(value, status); |
| 5429 handleChanged(); | |
| 5430 } | 3044 } |
| 5431 | 3045 |
| 5432 | |
| 5433 DecimalFormat& DecimalFormat::setAttribute( UNumberFormatAttribute attr, | 3046 DecimalFormat& DecimalFormat::setAttribute( UNumberFormatAttribute attr, |
| 5434 int32_t newValue, | 3047 int32_t newValue, |
| 5435 UErrorCode &status) { | 3048 UErrorCode &status) { |
| 5436 if(U_FAILURE(status)) return *this; | 3049 if(U_FAILURE(status)) return *this; |
| 5437 | 3050 |
| 5438 switch(attr) { | 3051 switch(attr) { |
| 5439 case UNUM_LENIENT_PARSE: | 3052 case UNUM_LENIENT_PARSE: |
| 5440 setLenient(newValue!=0); | 3053 setLenient(newValue!=0); |
| 5441 break; | 3054 break; |
| 5442 | 3055 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5521 break; | 3134 break; |
| 5522 #endif | 3135 #endif |
| 5523 | 3136 |
| 5524 /* These are stored in fBoolFlags */ | 3137 /* These are stored in fBoolFlags */ |
| 5525 case UNUM_PARSE_NO_EXPONENT: | 3138 case UNUM_PARSE_NO_EXPONENT: |
| 5526 case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS: | 3139 case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS: |
| 5527 case UNUM_PARSE_DECIMAL_MARK_REQUIRED: | 3140 case UNUM_PARSE_DECIMAL_MARK_REQUIRED: |
| 5528 if(!fBoolFlags.isValidValue(newValue)) { | 3141 if(!fBoolFlags.isValidValue(newValue)) { |
| 5529 status = U_ILLEGAL_ARGUMENT_ERROR; | 3142 status = U_ILLEGAL_ARGUMENT_ERROR; |
| 5530 } else { | 3143 } else { |
| 3144 if (attr == UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS) { |
| 3145 fImpl->setFailIfMoreThanMaxDigits((UBool) newValue); |
| 3146 } |
| 5531 fBoolFlags.set(attr, newValue); | 3147 fBoolFlags.set(attr, newValue); |
| 5532 } | 3148 } |
| 5533 break; | 3149 break; |
| 5534 | 3150 |
| 5535 case UNUM_SCALE: | 3151 case UNUM_SCALE: |
| 5536 fScale = newValue; | 3152 fImpl->setScale(newValue); |
| 5537 break; | 3153 break; |
| 5538 | 3154 |
| 5539 case UNUM_CURRENCY_USAGE: | 3155 case UNUM_CURRENCY_USAGE: |
| 5540 setCurrencyUsage((UCurrencyUsage)newValue, &status); | 3156 setCurrencyUsage((UCurrencyUsage)newValue, &status); |
| 3157 break; |
| 3158 |
| 3159 case UNUM_MINIMUM_GROUPING_DIGITS: |
| 3160 setMinimumGroupingDigits(newValue); |
| 3161 break; |
| 5541 | 3162 |
| 5542 default: | 3163 default: |
| 5543 status = U_UNSUPPORTED_ERROR; | 3164 status = U_UNSUPPORTED_ERROR; |
| 5544 break; | 3165 break; |
| 5545 } | 3166 } |
| 5546 return *this; | 3167 return *this; |
| 5547 } | 3168 } |
| 5548 | 3169 |
| 5549 int32_t DecimalFormat::getAttribute( UNumberFormatAttribute attr, | 3170 int32_t DecimalFormat::getAttribute( UNumberFormatAttribute attr, |
| 5550 UErrorCode &status ) const { | 3171 UErrorCode &status ) const { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5609 case UNUM_SECONDARY_GROUPING_SIZE: | 3230 case UNUM_SECONDARY_GROUPING_SIZE: |
| 5610 return getSecondaryGroupingSize(); | 3231 return getSecondaryGroupingSize(); |
| 5611 | 3232 |
| 5612 /* These are stored in fBoolFlags */ | 3233 /* These are stored in fBoolFlags */ |
| 5613 case UNUM_PARSE_NO_EXPONENT: | 3234 case UNUM_PARSE_NO_EXPONENT: |
| 5614 case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS: | 3235 case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS: |
| 5615 case UNUM_PARSE_DECIMAL_MARK_REQUIRED: | 3236 case UNUM_PARSE_DECIMAL_MARK_REQUIRED: |
| 5616 return fBoolFlags.get(attr); | 3237 return fBoolFlags.get(attr); |
| 5617 | 3238 |
| 5618 case UNUM_SCALE: | 3239 case UNUM_SCALE: |
| 5619 return fScale; | 3240 return fImpl->fScale; |
| 5620 | 3241 |
| 5621 case UNUM_CURRENCY_USAGE: | 3242 case UNUM_CURRENCY_USAGE: |
| 5622 return fCurrencyUsage; | 3243 return fImpl->getCurrencyUsage(); |
| 3244 |
| 3245 case UNUM_MINIMUM_GROUPING_DIGITS: |
| 3246 return getMinimumGroupingDigits(); |
| 5623 | 3247 |
| 5624 default: | 3248 default: |
| 5625 status = U_UNSUPPORTED_ERROR; | 3249 status = U_UNSUPPORTED_ERROR; |
| 5626 break; | 3250 break; |
| 5627 } | 3251 } |
| 5628 | 3252 |
| 5629 return -1; /* undefined */ | 3253 return -1; /* undefined */ |
| 5630 } | 3254 } |
| 5631 | 3255 |
| 5632 #if UCONFIG_HAVE_PARSEALLINPUT | 3256 #if UCONFIG_HAVE_PARSEALLINPUT |
| 5633 void DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) { | 3257 void DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) { |
| 5634 fParseAllInput = value; | 3258 fParseAllInput = value; |
| 5635 #if UCONFIG_FORMAT_FASTPATHS_49 | |
| 5636 handleChanged(); | |
| 5637 #endif | |
| 5638 } | 3259 } |
| 5639 #endif | 3260 #endif |
| 5640 | 3261 |
| 5641 void | |
| 5642 DecimalFormat::copyHashForAffix(const Hashtable* source, | |
| 5643 Hashtable* target, | |
| 5644 UErrorCode& status) { | |
| 5645 if ( U_FAILURE(status) ) { | |
| 5646 return; | |
| 5647 } | |
| 5648 int32_t pos = -1; | |
| 5649 const UHashElement* element = NULL; | |
| 5650 if ( source ) { | |
| 5651 while ( (element = source->nextElement(pos)) != NULL ) { | |
| 5652 const UHashTok keyTok = element->key; | |
| 5653 const UnicodeString* key = (UnicodeString*)keyTok.pointer; | |
| 5654 | |
| 5655 const UHashTok valueTok = element->value; | |
| 5656 const AffixesForCurrency* value = (AffixesForCurrency*)valueTok.poin
ter; | |
| 5657 AffixesForCurrency* copy = new AffixesForCurrency( | |
| 5658 value->negPrefixForCurrency, | |
| 5659 value->negSuffixForCurrency, | |
| 5660 value->posPrefixForCurrency, | |
| 5661 value->posSuffixForCurrency); | |
| 5662 target->put(UnicodeString(*key), copy, status); | |
| 5663 if ( U_FAILURE(status) ) { | |
| 5664 return; | |
| 5665 } | |
| 5666 } | |
| 5667 } | |
| 5668 } | |
| 5669 | |
| 5670 U_NAMESPACE_END | 3262 U_NAMESPACE_END |
| 5671 | 3263 |
| 5672 #endif /* #if !UCONFIG_NO_FORMATTING */ | 3264 #endif /* #if !UCONFIG_NO_FORMATTING */ |
| 5673 | 3265 |
| 5674 //eof | 3266 //eof |
| OLD | NEW |