< prev index next >

src/java.base/share/classes/java/text/DecimalFormat.java

Print this page
rev 54198 : [mq]: 8220224
   1 /*
   2  * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


1899             // digits, since truncating the exponent would result in an
1900             // unacceptable inaccuracy.
1901             int fieldStart = result.length();
1902 
1903             result.append(symbols.getExponentSeparator());
1904 
1905             delegate.formatted(Field.EXPONENT_SYMBOL, Field.EXPONENT_SYMBOL,
1906                     fieldStart, result.length(), result);
1907 
1908             // For zero values, we force the exponent to zero.  We
1909             // must do this here, and not earlier, because the value
1910             // is used to determine integer digit count above.
1911             if (digitList.isZero()) {
1912                 exponent = 0;
1913             }
1914 
1915             boolean negativeExponent = exponent < 0;
1916             if (negativeExponent) {
1917                 exponent = -exponent;
1918                 fieldStart = result.length();
1919                 result.append(symbols.getMinusSign());
1920                 delegate.formatted(Field.EXPONENT_SIGN, Field.EXPONENT_SIGN,
1921                         fieldStart, result.length(), result);
1922             }
1923             digitList.set(negativeExponent, exponent);
1924 
1925             int eFieldStart = result.length();
1926 
1927             for (int i=digitList.decimalAt; i<minExponentDigits; ++i) {
1928                 result.append(zero);
1929             }
1930             for (int i=0; i<digitList.decimalAt; ++i) {
1931                 result.append((i < digitList.count) ?
1932                         (char)(digitList.digits[i] + zeroDelta) : zero);
1933             }
1934             delegate.formatted(Field.EXPONENT, Field.EXPONENT, eFieldStart,
1935                     result.length(), result);
1936         } else {
1937             int iFieldStart = result.length();
1938 
1939             // Output the integer portion.  Here 'count' is the total


2458                     if (isParseIntegerOnly() || sawDecimal) {
2459                         break;
2460                     }
2461                     digits.decimalAt = digitCount; // Not digits.count!
2462                     sawDecimal = true;
2463                 } else if (!isExponent && ch == grouping && isGroupingUsed()) {
2464                     if (sawDecimal) {
2465                         break;
2466                     }
2467                     // Ignore grouping characters, if we are using them, but
2468                     // require that they be followed by a digit.  Otherwise
2469                     // we backup and reprocess them.
2470                     backup = position;
2471                 } else if (checkExponent && !isExponent && text.regionMatches(position, exponentString, 0, exponentString.length())
2472                         && !sawExponent) {
2473                     // Process the exponent by recursively calling this method.
2474                     ParsePosition pos = new ParsePosition(position + exponentString.length());
2475                     boolean[] stat = new boolean[STATUS_LENGTH];
2476                     DigitList exponentDigits = new DigitList();
2477 
2478                     if (subparse(text, pos, "", Character.toString(symbols.getMinusSign()), exponentDigits, true, stat) &&
2479                             exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) {
2480                         position = pos.index; // Advance past the exponent
2481                         exponent = (int)exponentDigits.getLong();
2482                         if (!stat[STATUS_POSITIVE]) {
2483                             exponent = -exponent;
2484                         }
2485                         sawExponent = true;
2486                     }
2487                     break; // Whether we fail or succeed, we exit this loop
2488                 } else {
2489                     break;
2490                 }
2491             }
2492 
2493             if (backup != -1) {
2494                 position = backup;
2495             }
2496 
2497             // If there was no decimal point we have an integer
2498             if (!sawDecimal) {


2974      * @param buffer a scratch StringBuffer; its contents will be lost
2975      * @return the expanded equivalent of pattern
2976      */
2977     private String expandAffix(String pattern, StringBuffer buffer) {
2978         buffer.setLength(0);
2979         for (int i=0; i<pattern.length(); ) {
2980             char c = pattern.charAt(i++);
2981             if (c == QUOTE) {
2982                 c = pattern.charAt(i++);
2983                 switch (c) {
2984                 case CURRENCY_SIGN:
2985                     if (i<pattern.length() &&
2986                         pattern.charAt(i) == CURRENCY_SIGN) {
2987                         ++i;
2988                         buffer.append(symbols.getInternationalCurrencySymbol());
2989                     } else {
2990                         buffer.append(symbols.getCurrencySymbol());
2991                     }
2992                     continue;
2993                 case PATTERN_PERCENT:
2994                     c = symbols.getPercent();
2995                     break;
2996                 case PATTERN_PER_MILLE:
2997                     c = symbols.getPerMill();
2998                     break;
2999                 case PATTERN_MINUS:
3000                     c = symbols.getMinusSign();
3001                     break;
3002                 }
3003             }
3004             buffer.append(c);
3005         }
3006         return buffer.toString();
3007     }
3008 
3009     /**
3010      * Expand an affix pattern into an array of FieldPositions describing
3011      * how the pattern would be expanded.
3012      * All characters in the
3013      * pattern are literal unless prefixed by QUOTE.  The following characters
3014      * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
3015      * PATTERN_MINUS, and CURRENCY_SIGN.  If CURRENCY_SIGN is doubled (QUOTE +
3016      * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
3017      * currency code.  Any other character after a QUOTE represents itself.
3018      * QUOTE must be followed by another character; QUOTE may not occur by
3019      * itself at the end of the pattern.
3020      *
3021      * @param pattern the non-null, possibly empty pattern
3022      * @return FieldPosition array of the resulting fields.
3023      */
3024     private FieldPosition[] expandAffix(String pattern) {
3025         ArrayList<FieldPosition> positions = null;
3026         int stringIndex = 0;
3027         for (int i=0; i<pattern.length(); ) {
3028             char c = pattern.charAt(i++);
3029             if (c == QUOTE) {
3030                 int field = -1;
3031                 Format.Field fieldID = null;

3032                 c = pattern.charAt(i++);
3033                 switch (c) {
3034                 case CURRENCY_SIGN:
3035                     String string;
3036                     if (i<pattern.length() &&
3037                         pattern.charAt(i) == CURRENCY_SIGN) {
3038                         ++i;
3039                         string = symbols.getInternationalCurrencySymbol();
3040                     } else {
3041                         string = symbols.getCurrencySymbol();
3042                     }
3043                     if (!string.isEmpty()) {
3044                         if (positions == null) {
3045                             positions = new ArrayList<>(2);
3046                         }
3047                         FieldPosition fp = new FieldPosition(Field.CURRENCY);
3048                         fp.setBeginIndex(stringIndex);
3049                         fp.setEndIndex(stringIndex + string.length());
3050                         positions.add(fp);
3051                         stringIndex += string.length();
3052                     }
3053                     continue;
3054                 case PATTERN_PERCENT:
3055                     c = symbols.getPercent();
3056                     field = -1;
3057                     fieldID = Field.PERCENT;
3058                     break;
3059                 case PATTERN_PER_MILLE:
3060                     c = symbols.getPerMill();
3061                     field = -1;
3062                     fieldID = Field.PERMILLE;
3063                     break;
3064                 case PATTERN_MINUS:
3065                     c = symbols.getMinusSign();
3066                     field = -1;
3067                     fieldID = Field.SIGN;
3068                     break;
3069                 }
3070                 if (fieldID != null) {

3071                     if (positions == null) {
3072                         positions = new ArrayList<>(2);
3073                     }
3074                     FieldPosition fp = new FieldPosition(fieldID, field);
3075                     fp.setBeginIndex(stringIndex);
3076                     fp.setEndIndex(stringIndex + 1);
3077                     positions.add(fp);


3078                 }
3079             }
3080             stringIndex++;
3081         }
3082         if (positions != null) {
3083             return positions.toArray(EmptyFieldPositionArray);
3084         }
3085         return EmptyFieldPositionArray;
3086     }
3087 
3088     /**
3089      * Appends an affix pattern to the given StringBuffer, quoting special
3090      * characters as needed.  Uses the internal affix pattern, if that exists,
3091      * or the literal affix, if the internal affix pattern is null.  The
3092      * appended string will generate the same affix pattern (or literal affix)
3093      * when passed to toPattern().
3094      *
3095      * @param buffer the affix string is appended to this
3096      * @param affixPattern a pattern such as posPrefixPattern; may be null
3097      * @param expAffix a corresponding expanded affix, such as positivePrefix.


3112                     appendAffix(buffer, affixPattern.substring(pos), localized);
3113                     break;
3114                 }
3115                 if (i > pos) {
3116                     appendAffix(buffer, affixPattern.substring(pos, i), localized);
3117                 }
3118                 char c = affixPattern.charAt(++i);
3119                 ++i;
3120                 if (c == QUOTE) {
3121                     buffer.append(c);
3122                     // Fall through and append another QUOTE below
3123                 } else if (c == CURRENCY_SIGN &&
3124                            i<affixPattern.length() &&
3125                            affixPattern.charAt(i) == CURRENCY_SIGN) {
3126                     ++i;
3127                     buffer.append(c);
3128                     // Fall through and append another CURRENCY_SIGN below
3129                 } else if (localized) {
3130                     switch (c) {
3131                     case PATTERN_PERCENT:
3132                         c = symbols.getPercent();
3133                         break;
3134                     case PATTERN_PER_MILLE:
3135                         c = symbols.getPerMill();
3136                         break;
3137                     case PATTERN_MINUS:
3138                         c = symbols.getMinusSign();
3139                         break;
3140                     }
3141                 }
3142                 buffer.append(c);
3143             }
3144         }
3145     }
3146 
3147     /**
3148      * Append an affix to the given StringBuffer, using quotes if
3149      * there are special characters.  Single quotes themselves must be
3150      * escaped in either case.
3151      */
3152     private void appendAffix(StringBuffer buffer, String affix, boolean localized) {
3153         boolean needQuote;
3154         if (localized) {
3155             needQuote = affix.indexOf(symbols.getZeroDigit()) >= 0
3156                 || affix.indexOf(symbols.getGroupingSeparator()) >= 0
3157                 || affix.indexOf(symbols.getDecimalSeparator()) >= 0
3158                 || affix.indexOf(symbols.getPercent()) >= 0
3159                 || affix.indexOf(symbols.getPerMill()) >= 0
3160                 || affix.indexOf(symbols.getDigit()) >= 0
3161                 || affix.indexOf(symbols.getPatternSeparator()) >= 0
3162                 || affix.indexOf(symbols.getMinusSign()) >= 0
3163                 || affix.indexOf(CURRENCY_SIGN) >= 0;
3164         } else {
3165             needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0
3166                 || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0
3167                 || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0
3168                 || affix.indexOf(PATTERN_PERCENT) >= 0
3169                 || affix.indexOf(PATTERN_PER_MILLE) >= 0
3170                 || affix.indexOf(PATTERN_DIGIT) >= 0
3171                 || affix.indexOf(PATTERN_SEPARATOR) >= 0
3172                 || affix.indexOf(PATTERN_MINUS) >= 0
3173                 || affix.indexOf(CURRENCY_SIGN) >= 0;
3174         }
3175         if (needQuote) buffer.append('\'');
3176         if (affix.indexOf('\'') < 0) buffer.append(affix);
3177         else {
3178             for (int j=0; j<affix.length(); ++j) {
3179                 char c = affix.charAt(j);
3180                 buffer.append(c);
3181                 if (c == '\'') buffer.append(c);
3182             }


3218                                   PATTERN_DIGIT);
3219                 }
3220             }
3221         if (useExponentialNotation)
3222         {
3223             result.append(localized ? symbols.getExponentSeparator() :
3224                   PATTERN_EXPONENT);
3225         for (i=0; i<minExponentDigits; ++i)
3226                     result.append(localized ? symbols.getZeroDigit() :
3227                                   PATTERN_ZERO_DIGIT);
3228         }
3229             if (j == 1) {
3230                 appendAffix(result, posSuffixPattern, positiveSuffix, localized);
3231                 if ((negSuffixPattern == posSuffixPattern && // n == p == null
3232                      negativeSuffix.equals(positiveSuffix))
3233                     || (negSuffixPattern != null &&
3234                         negSuffixPattern.equals(posSuffixPattern))) {
3235                     if ((negPrefixPattern != null && posPrefixPattern != null &&
3236                          negPrefixPattern.equals("'-" + posPrefixPattern)) ||
3237                         (negPrefixPattern == posPrefixPattern && // n == p == null
3238                          negativePrefix.equals(symbols.getMinusSign() + positivePrefix)))
3239                         break;
3240                 }
3241                 result.append(localized ? symbols.getPatternSeparator() :
3242                               PATTERN_SEPARATOR);
3243             } else appendAffix(result, negSuffixPattern, negativeSuffix, localized);
3244         }
3245         return result.toString();
3246     }
3247 
3248     /**
3249      * Apply the given pattern to this Format object.  A pattern is a
3250      * short-hand specification for the various formatting properties.
3251      * These properties can also be changed individually through the
3252      * various setter methods.
3253      * <p>
3254      * There is no limit to integer digits set
3255      * by this routine, since that is the typical end-user desire;
3256      * use setMaximumInteger if you want to set a real value.
3257      * For negative numbers, use a second pattern, separated by a semicolon
3258      * <P>Example <code>"#,#00.0#"</code> &rarr; 1,234.56


   1 /*
   2  * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


1899             // digits, since truncating the exponent would result in an
1900             // unacceptable inaccuracy.
1901             int fieldStart = result.length();
1902 
1903             result.append(symbols.getExponentSeparator());
1904 
1905             delegate.formatted(Field.EXPONENT_SYMBOL, Field.EXPONENT_SYMBOL,
1906                     fieldStart, result.length(), result);
1907 
1908             // For zero values, we force the exponent to zero.  We
1909             // must do this here, and not earlier, because the value
1910             // is used to determine integer digit count above.
1911             if (digitList.isZero()) {
1912                 exponent = 0;
1913             }
1914 
1915             boolean negativeExponent = exponent < 0;
1916             if (negativeExponent) {
1917                 exponent = -exponent;
1918                 fieldStart = result.length();
1919                 result.append(symbols.getMinusSignText());
1920                 delegate.formatted(Field.EXPONENT_SIGN, Field.EXPONENT_SIGN,
1921                         fieldStart, result.length(), result);
1922             }
1923             digitList.set(negativeExponent, exponent);
1924 
1925             int eFieldStart = result.length();
1926 
1927             for (int i=digitList.decimalAt; i<minExponentDigits; ++i) {
1928                 result.append(zero);
1929             }
1930             for (int i=0; i<digitList.decimalAt; ++i) {
1931                 result.append((i < digitList.count) ?
1932                         (char)(digitList.digits[i] + zeroDelta) : zero);
1933             }
1934             delegate.formatted(Field.EXPONENT, Field.EXPONENT, eFieldStart,
1935                     result.length(), result);
1936         } else {
1937             int iFieldStart = result.length();
1938 
1939             // Output the integer portion.  Here 'count' is the total


2458                     if (isParseIntegerOnly() || sawDecimal) {
2459                         break;
2460                     }
2461                     digits.decimalAt = digitCount; // Not digits.count!
2462                     sawDecimal = true;
2463                 } else if (!isExponent && ch == grouping && isGroupingUsed()) {
2464                     if (sawDecimal) {
2465                         break;
2466                     }
2467                     // Ignore grouping characters, if we are using them, but
2468                     // require that they be followed by a digit.  Otherwise
2469                     // we backup and reprocess them.
2470                     backup = position;
2471                 } else if (checkExponent && !isExponent && text.regionMatches(position, exponentString, 0, exponentString.length())
2472                         && !sawExponent) {
2473                     // Process the exponent by recursively calling this method.
2474                     ParsePosition pos = new ParsePosition(position + exponentString.length());
2475                     boolean[] stat = new boolean[STATUS_LENGTH];
2476                     DigitList exponentDigits = new DigitList();
2477 
2478                     if (subparse(text, pos, "", symbols.getMinusSignText(), exponentDigits, true, stat) &&
2479                             exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) {
2480                         position = pos.index; // Advance past the exponent
2481                         exponent = (int)exponentDigits.getLong();
2482                         if (!stat[STATUS_POSITIVE]) {
2483                             exponent = -exponent;
2484                         }
2485                         sawExponent = true;
2486                     }
2487                     break; // Whether we fail or succeed, we exit this loop
2488                 } else {
2489                     break;
2490                 }
2491             }
2492 
2493             if (backup != -1) {
2494                 position = backup;
2495             }
2496 
2497             // If there was no decimal point we have an integer
2498             if (!sawDecimal) {


2974      * @param buffer a scratch StringBuffer; its contents will be lost
2975      * @return the expanded equivalent of pattern
2976      */
2977     private String expandAffix(String pattern, StringBuffer buffer) {
2978         buffer.setLength(0);
2979         for (int i=0; i<pattern.length(); ) {
2980             char c = pattern.charAt(i++);
2981             if (c == QUOTE) {
2982                 c = pattern.charAt(i++);
2983                 switch (c) {
2984                 case CURRENCY_SIGN:
2985                     if (i<pattern.length() &&
2986                         pattern.charAt(i) == CURRENCY_SIGN) {
2987                         ++i;
2988                         buffer.append(symbols.getInternationalCurrencySymbol());
2989                     } else {
2990                         buffer.append(symbols.getCurrencySymbol());
2991                     }
2992                     continue;
2993                 case PATTERN_PERCENT:
2994                     buffer.append(symbols.getPercentText());
2995                     continue;
2996                 case PATTERN_PER_MILLE:
2997                     buffer.append(symbols.getPerMillText());
2998                     continue;
2999                 case PATTERN_MINUS:
3000                     buffer.append(symbols.getMinusSignText());
3001                     continue;
3002                 }
3003             }
3004             buffer.append(c);
3005         }
3006         return buffer.toString();
3007     }
3008 
3009     /**
3010      * Expand an affix pattern into an array of FieldPositions describing
3011      * how the pattern would be expanded.
3012      * All characters in the
3013      * pattern are literal unless prefixed by QUOTE.  The following characters
3014      * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
3015      * PATTERN_MINUS, and CURRENCY_SIGN.  If CURRENCY_SIGN is doubled (QUOTE +
3016      * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
3017      * currency code.  Any other character after a QUOTE represents itself.
3018      * QUOTE must be followed by another character; QUOTE may not occur by
3019      * itself at the end of the pattern.
3020      *
3021      * @param pattern the non-null, possibly empty pattern
3022      * @return FieldPosition array of the resulting fields.
3023      */
3024     private FieldPosition[] expandAffix(String pattern) {
3025         ArrayList<FieldPosition> positions = null;
3026         int stringIndex = 0;
3027         for (int i=0; i<pattern.length(); ) {
3028             char c = pattern.charAt(i++);
3029             if (c == QUOTE) {

3030                 Format.Field fieldID = null;
3031                 String string = null;
3032                 c = pattern.charAt(i++);
3033                 switch (c) {
3034                 case CURRENCY_SIGN:

3035                     if (i<pattern.length() &&
3036                         pattern.charAt(i) == CURRENCY_SIGN) {
3037                         ++i;
3038                         string = symbols.getInternationalCurrencySymbol();
3039                     } else {
3040                         string = symbols.getCurrencySymbol();
3041                     }
3042                     fieldID = Field.CURRENCY;
3043                     break;









3044                 case PATTERN_PERCENT:
3045                     string = symbols.getPercentText();

3046                     fieldID = Field.PERCENT;
3047                     break;
3048                 case PATTERN_PER_MILLE:
3049                     string = symbols.getPerMillText();

3050                     fieldID = Field.PERMILLE;
3051                     break;
3052                 case PATTERN_MINUS:
3053                     string = symbols.getMinusSignText();

3054                     fieldID = Field.SIGN;
3055                     break;
3056                 }
3057 
3058                 if (fieldID != null && !string.isEmpty()) {
3059                     if (positions == null) {
3060                         positions = new ArrayList<>(2);
3061                     }
3062                     FieldPosition fp = new FieldPosition(fieldID);
3063                     fp.setBeginIndex(stringIndex);
3064                     fp.setEndIndex(stringIndex + string.length());
3065                     positions.add(fp);
3066                     stringIndex += string.length();
3067                     continue;
3068                 }
3069             }
3070             stringIndex++;
3071         }
3072         if (positions != null) {
3073             return positions.toArray(EmptyFieldPositionArray);
3074         }
3075         return EmptyFieldPositionArray;
3076     }
3077 
3078     /**
3079      * Appends an affix pattern to the given StringBuffer, quoting special
3080      * characters as needed.  Uses the internal affix pattern, if that exists,
3081      * or the literal affix, if the internal affix pattern is null.  The
3082      * appended string will generate the same affix pattern (or literal affix)
3083      * when passed to toPattern().
3084      *
3085      * @param buffer the affix string is appended to this
3086      * @param affixPattern a pattern such as posPrefixPattern; may be null
3087      * @param expAffix a corresponding expanded affix, such as positivePrefix.


3102                     appendAffix(buffer, affixPattern.substring(pos), localized);
3103                     break;
3104                 }
3105                 if (i > pos) {
3106                     appendAffix(buffer, affixPattern.substring(pos, i), localized);
3107                 }
3108                 char c = affixPattern.charAt(++i);
3109                 ++i;
3110                 if (c == QUOTE) {
3111                     buffer.append(c);
3112                     // Fall through and append another QUOTE below
3113                 } else if (c == CURRENCY_SIGN &&
3114                            i<affixPattern.length() &&
3115                            affixPattern.charAt(i) == CURRENCY_SIGN) {
3116                     ++i;
3117                     buffer.append(c);
3118                     // Fall through and append another CURRENCY_SIGN below
3119                 } else if (localized) {
3120                     switch (c) {
3121                     case PATTERN_PERCENT:
3122                         buffer.append(symbols.getPercentText());
3123                         continue;
3124                     case PATTERN_PER_MILLE:
3125                         buffer.append(symbols.getPerMillText());
3126                         continue;
3127                     case PATTERN_MINUS:
3128                         buffer.append(symbols.getMinusSignText());
3129                         continue;
3130                     }
3131                 }
3132                 buffer.append(c);
3133             }
3134         }
3135     }
3136 
3137     /**
3138      * Append an affix to the given StringBuffer, using quotes if
3139      * there are special characters.  Single quotes themselves must be
3140      * escaped in either case.
3141      */
3142     private void appendAffix(StringBuffer buffer, String affix, boolean localized) {
3143         boolean needQuote;
3144         if (localized) {
3145             needQuote = affix.indexOf(symbols.getZeroDigit()) >= 0
3146                 || affix.indexOf(symbols.getGroupingSeparator()) >= 0
3147                 || affix.indexOf(symbols.getDecimalSeparator()) >= 0
3148                 || affix.indexOf(symbols.getPercentText()) >= 0
3149                 || affix.indexOf(symbols.getPerMillText()) >= 0
3150                 || affix.indexOf(symbols.getDigit()) >= 0
3151                 || affix.indexOf(symbols.getPatternSeparator()) >= 0
3152                 || affix.indexOf(symbols.getMinusSignText()) >= 0
3153                 || affix.indexOf(CURRENCY_SIGN) >= 0;
3154         } else {
3155             needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0
3156                 || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0
3157                 || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0
3158                 || affix.indexOf(PATTERN_PERCENT) >= 0
3159                 || affix.indexOf(PATTERN_PER_MILLE) >= 0
3160                 || affix.indexOf(PATTERN_DIGIT) >= 0
3161                 || affix.indexOf(PATTERN_SEPARATOR) >= 0
3162                 || affix.indexOf(PATTERN_MINUS) >= 0
3163                 || affix.indexOf(CURRENCY_SIGN) >= 0;
3164         }
3165         if (needQuote) buffer.append('\'');
3166         if (affix.indexOf('\'') < 0) buffer.append(affix);
3167         else {
3168             for (int j=0; j<affix.length(); ++j) {
3169                 char c = affix.charAt(j);
3170                 buffer.append(c);
3171                 if (c == '\'') buffer.append(c);
3172             }


3208                                   PATTERN_DIGIT);
3209                 }
3210             }
3211         if (useExponentialNotation)
3212         {
3213             result.append(localized ? symbols.getExponentSeparator() :
3214                   PATTERN_EXPONENT);
3215         for (i=0; i<minExponentDigits; ++i)
3216                     result.append(localized ? symbols.getZeroDigit() :
3217                                   PATTERN_ZERO_DIGIT);
3218         }
3219             if (j == 1) {
3220                 appendAffix(result, posSuffixPattern, positiveSuffix, localized);
3221                 if ((negSuffixPattern == posSuffixPattern && // n == p == null
3222                      negativeSuffix.equals(positiveSuffix))
3223                     || (negSuffixPattern != null &&
3224                         negSuffixPattern.equals(posSuffixPattern))) {
3225                     if ((negPrefixPattern != null && posPrefixPattern != null &&
3226                          negPrefixPattern.equals("'-" + posPrefixPattern)) ||
3227                         (negPrefixPattern == posPrefixPattern && // n == p == null
3228                          negativePrefix.equals(symbols.getMinusSignText() + positivePrefix)))
3229                         break;
3230                 }
3231                 result.append(localized ? symbols.getPatternSeparator() :
3232                               PATTERN_SEPARATOR);
3233             } else appendAffix(result, negSuffixPattern, negativeSuffix, localized);
3234         }
3235         return result.toString();
3236     }
3237 
3238     /**
3239      * Apply the given pattern to this Format object.  A pattern is a
3240      * short-hand specification for the various formatting properties.
3241      * These properties can also be changed individually through the
3242      * various setter methods.
3243      * <p>
3244      * There is no limit to integer digits set
3245      * by this routine, since that is the typical end-user desire;
3246      * use setMaximumInteger if you want to set a real value.
3247      * For negative numbers, use a second pattern, separated by a semicolon
3248      * <P>Example <code>"#,#00.0#"</code> &rarr; 1,234.56


< prev index next >