PatchSet 6504 
Date: 2005/05/15 17:05:16
Author: robilad
Branch: HEAD
Tag: (none) 
Log:
resynced with gnu classpath: text fix

2005-05-15  Dalibor Topic  <[EMAIL PROTECTED]>

        Resynced with GNU Classpath.

        2005-05-02  David Gilbert  <[EMAIL PROTECTED]>

        * java/text/DecimalFormat.java
        (hashCode): Reimplemented and added API docs.

Members: 
        ChangeLog:1.4029->1.4030 
        libraries/javalib/java/text/DecimalFormat.java:INITIAL->1.35 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.4029 kaffe/ChangeLog:1.4030
--- kaffe/ChangeLog:1.4029      Sun May 15 17:03:03 2005
+++ kaffe/ChangeLog     Sun May 15 17:05:16 2005
@@ -2,6 +2,15 @@
 
        Resynced with GNU Classpath.
 
+       2005-05-02  David Gilbert  <[EMAIL PROTECTED]>
+
+        * java/text/DecimalFormat.java
+        (hashCode): Reimplemented and added API docs.
+
+2005-05-15  Dalibor Topic  <[EMAIL PROTECTED]>
+
+       Resynced with GNU Classpath.
+
        2005-04-25  Roman Kennke  <[EMAIL PROTECTED]>
 
         * javax/swing/plaf/metal/MetalBorders.java:
