| 1 | /* DecimalFormat.java -- Formats and parses numbers
|
|---|
| 2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
|
|---|
| 3 |
|
|---|
| 4 | This file is part of GNU Classpath.
|
|---|
| 5 |
|
|---|
| 6 | GNU Classpath is free software; you can redistribute it and/or modify
|
|---|
| 7 | it under the terms of the GNU General Public License as published by
|
|---|
| 8 | the Free Software Foundation; either version 2, or (at your option)
|
|---|
| 9 | any later version.
|
|---|
| 10 |
|
|---|
| 11 | GNU Classpath is distributed in the hope that it will be useful, but
|
|---|
| 12 | WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|---|
| 14 | General Public License for more details.
|
|---|
| 15 |
|
|---|
| 16 | You should have received a copy of the GNU General Public License
|
|---|
| 17 | along with GNU Classpath; see the file COPYING. If not, write to the
|
|---|
| 18 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|---|
| 19 | 02111-1307 USA.
|
|---|
| 20 |
|
|---|
| 21 | Linking this library statically or dynamically with other modules is
|
|---|
| 22 | making a combined work based on this library. Thus, the terms and
|
|---|
| 23 | conditions of the GNU General Public License cover the whole
|
|---|
| 24 | combination.
|
|---|
| 25 |
|
|---|
| 26 | As a special exception, the copyright holders of this library give you
|
|---|
| 27 | permission to link this library with independent modules to produce an
|
|---|
| 28 | executable, regardless of the license terms of these independent
|
|---|
| 29 | modules, and to copy and distribute the resulting executable under
|
|---|
| 30 | terms of your choice, provided that you also meet, for each linked
|
|---|
| 31 | independent module, the terms and conditions of the license of that
|
|---|
| 32 | module. An independent module is a module which is not derived from
|
|---|
| 33 | or based on this library. If you modify this library, you may extend
|
|---|
| 34 | this exception to your version of the library, but you are not
|
|---|
| 35 | obligated to do so. If you do not wish to do so, delete this
|
|---|
| 36 | exception statement from your version. */
|
|---|
| 37 |
|
|---|
| 38 | package java.text;
|
|---|
| 39 |
|
|---|
| 40 | import java.util.Locale;
|
|---|
| 41 | import java.util.MissingResourceException;
|
|---|
| 42 | import java.util.ResourceBundle;
|
|---|
| 43 | import java.io.ObjectInputStream;
|
|---|
| 44 | import java.io.IOException;
|
|---|
| 45 |
|
|---|
| 46 | /**
|
|---|
| 47 | * @author Tom Tromey <[email protected]>
|
|---|
| 48 | * @date March 4, 1999
|
|---|
| 49 | */
|
|---|
| 50 | /* Written using "Java Class Libraries", 2nd edition, plus online
|
|---|
| 51 | * API docs for JDK 1.2 from http://www.javasoft.com.
|
|---|
| 52 | * Status: Believed complete and correct to 1.2.
|
|---|
| 53 | * Note however that the docs are very unclear about how format parsing
|
|---|
| 54 | * should work. No doubt there are problems here.
|
|---|
| 55 | */
|
|---|
| 56 | public class DecimalFormat extends NumberFormat
|
|---|
| 57 | {
|
|---|
| 58 | // This is a helper for applyPatternWithSymbols. It reads a prefix
|
|---|
| 59 | // or a suffix. It can cause some side-effects.
|
|---|
| 60 | private final int scanFix (String pattern, int index, StringBuffer buf,
|
|---|
| 61 | String patChars, DecimalFormatSymbols syms,
|
|---|
| 62 | boolean is_suffix)
|
|---|
| 63 | {
|
|---|
| 64 | int len = pattern.length();
|
|---|
| 65 | buf.setLength(0);
|
|---|
| 66 | boolean multiplierSet = false;
|
|---|
| 67 | while (index < len)
|
|---|
| 68 | {
|
|---|
| 69 | char c = pattern.charAt(index);
|
|---|
| 70 | if (c == '\'' && index + 1 < len
|
|---|
| 71 | && pattern.charAt(index + 1) == '\'')
|
|---|
| 72 | {
|
|---|
| 73 | buf.append(c);
|
|---|
| 74 | ++index;
|
|---|
| 75 | }
|
|---|
| 76 | else if (c == '\'' && index + 2 < len
|
|---|
| 77 | && pattern.charAt(index + 2) == '\'')
|
|---|
| 78 | {
|
|---|
| 79 | buf.append(pattern.charAt(index + 1));
|
|---|
| 80 | index += 2;
|
|---|
| 81 | }
|
|---|
| 82 | else if (c == '\u00a4')
|
|---|
| 83 | {
|
|---|
| 84 | if (index + 1 < len && pattern.charAt(index + 1) == '\u00a4')
|
|---|
| 85 | {
|
|---|
| 86 | buf.append(syms.getInternationalCurrencySymbol());
|
|---|
| 87 | ++index;
|
|---|
| 88 | }
|
|---|
| 89 | else
|
|---|
| 90 | buf.append(syms.getCurrencySymbol());
|
|---|
| 91 | }
|
|---|
| 92 | else if (is_suffix && c == syms.getPercent())
|
|---|
| 93 | {
|
|---|
| 94 | if (multiplierSet)
|
|---|
| 95 | throw new IllegalArgumentException ("multiplier already set " +
|
|---|
| 96 | "- index: " + index);
|
|---|
| 97 | multiplierSet = true;
|
|---|
| 98 | multiplier = 100;
|
|---|
| 99 | buf.append(c);
|
|---|
| 100 | }
|
|---|
| 101 | else if (is_suffix && c == syms.getPerMill())
|
|---|
| 102 | {
|
|---|
| 103 | if (multiplierSet)
|
|---|
| 104 | throw new IllegalArgumentException ("multiplier already set " +
|
|---|
| 105 | "- index: " + index);
|
|---|
| 106 | multiplierSet = true;
|
|---|
| 107 | multiplier = 1000;
|
|---|
| 108 | buf.append(c);
|
|---|
| 109 | }
|
|---|
| 110 | else if (patChars.indexOf(c) != -1)
|
|---|
| 111 | {
|
|---|
| 112 | // This is a pattern character.
|
|---|
| 113 | break;
|
|---|
| 114 | }
|
|---|
| 115 | else
|
|---|
| 116 | buf.append(c);
|
|---|
| 117 | ++index;
|
|---|
| 118 | }
|
|---|
| 119 |
|
|---|
| 120 | return index;
|
|---|
| 121 | }
|
|---|
| 122 |
|
|---|
| 123 | // A helper which reads a number format.
|
|---|
| 124 | private final int scanFormat (String pattern, int index,
|
|---|
| 125 | String patChars, DecimalFormatSymbols syms,
|
|---|
| 126 | boolean is_positive)
|
|---|
| 127 | {
|
|---|
| 128 | int max = pattern.length();
|
|---|
| 129 |
|
|---|
| 130 | int countSinceGroup = 0;
|
|---|
| 131 | int zeroCount = 0;
|
|---|
| 132 | boolean saw_group = false;
|
|---|
| 133 |
|
|---|
| 134 | //
|
|---|
| 135 | // Scan integer part.
|
|---|
| 136 | //
|
|---|
| 137 | while (index < max)
|
|---|
| 138 | {
|
|---|
| 139 | char c = pattern.charAt(index);
|
|---|
| 140 |
|
|---|
| 141 | if (c == syms.getDigit())
|
|---|
| 142 | {
|
|---|
| 143 | if (zeroCount > 0)
|
|---|
| 144 | throw new IllegalArgumentException ("digit mark following " +
|
|---|
| 145 | "zero - index: " + index);
|
|---|
| 146 | ++countSinceGroup;
|
|---|
| 147 | }
|
|---|
| 148 | else if (c == syms.getZeroDigit())
|
|---|
| 149 | {
|
|---|
| 150 | ++zeroCount;
|
|---|
| 151 | ++countSinceGroup;
|
|---|
| 152 | }
|
|---|
| 153 | else if (c == syms.getGroupingSeparator())
|
|---|
| 154 | {
|
|---|
| 155 | countSinceGroup = 0;
|
|---|
| 156 | saw_group = true;
|
|---|
| 157 | }
|
|---|
| 158 | else
|
|---|
| 159 | break;
|
|---|
| 160 |
|
|---|
| 161 | ++index;
|
|---|
| 162 | }
|
|---|
| 163 |
|
|---|
| 164 | // We can only side-effect when parsing the positive format.
|
|---|
| 165 | if (is_positive)
|
|---|
| 166 | {
|
|---|
| 167 | groupingUsed = saw_group;
|
|---|
| 168 | groupingSize = (byte) countSinceGroup;
|
|---|
| 169 | minimumIntegerDigits = zeroCount;
|
|---|
| 170 | }
|
|---|
| 171 |
|
|---|
| 172 | // Early termination.
|
|---|
| 173 | if (index == max || pattern.charAt(index) == syms.getGroupingSeparator())
|
|---|
| 174 | {
|
|---|
| 175 | if (is_positive)
|
|---|
| 176 | decimalSeparatorAlwaysShown = false;
|
|---|
| 177 | return index;
|
|---|
| 178 | }
|
|---|
| 179 |
|
|---|
| 180 | if (pattern.charAt(index) == syms.getDecimalSeparator())
|
|---|
| 181 | {
|
|---|
| 182 | ++index;
|
|---|
| 183 |
|
|---|
| 184 | //
|
|---|
| 185 | // Scan fractional part.
|
|---|
| 186 | //
|
|---|
| 187 | int hashCount = 0;
|
|---|
| 188 | zeroCount = 0;
|
|---|
| 189 | while (index < max)
|
|---|
| 190 | {
|
|---|
| 191 | char c = pattern.charAt(index);
|
|---|
| 192 | if (c == syms.getZeroDigit())
|
|---|
| 193 | {
|
|---|
| 194 | if (hashCount > 0)
|
|---|
| 195 | throw new IllegalArgumentException ("zero mark " +
|
|---|
| 196 | "following digit - index: " + index);
|
|---|
| 197 | ++zeroCount;
|
|---|
| 198 | }
|
|---|
| 199 | else if (c == syms.getDigit())
|
|---|
| 200 | {
|
|---|
| 201 | ++hashCount;
|
|---|
| 202 | }
|
|---|
| 203 | else if (c != syms.getExponential()
|
|---|
| 204 | && c != syms.getPatternSeparator()
|
|---|
| 205 | && patChars.indexOf(c) != -1)
|
|---|
| 206 | throw new IllegalArgumentException ("unexpected special " +
|
|---|
| 207 | "character - index: " + index);
|
|---|
| 208 | else
|
|---|
| 209 | break;
|
|---|
| 210 |
|
|---|
| 211 | ++index;
|
|---|
| 212 | }
|
|---|
| 213 |
|
|---|
| 214 | if (is_positive)
|
|---|
| 215 | {
|
|---|
| 216 | maximumFractionDigits = hashCount + zeroCount;
|
|---|
| 217 | minimumFractionDigits = zeroCount;
|
|---|
| 218 | }
|
|---|
| 219 |
|
|---|
| 220 | if (index == max)
|
|---|
| 221 | return index;
|
|---|
| 222 | }
|
|---|
| 223 |
|
|---|
| 224 | if (pattern.charAt(index) == syms.getExponential())
|
|---|
| 225 | {
|
|---|
| 226 | //
|
|---|
| 227 | // Scan exponential format.
|
|---|
| 228 | //
|
|---|
| 229 | zeroCount = 0;
|
|---|
| 230 | ++index;
|
|---|
| 231 | while (index < max)
|
|---|
| 232 | {
|
|---|
| 233 | char c = pattern.charAt(index);
|
|---|
| 234 | if (c == syms.getZeroDigit())
|
|---|
| 235 | ++zeroCount;
|
|---|
| 236 | else if (c == syms.getDigit())
|
|---|
| 237 | {
|
|---|
| 238 | if (zeroCount > 0)
|
|---|
| 239 | throw new
|
|---|
| 240 | IllegalArgumentException ("digit mark following zero " +
|
|---|
| 241 | "in exponent - index: " +
|
|---|
| 242 | index);
|
|---|
| 243 | }
|
|---|
| 244 | else if (patChars.indexOf(c) != -1)
|
|---|
| 245 | throw new IllegalArgumentException ("unexpected special " +
|
|---|
| 246 | "character - index: " +
|
|---|
| 247 | index);
|
|---|
| 248 | else
|
|---|
| 249 | break;
|
|---|
| 250 |
|
|---|
| 251 | ++index;
|
|---|
| 252 | }
|
|---|
| 253 |
|
|---|
| 254 | if (is_positive)
|
|---|
| 255 | {
|
|---|
| 256 | useExponentialNotation = true;
|
|---|
| 257 | minExponentDigits = (byte) zeroCount;
|
|---|
| 258 | }
|
|---|
| 259 | }
|
|---|
| 260 |
|
|---|
| 261 | return index;
|
|---|
| 262 | }
|
|---|
| 263 |
|
|---|
| 264 | // This helper function creates a string consisting of all the
|
|---|
| 265 | // characters which can appear in a pattern and must be quoted.
|
|---|
| 266 | private final String patternChars (DecimalFormatSymbols syms)
|
|---|
| 267 | {
|
|---|
| 268 | StringBuffer buf = new StringBuffer ();
|
|---|
| 269 | buf.append(syms.getDecimalSeparator());
|
|---|
| 270 | buf.append(syms.getDigit());
|
|---|
| 271 | buf.append(syms.getExponential());
|
|---|
| 272 | buf.append(syms.getGroupingSeparator());
|
|---|
| 273 | // Adding this one causes pattern application to fail.
|
|---|
| 274 | // Of course, omitting is causes toPattern to fail.
|
|---|
| 275 | // ... but we already have bugs there. FIXME.
|
|---|
| 276 | // buf.append(syms.getMinusSign());
|
|---|
| 277 | buf.append(syms.getPatternSeparator());
|
|---|
| 278 | buf.append(syms.getPercent());
|
|---|
| 279 | buf.append(syms.getPerMill());
|
|---|
| 280 | buf.append(syms.getZeroDigit());
|
|---|
| 281 | buf.append('\u00a4');
|
|---|
| 282 | return buf.toString();
|
|---|
| 283 | }
|
|---|
| 284 |
|
|---|
| 285 | private final void applyPatternWithSymbols (String pattern,
|
|---|
| 286 | DecimalFormatSymbols syms)
|
|---|
| 287 | {
|
|---|
| 288 | // Initialize to the state the parser expects.
|
|---|
| 289 | negativePrefix = "";
|
|---|
| 290 | negativeSuffix = "";
|
|---|
| 291 | positivePrefix = "";
|
|---|
| 292 | positiveSuffix = "";
|
|---|
| 293 | decimalSeparatorAlwaysShown = false;
|
|---|
| 294 | groupingSize = 0;
|
|---|
| 295 | minExponentDigits = 0;
|
|---|
| 296 | multiplier = 1;
|
|---|
| 297 | useExponentialNotation = false;
|
|---|
| 298 | groupingUsed = false;
|
|---|
| 299 | maximumFractionDigits = 0;
|
|---|
| 300 | maximumIntegerDigits = 309;
|
|---|
| 301 | minimumFractionDigits = 0;
|
|---|
| 302 | minimumIntegerDigits = 1;
|
|---|
| 303 |
|
|---|
| 304 | StringBuffer buf = new StringBuffer ();
|
|---|
| 305 | String patChars = patternChars (syms);
|
|---|
| 306 |
|
|---|
| 307 | int max = pattern.length();
|
|---|
| 308 | int index = scanFix (pattern, 0, buf, patChars, syms, false);
|
|---|
| 309 | positivePrefix = buf.toString();
|
|---|
| 310 |
|
|---|
| 311 | index = scanFormat (pattern, index, patChars, syms, true);
|
|---|
| 312 |
|
|---|
| 313 | index = scanFix (pattern, index, buf, patChars, syms, true);
|
|---|
| 314 | positiveSuffix = buf.toString();
|
|---|
| 315 |
|
|---|
| 316 | if (index == pattern.length())
|
|---|
| 317 | {
|
|---|
| 318 | // No negative info.
|
|---|
| 319 | negativePrefix = null;
|
|---|
| 320 | negativeSuffix = null;
|
|---|
| 321 | }
|
|---|
| 322 | else
|
|---|
| 323 | {
|
|---|
| 324 | if (pattern.charAt(index) != syms.getPatternSeparator())
|
|---|
| 325 | throw new IllegalArgumentException ("separator character " +
|
|---|
| 326 | "expected - index: " + index);
|
|---|
| 327 |
|
|---|
| 328 | index = scanFix (pattern, index + 1, buf, patChars, syms, false);
|
|---|
| 329 | negativePrefix = buf.toString();
|
|---|
| 330 |
|
|---|
| 331 | // We parse the negative format for errors but we don't let
|
|---|
| 332 | // it side-effect this object.
|
|---|
| 333 | index = scanFormat (pattern, index, patChars, syms, false);
|
|---|
| 334 |
|
|---|
| 335 | index = scanFix (pattern, index, buf, patChars, syms, true);
|
|---|
| 336 | negativeSuffix = buf.toString();
|
|---|
| 337 |
|
|---|
| 338 | if (index != pattern.length())
|
|---|
| 339 | throw new IllegalArgumentException ("end of pattern expected " +
|
|---|
| 340 | "- index: " + index);
|
|---|
| 341 | }
|
|---|
| 342 | }
|
|---|
| 343 |
|
|---|
| 344 | public void applyLocalizedPattern (String pattern)
|
|---|
| 345 | {
|
|---|
| 346 | // JCL p. 638 claims this throws a ParseException but p. 629
|
|---|
| 347 | // contradicts this. Empirical tests with patterns of "0,###.0"
|
|---|
| 348 | // and "#.#.#" corroborate the p. 629 statement that an
|
|---|
| 349 | // IllegalArgumentException is thrown.
|
|---|
| 350 | applyPatternWithSymbols (pattern, symbols);
|
|---|
| 351 | }
|
|---|
| 352 |
|
|---|
| 353 | public void applyPattern (String pattern)
|
|---|
| 354 | {
|
|---|
| 355 | // JCL p. 638 claims this throws a ParseException but p. 629
|
|---|
| 356 | // contradicts this. Empirical tests with patterns of "0,###.0"
|
|---|
| 357 | // and "#.#.#" corroborate the p. 629 statement that an
|
|---|
| 358 | // IllegalArgumentException is thrown.
|
|---|
| 359 | applyPatternWithSymbols (pattern, nonLocalizedSymbols);
|
|---|
| 360 | }
|
|---|
| 361 |
|
|---|
| 362 | public Object clone ()
|
|---|
| 363 | {
|
|---|
| 364 | DecimalFormat c = (DecimalFormat) super.clone ();
|
|---|
| 365 | c.symbols = (DecimalFormatSymbols) symbols.clone ();
|
|---|
| 366 | return c;
|
|---|
| 367 | }
|
|---|
| 368 |
|
|---|
| 369 | public DecimalFormat ()
|
|---|
| 370 | {
|
|---|
| 371 | this ("#,##0.###");
|
|---|
| 372 | }
|
|---|
| 373 |
|
|---|
| 374 | public DecimalFormat (String pattern)
|
|---|
| 375 | {
|
|---|
| 376 | this (pattern, new DecimalFormatSymbols ());
|
|---|
| 377 | }
|
|---|
| 378 |
|
|---|
| 379 | public DecimalFormat (String pattern, DecimalFormatSymbols symbols)
|
|---|
| 380 | {
|
|---|
| 381 | this.symbols = symbols;
|
|---|
| 382 | applyPattern (pattern);
|
|---|
| 383 | }
|
|---|
| 384 |
|
|---|
| 385 | private final boolean equals (String s1, String s2)
|
|---|
| 386 | {
|
|---|
| 387 | if (s1 == null || s2 == null)
|
|---|
| 388 | return s1 == s2;
|
|---|
| 389 | return s1.equals(s2);
|
|---|
| 390 | }
|
|---|
| 391 |
|
|---|
| 392 | public boolean equals (Object obj)
|
|---|
| 393 | {
|
|---|
| 394 | if (! (obj instanceof DecimalFormat))
|
|---|
| 395 | return false;
|
|---|
| 396 | DecimalFormat dup = (DecimalFormat) obj;
|
|---|
| 397 | return (decimalSeparatorAlwaysShown == dup.decimalSeparatorAlwaysShown
|
|---|
| 398 | && groupingSize == dup.groupingSize
|
|---|
| 399 | && minExponentDigits == dup.minExponentDigits
|
|---|
| 400 | && multiplier == dup.multiplier
|
|---|
| 401 | && equals(negativePrefix, dup.negativePrefix)
|
|---|
| 402 | && equals(negativeSuffix, dup.negativeSuffix)
|
|---|
| 403 | && equals(positivePrefix, dup.positivePrefix)
|
|---|
| 404 | && equals(positiveSuffix, dup.positiveSuffix)
|
|---|
| 405 | && symbols.equals(dup.symbols)
|
|---|
| 406 | && useExponentialNotation == dup.useExponentialNotation);
|
|---|
| 407 | }
|
|---|
| 408 |
|
|---|
| 409 | public StringBuffer format (double number, StringBuffer dest,
|
|---|
| 410 | FieldPosition fieldPos)
|
|---|
| 411 | {
|
|---|
| 412 | // A very special case.
|
|---|
| 413 | if (Double.isNaN(number))
|
|---|
| 414 | {
|
|---|
| 415 | dest.append(symbols.getNaN());
|
|---|
| 416 | if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD)
|
|---|
| 417 | {
|
|---|
| 418 | int index = dest.length();
|
|---|
| 419 | fieldPos.setBeginIndex(index - symbols.getNaN().length());
|
|---|
| 420 | fieldPos.setEndIndex(index);
|
|---|
| 421 | }
|
|---|
| 422 | return dest;
|
|---|
| 423 | }
|
|---|
| 424 |
|
|---|
| 425 | boolean is_neg = number < 0;
|
|---|
| 426 | if (is_neg)
|
|---|
| 427 | {
|
|---|
| 428 | if (negativePrefix != null)
|
|---|
| 429 | dest.append(negativePrefix);
|
|---|
| 430 | else
|
|---|
| 431 | {
|
|---|
| 432 | dest.append(symbols.getMinusSign());
|
|---|
| 433 | dest.append(positivePrefix);
|
|---|
| 434 | }
|
|---|
| 435 | number = - number;
|
|---|
| 436 | }
|
|---|
| 437 | else
|
|---|
| 438 | dest.append(positivePrefix);
|
|---|
| 439 |
|
|---|
| 440 | int integerBeginIndex = dest.length();
|
|---|
| 441 | int integerEndIndex = 0;
|
|---|
| 442 | if (Double.isInfinite (number))
|
|---|
| 443 | {
|
|---|
| 444 | dest.append(symbols.getInfinity());
|
|---|
| 445 | integerEndIndex = dest.length();
|
|---|
| 446 | }
|
|---|
| 447 | else
|
|---|
| 448 | {
|
|---|
| 449 | number *= multiplier;
|
|---|
| 450 |
|
|---|
| 451 | // Compute exponent.
|
|---|
| 452 | long exponent = 0;
|
|---|
| 453 | double baseNumber;
|
|---|
| 454 | if (useExponentialNotation)
|
|---|
| 455 | {
|
|---|
| 456 | exponent = (long) Math.floor (Math.log(number) / Math.log(10));
|
|---|
| 457 | if (minimumIntegerDigits > 0)
|
|---|
| 458 | exponent -= minimumIntegerDigits - 1;
|
|---|
| 459 | baseNumber = (long) (number / Math.pow(10.0, exponent));
|
|---|
| 460 | }
|
|---|
| 461 | else
|
|---|
| 462 | baseNumber = number;
|
|---|
| 463 |
|
|---|
| 464 | // Round to the correct number of digits.
|
|---|
| 465 | baseNumber += 5 * Math.pow(10.0, - maximumFractionDigits - 1);
|
|---|
| 466 |
|
|---|
| 467 | int index = dest.length();
|
|---|
| 468 | double intPart = Math.floor(baseNumber);
|
|---|
| 469 | int count = 0;
|
|---|
| 470 | while (count < maximumIntegerDigits
|
|---|
| 471 | && (intPart > 0 || count < minimumIntegerDigits))
|
|---|
| 472 | {
|
|---|
| 473 | long dig = (long) (intPart % 10);
|
|---|
| 474 | intPart = Math.floor(intPart / 10);
|
|---|
| 475 |
|
|---|
| 476 | // Append group separator if required.
|
|---|
| 477 | if (groupingUsed && count > 0 && count % groupingSize == 0)
|
|---|
| 478 | dest.insert(index, symbols.getGroupingSeparator());
|
|---|
| 479 |
|
|---|
| 480 | dest.insert(index, (char) (symbols.getZeroDigit() + dig));
|
|---|
| 481 |
|
|---|
| 482 | ++count;
|
|---|
| 483 | }
|
|---|
| 484 |
|
|---|
| 485 | integerEndIndex = dest.length();
|
|---|
| 486 |
|
|---|
| 487 | int decimal_index = integerEndIndex;
|
|---|
| 488 | int consecutive_zeros = 0;
|
|---|
| 489 | int total_digits = 0;
|
|---|
| 490 |
|
|---|
| 491 | // Strip integer part from NUMBER.
|
|---|
| 492 | double fracPart = baseNumber - Math.floor(baseNumber);
|
|---|
| 493 | for (count = 0;
|
|---|
| 494 | count < maximumFractionDigits
|
|---|
| 495 | && (fracPart != 0 || count < minimumFractionDigits);
|
|---|
| 496 | ++count)
|
|---|
| 497 | {
|
|---|
| 498 | ++total_digits;
|
|---|
| 499 | fracPart *= 10;
|
|---|
| 500 | long dig = (long) fracPart;
|
|---|
| 501 | if (dig == 0)
|
|---|
| 502 | ++consecutive_zeros;
|
|---|
| 503 | else
|
|---|
| 504 | consecutive_zeros = 0;
|
|---|
| 505 | dest.append((char) (symbols.getZeroDigit() + dig));
|
|---|
| 506 |
|
|---|
| 507 | // Strip integer part from FRACPART.
|
|---|
| 508 | fracPart = fracPart - Math.floor (fracPart);
|
|---|
| 509 | }
|
|---|
| 510 |
|
|---|
| 511 | // Strip extraneous trailing `0's. We can't always detect
|
|---|
| 512 | // these in the loop.
|
|---|
| 513 | int extra_zeros = Math.min (consecutive_zeros,
|
|---|
| 514 | total_digits - minimumFractionDigits);
|
|---|
| 515 | if (extra_zeros > 0)
|
|---|
| 516 | {
|
|---|
| 517 | dest.setLength(dest.length() - extra_zeros);
|
|---|
| 518 | total_digits -= extra_zeros;
|
|---|
| 519 | }
|
|---|
| 520 |
|
|---|
| 521 | // If required, add the decimal symbol.
|
|---|
| 522 | if (decimalSeparatorAlwaysShown
|
|---|
| 523 | || total_digits > 0)
|
|---|
| 524 | {
|
|---|
| 525 | dest.insert(decimal_index, symbols.getDecimalSeparator());
|
|---|
| 526 | if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD)
|
|---|
| 527 | {
|
|---|
| 528 | fieldPos.setBeginIndex(decimal_index + 1);
|
|---|
| 529 | fieldPos.setEndIndex(dest.length());
|
|---|
| 530 | }
|
|---|
| 531 | }
|
|---|
| 532 |
|
|---|
| 533 | // Finally, print the exponent.
|
|---|
| 534 | if (useExponentialNotation)
|
|---|
| 535 | {
|
|---|
| 536 | dest.append(symbols.getExponential());
|
|---|
| 537 | if (exponent < 0)
|
|---|
| 538 | {
|
|---|
| 539 | dest.append (symbols.getMinusSign ());
|
|---|
| 540 | exponent = - exponent;
|
|---|
| 541 | }
|
|---|
| 542 | index = dest.length();
|
|---|
| 543 | for (count = 0;
|
|---|
| 544 | exponent > 0 || count < minExponentDigits;
|
|---|
| 545 | ++count)
|
|---|
| 546 | {
|
|---|
| 547 | long dig = exponent % 10;
|
|---|
| 548 | exponent /= 10;
|
|---|
| 549 | dest.insert(index, (char) (symbols.getZeroDigit() + dig));
|
|---|
| 550 | }
|
|---|
| 551 | }
|
|---|
| 552 | }
|
|---|
| 553 |
|
|---|
| 554 | if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD)
|
|---|
| 555 | {
|
|---|
| 556 | fieldPos.setBeginIndex(integerBeginIndex);
|
|---|
| 557 | fieldPos.setEndIndex(integerEndIndex);
|
|---|
| 558 | }
|
|---|
| 559 |
|
|---|
| 560 | dest.append((is_neg && negativeSuffix != null)
|
|---|
| 561 | ? negativeSuffix
|
|---|
| 562 | : positiveSuffix);
|
|---|
| 563 | return dest;
|
|---|
| 564 | }
|
|---|
| 565 |
|
|---|
| 566 | public StringBuffer format (long number, StringBuffer dest,
|
|---|
| 567 | FieldPosition fieldPos)
|
|---|
| 568 | {
|
|---|
| 569 | // If using exponential notation, we just format as a double.
|
|---|
| 570 | if (useExponentialNotation)
|
|---|
| 571 | return format ((double) number, dest, fieldPos);
|
|---|
| 572 |
|
|---|
| 573 | boolean is_neg = number < 0;
|
|---|
| 574 | if (is_neg)
|
|---|
| 575 | {
|
|---|
| 576 | if (negativePrefix != null)
|
|---|
| 577 | dest.append(negativePrefix);
|
|---|
| 578 | else
|
|---|
| 579 | {
|
|---|
| 580 | dest.append(symbols.getMinusSign());
|
|---|
| 581 | dest.append(positivePrefix);
|
|---|
| 582 | }
|
|---|
| 583 | number = - number;
|
|---|
| 584 | }
|
|---|
| 585 | else
|
|---|
| 586 | dest.append(positivePrefix);
|
|---|
| 587 |
|
|---|
| 588 | int integerBeginIndex = dest.length();
|
|---|
| 589 | int index = dest.length();
|
|---|
| 590 | int count = 0;
|
|---|
| 591 | while (count < maximumIntegerDigits
|
|---|
| 592 | && (number > 0 || count < minimumIntegerDigits))
|
|---|
| 593 | {
|
|---|
| 594 | long dig = number % 10;
|
|---|
| 595 | number /= 10;
|
|---|
| 596 | // NUMBER and DIG will be less than 0 if the original number
|
|---|
| 597 | // was the most negative long.
|
|---|
| 598 | if (dig < 0)
|
|---|
| 599 | {
|
|---|
| 600 | dig = - dig;
|
|---|
| 601 | number = - number;
|
|---|
| 602 | }
|
|---|
| 603 |
|
|---|
| 604 | // Append group separator if required.
|
|---|
| 605 | if (groupingUsed && count > 0 && count % groupingSize == 0)
|
|---|
| 606 | dest.insert(index, symbols.getGroupingSeparator());
|
|---|
| 607 |
|
|---|
| 608 | dest.insert(index, (char) (symbols.getZeroDigit() + dig));
|
|---|
| 609 |
|
|---|
| 610 | ++count;
|
|---|
| 611 | }
|
|---|
| 612 |
|
|---|
| 613 | if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD)
|
|---|
| 614 | {
|
|---|
| 615 | fieldPos.setBeginIndex(integerBeginIndex);
|
|---|
| 616 | fieldPos.setEndIndex(dest.length());
|
|---|
| 617 | }
|
|---|
| 618 |
|
|---|
| 619 | if (decimalSeparatorAlwaysShown || minimumFractionDigits > 0)
|
|---|
| 620 | {
|
|---|
| 621 | dest.append(symbols.getDecimalSeparator());
|
|---|
| 622 | if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD)
|
|---|
| 623 | {
|
|---|
| 624 | fieldPos.setBeginIndex(dest.length());
|
|---|
| 625 | fieldPos.setEndIndex(dest.length() + minimumFractionDigits);
|
|---|
| 626 | }
|
|---|
| 627 | }
|
|---|
| 628 |
|
|---|
| 629 | for (count = 0; count < minimumFractionDigits; ++count)
|
|---|
| 630 | dest.append(symbols.getZeroDigit());
|
|---|
| 631 |
|
|---|
| 632 | dest.append((is_neg && negativeSuffix != null)
|
|---|
| 633 | ? negativeSuffix
|
|---|
| 634 | : positiveSuffix);
|
|---|
| 635 | return dest;
|
|---|
| 636 | }
|
|---|
| 637 |
|
|---|
| 638 | public DecimalFormatSymbols getDecimalFormatSymbols ()
|
|---|
| 639 | {
|
|---|
| 640 | return symbols;
|
|---|
| 641 | }
|
|---|
| 642 |
|
|---|
| 643 | public int getGroupingSize ()
|
|---|
| 644 | {
|
|---|
| 645 | return groupingSize;
|
|---|
| 646 | }
|
|---|
| 647 |
|
|---|
| 648 | public int getMultiplier ()
|
|---|
| 649 | {
|
|---|
| 650 | return multiplier;
|
|---|
| 651 | }
|
|---|
| 652 |
|
|---|
| 653 | public String getNegativePrefix ()
|
|---|
| 654 | {
|
|---|
| 655 | return negativePrefix;
|
|---|
| 656 | }
|
|---|
| 657 |
|
|---|
| 658 | public String getNegativeSuffix ()
|
|---|
| 659 | {
|
|---|
| 660 | return negativeSuffix;
|
|---|
| 661 | }
|
|---|
| 662 |
|
|---|
| 663 | public String getPositivePrefix ()
|
|---|
| 664 | {
|
|---|
| 665 | return positivePrefix;
|
|---|
| 666 | }
|
|---|
| 667 |
|
|---|
| 668 | public String getPositiveSuffix ()
|
|---|
| 669 | {
|
|---|
| 670 | return positiveSuffix;
|
|---|
| 671 | }
|
|---|
| 672 |
|
|---|
| 673 | public int hashCode ()
|
|---|
| 674 | {
|
|---|
| 675 | int hash = (negativeSuffix.hashCode() ^ negativePrefix.hashCode()
|
|---|
| 676 | ^positivePrefix.hashCode() ^ positiveSuffix.hashCode());
|
|---|
| 677 | // FIXME.
|
|---|
| 678 | return hash;
|
|---|
| 679 | }
|
|---|
| 680 |
|
|---|
| 681 | public boolean isDecimalSeparatorAlwaysShown ()
|
|---|
| 682 | {
|
|---|
| 683 | return decimalSeparatorAlwaysShown;
|
|---|
| 684 | }
|
|---|
| 685 |
|
|---|
| 686 | public Number parse (String str, ParsePosition pos)
|
|---|
| 687 | {
|
|---|
| 688 | // Our strategy is simple: copy the text into a buffer,
|
|---|
| 689 | // translating or omitting locale-specific information. Then
|
|---|
| 690 | // let Double or Long convert the number for us.
|
|---|
| 691 |
|
|---|
| 692 | boolean is_neg = false;
|
|---|
| 693 | int index = pos.getIndex();
|
|---|
| 694 | StringBuffer buf = new StringBuffer ();
|
|---|
| 695 |
|
|---|
| 696 | // We have to check both prefixes, because one might be empty.
|
|---|
| 697 | // We want to pick the longest prefix that matches.
|
|---|
| 698 | boolean got_pos = str.startsWith(positivePrefix, index);
|
|---|
| 699 | String np = (negativePrefix != null
|
|---|
| 700 | ? negativePrefix
|
|---|
| 701 | : positivePrefix + symbols.getMinusSign());
|
|---|
| 702 | boolean got_neg = str.startsWith(np, index);
|
|---|
| 703 |
|
|---|
| 704 | if (got_pos && got_neg)
|
|---|
| 705 | {
|
|---|
| 706 | // By checking this way, we preserve ambiguity in the case
|
|---|
| 707 | // where the negative format differs only in suffix. We
|
|---|
| 708 | // check this again later.
|
|---|
| 709 | if (np.length() > positivePrefix.length())
|
|---|
| 710 | {
|
|---|
| 711 | is_neg = true;
|
|---|
| 712 | index += np.length();
|
|---|
| 713 | }
|
|---|
| 714 | else
|
|---|
| 715 | index += positivePrefix.length();
|
|---|
| 716 | }
|
|---|
| 717 | else if (got_neg)
|
|---|
| 718 | {
|
|---|
| 719 | is_neg = true;
|
|---|
| 720 | index += np.length();
|
|---|
| 721 | }
|
|---|
| 722 | else if (got_pos)
|
|---|
| 723 | index += positivePrefix.length();
|
|---|
| 724 | else
|
|---|
| 725 | {
|
|---|
| 726 | pos.setErrorIndex (index);
|
|---|
| 727 | return null;
|
|---|
| 728 | }
|
|---|
| 729 |
|
|---|
| 730 | // FIXME: handle Inf and NaN.
|
|---|
| 731 |
|
|---|
| 732 | // FIXME: do we have to respect minimum/maxmimum digit stuff?
|
|---|
| 733 | // What about leading zeros? What about multiplier?
|
|---|
| 734 |
|
|---|
| 735 | int start_index = index;
|
|---|
| 736 | int max = str.length();
|
|---|
| 737 | char zero = symbols.getZeroDigit();
|
|---|
| 738 | int last_group = -1;
|
|---|
| 739 | boolean int_part = true;
|
|---|
| 740 | boolean exp_part = false;
|
|---|
| 741 | for (; index < max; ++index)
|
|---|
| 742 | {
|
|---|
| 743 | char c = str.charAt(index);
|
|---|
| 744 |
|
|---|
| 745 | // FIXME: what about grouping size?
|
|---|
| 746 | if (groupingUsed && c == symbols.getGroupingSeparator())
|
|---|
| 747 | {
|
|---|
| 748 | if (last_group != -1
|
|---|
| 749 | && (index - last_group) % groupingSize != 0)
|
|---|
| 750 | {
|
|---|
| 751 | pos.setErrorIndex(index);
|
|---|
| 752 | return null;
|
|---|
| 753 | }
|
|---|
| 754 | last_group = index;
|
|---|
| 755 | }
|
|---|
| 756 | else if (c >= zero && c <= zero + 9)
|
|---|
| 757 | {
|
|---|
| 758 | buf.append((char) (c - zero + '0'));
|
|---|
| 759 | exp_part = false;
|
|---|
| 760 | }
|
|---|
| 761 | else if (parseIntegerOnly)
|
|---|
| 762 | break;
|
|---|
| 763 | else if (c == symbols.getDecimalSeparator())
|
|---|
| 764 | {
|
|---|
| 765 | if (last_group != -1
|
|---|
| 766 | && (index - last_group) % groupingSize != 0)
|
|---|
| 767 | {
|
|---|
| 768 | pos.setErrorIndex(index);
|
|---|
| 769 | return null;
|
|---|
| 770 | }
|
|---|
| 771 | buf.append('.');
|
|---|
| 772 | int_part = false;
|
|---|
| 773 | }
|
|---|
| 774 | else if (c == symbols.getExponential())
|
|---|
| 775 | {
|
|---|
| 776 | buf.append('E');
|
|---|
| 777 | int_part = false;
|
|---|
| 778 | exp_part = true;
|
|---|
| 779 | }
|
|---|
| 780 | else if (exp_part
|
|---|
| 781 | && (c == '+' || c == '-' || c == symbols.getMinusSign()))
|
|---|
| 782 | {
|
|---|
| 783 | // For exponential notation.
|
|---|
| 784 | buf.append(c);
|
|---|
| 785 | }
|
|---|
| 786 | else
|
|---|
| 787 | break;
|
|---|
| 788 | }
|
|---|
| 789 |
|
|---|
| 790 | if (index == start_index)
|
|---|
| 791 | {
|
|---|
| 792 | // Didn't see any digits.
|
|---|
| 793 | pos.setErrorIndex(index);
|
|---|
| 794 | return null;
|
|---|
| 795 | }
|
|---|
| 796 |
|
|---|
| 797 | // Check the suffix. We must do this before converting the
|
|---|
| 798 | // buffer to a number to handle the case of a number which is
|
|---|
| 799 | // the most negative Long.
|
|---|
| 800 | boolean got_pos_suf = str.startsWith(positiveSuffix, index);
|
|---|
| 801 | String ns = (negativePrefix == null ? positiveSuffix : negativeSuffix);
|
|---|
| 802 | boolean got_neg_suf = str.startsWith(ns, index);
|
|---|
| 803 | if (is_neg)
|
|---|
| 804 | {
|
|---|
| 805 | if (! got_neg_suf)
|
|---|
| 806 | {
|
|---|
| 807 | pos.setErrorIndex(index);
|
|---|
| 808 | return null;
|
|---|
| 809 | }
|
|---|
| 810 | }
|
|---|
| 811 | else if (got_pos && got_neg && got_neg_suf)
|
|---|
| 812 | {
|
|---|
| 813 | is_neg = true;
|
|---|
| 814 | }
|
|---|
| 815 | else if (got_pos != got_pos_suf && got_neg != got_neg_suf)
|
|---|
| 816 | {
|
|---|
| 817 | pos.setErrorIndex(index);
|
|---|
| 818 | return null;
|
|---|
| 819 | }
|
|---|
| 820 |
|
|---|
| 821 | String suffix = is_neg ? ns : positiveSuffix;
|
|---|
| 822 | if (is_neg)
|
|---|
| 823 | buf.insert(0, '-');
|
|---|
| 824 |
|
|---|
| 825 | String t = buf.toString();
|
|---|
| 826 | Number result = null;
|
|---|
| 827 | try
|
|---|
| 828 | {
|
|---|
| 829 | result = new Long (t);
|
|---|
| 830 | }
|
|---|
| 831 | catch (NumberFormatException x1)
|
|---|
| 832 | {
|
|---|
| 833 | try
|
|---|
| 834 | {
|
|---|
| 835 | result = new Double (t);
|
|---|
| 836 | }
|
|---|
| 837 | catch (NumberFormatException x2)
|
|---|
| 838 | {
|
|---|
| 839 | }
|
|---|
| 840 | }
|
|---|
| 841 | if (result == null)
|
|---|
| 842 | {
|
|---|
| 843 | pos.setErrorIndex(index);
|
|---|
| 844 | return null;
|
|---|
| 845 | }
|
|---|
| 846 |
|
|---|
| 847 | pos.setIndex(index + suffix.length());
|
|---|
| 848 |
|
|---|
| 849 | return result;
|
|---|
| 850 | }
|
|---|
| 851 |
|
|---|
| 852 | public void setDecimalFormatSymbols (DecimalFormatSymbols newSymbols)
|
|---|
| 853 | {
|
|---|
| 854 | symbols = newSymbols;
|
|---|
| 855 | }
|
|---|
| 856 |
|
|---|
| 857 | public void setDecimalSeparatorAlwaysShown (boolean newValue)
|
|---|
| 858 | {
|
|---|
| 859 | decimalSeparatorAlwaysShown = newValue;
|
|---|
| 860 | }
|
|---|
| 861 |
|
|---|
| 862 | public void setGroupingSize (int groupSize)
|
|---|
| 863 | {
|
|---|
| 864 | groupingSize = (byte) groupSize;
|
|---|
| 865 | }
|
|---|
| 866 |
|
|---|
| 867 | public void setMaximumFractionDigits (int newValue)
|
|---|
| 868 | {
|
|---|
| 869 | maximumFractionDigits = Math.min(newValue, 340);
|
|---|
| 870 | }
|
|---|
| 871 |
|
|---|
| 872 | public void setMaximumIntegerDigits (int newValue)
|
|---|
| 873 | {
|
|---|
| 874 | maximumIntegerDigits = Math.min(newValue, 309);
|
|---|
| 875 | }
|
|---|
| 876 |
|
|---|
| 877 | public void setMinimumFractionDigits (int newValue)
|
|---|
| 878 | {
|
|---|
| 879 | minimumFractionDigits = Math.min(newValue, 340);
|
|---|
| 880 | }
|
|---|
| 881 |
|
|---|
| 882 | public void setMinimumIntegerDigits (int newValue)
|
|---|
| 883 | {
|
|---|
| 884 | minimumIntegerDigits = Math.min(newValue, 309);
|
|---|
| 885 | }
|
|---|
| 886 |
|
|---|
| 887 | public void setMultiplier (int newValue)
|
|---|
| 888 | {
|
|---|
| 889 | multiplier = newValue;
|
|---|
| 890 | }
|
|---|
| 891 |
|
|---|
| 892 | public void setNegativePrefix (String newValue)
|
|---|
| 893 | {
|
|---|
| 894 | negativePrefix = newValue;
|
|---|
| 895 | }
|
|---|
| 896 |
|
|---|
| 897 | public void setNegativeSuffix (String newValue)
|
|---|
| 898 | {
|
|---|
| 899 | negativeSuffix = newValue;
|
|---|
| 900 | }
|
|---|
| 901 |
|
|---|
| 902 | public void setPositivePrefix (String newValue)
|
|---|
| 903 | {
|
|---|
| 904 | positivePrefix = newValue;
|
|---|
| 905 | }
|
|---|
| 906 |
|
|---|
| 907 | public void setPositiveSuffix (String newValue)
|
|---|
| 908 | {
|
|---|
| 909 | positiveSuffix = newValue;
|
|---|
| 910 | }
|
|---|
| 911 |
|
|---|
| 912 | private final void quoteFix (StringBuffer buf, String text, String patChars)
|
|---|
| 913 | {
|
|---|
| 914 | int len = text.length();
|
|---|
| 915 | for (int index = 0; index < len; ++index)
|
|---|
| 916 | {
|
|---|
| 917 | char c = text.charAt(index);
|
|---|
| 918 | if (patChars.indexOf(c) != -1)
|
|---|
| 919 | {
|
|---|
| 920 | buf.append('\'');
|
|---|
| 921 | buf.append(c);
|
|---|
| 922 | buf.append('\'');
|
|---|
| 923 | }
|
|---|
| 924 | else
|
|---|
| 925 | buf.append(c);
|
|---|
| 926 | }
|
|---|
| 927 | }
|
|---|
| 928 |
|
|---|
| 929 | private final String computePattern (DecimalFormatSymbols syms)
|
|---|
| 930 | {
|
|---|
| 931 | StringBuffer mainPattern = new StringBuffer ();
|
|---|
| 932 | // We have to at least emit a zero for the minimum number of
|
|---|
| 933 | // digits. Past that we need hash marks up to the grouping
|
|---|
| 934 | // separator (and one beyond).
|
|---|
| 935 | int total_digits = Math.max(minimumIntegerDigits,
|
|---|
| 936 | groupingUsed ? groupingSize + 1: 0);
|
|---|
| 937 | for (int i = 0; i < total_digits - minimumIntegerDigits; ++i)
|
|---|
| 938 | mainPattern.append(syms.getDigit());
|
|---|
| 939 | for (int i = total_digits - minimumIntegerDigits; i < total_digits; ++i)
|
|---|
| 940 | mainPattern.append(syms.getZeroDigit());
|
|---|
| 941 | // Inserting the gropuing operator afterwards is easier.
|
|---|
| 942 | if (groupingUsed)
|
|---|
| 943 | mainPattern.insert(mainPattern.length() - groupingSize,
|
|---|
| 944 | syms.getGroupingSeparator());
|
|---|
| 945 | // See if we need decimal info.
|
|---|
| 946 | if (minimumFractionDigits > 0 || maximumFractionDigits > 0
|
|---|
| 947 | || decimalSeparatorAlwaysShown)
|
|---|
| 948 | mainPattern.append(syms.getDecimalSeparator());
|
|---|
| 949 | for (int i = 0; i < minimumFractionDigits; ++i)
|
|---|
| 950 | mainPattern.append(syms.getZeroDigit());
|
|---|
| 951 | for (int i = minimumFractionDigits; i < maximumFractionDigits; ++i)
|
|---|
| 952 | mainPattern.append(syms.getDigit());
|
|---|
| 953 | if (useExponentialNotation)
|
|---|
| 954 | {
|
|---|
| 955 | mainPattern.append(syms.getExponential());
|
|---|
| 956 | for (int i = 0; i < minExponentDigits; ++i)
|
|---|
| 957 | mainPattern.append(syms.getZeroDigit());
|
|---|
| 958 | if (minExponentDigits == 0)
|
|---|
| 959 | mainPattern.append(syms.getDigit());
|
|---|
| 960 | }
|
|---|
| 961 |
|
|---|
| 962 | String main = mainPattern.toString();
|
|---|
| 963 | String patChars = patternChars (syms);
|
|---|
| 964 | mainPattern.setLength(0);
|
|---|
| 965 |
|
|---|
| 966 | quoteFix (mainPattern, positivePrefix, patChars);
|
|---|
| 967 | mainPattern.append(main);
|
|---|
| 968 | quoteFix (mainPattern, positiveSuffix, patChars);
|
|---|
| 969 |
|
|---|
| 970 | if (negativePrefix != null)
|
|---|
| 971 | {
|
|---|
| 972 | quoteFix (mainPattern, negativePrefix, patChars);
|
|---|
| 973 | mainPattern.append(main);
|
|---|
| 974 | quoteFix (mainPattern, negativeSuffix, patChars);
|
|---|
| 975 | }
|
|---|
| 976 |
|
|---|
| 977 | return mainPattern.toString();
|
|---|
| 978 | }
|
|---|
| 979 |
|
|---|
| 980 | public String toLocalizedPattern ()
|
|---|
| 981 | {
|
|---|
| 982 | return computePattern (symbols);
|
|---|
| 983 | }
|
|---|
| 984 |
|
|---|
| 985 | public String toPattern ()
|
|---|
| 986 | {
|
|---|
| 987 | return computePattern (nonLocalizedSymbols);
|
|---|
| 988 | }
|
|---|
| 989 |
|
|---|
| 990 | // These names are fixed by the serialization spec.
|
|---|
| 991 | private boolean decimalSeparatorAlwaysShown;
|
|---|
| 992 | private byte groupingSize;
|
|---|
| 993 | private byte minExponentDigits;
|
|---|
| 994 | private int multiplier;
|
|---|
| 995 | private String negativePrefix;
|
|---|
| 996 | private String negativeSuffix;
|
|---|
| 997 | private String positivePrefix;
|
|---|
| 998 | private String positiveSuffix;
|
|---|
| 999 | private int serialVersionOnStream = 1;
|
|---|
| 1000 | private DecimalFormatSymbols symbols;
|
|---|
| 1001 | private boolean useExponentialNotation;
|
|---|
| 1002 | private static final long serialVersionUID = 864413376551465018L;
|
|---|
| 1003 |
|
|---|
| 1004 | private void readObject(ObjectInputStream stream)
|
|---|
| 1005 | throws IOException, ClassNotFoundException
|
|---|
| 1006 | {
|
|---|
| 1007 | stream.defaultReadObject();
|
|---|
| 1008 | if (serialVersionOnStream < 1)
|
|---|
| 1009 | {
|
|---|
| 1010 | useExponentialNotation = false;
|
|---|
| 1011 | serialVersionOnStream = 1;
|
|---|
| 1012 | }
|
|---|
| 1013 | }
|
|---|
| 1014 |
|
|---|
| 1015 | // The locale-independent pattern symbols happen to be the same as
|
|---|
| 1016 | // the US symbols.
|
|---|
| 1017 | private static final DecimalFormatSymbols nonLocalizedSymbols
|
|---|
| 1018 | = new DecimalFormatSymbols (Locale.US);
|
|---|
| 1019 | }
|
|---|