    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one
    003 * or more contributor license agreements.  See the NOTICE file
    004 * distributed with this work for additional information
    005 * regarding copyright ownership.  The ASF licenses this file
    006 * to you under the Apache License, Version 2.0 (the
    007 * "License"); you may not use this file except in compliance
    008 * with the License.  You may obtain a copy of the License at
    009 *
    010 *   https://www.apache.org/licenses/LICENSE-2.0
    011 *
    012 * Unless required by applicable law or agreed to in writing,
    013 * software distributed under the License is distributed on an
    014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015 * KIND, either express or implied.  See the License for the
    016 * specific language governing permissions and limitations
    017 * under the License.
    018 */
    019package org.apache.bcel.classfile;
    020
    021import java.io.DataOutputStream;
    022import java.io.IOException;
    023
    024import org.apache.bcel.Const;
    025
    026/**
    027 * @since 6.0
    028 */
    029public class SimpleElementValue extends ElementValue {
    030    private int index;
    031
    032    public SimpleElementValue(final int type, final int index, final ConstantPool cpool) {
    033        super(type, cpool);
    034        this.index = index;
    035    }
    036
    037    @Override
    038    public void dump(final DataOutputStream dos) throws IOException {
    039        final int type = super.getType();
    040        dos.writeByte(type); // u1 kind of value
    041        switch (type) {
    042        case PRIMITIVE_INT:
    043        case PRIMITIVE_BYTE:
    044        case PRIMITIVE_CHAR:
    045        case PRIMITIVE_FLOAT:
    046        case PRIMITIVE_LONG:
    047        case PRIMITIVE_BOOLEAN:
    048        case PRIMITIVE_SHORT:
    049        case PRIMITIVE_DOUBLE:
    050        case STRING:
    051            dos.writeShort(getIndex());
    052            break;
    053        default:
    054            throw new ClassFormatException("SimpleElementValue doesn't know how to write out type " + type);
    055        }
    056    }
    057
    058    /**
    059     * @return Value entry index in the cpool
    060     */
    061    public int getIndex() {
    062        return index;
    063    }
    064
    065    public boolean getValueBoolean() {
    066        if (super.getType() != PRIMITIVE_BOOLEAN) {
    067            throw new IllegalStateException("Don't call getValueBoolean() on a non BOOLEAN ElementValue");
    068        }
    069        final ConstantInteger bo = (ConstantInteger) super.getConstantPool().getConstant(getIndex());
    070        return bo.getBytes() != 0;
    071    }
    072
    073    public byte getValueByte() {
    074        if (super.getType() != PRIMITIVE_BYTE) {
    075            throw new IllegalStateException("Don't call getValueByte() on a non BYTE ElementValue");
    076        }
    077        return (byte) super.getConstantPool().getConstantInteger(getIndex()).getBytes();
    078    }
    079
    080    public char getValueChar() {
    081        if (super.getType() != PRIMITIVE_CHAR) {
    082            throw new IllegalStateException("Don't call getValueChar() on a non CHAR ElementValue");
    083        }
    084        return (char) super.getConstantPool().getConstantInteger(getIndex()).getBytes();
    085    }
    086
    087    public double getValueDouble() {
    088        if (super.getType() != PRIMITIVE_DOUBLE) {
    089            throw new IllegalStateException("Don't call getValueDouble() on a non DOUBLE ElementValue");
    090        }
    091        final ConstantDouble d = (ConstantDouble) super.getConstantPool().getConstant(getIndex());
    092        return d.getBytes();
    093    }
    094
    095    public float getValueFloat() {
    096        if (super.getType() != PRIMITIVE_FLOAT) {
    097            throw new IllegalStateException("Don't call getValueFloat() on a non FLOAT ElementValue");
    098        }
    099        final ConstantFloat f = (ConstantFloat) super.getConstantPool().getConstant(getIndex());
    100        return f.getBytes();
    101    }
    102
    103    public int getValueInt() {
    104        if (super.getType() != PRIMITIVE_INT) {
    105            throw new IllegalStateException("Don't call getValueInt() on a non INT ElementValue");
    106        }
    107        return super.getConstantPool().getConstantInteger(getIndex()).getBytes();
    108    }
    109
    110    public long getValueLong() {
    111        if (super.getType() != PRIMITIVE_LONG) {
    112            throw new IllegalStateException("Don't call getValueLong() on a non LONG ElementValue");
    113        }
    114        final ConstantLong j = (ConstantLong) super.getConstantPool().getConstant(getIndex());
    115        return j.getBytes();
    116    }
    117
    118    public short getValueShort() {
    119        if (super.getType() != PRIMITIVE_SHORT) {
    120            throw new IllegalStateException("Don't call getValueShort() on a non SHORT ElementValue");
    121        }
    122        final ConstantInteger s = (ConstantInteger) super.getConstantPool().getConstant(getIndex());
    123        return (short) s.getBytes();
    124    }
    125
    126    public String getValueString() {
    127        if (super.getType() != STRING) {
    128            throw new IllegalStateException("Don't call getValueString() on a non STRING ElementValue");
    129        }
    130        return super.getConstantPool().getConstantUtf8(getIndex()).getBytes();
    131    }
    132
    133    public void setIndex(final int index) {
    134        this.index = index;
    135    }
    136
    137    // Whatever kind of value it is, return it as a string
    138    @Override
    139    public String stringifyValue() {
    140        final ConstantPool cpool = super.getConstantPool();
    141        final int type = super.getType();
    142        switch (type) {
    143        case PRIMITIVE_INT:
    144            return Integer.toString(cpool.getConstantInteger(getIndex()).getBytes());
    145        case PRIMITIVE_LONG:
    146            final ConstantLong j = cpool.getConstant(getIndex(), Const.CONSTANT_Long, ConstantLong.class);
    147            return Long.toString(j.getBytes());
    148        case PRIMITIVE_DOUBLE:
    149            final ConstantDouble d = cpool.getConstant(getIndex(), Const.CONSTANT_Double, ConstantDouble.class);
    150            return Double.toString(d.getBytes());
    151        case PRIMITIVE_FLOAT:
    152            final ConstantFloat f = cpool.getConstant(getIndex(), Const.CONSTANT_Float, ConstantFloat.class);
    153            return Float.toString(f.getBytes());
    154        case PRIMITIVE_SHORT:
    155            final ConstantInteger s = cpool.getConstantInteger(getIndex());
    156            return Integer.toString(s.getBytes());
    157        case PRIMITIVE_BYTE:
    158            final ConstantInteger b = cpool.getConstantInteger(getIndex());
    159            return Integer.toString(b.getBytes());
    160        case PRIMITIVE_CHAR:
    161            final ConstantInteger ch = cpool.getConstantInteger(getIndex());
    162            return String.valueOf((char) ch.getBytes());
    163        case PRIMITIVE_BOOLEAN:
    164            final ConstantInteger bo = cpool.getConstantInteger(getIndex());
    165            if (bo.getBytes() == 0) {
    166                return "false";
    167            }
    168            return "true";
    169        case STRING:
    170            return cpool.getConstantUtf8(getIndex()).getBytes();
    171        default:
    172            throw new IllegalStateException("SimpleElementValue class does not know how to stringify type " + type);
    173        }
    174    }
    175
    176    @Override
    177    public String toString() {
    178        return stringifyValue();
    179    }
    180}