===================================================================
Checking out kaffe/libraries/javalib/java/text/DecimalFormat.java
RCS:  /home/cvs/kaffe/kaffe/libraries/javalib/java/text/DecimalFormat.java,v
VERS: 1.35
***************
--- /dev/null   Sun Aug  4 19:57:58 2002
+++ kaffe/libraries/javalib/java/text/DecimalFormat.java        Sun May 15 
17:17:25 2005
@@ -0,0 +1,1410 @@
+/* DecimalFormat.java -- Formats and parses numbers
+   Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005  Free Software Foundation, 
Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+ 
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.text;
+
+import gnu.java.text.AttributedFormatBuffer;
+import gnu.java.text.FormatBuffer;
+import gnu.java.text.FormatCharacterIterator;
+import gnu.java.text.StringFormatBuffer;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.Currency;
+import java.util.HashMap;
+import java.util.Locale;
+
+/**
+ * @author Tom Tromey ([EMAIL PROTECTED])
+ * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @date March 4, 1999
+ */
+/* Written using "Java Class Libraries", 2nd edition, plus online
+ * API docs for JDK 1.2 from http://www.javasoft.com.
+ * Status:  Believed complete and correct to 1.2.
+ * Note however that the docs are very unclear about how format parsing
+ * should work.  No doubt there are problems here.
+ */
+public class DecimalFormat extends NumberFormat
+{
+  // This is a helper for applyPatternWithSymbols.  It reads a prefix
+  // or a suffix.  It can cause some side-effects.
+  private int scanFix (String pattern, int index, FormatBuffer buf,
+                       String patChars, DecimalFormatSymbols syms,
+                       boolean is_suffix)
+    {
+    int len = pattern.length();
+    boolean quoteStarted = false;
+    buf.clear();
+    
+    boolean multiplierSet = false;
+    while (index < len)
+      {
+       char c = pattern.charAt(index);
+
+       if (quoteStarted)
+         {
+           if (c == '\'')
+             quoteStarted = false;
+           else
+             buf.append(c);
+           index++;
+           continue;
+         }
+
+       if (c == '\'' && index + 1 < len
+           && pattern.charAt(index + 1) == '\'')
+         {
+           buf.append(c);
+           index++;
+         }
+       else if (c == '\'')
+         {
+           quoteStarted = true;
+         }
+       else if (c == '\u00a4')
+         {
+                       /* Currency interpreted later */
+                       buf.append(c);
+               }
+       else if (c == syms.getPercent())
+         {
+           if (multiplierSet)
+             throw new IllegalArgumentException ("multiplier already set " +
+                                                 "- index: " + index);
+           multiplierSet = true;
+           multiplier = 100;
+           buf.append(c, NumberFormat.Field.PERCENT);
+         }
+       else if (c == syms.getPerMill())
+         {
+           if (multiplierSet)
+             throw new IllegalArgumentException ("multiplier already set " +
+                                                 "- index: " + index);
+           multiplierSet = true;
+           multiplier = 1000;
+           buf.append(c, NumberFormat.Field.PERMILLE);
+         }
+       else if (patChars.indexOf(c) != -1)
+         {
+           // This is a pattern character.
+           break;
+         }
+       else
+               {
+                       buf.append(c);
+               }
+       index++;
+      }
+
+    if (quoteStarted)
+      throw new IllegalArgumentException ("pattern is lacking a closing 
quote");
+
+    return index;
+  }
+
+  // A helper which reads a number format.
+  private int scanFormat (String pattern, int index, String patChars,
+                          DecimalFormatSymbols syms, boolean is_positive)
+  {
+    int max = pattern.length();
+
+    int countSinceGroup = 0;
+    int zeroCount = 0;
+    boolean saw_group = false;
+
+    //
+    // Scan integer part.
+    //
+    while (index < max)
+      {
+       char c = pattern.charAt(index);
+
+       if (c == syms.getDigit())
+         {
+           if (zeroCount > 0)
+             throw new IllegalArgumentException ("digit mark following " +
+                                                 "zero - index: " + index);
+           ++countSinceGroup;
+         }
+       else if (c == syms.getZeroDigit())
+         {
+           ++zeroCount;
+           ++countSinceGroup;
+         }
+       else if (c == syms.getGroupingSeparator())
+         {
+           countSinceGroup = 0;
+           saw_group = true;
+         }
+       else
+         break;
+
+       ++index;
+      }
+
+    // We can only side-effect when parsing the positive format.
+    if (is_positive)
+      {
+       groupingUsed = saw_group;
+       groupingSize = (byte) countSinceGroup;
+       minimumIntegerDigits = zeroCount;
+      }
+
+    // Early termination.
+    if (index == max || pattern.charAt(index) == syms.getGroupingSeparator())
+      {
+       if (is_positive)
+         decimalSeparatorAlwaysShown = false;
+       return index;
+      }
+
+    if (pattern.charAt(index) == syms.getDecimalSeparator())
+      {
+       ++index;
+
+       //
+       // Scan fractional part.
+       //
+       int hashCount = 0;
+       zeroCount = 0;
+       while (index < max)
+         {
+           char c = pattern.charAt(index);
+           if (c == syms.getZeroDigit())
+             {
+               if (hashCount > 0)
+                 throw new IllegalArgumentException ("zero mark " +
+                                                     "following digit - index: 
" + index);
+               ++zeroCount;
+             }
+           else if (c == syms.getDigit())
+             {
+               ++hashCount;
+             }
+           else if (c != syms.getExponential()
+                    && c != syms.getPatternSeparator()
+                    && c != syms.getPercent()
+                    && c != syms.getPerMill()
+                    && patChars.indexOf(c) != -1)
+             throw new IllegalArgumentException ("unexpected special " +
+                                                 "character - index: " + 
index);
+           else
+             break;
+
+           ++index;
+         }
+
+       if (is_positive)
+         {
+           maximumFractionDigits = hashCount + zeroCount;
+           minimumFractionDigits = zeroCount;
+         }
+
+       if (index == max)
+         return index;
+      }
+
+    if (pattern.charAt(index) == syms.getExponential())
+      {
+       //
+       // Scan exponential format.
+       //
+       zeroCount = 0;
+       ++index;
+       while (index < max)
+         {
+           char c = pattern.charAt(index);
+           if (c == syms.getZeroDigit())
+             ++zeroCount;
+           else if (c == syms.getDigit())
+             {
+               if (zeroCount > 0)
+                 throw new
+                   IllegalArgumentException ("digit mark following zero " +
+                                             "in exponent - index: " +
+                                             index);
+             }
+           else if (patChars.indexOf(c) != -1)
+             throw new IllegalArgumentException ("unexpected special " +
+                                                 "character - index: " +
+                                                 index);
+           else
+             break;
+
+           ++index;
+         }
+
+       if (is_positive)
+         {
+           useExponentialNotation = true;
+           minExponentDigits = (byte) zeroCount;
+         }
+
+       maximumIntegerDigits = groupingSize;
+       groupingSize = 0;
+       if (maximumIntegerDigits > minimumIntegerDigits && maximumIntegerDigits 
> 0)
+         {
+           minimumIntegerDigits = 1;
+           exponentRound = maximumIntegerDigits;
+         }
+       else
+         exponentRound = 1;
+      }
+
+    return index;
+  }
+
+  // This helper function creates a string consisting of all the
+  // characters which can appear in a pattern and must be quoted.
+  private String patternChars (DecimalFormatSymbols syms)
+  {
+    StringBuffer buf = new StringBuffer ();
+    buf.append(syms.getDecimalSeparator());
+    buf.append(syms.getDigit());
+    buf.append(syms.getExponential());
+    buf.append(syms.getGroupingSeparator());
+    // Adding this one causes pattern application to fail.
+    // Of course, omitting is causes toPattern to fail.
+    // ... but we already have bugs there.  FIXME.
+    // buf.append(syms.getMinusSign());
+    buf.append(syms.getPatternSeparator());
+    buf.append(syms.getPercent());
+    buf.append(syms.getPerMill());
+    buf.append(syms.getZeroDigit());
+    buf.append('\u00a4');
+    return buf.toString();
+  }
+
+  private void applyPatternWithSymbols(String pattern, DecimalFormatSymbols 
syms)
+  {
+    // Initialize to the state the parser expects.
+    negativePrefix = "";
+    negativeSuffix = "";
+    positivePrefix = "";
+    positiveSuffix = "";
+    decimalSeparatorAlwaysShown = false;
+    groupingSize = 0;
+    minExponentDigits = 0;
+    multiplier = 1;
+    useExponentialNotation = false;
+    groupingUsed = false;
+    maximumFractionDigits = 0;
+    maximumIntegerDigits = MAXIMUM_INTEGER_DIGITS;
+    minimumFractionDigits = 0;
+    minimumIntegerDigits = 1;
+
+    AttributedFormatBuffer buf = new AttributedFormatBuffer ();
+    String patChars = patternChars (syms);
+
+    int max = pattern.length();
+    int index = scanFix (pattern, 0, buf, patChars, syms, false);
+    buf.sync();
+    positivePrefix = buf.getBuffer().toString();
+    positivePrefixRanges = buf.getRanges();
+    positivePrefixAttrs = buf.getAttributes();
+
+    index = scanFormat (pattern, index, patChars, syms, true);
+
+    index = scanFix (pattern, index, buf, patChars, syms, true);
+    buf.sync();
+    positiveSuffix = buf.getBuffer().toString();
+    positiveSuffixRanges = buf.getRanges();
+    positiveSuffixAttrs = buf.getAttributes();
+
+    if (index == pattern.length())
+      {
+       // No negative info.
+       negativePrefix = null;
+       negativeSuffix = null;
+      }
+    else
+      {
+       if (pattern.charAt(index) != syms.getPatternSeparator())
+         throw new IllegalArgumentException ("separator character " +
+                                             "expected - index: " + index);
+
+       index = scanFix (pattern, index + 1, buf, patChars, syms, false);
+       buf.sync();
+       negativePrefix = buf.getBuffer().toString();
+       negativePrefixRanges = buf.getRanges();
+       negativePrefixAttrs = buf.getAttributes();
+
+       // We parse the negative format for errors but we don't let
+       // it side-effect this object.
+       index = scanFormat (pattern, index, patChars, syms, false);
+
+       index = scanFix (pattern, index, buf, patChars, syms, true);
+       buf.sync();
+       negativeSuffix = buf.getBuffer().toString();
+       negativeSuffixRanges = buf.getRanges();
+       negativeSuffixAttrs = buf.getAttributes();
+
+       if (index != pattern.length())
+         throw new IllegalArgumentException ("end of pattern expected " +
+                                             "- index: " + index);
+      }
+  }
+
+  public void applyLocalizedPattern (String pattern)
+  {
+    // JCL p. 638 claims this throws a ParseException but p. 629
+    // contradicts this.  Empirical tests with patterns of "0,###.0"
+    // and "#.#.#" corroborate the p. 629 statement that an
+    // IllegalArgumentException is thrown.
+    applyPatternWithSymbols (pattern, symbols);
+  }
+
+  public void applyPattern (String pattern)
+  {
+    // JCL p. 638 claims this throws a ParseException but p. 629
+    // contradicts this.  Empirical tests with patterns of "0,###.0"
+    // and "#.#.#" corroborate the p. 629 statement that an
+    // IllegalArgumentException is thrown.
+    applyPatternWithSymbols (pattern, nonLocalizedSymbols);
+  }
+
+  public Object clone ()
+  {
+    DecimalFormat c = (DecimalFormat) super.clone ();
+    c.symbols = (DecimalFormatSymbols) symbols.clone ();
+    return c;
+  }
+
+  /**
+   * Constructs a <code>DecimalFormat</code> which uses the default
+   * pattern and symbols.
+   */
+  public DecimalFormat ()
+  {
+    this ("#,##0.###");
+  }
+
+  /**
+   * Constructs a <code>DecimalFormat</code> which uses the given
+   * pattern and the default symbols for formatting and parsing.
+   *
+   * @param pattern the non-localized pattern to use.
+   * @throws NullPointerException if any argument is null.
+   * @throws IllegalArgumentException if the pattern is invalid.
+   */
+  public DecimalFormat (String pattern)
+  {
+    this (pattern, new DecimalFormatSymbols ());
+  }
+
+  /**
+   * Constructs a <code>DecimalFormat</code> using the given pattern
+   * and formatting symbols.  This construction method is used to give
+   * complete control over the formatting process.  
+   *
+   * @param pattern the non-localized pattern to use.
+   * @param symbols the set of symbols used for parsing and formatting.
+   * @throws NullPointerException if any argument is null.
+   * @throws IllegalArgumentException if the pattern is invalid.
+   */
+  public DecimalFormat (String pattern, DecimalFormatSymbols symbols)
+  {
+    if (symbols == null)
+      {
+        throw new NullPointerException("Supplied set of symbols is null.");
+      }
+    this.symbols = symbols;
+    applyPattern(pattern);
+  }
+
+  private boolean equals(String s1, String s2)
+  {
+    if (s1 == null || s2 == null)
+      return s1 == s2;
+    return s1.equals(s2);
+  }
+
+  public boolean equals (Object obj)
+  {
+    if (! (obj instanceof DecimalFormat))
+      return false;
+    DecimalFormat dup = (DecimalFormat) obj;
+    return (decimalSeparatorAlwaysShown == dup.decimalSeparatorAlwaysShown
+           && groupingSize == dup.groupingSize
+           && minExponentDigits == dup.minExponentDigits
+           && multiplier == dup.multiplier
+           && equals(negativePrefix, dup.negativePrefix)
+           && equals(negativeSuffix, dup.negativeSuffix)
+           && equals(positivePrefix, dup.positivePrefix)
+           && equals(positiveSuffix, dup.positiveSuffix)
+           && symbols.equals(dup.symbols)
+           && useExponentialNotation == dup.useExponentialNotation);
+  }
+
+  private void formatInternal (double number, FormatBuffer dest,
+                              FieldPosition fieldPos)
+  {
+    // A very special case.
+    if (Double.isNaN(number))
+      {
+       dest.append(symbols.getNaN());
+       if (fieldPos != null && 
+           (fieldPos.getField() == INTEGER_FIELD ||
+            fieldPos.getFieldAttribute() == NumberFormat.Field.INTEGER))
+         {
+           int index = dest.length();
+           fieldPos.setBeginIndex(index - symbols.getNaN().length());
+           fieldPos.setEndIndex(index);
+         }
+       return;
+      }
+               
+    boolean is_neg = number < 0;
+    if (is_neg)
+      {
+       if (negativePrefix != null)
+         {
+           dest.append(substituteCurrency(negativePrefix, number),
+                       negativePrefixRanges, negativePrefixAttrs);
+         }
+       else
+         {
+           dest.append(symbols.getMinusSign(), NumberFormat.Field.SIGN);
+           dest.append(substituteCurrency(positivePrefix, number),
+                       positivePrefixRanges, positivePrefixAttrs);
+         }
+       number = - number;
+      }
+    else
+      {
+       dest.append(substituteCurrency(positivePrefix, number),
+                   positivePrefixRanges, positivePrefixAttrs);
+      }
+    int integerBeginIndex = dest.length();
+    int integerEndIndex = 0;
+    int zeroStart = symbols.getZeroDigit() - '0';
+               
+    if (Double.isInfinite (number))
+      {
+       dest.append(symbols.getInfinity());
+       integerEndIndex = dest.length();
+      }
+    else
+      {
+       number *= multiplier;
+       
+       // Compute exponent.
+       long exponent = 0;
+       double baseNumber;
+       if (useExponentialNotation)
+         {
+           exponent = (long) Math.floor (Math.log(number) / Math.log(10));
+           exponent = exponent - (exponent % exponentRound);
+           if (minimumIntegerDigits > 0)
+             exponent -= minimumIntegerDigits - 1;
+           baseNumber = (number / Math.pow(10.0, exponent));
+         }
+       else
+         baseNumber = number;
+
+       // Round to the correct number of digits.
+       baseNumber += 5 * Math.pow(10.0, - maximumFractionDigits - 1);
+
+       int index = dest.length();
+       //double intPart = Math.floor(baseNumber);
+       String intPart = Long.toString((long)Math.floor(baseNumber));
+       int count, groupPosition = intPart.length();
+
+       dest.setDefaultAttribute(NumberFormat.Field.INTEGER);
+
+       for (count = 0; count < minimumIntegerDigits-intPart.length(); count++)
+         dest.append(symbols.getZeroDigit());
+
+       for (count = 0;
+            count < maximumIntegerDigits && count < intPart.length();
+            count++)
+         {
+           int dig = intPart.charAt(count);
+
+           // Append group separator if required.
+           if (groupingUsed && count > 0 && groupingSize != 0 && groupPosition 
% groupingSize == 0)
+             {
+               dest.append(symbols.getGroupingSeparator(), 
NumberFormat.Field.GROUPING_SEPARATOR);
+               dest.setDefaultAttribute(NumberFormat.Field.INTEGER);
+             }
+           dest.append((char) (zeroStart + dig));
+
+           groupPosition--;
+         }
+       dest.setDefaultAttribute(null);
+
+       integerEndIndex = dest.length();
+          
+       int decimal_index = integerEndIndex;
+       int consecutive_zeros = 0;
+       int total_digits = 0;
+
+       int localMaximumFractionDigits = maximumFractionDigits;
+
+       if (useExponentialNotation)
+         localMaximumFractionDigits += minimumIntegerDigits - count;
+
+       // Strip integer part from NUMBER.
+       double fracPart = baseNumber - Math.floor(baseNumber);
+       
+       if ( ((fracPart != 0 || minimumFractionDigits > 0) && 
localMaximumFractionDigits > 0)
+            || decimalSeparatorAlwaysShown)
+         {
+           dest.append (symbols.getDecimalSeparator(), 
NumberFormat.Field.DECIMAL_SEPARATOR);
+         }
+
+       int fraction_begin = dest.length();
+       dest.setDefaultAttribute(NumberFormat.Field.FRACTION);
+       for (count = 0;
+            count < localMaximumFractionDigits
+              && (fracPart != 0 || count < minimumFractionDigits);
+            ++count)
+         {
+           ++total_digits;
+           fracPart *= 10;
+           long dig = (long) fracPart;
+           if (dig == 0)
+             ++consecutive_zeros;
+           else
+             consecutive_zeros = 0;
+           dest.append((char) (symbols.getZeroDigit() + dig));
+
+           // Strip integer part from FRACPART.
+           fracPart = fracPart - Math.floor (fracPart);
+         }
+
+       // Strip extraneous trailing `0's.  We can't always detect
+       // these in the loop.
+       int extra_zeros = Math.min (consecutive_zeros,
+                                   total_digits - minimumFractionDigits);
+       if (extra_zeros > 0)
+         {
+           dest.cutTail(extra_zeros);
+           total_digits -= extra_zeros;
+           if (total_digits == 0 && !decimalSeparatorAlwaysShown)
+             dest.cutTail(1);
+         }
+
+       if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD)
+         {
+           fieldPos.setBeginIndex(fraction_begin);
+           fieldPos.setEndIndex(dest.length());
+         }
+
+       // Finally, print the exponent.
+       if (useExponentialNotation)
+         {
+           dest.append(symbols.getExponential(), 
NumberFormat.Field.EXPONENT_SYMBOL);      
+           if (exponent < 0)
+             {
+               dest.append (symbols.getMinusSign (), 
NumberFormat.Field.EXPONENT_SIGN);
+               exponent = - exponent;
+             }
+           index = dest.length();
+           dest.setDefaultAttribute(NumberFormat.Field.EXPONENT);
+           String exponentString = Long.toString ((long) exponent);
+           
+           for (count = 0; count < minExponentDigits-exponentString.length();
+                count++)
+             dest.append((char) symbols.getZeroDigit());
+
+           for (count = 0;
+                count < exponentString.length();
+                ++count)
+             {
+               int dig = exponentString.charAt(count);
+               dest.append((char) (zeroStart + dig));
+             }
+         }
+      }
+
+    if (fieldPos != null && 
+       (fieldPos.getField() == INTEGER_FIELD ||
+        fieldPos.getFieldAttribute() == NumberFormat.Field.INTEGER))
+      {
+       fieldPos.setBeginIndex(integerBeginIndex);
+       fieldPos.setEndIndex(integerEndIndex);
+      }
+               
+    if (is_neg && negativeSuffix != null)
+      {
+       dest.append(substituteCurrency(negativeSuffix, number),
+                   negativeSuffixRanges, negativeSuffixAttrs);
+      }
+    else
+      {
+       dest.append(substituteCurrency(positiveSuffix, number),
+                   positiveSuffixRanges, positiveSuffixAttrs);
+      }
+  }
+
+  public StringBuffer format (double number, StringBuffer dest,
+                             FieldPosition fieldPos)
+  {
+    formatInternal (number, new StringFormatBuffer(dest), fieldPos);
+    return dest;
+  }
+
+  public AttributedCharacterIterator formatToCharacterIterator (Object value)
+  {
+    AttributedFormatBuffer sbuf = new AttributedFormatBuffer();
+
+    if (value instanceof Number)
+      formatInternal(((Number) value).doubleValue(), sbuf, null);
+    else
+      throw new IllegalArgumentException 
+       ("Cannot format given Object as a Number");
+    
+    sbuf.sync();
+    return new FormatCharacterIterator(sbuf.getBuffer().toString(), 
+                                      sbuf.getRanges(), 
+                                      sbuf.getAttributes());
+  }
+
+  public StringBuffer format (long number, StringBuffer dest,
+                             FieldPosition fieldPos)
+  {
+    // If using exponential notation, we just format as a double.
+    if (useExponentialNotation)
+       return format ((double) number, dest, fieldPos);
+
+    boolean is_neg = number < 0;
+    if (is_neg)
+      {
+       if (negativePrefix != null)
+         dest.append(substituteCurrency(negativePrefix, number));
+       else
+         {
+           dest.append(symbols.getMinusSign());
+           dest.append(substituteCurrency(positivePrefix, number));
+         }
+       number = - number;
+      }
+    else
+      dest.append(substituteCurrency(positivePrefix, number));
+
+    int integerBeginIndex = dest.length();
+    int index = dest.length();
+    int count = 0;
+
+    /* Handle percentages, etc. */
+    number *= multiplier;
+    while (count < maximumIntegerDigits
+          && (number > 0 || count < minimumIntegerDigits))
+      {
+       long dig = number % 10;
+       number /= 10;
+       // NUMBER and DIG will be less than 0 if the original number
+       // was the most negative long.
+       if (dig < 0)
+         {
+           dig = - dig;
+           number = - number;
+         }
+
+       // Append group separator if required.
+       if (groupingUsed && count > 0 && groupingSize != 0 && count % 
groupingSize == 0)
+         dest.insert(index, symbols.getGroupingSeparator());
+
+       dest.insert(index, (char) (symbols.getZeroDigit() + dig));
+
+       ++count;
+      }
+
+    if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD)
+      {
+       fieldPos.setBeginIndex(integerBeginIndex);
+       fieldPos.setEndIndex(dest.length());
+      }
+
+    if (decimalSeparatorAlwaysShown || minimumFractionDigits > 0)
+      {
+       dest.append(symbols.getDecimalSeparator());
+       if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD)
+         {
+           fieldPos.setBeginIndex(dest.length());
+           fieldPos.setEndIndex(dest.length() + minimumFractionDigits);
+         }
+      }
+
+    for (count = 0; count < minimumFractionDigits; ++count)
+      dest.append(symbols.getZeroDigit());
+
+    dest.append((is_neg && negativeSuffix != null)
+               ? substituteCurrency(negativeSuffix, number)
+               : substituteCurrency(positiveSuffix, number));
+    return dest;
+  }
+
+  /**
+   * Returns the currency corresponding to the currency symbol stored
+   * in the instance of <code>DecimalFormatSymbols</code> used by this
+   * <code>DecimalFormat</code>.
+   *
+   * @return A new instance of <code>Currency</code> if
+   * the currency code matches a known one, null otherwise.
+   */
+  public Currency getCurrency()
+  {
+    return symbols.getCurrency();
+  }
+
+  public DecimalFormatSymbols getDecimalFormatSymbols ()
+  {
+    return symbols;
+  }
+
+  public int getGroupingSize ()
+  {
+    return groupingSize;
+  }
+
+  public int getMultiplier ()
+  {
+    return multiplier;
+  }
+
+  public String getNegativePrefix ()
+  {
+    return negativePrefix;
+  }
+
+  public String getNegativeSuffix ()
+  {
+    return negativeSuffix;
+  }
+
+  public String getPositivePrefix ()
+  {
+    return positivePrefix;
+  }
+
+  public String getPositiveSuffix ()
+  {
+    return positiveSuffix;
+  }
+
+  /**
+   * Returns a hash code for this object.
+   *
+   * @return A hash code.
+   */
+  public int hashCode()
+  {
+    return toPattern().hashCode();
+  }
+
+  public boolean isDecimalSeparatorAlwaysShown ()
+  {
+    return decimalSeparatorAlwaysShown;
+  }
+
+  public Number parse (String str, ParsePosition pos)
+  {
+    /*
+     * Our strategy is simple: copy the text into separate buffers: one for 
the int part,
+     * one for the fraction part and for the exponential part.
+     * We translate or omit locale-specific information.  
+     * If exponential is sufficiently big we merge the fraction and int part 
and
+     * remove the '.' and then we use Long to convert the number. In the other
+     * case, we use Double to convert the full number.
+     */
+
+    boolean is_neg = false;
+    int index = pos.getIndex();
+    StringBuffer int_buf = new StringBuffer ();
+        
+    // We have to check both prefixes, because one might be empty.  We
+    // want to pick the longest prefix that matches.
+    boolean got_pos = str.startsWith(positivePrefix, index);
+    String np = (negativePrefix != null
+                ? negativePrefix
+                : positivePrefix + symbols.getMinusSign());
+    boolean got_neg = str.startsWith(np, index);
+
+    if (got_pos && got_neg)
+      {
+       // By checking this way, we preserve ambiguity in the case
+       // where the negative format differs only in suffix.  We
+       // check this again later.
+       if (np.length() > positivePrefix.length())
+         {
+           is_neg = true;
+           index += np.length();
+         }
+       else
+         index += positivePrefix.length();
+      }
+    else if (got_neg)
+      {
+       is_neg = true;
+       index += np.length();
+      }
+    else if (got_pos)
+      index += positivePrefix.length();
+    else
+      {
+       pos.setErrorIndex (index);
+       return null;
+      }
+
+    // FIXME: handle Inf and NaN.
+
+    // FIXME: do we have to respect minimum digits?
+    // What about multiplier?
+
+    StringBuffer buf = int_buf;
+    StringBuffer frac_buf = null;
+    StringBuffer exp_buf = null;
+    int start_index = index;
+    int max = str.length();
+    int exp_index = -1;
+    int last = index + maximumIntegerDigits; 
+
+    if (maximumFractionDigits > 0)
+      last += maximumFractionDigits + 1;
+    
+    if (useExponentialNotation)
+      last += minExponentDigits + 1;
+
+    if (last > 0 && max > last)
+      max = last;
+
+    char zero = symbols.getZeroDigit();
+    int last_group = -1;
+    boolean int_part = true;
+    boolean exp_part = false;
+    for (; index < max; ++index)
+      {
+       char c = str.charAt(index);
+
+       // FIXME: what about grouping size?
+       if (groupingUsed && c == symbols.getGroupingSeparator())
+         {
+           if (last_group != -1 
+               && groupingSize != 0  
+               && (index - last_group) % groupingSize != 0)
+             {
+               pos.setErrorIndex(index);
+               return null;
+             }
+           last_group = index+1;
+         }
+       else if (c >= zero && c <= zero + 9)
+         {
+           buf.append((char) (c - zero + '0'));
+         }
+       else if (parseIntegerOnly)
+         break;
+       else if (c == symbols.getDecimalSeparator())
+         {
+           if (last_group != -1 
+               && groupingSize != 0 
+               && (index - last_group) % groupingSize != 0)
+             {
+               pos.setErrorIndex(index);
+               return null;
+             }
+           buf = frac_buf = new StringBuffer();
+           frac_buf.append('.');
+           int_part = false;
+         }
+       else if (c == symbols.getExponential())
+         {
+           buf = exp_buf = new StringBuffer();
+           int_part = false;
+           exp_part = true;

*** Patch too long, truncated ***

_______________________________________________
kaffe mailing list
[email protected]
http://kaffe.org/cgi-bin/mailman/listinfo/kaffe

Reply via email to