/************************************************************************** * Copyright (c) 2001 by Punch Telematix. All rights reserved. * * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted provided that the following conditions * * are met: * * 1. Redistributions of source code must retain the above copyright * * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * 3. Neither the name of Punch Telematix nor the names of * * other contributors may be used to endorse or promote products * * derived from this software without specific prior written permission.* * * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * * IN NO EVENT SHALL PUNCH TELEMATIX OR OTHER CONTRIBUTORS BE LIABLE * * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * **************************************************************************/ /* ** $Id: ChoiceFormat.java,v 1.1.1.1 2004/07/12 14:07:47 cvs Exp $ */ package java.text; import java.util.Arrays; import java.util.StringTokenizer; public class ChoiceFormat extends NumberFormat { private static final long serialVersionUID = 1795184449645032964L; public final static double nextDouble(double d){ return nextDouble(d,true); } public static double nextDouble(double d, boolean next){ if(!Double.isNaN(d)){ if(Double.isInfinite(d)){ if(d > 0 && !next){ return Double.MAX_VALUE; } if(d < 0 && next){ return -Double.MAX_VALUE; } return d; } if(d == 0.0){ return next ? Double.MIN_VALUE : -Double.MIN_VALUE; } if(!next && d <= - Double.MAX_VALUE){ return Double.NEGATIVE_INFINITY; } return Double.longBitsToDouble(Double.doubleToLongBits(d)+(next ? 1 : -1)); } return Double.NaN; } public final static double previousDouble(double d){ return nextDouble(d,false); } //dictated by serialized form private String[] choiceFormats; private double[] choiceLimits; public ChoiceFormat(String newPattern){ applyPattern(newPattern); } public ChoiceFormat(double[] limits, String[] formats){ setChoices(limits,formats); } private void checkLimits(double[] limits){ double prev = limits[0]; for(int i = 1 ; i < limits.length ; i++){ double next = limits[i]; if(next < prev){ throw new IllegalArgumentException(); } prev = next; } } private double parseDouble(String value){ value = value.trim(); try { return Double.parseDouble(value); } catch(NumberFormatException nfe){ if(value.equals("-\u221E")){ return Double.NEGATIVE_INFINITY; } if(value.equals("\u221E")){ return Double.POSITIVE_INFINITY; } throw new IllegalArgumentException("bad double value encountered"); } } public void applyPattern(String pattern){ StringTokenizer st = new StringTokenizer(pattern,"|"); int len = st.countTokens(); if(len == 0){ throw new IllegalArgumentException("pattern contains no choices"); } String[] formats = new String[len]; double[] limits = new double[len]; for(int i = 0 ; i < len ; i++){ String token = st.nextToken(); int idx = token.indexOf('<'); if(idx == -1){ idx = token.indexOf('#'); if(idx == -1){ idx = token.indexOf('\u2264'); if(idx ==- 1){ throw new IllegalArgumentException("bad pattern applied"); } } double d = parseDouble(token.substring(0,idx)); limits[i] = d; } else { double d = nextDouble(parseDouble(token.substring(0,idx))); limits[i] = d; } formats[i] = token.substring(idx+1); } checkLimits(limits); choiceFormats = formats; choiceLimits = limits; } public Object clone(){ ChoiceFormat cf = (ChoiceFormat)super.clone(); cf.choiceLimits = (double[])choiceLimits.clone(); cf.choiceFormats = (String[])choiceFormats.clone(); return cf; } public boolean equals(Object o){ if(!(o instanceof ChoiceFormat)){ return false; } ChoiceFormat cf = (ChoiceFormat)o; return Arrays.equals(this.choiceFormats,cf.choiceFormats) && Arrays.equals(this.choiceLimits, cf.choiceLimits); } public StringBuffer format(long num, StringBuffer app, FieldPosition pos){ return format((double)num,app,pos); } public StringBuffer format(double num, StringBuffer app, FieldPosition pos){ if(Double.isNaN(num)){ app.append(choiceFormats[0]); } else { for(int i = 0 ; i < choiceLimits.length ; i++){ double limit = choiceLimits[i]; if(num < limit){// || (num == limit && limit == prev)){ app.append(choiceFormats[(i > 0 ? i-1 : 0)]); return app; } } int l = choiceFormats.length; if(l > 0){ app.append(choiceFormats[l-1]); } } return app; } public Object[] getFormats(){ return choiceFormats; } public double[] getLimits(){ return choiceLimits; } public int hashCode(){ int hash = 1; if(choiceLimits != null){ for (int i = 0 ; i < choiceLimits.length ; i++){ hash += (Double.doubleToLongBits(choiceLimits[i])) ^ choiceFormats[i].hashCode(); } } return hash; } public Number parse(String srcStr, ParsePosition pos){ int start = pos.getIndex(); for(int i = 0 ; i < choiceFormats.length ; i++){ if(srcStr.regionMatches(start,choiceFormats[i],0 ,choiceFormats[i].length())){ pos.setIndex(start+choiceFormats[i].length()); return new Double(choiceLimits[i]); } } return new Double(Double.NaN); } public void setChoices(double[] limits, String[] formats){ if(limits.length != formats.length || limits.length == 0){ throw new IllegalArgumentException(); } checkLimits(limits); choiceFormats = formats; choiceLimits = limits; } public String toPattern(){ StringBuffer pattern = new StringBuffer(128); for (int i = 0 ; i < choiceLimits.length ; i++){ pattern.append(choiceLimits[i]); pattern.append('#'); pattern.append(choiceFormats[i]); pattern.append('|'); } pattern.setLength(pattern.length()-1); return pattern.toString(); } }