Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Side by Side Diff: source/i18n/decimfmt.cpp

Issue 845603002: Update ICU to 54.1 step 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@master
Patch Set: remove unusued directories Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « source/i18n/decimalformatpattern.cpp ('k') | source/i18n/digitlst.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ******************************************************************************* 2 *******************************************************************************
3 * Copyright (C) 1997-2013, International Business Machines Corporation and * 3 * Copyright (C) 1997-2014, 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 #include "digitlst.h" 64 #include "digitlst.h"
65 #include "cstring.h" 65 #include "cstring.h"
66 #include "umutex.h" 66 #include "umutex.h"
67 #include "uassert.h" 67 #include "uassert.h"
68 #include "putilimp.h" 68 #include "putilimp.h"
69 #include <math.h> 69 #include <math.h>
70 #include "hash.h" 70 #include "hash.h"
71 #include "decfmtst.h" 71 #include "decfmtst.h"
72 #include "dcfmtimp.h" 72 #include "dcfmtimp.h"
73 #include "plurrule_impl.h" 73 #include "plurrule_impl.h"
74 #include "decimalformatpattern.h"
74 75
75 /* 76 /*
76 * On certain platforms, round is a macro defined in math.h 77 * On certain platforms, round is a macro defined in math.h
77 * This undefine is to avoid conflict between the macro and 78 * This undefine is to avoid conflict between the macro and
78 * the function defined below. 79 * the function defined below.
79 */ 80 */
80 #ifdef round 81 #ifdef round
81 #undef round 82 #undef round
82 #endif 83 #endif
83 84
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 static const char fgLatn[]="latn"; 282 static const char fgLatn[]="latn";
282 static const char fgPatterns[]="patterns"; 283 static const char fgPatterns[]="patterns";
283 static const char fgDecimalFormat[]="decimalFormat"; 284 static const char fgDecimalFormat[]="decimalFormat";
284 static const char fgCurrencyFormat[]="currencyFormat"; 285 static const char fgCurrencyFormat[]="currencyFormat";
285 286
286 static const UChar fgTripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0}; 287 static const UChar fgTripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0};
287 288
288 inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; } 289 inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; }
289 inline int32_t _max(int32_t a, int32_t b) { return (a<b) ? b : a; } 290 inline int32_t _max(int32_t a, int32_t b) { return (a<b) ? b : a; }
290 291
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
291 //------------------------------------------------------------------------------ 313 //------------------------------------------------------------------------------
292 // Constructs a DecimalFormat instance in the default locale. 314 // Constructs a DecimalFormat instance in the default locale.
293 315
294 DecimalFormat::DecimalFormat(UErrorCode& status) { 316 DecimalFormat::DecimalFormat(UErrorCode& status) {
295 init(); 317 init();
296 UParseError parseError; 318 UParseError parseError;
297 construct(status, parseError); 319 construct(status, parseError);
298 } 320 }
299 321
300 //------------------------------------------------------------------------------ 322 //------------------------------------------------------------------------------
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 fRoundingMode = kRoundHalfEven; 413 fRoundingMode = kRoundHalfEven;
392 fPad = 0; 414 fPad = 0;
393 fFormatWidth = 0; 415 fFormatWidth = 0;
394 fPadPosition = kPadBeforePrefix; 416 fPadPosition = kPadBeforePrefix;
395 fStyle = UNUM_DECIMAL; 417 fStyle = UNUM_DECIMAL;
396 fCurrencySignCount = fgCurrencySignCountZero; 418 fCurrencySignCount = fgCurrencySignCountZero;
397 fAffixPatternsForCurrency = NULL; 419 fAffixPatternsForCurrency = NULL;
398 fAffixesForCurrency = NULL; 420 fAffixesForCurrency = NULL;
399 fPluralAffixesForCurrency = NULL; 421 fPluralAffixesForCurrency = NULL;
400 fCurrencyPluralInfo = NULL; 422 fCurrencyPluralInfo = NULL;
423 fCurrencyUsage = UCURR_USAGE_STANDARD;
401 #if UCONFIG_HAVE_PARSEALLINPUT 424 #if UCONFIG_HAVE_PARSEALLINPUT
402 fParseAllInput = UNUM_MAYBE; 425 fParseAllInput = UNUM_MAYBE;
403 #endif 426 #endif
404 427
405 #if UCONFIG_FORMAT_FASTPATHS_49 428 #if UCONFIG_FORMAT_FASTPATHS_49
406 DecimalFormatInternal &data = internalData(fReserved); 429 DecimalFormatInternal &data = internalData(fReserved);
407 data.fFastFormatStatus=kFastpathUNKNOWN; // don't try to calculate the fastp ath until later. 430 data.fFastFormatStatus=kFastpathUNKNOWN; // don't try to calculate the fastp ath until later.
408 data.fFastParseStatus=kFastpathUNKNOWN; // don't try to calculate the fastpa th until later. 431 data.fFastParseStatus=kFastpathUNKNOWN; // don't try to calculate the fastpa th until later.
409 #endif 432 #endif
410 fStaticSets = NULL; 433 fStaticSets = NULL;
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 807
785 /* sfb 990629 */ 808 /* sfb 990629 */
786 fFormatWidth = rhs.fFormatWidth; 809 fFormatWidth = rhs.fFormatWidth;
787 fPad = rhs.fPad; 810 fPad = rhs.fPad;
788 fPadPosition = rhs.fPadPosition; 811 fPadPosition = rhs.fPadPosition;
789 /* end sfb */ 812 /* end sfb */
790 fMinSignificantDigits = rhs.fMinSignificantDigits; 813 fMinSignificantDigits = rhs.fMinSignificantDigits;
791 fMaxSignificantDigits = rhs.fMaxSignificantDigits; 814 fMaxSignificantDigits = rhs.fMaxSignificantDigits;
792 fUseSignificantDigits = rhs.fUseSignificantDigits; 815 fUseSignificantDigits = rhs.fUseSignificantDigits;
793 fFormatPattern = rhs.fFormatPattern; 816 fFormatPattern = rhs.fFormatPattern;
817 fCurrencyUsage = rhs.fCurrencyUsage;
794 fStyle = rhs.fStyle; 818 fStyle = rhs.fStyle;
795 fCurrencySignCount = rhs.fCurrencySignCount;
796 _clone_ptr(&fCurrencyPluralInfo, rhs.fCurrencyPluralInfo); 819 _clone_ptr(&fCurrencyPluralInfo, rhs.fCurrencyPluralInfo);
797 deleteHashForAffixPattern(); 820 deleteHashForAffixPattern();
798 if (rhs.fAffixPatternsForCurrency) { 821 if (rhs.fAffixPatternsForCurrency) {
799 UErrorCode status = U_ZERO_ERROR; 822 UErrorCode status = U_ZERO_ERROR;
800 fAffixPatternsForCurrency = initHashForAffixPattern(status); 823 fAffixPatternsForCurrency = initHashForAffixPattern(status);
801 copyHashForAffixPattern(rhs.fAffixPatternsForCurrency, 824 copyHashForAffixPattern(rhs.fAffixPatternsForCurrency,
802 fAffixPatternsForCurrency, status); 825 fAffixPatternsForCurrency, status);
803 } 826 }
804 deleteHashForAffix(fAffixesForCurrency); 827 deleteHashForAffix(fAffixesForCurrency);
805 if (rhs.fAffixesForCurrency) { 828 if (rhs.fAffixesForCurrency) {
806 UErrorCode status = U_ZERO_ERROR; 829 UErrorCode status = U_ZERO_ERROR;
807 fAffixesForCurrency = initHashForAffixPattern(status); 830 fAffixesForCurrency = initHashForAffixPattern(status);
808 copyHashForAffix(rhs.fAffixesForCurrency, fAffixesForCurrency, statu s); 831 copyHashForAffix(rhs.fAffixesForCurrency, fAffixesForCurrency, statu s);
809 } 832 }
810 deleteHashForAffix(fPluralAffixesForCurrency); 833 deleteHashForAffix(fPluralAffixesForCurrency);
811 if (rhs.fPluralAffixesForCurrency) { 834 if (rhs.fPluralAffixesForCurrency) {
812 UErrorCode status = U_ZERO_ERROR; 835 UErrorCode status = U_ZERO_ERROR;
813 fPluralAffixesForCurrency = initHashForAffixPattern(status); 836 fPluralAffixesForCurrency = initHashForAffixPattern(status);
814 copyHashForAffix(rhs.fPluralAffixesForCurrency, fPluralAffixesForCur rency, status); 837 copyHashForAffix(rhs.fPluralAffixesForCurrency, fPluralAffixesForCur rency, status);
815 } 838 }
839 #if UCONFIG_FORMAT_FASTPATHS_49
840 DecimalFormatInternal &data = internalData(fReserved);
841 const DecimalFormatInternal &rhsData = internalData(rhs.fReserved);
842 data = rhsData;
843 #endif
816 } 844 }
817 #if UCONFIG_FORMAT_FASTPATHS_49
818 handleChanged();
819 #endif
820 return *this; 845 return *this;
821 } 846 }
822 847
823 //------------------------------------------------------------------------------ 848 //------------------------------------------------------------------------------
824 849
825 UBool 850 UBool
826 DecimalFormat::operator==(const Format& that) const 851 DecimalFormat::operator==(const Format& that) const
827 { 852 {
828 if (this == &that) 853 if (this == &that)
829 return TRUE; 854 return TRUE;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 debugout(*other->fNegSuffixPattern); 922 debugout(*other->fNegSuffixPattern);
898 } 923 }
899 } 924 }
900 if (!((fRoundingIncrement == other->fRoundingIncrement) // both null 925 if (!((fRoundingIncrement == other->fRoundingIncrement) // both null
901 || (fRoundingIncrement != NULL && 926 || (fRoundingIncrement != NULL &&
902 other->fRoundingIncrement != NULL && 927 other->fRoundingIncrement != NULL &&
903 *fRoundingIncrement == *other->fRoundingIncrement))) { 928 *fRoundingIncrement == *other->fRoundingIncrement))) {
904 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 929 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
905 debug("Rounding Increment !="); 930 debug("Rounding Increment !=");
906 } 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 }
907 if (getMultiplier() != other->getMultiplier()) { 936 if (getMultiplier() != other->getMultiplier()) {
908 if (first) { printf("[ "); first = FALSE; } 937 if (first) { printf("[ "); first = FALSE; }
909 printf("Multiplier %ld != %ld", getMultiplier(), other->getMultiplier()) ; 938 printf("Multiplier %ld != %ld", getMultiplier(), other->getMultiplier()) ;
910 } 939 }
911 if (fGroupingSize != other->fGroupingSize) { 940 if (fGroupingSize != other->fGroupingSize) {
912 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 941 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
913 printf("Grouping Size %ld != %ld", fGroupingSize, other->fGroupingSize); 942 printf("Grouping Size %ld != %ld", fGroupingSize, other->fGroupingSize);
914 } 943 }
915 if (fGroupingSize2 != other->fGroupingSize2) { 944 if (fGroupingSize2 != other->fGroupingSize2) {
916 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 945 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
917 printf("Secondary Grouping Size %ld != %ld", fGroupingSize2, other->fGro upingSize2); 946 printf("Secondary Grouping Size %ld != %ld", fGroupingSize2, other->fGro upingSize2);
918 } 947 }
919 if (fDecimalSeparatorAlwaysShown != other->fDecimalSeparatorAlwaysShown) { 948 if (fDecimalSeparatorAlwaysShown != other->fDecimalSeparatorAlwaysShown) {
920 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 949 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
921 printf("Dec Sep Always %d != %d", fDecimalSeparatorAlwaysShown, other->f DecimalSeparatorAlwaysShown); 950 printf("fDecimalSeparatorAlwaysShown %d != %d", fDecimalSeparatorAlwaysS hown, other->fDecimalSeparatorAlwaysShown);
922 } 951 }
923 if (fUseExponentialNotation != other->fUseExponentialNotation) { 952 if (fUseExponentialNotation != other->fUseExponentialNotation) {
924 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 953 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
925 debug("Use Exp !="); 954 debug("fUseExponentialNotation !=");
926 } 955 }
927 if (!(!fUseExponentialNotation || 956 if (fUseExponentialNotation &&
928 fMinExponentDigits != other->fMinExponentDigits)) { 957 fMinExponentDigits != other->fMinExponentDigits) {
929 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 958 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
930 debug("Exp Digits !="); 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 !=");
931 } 969 }
932 if (*fSymbols != *(other->fSymbols)) { 970 if (*fSymbols != *(other->fSymbols)) {
933 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 971 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
934 debug("Symbols !="); 972 debug("Symbols !=");
935 } 973 }
936 // TODO Add debug stuff for significant digits here 974 // TODO Add debug stuff for significant digits here
937 if (fUseSignificantDigits != other->fUseSignificantDigits) { 975 if (fUseSignificantDigits != other->fUseSignificantDigits) {
976 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
938 debug("fUseSignificantDigits !="); 977 debug("fUseSignificantDigits !=");
939 } 978 }
940 if (fUseSignificantDigits && 979 if (fUseSignificantDigits &&
941 fMinSignificantDigits != other->fMinSignificantDigits) { 980 fMinSignificantDigits != other->fMinSignificantDigits) {
981 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
942 debug("fMinSignificantDigits !="); 982 debug("fMinSignificantDigits !=");
943 } 983 }
944 if (fUseSignificantDigits && 984 if (fUseSignificantDigits &&
945 fMaxSignificantDigits != other->fMaxSignificantDigits) { 985 fMaxSignificantDigits != other->fMaxSignificantDigits) {
986 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
946 debug("fMaxSignificantDigits !="); 987 debug("fMaxSignificantDigits !=");
947 } 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 }
948 1011
949 if (!first) { printf(" ]"); } 1012 if (!first) { printf(" ]"); }
950 if (fCurrencySignCount != other->fCurrencySignCount) { 1013 if (fCurrencySignCount != other->fCurrencySignCount) {
951 debug("fCurrencySignCount !="); 1014 debug("fCurrencySignCount !=");
952 } 1015 }
953 if (fCurrencyPluralInfo == other->fCurrencyPluralInfo) { 1016 if (fCurrencyPluralInfo == other->fCurrencyPluralInfo) {
954 debug("fCurrencyPluralInfo == "); 1017 debug("fCurrencyPluralInfo == ");
955 if (fCurrencyPluralInfo == NULL) { 1018 if (fCurrencyPluralInfo == NULL) {
956 debug("fCurrencyPluralInfo == NULL"); 1019 debug("fCurrencyPluralInfo == NULL");
957 } 1020 }
958 } 1021 }
959 if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL && 1022 if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL &&
960 *fCurrencyPluralInfo != *(other->fCurrencyPluralInfo)) { 1023 *fCurrencyPluralInfo != *(other->fCurrencyPluralInfo)) {
961 debug("fCurrencyPluralInfo !="); 1024 debug("fCurrencyPluralInfo !=");
962 } 1025 }
963 if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo == NULL || 1026 if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo == NULL ||
964 fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo != NULL) { 1027 fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo != NULL) {
965 debug("fCurrencyPluralInfo one NULL, the other not"); 1028 debug("fCurrencyPluralInfo one NULL, the other not");
966 } 1029 }
967 if (fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo == NULL) { 1030 if (fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo == NULL) {
968 debug("fCurrencyPluralInfo == "); 1031 debug("fCurrencyPluralInfo == ");
969 } 1032 }
970 } 1033 }
971 #endif 1034 #endif
972 1035
973 return (NumberFormat::operator==(that) && 1036 return (
974 ((fCurrencySignCount == fgCurrencySignCountInPluralFormat) ? 1037 NumberFormat::operator==(that) &&
975 (fAffixPatternsForCurrency->equals(*other->fAffixPatternsForCurrency )) : 1038
976 (((fPosPrefixPattern == other->fPosPrefixPattern && // both null 1039 ((fCurrencySignCount == fgCurrencySignCountInPluralFormat) ?
977 fPositivePrefix == other->fPositivePrefix) 1040 (fAffixPatternsForCurrency->equals(*other->fAffixPatternsForCurrency)) :
978 || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 && 1041 (((fPosPrefixPattern == other->fPosPrefixPattern && // both null
979 *fPosPrefixPattern == *other->fPosPrefixPattern)) && 1042 fPositivePrefix == other->fPositivePrefix)
980 ((fPosSuffixPattern == other->fPosSuffixPattern && // both null 1043 || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 &&
981 fPositiveSuffix == other->fPositiveSuffix) 1044 *fPosPrefixPattern == *other->fPosPrefixPattern)) &&
982 || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 && 1045 ((fPosSuffixPattern == other->fPosSuffixPattern && // both null
983 *fPosSuffixPattern == *other->fPosSuffixPattern)) && 1046 fPositiveSuffix == other->fPositiveSuffix)
984 ((fNegPrefixPattern == other->fNegPrefixPattern && // both null 1047 || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 &&
985 fNegativePrefix == other->fNegativePrefix) 1048 *fPosSuffixPattern == *other->fPosSuffixPattern)) &&
986 || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 && 1049 ((fNegPrefixPattern == other->fNegPrefixPattern && // both null
987 *fNegPrefixPattern == *other->fNegPrefixPattern)) && 1050 fNegativePrefix == other->fNegativePrefix)
988 ((fNegSuffixPattern == other->fNegSuffixPattern && // both null 1051 || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 &&
989 fNegativeSuffix == other->fNegativeSuffix) 1052 *fNegPrefixPattern == *other->fNegPrefixPattern)) &&
990 || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 && 1053 ((fNegSuffixPattern == other->fNegSuffixPattern && // both null
991 *fNegSuffixPattern == *other->fNegSuffixPattern)))) && 1054 fNegativeSuffix == other->fNegativeSuffix)
992 ((fRoundingIncrement == other->fRoundingIncrement) // both null 1055 || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 &&
993 || (fRoundingIncrement != NULL && 1056 *fNegSuffixPattern == *other->fNegSuffixPattern)))) &&
994 other->fRoundingIncrement != NULL && 1057
995 *fRoundingIncrement == *other->fRoundingIncrement)) && 1058 ((fRoundingIncrement == other->fRoundingIncrement) // both null
1059 || (fRoundingIncrement != NULL &&
1060 other->fRoundingIncrement != NULL &&
1061 *fRoundingIncrement == *other->fRoundingIncrement)) &&
1062
1063 fRoundingMode == other->fRoundingMode &&
996 getMultiplier() == other->getMultiplier() && 1064 getMultiplier() == other->getMultiplier() &&
997 fGroupingSize == other->fGroupingSize && 1065 fGroupingSize == other->fGroupingSize &&
998 fGroupingSize2 == other->fGroupingSize2 && 1066 fGroupingSize2 == other->fGroupingSize2 &&
999 fDecimalSeparatorAlwaysShown == other->fDecimalSeparatorAlwaysShown && 1067 fDecimalSeparatorAlwaysShown == other->fDecimalSeparatorAlwaysShown &&
1000 fUseExponentialNotation == other->fUseExponentialNotation && 1068 fUseExponentialNotation == other->fUseExponentialNotation &&
1069
1001 (!fUseExponentialNotation || 1070 (!fUseExponentialNotation ||
1002 fMinExponentDigits == other->fMinExponentDigits) && 1071 (fMinExponentDigits == other->fMinExponentDigits && fExponentSignAlw aysShown == other->fExponentSignAlwaysShown)) &&
1072
1073 fBoolFlags.getAll() == other->fBoolFlags.getAll() &&
1003 *fSymbols == *(other->fSymbols) && 1074 *fSymbols == *(other->fSymbols) &&
1004 fUseSignificantDigits == other->fUseSignificantDigits && 1075 fUseSignificantDigits == other->fUseSignificantDigits &&
1076
1005 (!fUseSignificantDigits || 1077 (!fUseSignificantDigits ||
1006 (fMinSignificantDigits == other->fMinSignificantDigits && 1078 (fMinSignificantDigits == other->fMinSignificantDigits && fMaxSignif icantDigits == other->fMaxSignificantDigits)) &&
1007 fMaxSignificantDigits == 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
1008 fCurrencySignCount == other->fCurrencySignCount && 1087 fCurrencySignCount == other->fCurrencySignCount &&
1088
1009 ((fCurrencyPluralInfo == other->fCurrencyPluralInfo && 1089 ((fCurrencyPluralInfo == other->fCurrencyPluralInfo &&
1010 fCurrencyPluralInfo == NULL) || 1090 fCurrencyPluralInfo == NULL) ||
1011 (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL && 1091 (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL &&
1012 *fCurrencyPluralInfo == *(other->fCurrencyPluralInfo)))); 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 );
1013 } 1100 }
1014 1101
1015 //------------------------------------------------------------------------------ 1102 //------------------------------------------------------------------------------
1016 1103
1017 Format* 1104 Format*
1018 DecimalFormat::clone() const 1105 DecimalFormat::clone() const
1019 { 1106 {
1020 return new DecimalFormat(*this); 1107 return new DecimalFormat(*this);
1021 } 1108 }
1022 1109
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 } else if(fNegativePrefix.length()>1 1317 } else if(fNegativePrefix.length()>1
1231 || ((fNegativePrefix.length()==1) && (fNegativePrefix.charAt(0)!=0x0 02D))) { 1318 || ((fNegativePrefix.length()==1) && (fNegativePrefix.charAt(0)!=0x0 02D))) {
1232 debug("No Parse fastpath: negative prefix that isn't '-'"); 1319 debug("No Parse fastpath: negative prefix that isn't '-'");
1233 } else if(fNegativeSuffix.length()>0) { 1320 } else if(fNegativeSuffix.length()>0) {
1234 debug("No Parse fastpath: negative suffix"); 1321 debug("No Parse fastpath: negative suffix");
1235 } else { 1322 } else {
1236 data.fFastParseStatus = kFastpathYES; 1323 data.fFastParseStatus = kFastpathYES;
1237 debug("parse fastpath: YES"); 1324 debug("parse fastpath: YES");
1238 } 1325 }
1239 1326
1240 if (fGroupingSize!=0 && isGroupingUsed()) { 1327 if(fUseExponentialNotation) {
1241 debug("No format fastpath: fGroupingSize!=0 and grouping is used");
1242 #ifdef FMT_DEBUG
1243 printf("groupingsize=%d\n", fGroupingSize);
1244 #endif
1245 } else if(fGroupingSize2!=0 && isGroupingUsed()) {
1246 debug("No format fastpath: fGroupingSize2!=0");
1247 } else if(fUseExponentialNotation) {
1248 debug("No format fastpath: fUseExponentialNotation"); 1328 debug("No format fastpath: fUseExponentialNotation");
1249 } else if(fFormatWidth!=0) { 1329 } else if(fFormatWidth!=0) {
1250 debug("No format fastpath: fFormatWidth!=0"); 1330 debug("No format fastpath: fFormatWidth!=0");
1251 } else if(fMinSignificantDigits!=1) { 1331 } else if(fMinSignificantDigits!=1) {
1252 debug("No format fastpath: fMinSignificantDigits!=1"); 1332 debug("No format fastpath: fMinSignificantDigits!=1");
1253 } else if(fMultiplier!=NULL) { 1333 } else if(fMultiplier!=NULL) {
1254 debug("No format fastpath: fMultiplier!=NULL"); 1334 debug("No format fastpath: fMultiplier!=NULL");
1255 } else if(fScale!=0) { 1335 } else if(fScale!=0) {
1256 debug("No format fastpath: fScale!=0"); 1336 debug("No format fastpath: fScale!=0");
1257 } else if(0x0030 != getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).cha r32At(0)) { 1337 } else if(0x0030 != getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).cha r32At(0)) {
1258 debug("No format fastpath: 0x0030 != getConstSymbol(DecimalFormatSymbols::kZ eroDigitSymbol).char32At(0)"); 1338 debug("No format fastpath: 0x0030 != getConstSymbol(DecimalFormatSymbols::kZ eroDigitSymbol).char32At(0)");
1259 } else if(fDecimalSeparatorAlwaysShown) { 1339 } else if(fDecimalSeparatorAlwaysShown) {
1260 debug("No format fastpath: fDecimalSeparatorAlwaysShown"); 1340 debug("No format fastpath: fDecimalSeparatorAlwaysShown");
1261 } else if(getMinimumFractionDigits()>0) { 1341 } else if(getMinimumFractionDigits()>0) {
1262 debug("No format fastpath: fMinFractionDigits>0"); 1342 debug("No format fastpath: fMinFractionDigits>0");
1263 } else if(fCurrencySignCount != fgCurrencySignCountZero) { 1343 } else if(fCurrencySignCount != fgCurrencySignCountZero) {
1264 debug("No format fastpath: fCurrencySignCount != fgCurrencySignCountZero"); 1344 debug("No format fastpath: fCurrencySignCount != fgCurrencySignCountZero");
1265 } else if(fRoundingIncrement!=0) { 1345 } else if(fRoundingIncrement!=0) {
1266 debug("No format fastpath: 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");
1267 } else { 1358 } else {
1268 data.fFastFormatStatus = kFastpathYES; 1359 data.fFastFormatStatus = kFastpathYES;
1269 debug("format:kFastpathYES!"); 1360 debug("format:kFastpathYES!");
1270 } 1361 }
1271 1362
1272 1363
1273 } 1364 }
1274 #endif 1365 #endif
1275 //------------------------------------------------------------------------------ 1366 //------------------------------------------------------------------------------
1276 1367
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 // const UnicodeString *posSuffix = fPosSuffixPattern; 1411 // const UnicodeString *posSuffix = fPosSuffixPattern;
1321 // const UnicodeString *negSuffix = fNegSuffixPattern; 1412 // const UnicodeString *negSuffix = fNegSuffixPattern;
1322 1413
1323 const DecimalFormatInternal &data = internalData(fReserved); 1414 const DecimalFormatInternal &data = internalData(fReserved);
1324 1415
1325 #ifdef FMT_DEBUG 1416 #ifdef FMT_DEBUG
1326 data.dump(); 1417 data.dump();
1327 printf("fastpath? [%d]\n", number); 1418 printf("fastpath? [%d]\n", number);
1328 #endif 1419 #endif
1329 1420
1330 if( data.fFastFormatStatus==kFastpathYES) { 1421 if( data.fFastFormatStatus==kFastpathYES ||
1422 data.fFastFormatStatus==kFastpathMAYBE) {
1423 int32_t noGroupingThreshold = 0;
1331 1424
1332 #define kZero 0x0030 1425 #define kZero 0x0030
1333 const int32_t MAX_IDX = MAX_DIGITS+2; 1426 const int32_t MAX_IDX = MAX_DIGITS+2;
1334 UChar outputStr[MAX_IDX]; 1427 UChar outputStr[MAX_IDX];
1335 int32_t destIdx = MAX_IDX; 1428 int32_t destIdx = MAX_IDX;
1336 outputStr[--destIdx] = 0; // term 1429 outputStr[--destIdx] = 0; // term
1337 1430
1431 if (data.fFastFormatStatus==kFastpathMAYBE) {
1432 noGroupingThreshold = destIdx - fGroupingSize;
1433 }
1338 int64_t n = number; 1434 int64_t n = number;
1339 if (number < 1) { 1435 if (number < 1) {
1340 // Negative numbers are slightly larger than positive 1436 // Negative numbers are slightly larger than positive
1341 // output the first digit (or the leading zero) 1437 // output the first digit (or the leading zero)
1342 outputStr[--destIdx] = (-(n % 10) + kZero); 1438 outputStr[--destIdx] = (-(n % 10) + kZero);
1343 n /= -10; 1439 n /= -10;
1344 } 1440 }
1345 // get any remaining digits 1441 // get any remaining digits
1346 while (n > 0) { 1442 while (n > 0) {
1443 if (destIdx == noGroupingThreshold) {
1444 goto slowPath;
1445 }
1347 outputStr[--destIdx] = (n % 10) + kZero; 1446 outputStr[--destIdx] = (n % 10) + kZero;
1348 n /= 10; 1447 n /= 10;
1349 } 1448 }
1350
1351 1449
1352 // Slide the number to the start of the output str 1450 // Slide the number to the start of the output str
1353 U_ASSERT(destIdx >= 0); 1451 U_ASSERT(destIdx >= 0);
1354 int32_t length = MAX_IDX - destIdx -1; 1452 int32_t length = MAX_IDX - destIdx -1;
1355 /*int32_t prefixLen = */ appendAffix(appendTo, number, handler, number<0, TR UE); 1453 /*int32_t prefixLen = */ appendAffix(appendTo, number, handler, number<0, TR UE);
1356 int32_t maxIntDig = getMaximumIntegerDigits(); 1454 int32_t maxIntDig = getMaximumIntegerDigits();
1357 int32_t destlength = length<=maxIntDig?length:maxIntDig; // dest length pinn ed to max int digits 1455 int32_t destlength = length<=maxIntDig?length:maxIntDig; // dest length pinn ed to max int digits
1358 1456
1359 if(length>maxIntDig && fBoolFlags.contains(UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX _DIGITS)) { 1457 if(length>maxIntDig && fBoolFlags.contains(UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX _DIGITS)) {
1360 status = U_ILLEGAL_ARGUMENT_ERROR; 1458 status = U_ILLEGAL_ARGUMENT_ERROR;
(...skipping 21 matching lines...) Expand all
1382 1480
1383 #ifdef FMT_DEBUG 1481 #ifdef FMT_DEBUG
1384 printf("Writing [%s] length [%d] max %d for [%d]\n", outputStr+destIdx, length, MAX_IDX, number); 1482 printf("Writing [%s] length [%d] max %d for [%d]\n", outputStr+destIdx, length, MAX_IDX, number);
1385 #endif 1483 #endif
1386 1484
1387 #undef kZero 1485 #undef kZero
1388 1486
1389 return appendTo; 1487 return appendTo;
1390 } // end fastpath 1488 } // end fastpath
1391 #endif 1489 #endif
1490 slowPath:
1392 1491
1393 // Else the slow way - via DigitList 1492 // Else the slow way - via DigitList
1394 DigitList digits; 1493 DigitList digits;
1395 digits.set(number); 1494 digits.set(number);
1396 return _format(digits, appendTo, handler, status); 1495 return _format(digits, appendTo, handler, status);
1397 } 1496 }
1398 1497
1399 //------------------------------------------------------------------------------ 1498 //------------------------------------------------------------------------------
1400 1499
1401 UnicodeString& 1500 UnicodeString&
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1614 } 1713 }
1615 1714
1616 if (adjustedNum.isInfinite()) { 1715 if (adjustedNum.isInfinite()) {
1617 return adjustedNum; 1716 return adjustedNum;
1618 } 1717 }
1619 1718
1620 if (fUseExponentialNotation || areSignificantDigitsUsed()) { 1719 if (fUseExponentialNotation || areSignificantDigitsUsed()) {
1621 int32_t sigDigits = precision(); 1720 int32_t sigDigits = precision();
1622 if (sigDigits > 0) { 1721 if (sigDigits > 0) {
1623 adjustedNum.round(sigDigits); 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);
1624 } 1730 }
1625 } else { 1731 } else {
1626 // Fixed point format. Round to a set number of fraction digits. 1732 // Fixed point format. Round to a set number of fraction digits.
1627 int32_t numFractionDigits = precision(); 1733 int32_t numFractionDigits = precision();
1628 adjustedNum.roundFixedPoint(numFractionDigits); 1734 adjustedNum.roundFixedPoint(numFractionDigits);
1629 } 1735 }
1630 if (fRoundingMode == kRoundUnnecessary && (adjustedNum.fContext.status & DEC _Inexact)) { 1736 if (fRoundingMode == kRoundUnnecessary && (adjustedNum.fContext.status & DEC _Inexact)) {
1631 status = U_FORMAT_INEXACT_ERROR; 1737 status = U_FORMAT_INEXACT_ERROR;
1632 return adjustedNum; 1738 return adjustedNum;
1633 } 1739 }
(...skipping 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after
2831 break; // Whether we fail or succeed, we exit this loop 2937 break; // Whether we fail or succeed, we exit this loop
2832 } else { 2938 } else {
2833 break; 2939 break;
2834 } 2940 }
2835 } else { // not parsing exponent 2941 } else { // not parsing exponent
2836 break; 2942 break;
2837 } 2943 }
2838 } 2944 }
2839 } 2945 }
2840 2946
2947 // if we didn't see a decimal and it is required, check to see if the pa ttern had one
2948 if(!sawDecimal && isDecimalPatternMatchRequired())
2949 {
2950 if(fFormatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSym bol) != 0)
2951 {
2952 parsePosition.setIndex(oldStart);
2953 parsePosition.setErrorIndex(position);
2954 debug("decimal point match required fail!");
2955 return FALSE;
2956 }
2957 }
2958
2841 if (backup != -1) 2959 if (backup != -1)
2842 { 2960 {
2843 position = backup; 2961 position = backup;
2844 } 2962 }
2845 2963
2846 if (strictParse && !sawDecimal) { 2964 if (strictParse && !sawDecimal) {
2847 if (lastGroup != -1 && position - lastGroup != fGroupingSize + 1) { 2965 if (lastGroup != -1 && position - lastGroup != fGroupingSize + 1) {
2848 strictFail = TRUE; 2966 strictFail = TRUE;
2849 } 2967 }
2850 } 2968 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
2944 0//bits 3062 0//bits
2945 ); 3063 );
2946 3064
2947 if (U_FAILURE(err)) { 3065 if (U_FAILURE(err)) {
2948 #ifdef FMT_DEBUG 3066 #ifdef FMT_DEBUG
2949 printf(" err setting %s\n", u_errorName(err)); 3067 printf(" err setting %s\n", u_errorName(err));
2950 #endif 3068 #endif
2951 parsePosition.setErrorIndex(position); 3069 parsePosition.setErrorIndex(position);
2952 return FALSE; 3070 return FALSE;
2953 } 3071 }
3072
3073 // check if we missed a required decimal point
3074 if(fastParseOk && isDecimalPatternMatchRequired())
3075 {
3076 if(fFormatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSymbol) != 0)
3077 {
3078 parsePosition.setIndex(oldStart);
3079 parsePosition.setErrorIndex(position);
3080 debug("decimal point match required fail!");
3081 return FALSE;
3082 }
3083 }
3084
3085
2954 return TRUE; 3086 return TRUE;
2955 } 3087 }
2956 3088
2957 /** 3089 /**
2958 * Starting at position, advance past a run of pad characters, if any. 3090 * Starting at position, advance past a run of pad characters, if any.
2959 * Return the index of the first character after position that is not a pad 3091 * Return the index of the first character after position that is not a pad
2960 * character. Result is >= position. 3092 * character. Result is >= position.
2961 */ 3093 */
2962 int32_t DecimalFormat::skipPadding(const UnicodeString& text, int32_t position) const { 3094 int32_t DecimalFormat::skipPadding(const UnicodeString& text, int32_t position) const {
2963 int32_t padLen = U16_LENGTH(fPad); 3095 int32_t padLen = U16_LENGTH(fPad);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
3039 3171
3040 #define TRIM_BUFLEN 32 3172 #define TRIM_BUFLEN 32
3041 UnicodeString& DecimalFormat::trimMarksFromAffix(const UnicodeString& affix, Uni codeString& trimmedAffix) { 3173 UnicodeString& DecimalFormat::trimMarksFromAffix(const UnicodeString& affix, Uni codeString& trimmedAffix) {
3042 UChar trimBuf[TRIM_BUFLEN]; 3174 UChar trimBuf[TRIM_BUFLEN];
3043 int32_t affixLen = affix.length(); 3175 int32_t affixLen = affix.length();
3044 int32_t affixPos, trimLen = 0; 3176 int32_t affixPos, trimLen = 0;
3045 3177
3046 for (affixPos = 0; affixPos < affixLen; affixPos++) { 3178 for (affixPos = 0; affixPos < affixLen; affixPos++) {
3047 UChar c = affix.charAt(affixPos); 3179 UChar c = affix.charAt(affixPos);
3048 if (!IS_BIDI_MARK(c)) { 3180 if (!IS_BIDI_MARK(c)) {
3049 » if (trimLen < TRIM_BUFLEN) { 3181 if (trimLen < TRIM_BUFLEN) {
3050 » » trimBuf[trimLen++] = c; 3182 trimBuf[trimLen++] = c;
3051 » } else { 3183 } else {
3052 » » trimLen = 0; 3184 trimLen = 0;
3053 » » break; 3185 break;
3054 » } 3186 }
3055 } 3187 }
3056 } 3188 }
3057 return (trimLen > 0)? trimmedAffix.setTo(trimBuf, trimLen): trimmedAffix.set To(affix); 3189 return (trimLen > 0)? trimmedAffix.setTo(trimBuf, trimLen): trimmedAffix.set To(affix);
3058 } 3190 }
3059 3191
3060 /** 3192 /**
3061 * Return the length matched by the given affix, or -1 if none. 3193 * Return the length matched by the given affix, or -1 if none.
3062 * Runs of white space in the affix, match runs of white space in 3194 * Runs of white space in the affix, match runs of white space in
3063 * the input. Pattern white space and input white space are 3195 * the input. Pattern white space and input white space are
3064 * determined differently; see code. 3196 * determined differently; see code.
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
3337 if (U_SUCCESS(ec) && ppos.getIndex() != pos) { 3469 if (U_SUCCESS(ec) && ppos.getIndex() != pos) {
3338 if (currency) { 3470 if (currency) {
3339 u_strcpy(currency, curr); 3471 u_strcpy(currency, curr);
3340 } else { 3472 } else {
3341 // The formatter is currency-style but the client has no t requested 3473 // The formatter is currency-style but the client has no t requested
3342 // the value of the parsed currency. In this case, if th at value does 3474 // the value of the parsed currency. In this case, if th at value does
3343 // not match the formatter's current value, then the par se fails. 3475 // not match the formatter's current value, then the par se fails.
3344 UChar effectiveCurr[4]; 3476 UChar effectiveCurr[4];
3345 getEffectiveCurrency(effectiveCurr, ec); 3477 getEffectiveCurrency(effectiveCurr, ec);
3346 if ( U_FAILURE(ec) || u_strncmp(curr,effectiveCurr,4) != 0 ) { 3478 if ( U_FAILURE(ec) || u_strncmp(curr,effectiveCurr,4) != 0 ) {
3347 » pos = -1; 3479 pos = -1;
3348 » continue; 3480 continue;
3349 } 3481 }
3350 } 3482 }
3351 pos = ppos.getIndex(); 3483 pos = ppos.getIndex();
3352 } else if (!isLenient()){ 3484 } else if (!isLenient()){
3353 pos = -1; 3485 pos = -1;
3354 } 3486 }
3355 continue; 3487 continue;
3356 } 3488 }
3357 case kPatternPercent: 3489 case kPatternPercent:
3358 affix = &getConstSymbol(DecimalFormatSymbols::kPercentSymbol); 3490 affix = &getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
4000 #endif 4132 #endif
4001 } 4133 }
4002 4134
4003 //------------------------------------------------------------------------------ 4135 //------------------------------------------------------------------------------
4004 // Gets the grouping size of the number pattern. For example, thousand or 10 4136 // Gets the grouping size of the number pattern. For example, thousand or 10
4005 // thousand groupings. 4137 // thousand groupings.
4006 4138
4007 int32_t 4139 int32_t
4008 DecimalFormat::getGroupingSize() const 4140 DecimalFormat::getGroupingSize() const
4009 { 4141 {
4010 return fGroupingSize; 4142 return isGroupingUsed() ? fGroupingSize : 0;
4011 } 4143 }
4012 4144
4013 //------------------------------------------------------------------------------ 4145 //------------------------------------------------------------------------------
4014 // Gets the grouping size of the number pattern. 4146 // Gets the grouping size of the number pattern.
4015 4147
4016 void 4148 void
4017 DecimalFormat::setGroupingSize(int32_t newValue) 4149 DecimalFormat::setGroupingSize(int32_t newValue)
4018 { 4150 {
4019 fGroupingSize = newValue; 4151 fGroupingSize = newValue;
4020 #if UCONFIG_FORMAT_FASTPATHS_49 4152 #if UCONFIG_FORMAT_FASTPATHS_49
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4056 void 4188 void
4057 DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue) 4189 DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue)
4058 { 4190 {
4059 fDecimalSeparatorAlwaysShown = newValue; 4191 fDecimalSeparatorAlwaysShown = newValue;
4060 #if UCONFIG_FORMAT_FASTPATHS_49 4192 #if UCONFIG_FORMAT_FASTPATHS_49
4061 handleChanged(); 4193 handleChanged();
4062 #endif 4194 #endif
4063 } 4195 }
4064 4196
4065 //------------------------------------------------------------------------------ 4197 //------------------------------------------------------------------------------
4198 // Checks if decimal point pattern match is required
4199 UBool
4200 DecimalFormat::isDecimalPatternMatchRequired(void) const
4201 {
4202 return fBoolFlags.contains(UNUM_PARSE_DECIMAL_MARK_REQUIRED);
4203 }
4204
4205 //------------------------------------------------------------------------------
4206 // Checks if decimal point pattern match is required
4207
4208 void
4209 DecimalFormat::setDecimalPatternMatchRequired(UBool newValue)
4210 {
4211 fBoolFlags.set(UNUM_PARSE_DECIMAL_MARK_REQUIRED, newValue);
4212 }
4213
4214
4215 //------------------------------------------------------------------------------
4066 // Emits the pattern of this DecimalFormat instance. 4216 // Emits the pattern of this DecimalFormat instance.
4067 4217
4068 UnicodeString& 4218 UnicodeString&
4069 DecimalFormat::toPattern(UnicodeString& result) const 4219 DecimalFormat::toPattern(UnicodeString& result) const
4070 { 4220 {
4071 return toPattern(result, FALSE); 4221 return toPattern(result, FALSE);
4072 } 4222 }
4073 4223
4074 //------------------------------------------------------------------------------ 4224 //------------------------------------------------------------------------------
4075 // Emits the localized pattern this DecimalFormat instance. 4225 // Emits the localized pattern this DecimalFormat instance.
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after
4805 void 4955 void
4806 DecimalFormat::applyPatternWithoutExpandAffix(const UnicodeString& pattern, 4956 DecimalFormat::applyPatternWithoutExpandAffix(const UnicodeString& pattern,
4807 UBool localized, 4957 UBool localized,
4808 UParseError& parseError, 4958 UParseError& parseError,
4809 UErrorCode& status) 4959 UErrorCode& status)
4810 { 4960 {
4811 if (U_FAILURE(status)) 4961 if (U_FAILURE(status))
4812 { 4962 {
4813 return; 4963 return;
4814 } 4964 }
4815 // Clear error struct 4965 DecimalFormatPatternParser patternParser;
4816 parseError.offset = -1; 4966 if (localized) {
4817 parseError.preContext[0] = parseError.postContext[0] = (UChar)0; 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 }
4818 4979
4819 // Set the significant pattern symbols 4980 setMinimumIntegerDigits(out.fMinimumIntegerDigits);
4820 UChar32 zeroDigit = kPatternZeroDigit; // '0' 4981 setMaximumIntegerDigits(out.fMaximumIntegerDigits);
4821 UChar32 sigDigit = kPatternSignificantDigit; // '@' 4982 setMinimumFractionDigits(out.fMinimumFractionDigits);
4822 UnicodeString groupingSeparator ((UChar)kPatternGroupingSeparator); 4983 setMaximumFractionDigits(out.fMaximumFractionDigits);
4823 UnicodeString decimalSeparator ((UChar)kPatternDecimalSeparator); 4984 setSignificantDigitsUsed(out.fUseSignificantDigits);
4824 UnicodeString percent ((UChar)kPatternPercent); 4985 if (out.fUseSignificantDigits) {
4825 UnicodeString perMill ((UChar)kPatternPerMill); 4986 setMinimumSignificantDigits(out.fMinimumSignificantDigits);
4826 UnicodeString digit ((UChar)kPatternDigit); // '#' 4987 setMaximumSignificantDigits(out.fMaximumSignificantDigits);
4827 UnicodeString separator ((UChar)kPatternSeparator);
4828 UnicodeString exponent ((UChar)kPatternExponent);
4829 UnicodeString plus ((UChar)kPatternPlus);
4830 UnicodeString minus ((UChar)kPatternMinus);
4831 UnicodeString padEscape ((UChar)kPatternPadEscape);
4832 // Substitute with the localized symbols if necessary
4833 if (localized) {
4834 zeroDigit = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char3 2At(0);
4835 sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol) .char32At(0);
4836 groupingSeparator. remove().append(getConstSymbol(DecimalFormatSymbols: :kGroupingSeparatorSymbol));
4837 decimalSeparator. remove().append(getConstSymbol(DecimalFormatSymbols: :kDecimalSeparatorSymbol));
4838 percent. remove().append(getConstSymbol(DecimalFormatSymbols: :kPercentSymbol));
4839 perMill. remove().append(getConstSymbol(DecimalFormatSymbols: :kPerMillSymbol));
4840 digit. remove().append(getConstSymbol(DecimalFormatSymbols: :kDigitSymbol));
4841 separator. remove().append(getConstSymbol(DecimalFormatSymbols: :kPatternSeparatorSymbol));
4842 exponent. remove().append(getConstSymbol(DecimalFormatSymbols: :kExponentialSymbol));
4843 plus. remove().append(getConstSymbol(DecimalFormatSymbols: :kPlusSignSymbol));
4844 minus. remove().append(getConstSymbol(DecimalFormatSymbols: :kMinusSignSymbol));
4845 padEscape. remove().append(getConstSymbol(DecimalFormatSymbols: :kPadEscapeSymbol));
4846 } 4988 }
4847 UChar nineDigit = (UChar)(zeroDigit + 9); 4989 fUseExponentialNotation = out.fUseExponentialNotation;
4848 int32_t digitLen = digit.length(); 4990 if (out.fUseExponentialNotation) {
4849 int32_t groupSepLen = groupingSeparator.length(); 4991 fMinExponentDigits = out.fMinExponentDigits;
4850 int32_t decimalSepLen = decimalSeparator.length(); 4992 }
4851 4993 fExponentSignAlwaysShown = out.fExponentSignAlwaysShown;
4852 int32_t pos = 0; 4994 fCurrencySignCount = out.fCurrencySignCount;
4853 int32_t patLen = pattern.length(); 4995 setGroupingUsed(out.fGroupingUsed);
4854 // Part 0 is the positive pattern. Part 1, if present, is the negative 4996 if (out.fGroupingUsed) {
4855 // pattern. 4997 fGroupingSize = out.fGroupingSize;
4856 for (int32_t part=0; part<2 && pos<patLen; ++part) { 4998 fGroupingSize2 = out.fGroupingSize2;
4857 // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix, 4999 }
4858 // 2=suffix, 3=prefix in quote, 4=suffix in quote. Subpart 0 is 5000 setMultiplier(out.fMultiplier);
4859 // between the prefix and suffix, and consists of pattern 5001 fDecimalSeparatorAlwaysShown = out.fDecimalSeparatorAlwaysShown;
4860 // characters. In the prefix and suffix, percent, perMill, and 5002 fFormatWidth = out.fFormatWidth;
4861 // currency symbols are recognized and translated. 5003 if (out.fRoundingIncrementUsed) {
4862 int32_t subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0; 5004 if (fRoundingIncrement != NULL) {
4863 5005 *fRoundingIncrement = out.fRoundingIncrement;
4864 // It's important that we don't change any fields of this object 5006 } else {
4865 // prematurely. We set the following variables for the multiplier, 5007 fRoundingIncrement = new DigitList(out.fRoundingIncrement);
4866 // grouping, etc., and then only change the actual object fields if 5008 /* test for NULL */
4867 // everything parses correctly. This also lets us register 5009 if (fRoundingIncrement == NULL) {
4868 // the data from part 0 and ignore the part 1, except for the 5010 status = U_MEMORY_ALLOCATION_ERROR;
4869 // prefix and suffix. 5011 return;
4870 UnicodeString prefix;
4871 UnicodeString suffix;
4872 int32_t decimalPos = -1;
4873 int32_t multiplier = 1;
4874 int32_t digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0, sig DigitCount = 0;
4875 int8_t groupingCount = -1;
4876 int8_t groupingCount2 = -1;
4877 int32_t padPos = -1;
4878 UChar32 padChar = 0;
4879 int32_t roundingPos = -1;
4880 DigitList roundingInc;
4881 int8_t expDigits = -1;
4882 UBool expSignAlways = FALSE;
4883
4884 // The affix is either the prefix or the suffix.
4885 UnicodeString* affix = &prefix;
4886
4887 int32_t start = pos;
4888 UBool isPartDone = FALSE;
4889 UChar32 ch;
4890
4891 for (; !isPartDone && pos < patLen; ) {
4892 // Todo: account for surrogate pairs
4893 ch = pattern.char32At(pos);
4894 switch (subpart) {
4895 case 0: // Pattern proper subpart (between prefix & suffix)
4896 // Process the digits, decimal, and grouping characters. We
4897 // record five pieces of information. We expect the digits
4898 // to occur in the pattern ####00.00####, and we record the
4899 // number of left digits, zero (central) digits, and right
4900 // digits. The position of the last grouping character is
4901 // recorded (should be somewhere within the first two blocks
4902 // of characters), as is the position of the decimal point,
4903 // if any (should be in the zero digits). If there is no
4904 // decimal point, then there should be no right digits.
4905 if (pattern.compare(pos, digitLen, digit) == 0) {
4906 if (zeroDigitCount > 0 || sigDigitCount > 0) {
4907 ++digitRightCount;
4908 } else {
4909 ++digitLeftCount;
4910 }
4911 if (groupingCount >= 0 && decimalPos < 0) {
4912 ++groupingCount;
4913 }
4914 pos += digitLen;
4915 } else if ((ch >= zeroDigit && ch <= nineDigit) ||
4916 ch == sigDigit) {
4917 if (digitRightCount > 0) {
4918 // Unexpected '0'
4919 debug("Unexpected '0'")
4920 status = U_UNEXPECTED_TOKEN;
4921 syntaxError(pattern,pos,parseError);
4922 return;
4923 }
4924 if (ch == sigDigit) {
4925 ++sigDigitCount;
4926 } else {
4927 if (ch != zeroDigit && roundingPos < 0) {
4928 roundingPos = digitLeftCount + zeroDigitCount;
4929 }
4930 if (roundingPos >= 0) {
4931 roundingInc.append((char)(ch - zeroDigit + '0'));
4932 }
4933 ++zeroDigitCount;
4934 }
4935 if (groupingCount >= 0 && decimalPos < 0) {
4936 ++groupingCount;
4937 }
4938 pos += U16_LENGTH(ch);
4939 } else if (pattern.compare(pos, groupSepLen, groupingSeparator) == 0) {
4940 if (decimalPos >= 0) {
4941 // Grouping separator after decimal
4942 debug("Grouping separator after decimal")
4943 status = U_UNEXPECTED_TOKEN;
4944 syntaxError(pattern,pos,parseError);
4945 return;
4946 }
4947 groupingCount2 = groupingCount;
4948 groupingCount = 0;
4949 pos += groupSepLen;
4950 } else if (pattern.compare(pos, decimalSepLen, decimalSeparator) == 0) {
4951 if (decimalPos >= 0) {
4952 // Multiple decimal separators
4953 debug("Multiple decimal separators")
4954 status = U_MULTIPLE_DECIMAL_SEPARATORS;
4955 syntaxError(pattern,pos,parseError);
4956 return;
4957 }
4958 // Intentionally incorporate the digitRightCount,
4959 // even though it is illegal for this to be > 0
4960 // at this point. We check pattern syntax below.
4961 decimalPos = digitLeftCount + zeroDigitCount + digitRightCou nt;
4962 pos += decimalSepLen;
4963 } else {
4964 if (pattern.compare(pos, exponent.length(), exponent) == 0) {
4965 if (expDigits >= 0) {
4966 // Multiple exponential symbols
4967 debug("Multiple exponential symbols")
4968 status = U_MULTIPLE_EXPONENTIAL_SYMBOLS;
4969 syntaxError(pattern,pos,parseError);
4970 return;
4971 }
4972 if (groupingCount >= 0) {
4973 // Grouping separator in exponential pattern
4974 debug("Grouping separator in exponential pattern")
4975 status = U_MALFORMED_EXPONENTIAL_PATTERN;
4976 syntaxError(pattern,pos,parseError);
4977 return;
4978 }
4979 pos += exponent.length();
4980 // Check for positive prefix
4981 if (pos < patLen
4982 && pattern.compare(pos, plus.length(), plus) == 0) {
4983 expSignAlways = TRUE;
4984 pos += plus.length();
4985 }
4986 // Use lookahead to parse out the exponential part of th e
4987 // pattern, then jump into suffix subpart.
4988 expDigits = 0;
4989 while (pos < patLen &&
4990 pattern.char32At(pos) == zeroDigit) {
4991 ++expDigits;
4992 pos += U16_LENGTH(zeroDigit);
4993 }
4994
4995 // 1. Require at least one mantissa pattern digit
4996 // 2. Disallow "#+ @" in mantissa
4997 // 3. Require at least one exponent pattern digit
4998 if (((digitLeftCount + zeroDigitCount) < 1 &&
4999 (sigDigitCount + digitRightCount) < 1) ||
5000 (sigDigitCount > 0 && digitLeftCount > 0) ||
5001 expDigits < 1) {
5002 // Malformed exponential pattern
5003 debug("Malformed exponential pattern")
5004 status = U_MALFORMED_EXPONENTIAL_PATTERN;
5005 syntaxError(pattern,pos,parseError);
5006 return;
5007 }
5008 }
5009 // Transition to suffix subpart
5010 subpart = 2; // suffix subpart
5011 affix = &suffix;
5012 sub0Limit = pos;
5013 continue;
5014 }
5015 break;
5016 case 1: // Prefix subpart
5017 case 2: // Suffix subpart
5018 // Process the prefix / suffix characters
5019 // Process unquoted characters seen in prefix or suffix
5020 // subpart.
5021
5022 // Several syntax characters implicitly begins the
5023 // next subpart if we are in the prefix; otherwise
5024 // they are illegal if unquoted.
5025 if (!pattern.compare(pos, digitLen, digit) ||
5026 !pattern.compare(pos, groupSepLen, groupingSeparator) ||
5027 !pattern.compare(pos, decimalSepLen, decimalSeparator) ||
5028 (ch >= zeroDigit && ch <= nineDigit) ||
5029 ch == sigDigit) {
5030 if (subpart == 1) { // prefix subpart
5031 subpart = 0; // pattern proper subpart
5032 sub0Start = pos; // Reprocess this character
5033 continue;
5034 } else {
5035 status = U_UNQUOTED_SPECIAL;
5036 syntaxError(pattern,pos,parseError);
5037 return;
5038 }
5039 } else if (ch == kCurrencySign) {
5040 affix->append(kQuote); // Encode currency
5041 // Use lookahead to determine if the currency sign is
5042 // doubled or not.
5043 U_ASSERT(U16_LENGTH(kCurrencySign) == 1);
5044 if ((pos+1) < pattern.length() && pattern[pos+1] == kCurrenc ySign) {
5045 affix->append(kCurrencySign);
5046 ++pos; // Skip over the doubled character
5047 if ((pos+1) < pattern.length() &&
5048 pattern[pos+1] == kCurrencySign) {
5049 affix->append(kCurrencySign);
5050 ++pos; // Skip over the doubled character
5051 fCurrencySignCount = fgCurrencySignCountInPluralForm at;
5052 } else {
5053 fCurrencySignCount = fgCurrencySignCountInISOFormat;
5054 }
5055 } else {
5056 fCurrencySignCount = fgCurrencySignCountInSymbolFormat;
5057 }
5058 // Fall through to append(ch)
5059 } else if (ch == kQuote) {
5060 // A quote outside quotes indicates either the opening
5061 // quote or two quotes, which is a quote literal. That is,
5062 // we have the first quote in 'do' or o''clock.
5063 U_ASSERT(U16_LENGTH(kQuote) == 1);
5064 ++pos;
5065 if (pos < pattern.length() && pattern[pos] == kQuote) {
5066 affix->append(kQuote); // Encode quote
5067 // Fall through to append(ch)
5068 } else {
5069 subpart += 2; // open quote
5070 continue;
5071 }
5072 } else if (pattern.compare(pos, separator.length(), separator) = = 0) {
5073 // Don't allow separators in the prefix, and don't allow
5074 // separators in the second pattern (part == 1).
5075 if (subpart == 1 || part == 1) {
5076 // Unexpected separator
5077 debug("Unexpected separator")
5078 status = U_UNEXPECTED_TOKEN;
5079 syntaxError(pattern,pos,parseError);
5080 return;
5081 }
5082 sub2Limit = pos;
5083 isPartDone = TRUE; // Go to next part
5084 pos += separator.length();
5085 break;
5086 } else if (pattern.compare(pos, percent.length(), percent) == 0) {
5087 // Next handle characters which are appended directly.
5088 if (multiplier != 1) {
5089 // Too many percent/perMill characters
5090 debug("Too many percent characters")
5091 status = U_MULTIPLE_PERCENT_SYMBOLS;
5092 syntaxError(pattern,pos,parseError);
5093 return;
5094 }
5095 affix->append(kQuote); // Encode percent/perMill
5096 affix->append(kPatternPercent); // Use unlocalized pattern c har
5097 multiplier = 100;
5098 pos += percent.length();
5099 break;
5100 } else if (pattern.compare(pos, perMill.length(), perMill) == 0) {
5101 // Next handle characters which are appended directly.
5102 if (multiplier != 1) {
5103 // Too many percent/perMill characters
5104 debug("Too many perMill characters")
5105 status = U_MULTIPLE_PERMILL_SYMBOLS;
5106 syntaxError(pattern,pos,parseError);
5107 return;
5108 }
5109 affix->append(kQuote); // Encode percent/perMill
5110 affix->append(kPatternPerMill); // Use unlocalized pattern c har
5111 multiplier = 1000;
5112 pos += perMill.length();
5113 break;
5114 } else if (pattern.compare(pos, padEscape.length(), padEscape) = = 0) {
5115 if (padPos >= 0 || // Multiple pad specifiers
5116 (pos+1) == pattern.length()) { // Nothing after padEscap e
5117 debug("Multiple pad specifiers")
5118 status = U_MULTIPLE_PAD_SPECIFIERS;
5119 syntaxError(pattern,pos,parseError);
5120 return;
5121 }
5122 padPos = pos;
5123 pos += padEscape.length();
5124 padChar = pattern.char32At(pos);
5125 pos += U16_LENGTH(padChar);
5126 break;
5127 } else if (pattern.compare(pos, minus.length(), minus) == 0) {
5128 affix->append(kQuote); // Encode minus
5129 affix->append(kPatternMinus);
5130 pos += minus.length();
5131 break;
5132 } else if (pattern.compare(pos, plus.length(), plus) == 0) {
5133 affix->append(kQuote); // Encode plus
5134 affix->append(kPatternPlus);
5135 pos += plus.length();
5136 break;
5137 }
5138 // Unquoted, non-special characters fall through to here, as
5139 // well as other code which needs to append something to the
5140 // affix.
5141 affix->append(ch);
5142 pos += U16_LENGTH(ch);
5143 break;
5144 case 3: // Prefix subpart, in quote
5145 case 4: // Suffix subpart, in quote
5146 // A quote within quotes indicates either the closing
5147 // quote or two quotes, which is a quote literal. That is,
5148 // we have the second quote in 'do' or 'don''t'.
5149 if (ch == kQuote) {
5150 ++pos;
5151 if (pos < pattern.length() && pattern[pos] == kQuote) {
5152 affix->append(kQuote); // Encode quote
5153 // Fall through to append(ch)
5154 } else {
5155 subpart -= 2; // close quote
5156 continue;
5157 }
5158 }
5159 affix->append(ch);
5160 pos += U16_LENGTH(ch);
5161 break;
5162 } 5012 }
5163 } 5013 }
5164 5014 } else {
5165 if (sub0Limit == 0) {
5166 sub0Limit = pattern.length();
5167 }
5168
5169 if (sub2Limit == 0) {
5170 sub2Limit = pattern.length();
5171 }
5172
5173 /* Handle patterns with no '0' pattern character. These patterns
5174 * are legal, but must be recodified to make sense. "##.###" ->
5175 * "#0.###". ".###" -> ".0##".
5176 *
5177 * We allow patterns of the form "####" to produce a zeroDigitCount
5178 * of zero (got that?); although this seems like it might make it
5179 * possible for format() to produce empty strings, format() checks
5180 * for this condition and outputs a zero digit in this situation.
5181 * Having a zeroDigitCount of zero yields a minimum integer digits
5182 * of zero, which allows proper round-trip patterns. We don't want
5183 * "#" to become "#0" when toPattern() is called (even though that's
5184 * what it really is, semantically).
5185 */
5186 if (zeroDigitCount == 0 && sigDigitCount == 0 &&
5187 digitLeftCount > 0 && decimalPos >= 0) {
5188 // Handle "###.###" and "###." and ".###"
5189 int n = decimalPos;
5190 if (n == 0)
5191 ++n; // Handle ".###"
5192 digitRightCount = digitLeftCount - n;
5193 digitLeftCount = n - 1;
5194 zeroDigitCount = 1;
5195 }
5196
5197 // Do syntax checking on the digits, decimal points, and quotes.
5198 if ((decimalPos < 0 && digitRightCount > 0 && sigDigitCount == 0) ||
5199 (decimalPos >= 0 &&
5200 (sigDigitCount > 0 ||
5201 decimalPos < digitLeftCount ||
5202 decimalPos > (digitLeftCount + zeroDigitCount))) ||
5203 groupingCount == 0 || groupingCount2 == 0 ||
5204 (sigDigitCount > 0 && zeroDigitCount > 0) ||
5205 subpart > 2)
5206 { // subpart > 2 == unmatched quote
5207 debug("Syntax error")
5208 status = U_PATTERN_SYNTAX_ERROR;
5209 syntaxError(pattern,pos,parseError);
5210 return;
5211 }
5212
5213 // Make sure pad is at legal position before or after affix.
5214 if (padPos >= 0) {
5215 if (padPos == start) {
5216 padPos = kPadBeforePrefix;
5217 } else if (padPos+2 == sub0Start) {
5218 padPos = kPadAfterPrefix;
5219 } else if (padPos == sub0Limit) {
5220 padPos = kPadBeforeSuffix;
5221 } else if (padPos+2 == sub2Limit) {
5222 padPos = kPadAfterSuffix;
5223 } else {
5224 // Illegal pad position
5225 debug("Illegal pad position")
5226 status = U_ILLEGAL_PAD_POSITION;
5227 syntaxError(pattern,pos,parseError);
5228 return;
5229 }
5230 }
5231
5232 if (part == 0) {
5233 delete fPosPrefixPattern;
5234 delete fPosSuffixPattern;
5235 delete fNegPrefixPattern;
5236 delete fNegSuffixPattern;
5237 fPosPrefixPattern = new UnicodeString(prefix);
5238 /* test for NULL */
5239 if (fPosPrefixPattern == 0) {
5240 status = U_MEMORY_ALLOCATION_ERROR;
5241 return;
5242 }
5243 fPosSuffixPattern = new UnicodeString(suffix);
5244 /* test for NULL */
5245 if (fPosSuffixPattern == 0) {
5246 status = U_MEMORY_ALLOCATION_ERROR;
5247 delete fPosPrefixPattern;
5248 return;
5249 }
5250 fNegPrefixPattern = 0;
5251 fNegSuffixPattern = 0;
5252
5253 fUseExponentialNotation = (expDigits >= 0);
5254 if (fUseExponentialNotation) {
5255 fMinExponentDigits = expDigits;
5256 }
5257 fExponentSignAlwaysShown = expSignAlways;
5258 int32_t digitTotalCount = digitLeftCount + zeroDigitCount + digitRig htCount;
5259 // The effectiveDecimalPos is the position the decimal is at or
5260 // would be at if there is no decimal. Note that if
5261 // decimalPos<0, then digitTotalCount == digitLeftCount +
5262 // zeroDigitCount.
5263 int32_t effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTo talCount;
5264 UBool isSigDig = (sigDigitCount > 0);
5265 setSignificantDigitsUsed(isSigDig);
5266 if (isSigDig) {
5267 setMinimumSignificantDigits(sigDigitCount);
5268 setMaximumSignificantDigits(sigDigitCount + digitRightCount);
5269 } else {
5270 int32_t minInt = effectiveDecimalPos - digitLeftCount;
5271 setMinimumIntegerDigits(minInt);
5272 setMaximumIntegerDigits(fUseExponentialNotation
5273 ? digitLeftCount + getMinimumIntegerDigits()
5274 : NumberFormat::gDefaultMaxIntegerDigits);
5275 setMaximumFractionDigits(decimalPos >= 0
5276 ? (digitTotalCount - decimalPos) : 0);
5277 setMinimumFractionDigits(decimalPos >= 0
5278 ? (digitLeftCount + zeroDigitCount - decimalPos) : 0);
5279 }
5280 setGroupingUsed(groupingCount > 0);
5281 fGroupingSize = (groupingCount > 0) ? groupingCount : 0;
5282 fGroupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCo unt)
5283 ? groupingCount2 : 0;
5284 setMultiplier(multiplier);
5285 setDecimalSeparatorAlwaysShown(decimalPos == 0
5286 || decimalPos == digitTotalCount);
5287 if (padPos >= 0) {
5288 fPadPosition = (EPadPosition) padPos;
5289 // To compute the format width, first set up sub0Limit -
5290 // sub0Start. Add in prefix/suffix length later.
5291
5292 // fFormatWidth = prefix.length() + suffix.length() +
5293 // sub0Limit - sub0Start;
5294 fFormatWidth = sub0Limit - sub0Start;
5295 fPad = padChar;
5296 } else {
5297 fFormatWidth = 0;
5298 }
5299 if (roundingPos >= 0) {
5300 roundingInc.setDecimalAt(effectiveDecimalPos - roundingPos);
5301 if (fRoundingIncrement != NULL) {
5302 *fRoundingIncrement = roundingInc;
5303 } else {
5304 fRoundingIncrement = new DigitList(roundingInc);
5305 /* test for NULL */
5306 if (fRoundingIncrement == NULL) {
5307 status = U_MEMORY_ALLOCATION_ERROR;
5308 delete fPosPrefixPattern;
5309 delete fPosSuffixPattern;
5310 return;
5311 }
5312 }
5313 fRoundingMode = kRoundHalfEven;
5314 } else {
5315 setRoundingIncrement(0.0);
5316 }
5317 } else {
5318 fNegPrefixPattern = new UnicodeString(prefix);
5319 /* test for NULL */
5320 if (fNegPrefixPattern == 0) {
5321 status = U_MEMORY_ALLOCATION_ERROR;
5322 return;
5323 }
5324 fNegSuffixPattern = new UnicodeString(suffix);
5325 /* test for NULL */
5326 if (fNegSuffixPattern == 0) {
5327 delete fNegPrefixPattern;
5328 status = U_MEMORY_ALLOCATION_ERROR;
5329 return;
5330 }
5331 }
5332 }
5333
5334 if (pattern.length() == 0) {
5335 delete fNegPrefixPattern;
5336 delete fNegSuffixPattern;
5337 fNegPrefixPattern = NULL;
5338 fNegSuffixPattern = NULL;
5339 if (fPosPrefixPattern != NULL) {
5340 fPosPrefixPattern->remove();
5341 } else {
5342 fPosPrefixPattern = new UnicodeString();
5343 /* test for NULL */
5344 if (fPosPrefixPattern == 0) {
5345 status = U_MEMORY_ALLOCATION_ERROR;
5346 return;
5347 }
5348 }
5349 if (fPosSuffixPattern != NULL) {
5350 fPosSuffixPattern->remove();
5351 } else {
5352 fPosSuffixPattern = new UnicodeString();
5353 /* test for NULL */
5354 if (fPosSuffixPattern == 0) {
5355 delete fPosPrefixPattern;
5356 status = U_MEMORY_ALLOCATION_ERROR;
5357 return;
5358 }
5359 }
5360
5361 setMinimumIntegerDigits(0);
5362 setMaximumIntegerDigits(kDoubleIntegerDigits);
5363 setMinimumFractionDigits(0);
5364 setMaximumFractionDigits(kDoubleFractionDigits);
5365
5366 fUseExponentialNotation = FALSE;
5367 fCurrencySignCount = fgCurrencySignCountZero;
5368 setGroupingUsed(FALSE);
5369 fGroupingSize = 0;
5370 fGroupingSize2 = 0;
5371 setMultiplier(1);
5372 setDecimalSeparatorAlwaysShown(FALSE);
5373 fFormatWidth = 0;
5374 setRoundingIncrement(0.0); 5015 setRoundingIncrement(0.0);
5375 } 5016 }
5376 5017 fPad = out.fPad;
5377 // If there was no negative pattern, or if the negative pattern is 5018 switch (out.fPadPosition) {
5378 // identical to the positive pattern, then prepend the minus sign to the 5019 case DecimalFormatPattern::kPadBeforePrefix:
5379 // positive pattern to form the negative pattern. 5020 fPadPosition = kPadBeforePrefix;
5380 if (fNegPrefixPattern == NULL || 5021 break;
5381 (*fNegPrefixPattern == *fPosPrefixPattern 5022 case DecimalFormatPattern::kPadAfterPrefix:
5382 && *fNegSuffixPattern == *fPosSuffixPattern)) { 5023 fPadPosition = kPadAfterPrefix;
5383 _copy_ptr(&fNegSuffixPattern, fPosSuffixPattern); 5024 break;
5384 if (fNegPrefixPattern == NULL) { 5025 case DecimalFormatPattern::kPadBeforeSuffix:
5385 fNegPrefixPattern = new UnicodeString(); 5026 fPadPosition = kPadBeforeSuffix;
5386 /* test for NULL */ 5027 break;
5387 if (fNegPrefixPattern == 0) { 5028 case DecimalFormatPattern::kPadAfterSuffix:
5388 status = U_MEMORY_ALLOCATION_ERROR; 5029 fPadPosition = kPadAfterSuffix;
5389 return; 5030 break;
5390 }
5391 } else {
5392 fNegPrefixPattern->remove();
5393 }
5394 fNegPrefixPattern->append(kQuote).append(kPatternMinus)
5395 .append(*fPosPrefixPattern);
5396 } 5031 }
5397 #ifdef FMT_DEBUG 5032 copyString(out.fNegPrefixPattern, out.fNegPatternsBogus, fNegPrefixPattern, status);
5398 UnicodeString s; 5033 copyString(out.fNegSuffixPattern, out.fNegPatternsBogus, fNegSuffixPattern, status);
5399 s.append((UnicodeString)"\"").append(pattern).append((UnicodeString)"\"->"); 5034 copyString(out.fPosPrefixPattern, out.fPosPatternsBogus, fPosPrefixPattern, status);
5400 debugout(s); 5035 copyString(out.fPosSuffixPattern, out.fPosPatternsBogus, fPosSuffixPattern, status);
5401 #endif
5402
5403 // save the pattern
5404 fFormatPattern = pattern;
5405 } 5036 }
5406 5037
5407 5038
5408 void 5039 void
5409 DecimalFormat::expandAffixAdjustWidth(const UnicodeString* pluralCount) { 5040 DecimalFormat::expandAffixAdjustWidth(const UnicodeString* pluralCount) {
5410 expandAffixes(pluralCount); 5041 expandAffixes(pluralCount);
5411 if (fFormatWidth > 0) { 5042 if (fFormatWidth > 0) {
5412 // Finish computing format width (see above) 5043 // Finish computing format width (see above)
5413 // TODO: how to handle fFormatWidth, 5044 // TODO: how to handle fFormatWidth,
5414 // need to save in f(Plural)AffixesForCurrecy? 5045 // need to save in f(Plural)AffixesForCurrecy?
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
5565 5196
5566 // Note: The code is ordered so that this object is *not changed* 5197 // Note: The code is ordered so that this object is *not changed*
5567 // until we are sure we are going to succeed. 5198 // until we are sure we are going to succeed.
5568 5199
5569 // NULL or empty currency is *legal* and indicates no currency. 5200 // NULL or empty currency is *legal* and indicates no currency.
5570 UBool isCurr = (theCurrency && *theCurrency); 5201 UBool isCurr = (theCurrency && *theCurrency);
5571 5202
5572 double rounding = 0.0; 5203 double rounding = 0.0;
5573 int32_t frac = 0; 5204 int32_t frac = 0;
5574 if (fCurrencySignCount != fgCurrencySignCountZero && isCurr) { 5205 if (fCurrencySignCount != fgCurrencySignCountZero && isCurr) {
5575 rounding = ucurr_getRoundingIncrement(theCurrency, &ec); 5206 rounding = ucurr_getRoundingIncrementForUsage(theCurrency, fCurrencyUsag e, &ec);
5576 frac = ucurr_getDefaultFractionDigits(theCurrency, &ec); 5207 frac = ucurr_getDefaultFractionDigitsForUsage(theCurrency, fCurrencyUsag e, &ec);
5577 } 5208 }
5578 5209
5579 NumberFormat::setCurrency(theCurrency, ec); 5210 NumberFormat::setCurrency(theCurrency, ec);
5580 if (U_FAILURE(ec)) return; 5211 if (U_FAILURE(ec)) return;
5581 5212
5582 if (fCurrencySignCount != fgCurrencySignCountZero) { 5213 if (fCurrencySignCount != fgCurrencySignCountZero) {
5583 // NULL or empty currency is *legal* and indicates no currency. 5214 // NULL or empty currency is *legal* and indicates no currency.
5584 if (isCurr) { 5215 if (isCurr) {
5585 setRoundingIncrement(rounding); 5216 setRoundingIncrement(rounding);
5586 setMinimumFractionDigits(frac); 5217 setMinimumFractionDigits(frac);
(...skipping 15 matching lines...) Expand all
5602 UParseError parseErr; 5233 UParseError parseErr;
5603 applyPattern(savedPtn, FALSE, parseErr, ec); 5234 applyPattern(savedPtn, FALSE, parseErr, ec);
5604 } 5235 }
5605 // set the currency after apply pattern to get the correct rounding/fraction 5236 // set the currency after apply pattern to get the correct rounding/fraction
5606 setCurrencyInternally(theCurrency, ec); 5237 setCurrencyInternally(theCurrency, ec);
5607 #if UCONFIG_FORMAT_FASTPATHS_49 5238 #if UCONFIG_FORMAT_FASTPATHS_49
5608 handleChanged(); 5239 handleChanged();
5609 #endif 5240 #endif
5610 } 5241 }
5611 5242
5243 void DecimalFormat::setCurrencyUsage(UCurrencyUsage newContext, UErrorCode* ec){
5244 fCurrencyUsage = newContext;
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 }
5260
5261 UCurrencyUsage DecimalFormat::getCurrencyUsage() const {
5262 return fCurrencyUsage;
5263 }
5264
5612 // Deprecated variant with no UErrorCode parameter 5265 // Deprecated variant with no UErrorCode parameter
5613 void DecimalFormat::setCurrency(const UChar* theCurrency) { 5266 void DecimalFormat::setCurrency(const UChar* theCurrency) {
5614 UErrorCode ec = U_ZERO_ERROR; 5267 UErrorCode ec = U_ZERO_ERROR;
5615 setCurrency(theCurrency, ec); 5268 setCurrency(theCurrency, ec);
5616 #if UCONFIG_FORMAT_FASTPATHS_49 5269 #if UCONFIG_FORMAT_FASTPATHS_49
5617 handleChanged(); 5270 handleChanged();
5618 #endif 5271 #endif
5619 } 5272 }
5620 5273
5621 void DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const { 5274 void DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const {
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
5747 value->posSuffixPatternForCurrency, 5400 value->posSuffixPatternForCurrency,
5748 value->patternType); 5401 value->patternType);
5749 target->put(UnicodeString(*key), copy, status); 5402 target->put(UnicodeString(*key), copy, status);
5750 if ( U_FAILURE(status) ) { 5403 if ( U_FAILURE(status) ) {
5751 return; 5404 return;
5752 } 5405 }
5753 } 5406 }
5754 } 5407 }
5755 } 5408 }
5756 5409
5410 // this is only overridden to call handleChanged() for fastpath purposes.
5411 void
5412 DecimalFormat::setGroupingUsed(UBool newValue) {
5413 NumberFormat::setGroupingUsed(newValue);
5414 handleChanged();
5415 }
5416
5417 // this is only overridden to call handleChanged() for fastpath purposes.
5418 void
5419 DecimalFormat::setParseIntegerOnly(UBool newValue) {
5420 NumberFormat::setParseIntegerOnly(newValue);
5421 handleChanged();
5422 }
5423
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
5427 DecimalFormat::setContext(UDisplayContext value, UErrorCode& status) {
5428 NumberFormat::setContext(value, status);
5429 handleChanged();
5430 }
5431
5432
5757 DecimalFormat& DecimalFormat::setAttribute( UNumberFormatAttribute attr, 5433 DecimalFormat& DecimalFormat::setAttribute( UNumberFormatAttribute attr,
5758 int32_t newValue, 5434 int32_t newValue,
5759 UErrorCode &status) { 5435 UErrorCode &status) {
5760 if(U_FAILURE(status)) return *this; 5436 if(U_FAILURE(status)) return *this;
5761 5437
5762 switch(attr) { 5438 switch(attr) {
5763 case UNUM_LENIENT_PARSE: 5439 case UNUM_LENIENT_PARSE:
5764 setLenient(newValue!=0); 5440 setLenient(newValue!=0);
5765 break; 5441 break;
5766 5442
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
5841 5517
5842 #if UCONFIG_HAVE_PARSEALLINPUT 5518 #if UCONFIG_HAVE_PARSEALLINPUT
5843 case UNUM_PARSE_ALL_INPUT: 5519 case UNUM_PARSE_ALL_INPUT:
5844 setParseAllInput((UNumberFormatAttributeValue)newValue); 5520 setParseAllInput((UNumberFormatAttributeValue)newValue);
5845 break; 5521 break;
5846 #endif 5522 #endif
5847 5523
5848 /* These are stored in fBoolFlags */ 5524 /* These are stored in fBoolFlags */
5849 case UNUM_PARSE_NO_EXPONENT: 5525 case UNUM_PARSE_NO_EXPONENT:
5850 case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS: 5526 case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS:
5527 case UNUM_PARSE_DECIMAL_MARK_REQUIRED:
5851 if(!fBoolFlags.isValidValue(newValue)) { 5528 if(!fBoolFlags.isValidValue(newValue)) {
5852 status = U_ILLEGAL_ARGUMENT_ERROR; 5529 status = U_ILLEGAL_ARGUMENT_ERROR;
5853 } else { 5530 } else {
5854 fBoolFlags.set(attr, newValue); 5531 fBoolFlags.set(attr, newValue);
5855 } 5532 }
5856 break; 5533 break;
5857 5534
5858 case UNUM_SCALE: 5535 case UNUM_SCALE:
5859 fScale = newValue; 5536 fScale = newValue;
5860 break; 5537 break;
5861 5538
5539 case UNUM_CURRENCY_USAGE:
5540 setCurrencyUsage((UCurrencyUsage)newValue, &status);
5541
5862 default: 5542 default:
5863 status = U_UNSUPPORTED_ERROR; 5543 status = U_UNSUPPORTED_ERROR;
5864 break; 5544 break;
5865 } 5545 }
5866 return *this; 5546 return *this;
5867 } 5547 }
5868 5548
5869 int32_t DecimalFormat::getAttribute( UNumberFormatAttribute attr, 5549 int32_t DecimalFormat::getAttribute( UNumberFormatAttribute attr,
5870 UErrorCode &status ) const { 5550 UErrorCode &status ) const {
5871 if(U_FAILURE(status)) return -1; 5551 if(U_FAILURE(status)) return -1;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
5925 5605
5926 case UNUM_PADDING_POSITION: 5606 case UNUM_PADDING_POSITION:
5927 return getPadPosition(); 5607 return getPadPosition();
5928 5608
5929 case UNUM_SECONDARY_GROUPING_SIZE: 5609 case UNUM_SECONDARY_GROUPING_SIZE:
5930 return getSecondaryGroupingSize(); 5610 return getSecondaryGroupingSize();
5931 5611
5932 /* These are stored in fBoolFlags */ 5612 /* These are stored in fBoolFlags */
5933 case UNUM_PARSE_NO_EXPONENT: 5613 case UNUM_PARSE_NO_EXPONENT:
5934 case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS: 5614 case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS:
5615 case UNUM_PARSE_DECIMAL_MARK_REQUIRED:
5935 return fBoolFlags.get(attr); 5616 return fBoolFlags.get(attr);
5936 5617
5937 case UNUM_SCALE: 5618 case UNUM_SCALE:
5938 return fScale; 5619 return fScale;
5939 5620
5621 case UNUM_CURRENCY_USAGE:
5622 return fCurrencyUsage;
5623
5940 default: 5624 default:
5941 status = U_UNSUPPORTED_ERROR; 5625 status = U_UNSUPPORTED_ERROR;
5942 break; 5626 break;
5943 } 5627 }
5944 5628
5945 return -1; /* undefined */ 5629 return -1; /* undefined */
5946 } 5630 }
5947 5631
5948 #if UCONFIG_HAVE_PARSEALLINPUT 5632 #if UCONFIG_HAVE_PARSEALLINPUT
5949 void DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) { 5633 void DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
5981 } 5665 }
5982 } 5666 }
5983 } 5667 }
5984 } 5668 }
5985 5669
5986 U_NAMESPACE_END 5670 U_NAMESPACE_END
5987 5671
5988 #endif /* #if !UCONFIG_NO_FORMATTING */ 5672 #endif /* #if !UCONFIG_NO_FORMATTING */
5989 5673
5990 //eof 5674 //eof
OLDNEW
« no previous file with comments | « source/i18n/decimalformatpattern.cpp ('k') | source/i18n/digitlst.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698