summaryrefslogtreecommitdiff
path: root/libjava/java/text/ChoiceFormat.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/text/ChoiceFormat.java')
-rw-r--r--libjava/java/text/ChoiceFormat.java310
1 files changed, 310 insertions, 0 deletions
diff --git a/libjava/java/text/ChoiceFormat.java b/libjava/java/text/ChoiceFormat.java
new file mode 100644
index 00000000000..bed62a75e53
--- /dev/null
+++ b/libjava/java/text/ChoiceFormat.java
@@ -0,0 +1,310 @@
+// ChoiceFormat.java - Formatter for `switch'-like string substitution.
+
+/* Copyright (C) 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.text;
+
+import java.util.Vector;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date March 9, 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.1.
+ */
+
+public class ChoiceFormat extends NumberFormat
+{
+ // Note: we assume the same kind of quoting rules apply here.
+ // This isn't explicitly documented. But for instance we accept
+ // '#' as a literal hash in a format string.
+ public void applyPattern (String newPattern)
+ {
+ int index = 0, max = newPattern.length();
+ Vector stringVec = new Vector ();
+ Vector limitVec = new Vector ();
+ StringBuffer buf = new StringBuffer ();
+
+ while (true)
+ {
+ // Find end of double.
+ int dstart = index;
+ while (index < max)
+ {
+ char c = newPattern.charAt(index);
+ if (c == '#' || c == '\u2064' || c == '<')
+ break;
+ ++index;
+ }
+
+ if (index == max)
+ throw new IllegalArgumentException ("unexpected end of text");
+ Double d = new Double (newPattern.substring(dstart, index));
+
+ if (newPattern.charAt(index) == '<')
+ d = new Double (nextDouble (d.doubleValue()));
+
+ limitVec.addElement(d);
+
+ // Scan text.
+ ++index;
+ buf.setLength(0);
+ while (index < max)
+ {
+ char c = newPattern.charAt(index);
+ if (c == '\'' && index < max + 1
+ && newPattern.charAt(index + 1) == '\'')
+ {
+ buf.append(c);
+ ++index;
+ }
+ else if (c == '\'' && index < max + 2)
+ {
+ buf.append(newPattern.charAt(index + 1));
+ index += 2;
+ }
+ else if (c == '|')
+ break;
+ else
+ buf.append(c);
+ ++index;
+ }
+
+ stringVec.addElement(buf.toString());
+ if (index == max)
+ break;
+ ++index;
+ }
+
+ strings = new String[stringVec.size()];
+ stringVec.copyInto(strings);
+
+ limits = new double[limitVec.size()];
+ for (int i = 0; i < limits.length; ++i)
+ {
+ Double d = (Double) limitVec.elementAt(i);
+ limits[i] = d.doubleValue();
+ }
+ }
+
+ public ChoiceFormat (String newPattern)
+ {
+ super ();
+ applyPattern (newPattern);
+ }
+
+ public ChoiceFormat (double[] limits, String[] strings)
+ {
+ super ();
+ setChoices (limits, strings);
+ }
+
+ public Object clone ()
+ {
+ return new ChoiceFormat (limits, strings);
+ }
+
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof ChoiceFormat))
+ return false;
+ ChoiceFormat cf = (ChoiceFormat) obj;
+ if (limits.length != cf.limits.length)
+ return false;
+ for (int i = limits.length - 1; i >= 0; --i)
+ {
+ if (limits[i] != cf.limits[i]
+ || !strings[i].equals(cf.strings[i]))
+ return false;
+ }
+ return true;
+ }
+
+ public StringBuffer format (long num, StringBuffer appendBuf,
+ FieldPosition pos)
+ {
+ return format ((double) num, appendBuf, pos);
+ }
+
+ public StringBuffer format (double num, StringBuffer appendBuf,
+ FieldPosition pos)
+ {
+ if (limits.length == 0)
+ return appendBuf;
+
+ int index = 0;
+ if (! Double.isNaN(num) && num >= limits[0])
+ {
+ for (; index < limits.length - 1; ++index)
+ {
+ if (limits[index] <= num
+ && index != limits.length - 2
+ && num < limits[index + 1])
+ break;
+ }
+ }
+
+ return appendBuf.append(strings[index]);
+ }
+
+ public Object[] getFormats ()
+ {
+ return (Object[]) strings.clone();
+ }
+
+ public double[] getLimits ()
+ {
+ return (double[]) limits.clone();
+ }
+
+ public int hashCode ()
+ {
+ int hash = 0;
+ for (int i = 0; i < limits.length; ++i)
+ {
+ long v = Double.doubleToLongBits(limits[i]);
+ hash ^= (v ^ (v >>> 32));
+ hash ^= strings[i].hashCode();
+ }
+ return hash;
+ }
+
+ public static final double nextDouble (double d)
+ {
+ return nextDouble (d, true);
+ }
+
+ public static final double nextDouble (double d, boolean next)
+ {
+ if (Double.isInfinite(d) || Double.isNaN(d))
+ return d;
+
+ long bits = Double.doubleToLongBits(d);
+
+ long mantMask = (1L << mantissaBits) - 1;
+ long mantissa = bits & mantMask;
+
+ long expMask = (1L << exponentBits) - 1;
+ long exponent = (bits >>> mantissaBits) & expMask;
+
+ if (next ^ (bits < 0)) // Increment magnitude
+ {
+ if (mantissa == (1L << mantissaBits) - 1)
+ {
+ mantissa = 0L;
+ exponent++;
+
+ // Check for absolute overflow.
+ if (exponent >= (1L << mantissaBits))
+ return (bits > 0) ? Double.POSITIVE_INFINITY
+ : Double.NEGATIVE_INFINITY;
+ }
+ else
+ mantissa++;
+ }
+ else // Decrement magnitude
+ {
+ if (exponent == 0L && mantissa == 0L)
+ {
+ // The only case where there is a change of sign
+ return next ? Double.MIN_VALUE : -Double.MIN_VALUE;
+ }
+ else
+ {
+ if (mantissa == 0L)
+ {
+ mantissa = (1L << mantissaBits) - 1;
+ exponent--;
+ }
+ else
+ mantissa--;
+ }
+ }
+
+ long result = bits < 0 ? 1 : 0;
+ result = (result << exponentBits) | exponent;
+ result = (result << mantissaBits) | mantissa;
+ return Double.longBitsToDouble(result);
+ }
+
+ public Number parse (String sourceStr, ParsePosition pos)
+ {
+ int index = pos.getIndex();
+ for (int i = 0; i < limits.length; ++i)
+ {
+ if (sourceStr.startsWith(strings[i], index))
+ {
+ pos.setIndex(index + strings[i].length());
+ return new Double (limits[i]);
+ }
+ }
+ pos.setErrorIndex(index);
+ return new Double (Double.NaN);
+ }
+
+ public static final double previousDouble (double d)
+ {
+ return nextDouble (d, false);
+ }
+
+ public void setChoices (double[] limits, String[] strings)
+ {
+ if (limits == null || strings == null)
+ throw new NullPointerException ();
+ if (limits.length != strings.length)
+ throw new IllegalArgumentException ();
+ this.strings = (String[]) strings.clone();
+ this.limits = (double[]) limits.clone();
+ }
+
+ private final void quoteString (StringBuffer dest, String text)
+ {
+ int max = text.length();
+ for (int i = 0; i < max; ++i)
+ {
+ char c = text.charAt(i);
+ if (c == '\'')
+ {
+ dest.append(c);
+ dest.append(c);
+ }
+ else if (c == '#' || c == '|' || c == '\u2064' || c == '<')
+ {
+ dest.append('\'');
+ dest.append(c);
+ dest.append('\'');
+ }
+ else
+ dest.append(c);
+ }
+ }
+
+ public String toPattern ()
+ {
+ StringBuffer result = new StringBuffer ();
+ for (int i = 0; i < limits.length; ++i)
+ {
+ result.append(limits[i]);
+ result.append('#');
+ quoteString (result, strings[i]);
+ }
+ return result.toString();
+ }
+
+ // Formats and limits.
+ private String[] strings;
+ private double[] limits;
+
+ // Number of mantissa bits in double.
+ private static final int mantissaBits = 52;
+ // Number of exponent bits in a double.
+ private static final int exponentBits = 11;
+}