001    /*
002     * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
003     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004     *
005     * This code is free software; you can redistribute it and/or modify it
006     * under the terms of the GNU General Public License version 2 only, as
007     * published by the Free Software Foundation.  Sun designates this
008     * particular file as subject to the "Classpath" exception as provided
009     * by Sun in the LICENSE file that accompanied this code.
010     *
011     * This code is distributed in the hope that it will be useful, but WITHOUT
012     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013     * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014     * version 2 for more details (a copy is included in the LICENSE file that
015     * accompanied this code).
016     *
017     * You should have received a copy of the GNU General Public License version
018     * 2 along with this work; if not, write to the Free Software Foundation,
019     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020     *
021     * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022     * CA 95054 USA or visit www.sun.com if you need additional information or
023     * have any questions.
024     */
025    
026    package com.sun.tools.javac.util;
027    
028    import com.sun.tools.javac.code.Type;
029    
030    import static com.sun.tools.javac.code.TypeTags.*;
031    
032    /**
033     * Utilities for operating on constant values.
034     *
035     * <p><b>This is NOT part of any API supported by Sun Microsystems.  If
036     * you write code that depends on this, you do so at your own risk.
037     * This code and its internal interfaces are subject to change or
038     * deletion without notice.</b>
039     */
040    public class Constants {
041    
042        /**
043         * Converts a constant in internal representation (in which
044         * boolean, char, byte, short, and int are each represented by an
045         * Integer) into standard representation.  Other values (including
046         * null) are returned unchanged.
047         */
048        public static Object decode(Object value, Type type) {
049            if (value instanceof Integer) {
050                int i = (Integer) value;
051                switch (type.tag) {
052                case BOOLEAN:  return i != 0;
053                case CHAR:     return (char) i;
054                case BYTE:     return (byte) i;
055                case SHORT:    return (short) i;
056                }
057            }
058            return value;
059        }
060    
061        /**
062         * Returns a string representation of a constant value (given in
063         * internal representation), quoted and formatted as in Java source.
064         */
065        public static String format(Object value, Type type) {
066            value = decode(value, type);
067            switch (type.tag) {
068            case BYTE:      return formatByte((Byte) value);
069            case LONG:      return formatLong((Long) value);
070            case FLOAT:     return formatFloat((Float) value);
071            case DOUBLE:    return formatDouble((Double) value);
072            case CHAR:      return formatChar((Character) value);
073            }
074            if (value instanceof String)
075                return formatString((String) value);
076            return value + "";
077        }
078    
079        /**
080         * Returns a string representation of a constant value (given in
081         * standard wrapped representation), quoted and formatted as in
082         * Java source.
083         */
084        public static String format(Object value) {
085            if (value instanceof Byte)      return formatByte((Byte) value);
086            if (value instanceof Long)      return formatLong((Long) value);
087            if (value instanceof Float)     return formatFloat((Float) value);
088            if (value instanceof Double)    return formatDouble((Double) value);
089            if (value instanceof Character) return formatChar((Character) value);
090            if (value instanceof String)    return formatString((String) value);
091            return value + "";
092        }
093    
094        private static String formatByte(byte b) {
095            return String.format("0x%02x", b);
096        }
097    
098        private static String formatLong(long lng) {
099            return lng + "L";
100        }
101    
102        private static String formatFloat(float f) {
103            if (Float.isNaN(f))
104                return "0.0f/0.0f";
105            else if (Float.isInfinite(f))
106                return (f < 0) ? "-1.0f/0.0f" : "1.0f/0.0f";
107            else
108                return f + "f";
109        }
110    
111        private static String formatDouble(double d) {
112            if (Double.isNaN(d))
113                return "0.0/0.0";
114            else if (Double.isInfinite(d))
115                return (d < 0) ? "-1.0/0.0" : "1.0/0.0";
116            else
117                return d + "";
118        }
119    
120        private static String formatChar(char c) {
121            return '\'' + Convert.quote(c) + '\'';
122        }
123    
124        private static String formatString(String s) {
125            return '"' + Convert.quote(s) + '"';
126        }
127    }