1/* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4/* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21package com.sun.org.apache.bcel.internal.generic; 22 23import java.io.DataInput; 24import java.io.DataOutputStream; 25import java.io.IOException; 26 27import com.sun.org.apache.bcel.internal.classfile.AnnotationElementValue; 28import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; 29import com.sun.org.apache.bcel.internal.classfile.ArrayElementValue; 30import com.sun.org.apache.bcel.internal.classfile.ClassElementValue; 31import com.sun.org.apache.bcel.internal.classfile.ElementValue; 32import com.sun.org.apache.bcel.internal.classfile.EnumElementValue; 33import com.sun.org.apache.bcel.internal.classfile.SimpleElementValue; 34 35/** 36 * @since 6.0 37 */ 38public abstract class ElementValueGen 39{ 40 private final int type; 41 private final ConstantPoolGen cpGen; 42 43 protected ElementValueGen(final int type, final ConstantPoolGen cpGen) 44 { 45 this.type = type; 46 this.cpGen = cpGen; 47 } 48 49 /** 50 * Subtypes return an immutable variant of the ElementValueGen 51 */ 52 public abstract ElementValue getElementValue(); 53 54 public int getElementValueType() 55 { 56 return type; 57 } 58 59 public abstract String stringifyValue(); 60 61 public abstract void dump(DataOutputStream dos) throws IOException; 62 63 public static final int STRING = 's'; 64 65 public static final int ENUM_CONSTANT = 'e'; 66 67 public static final int CLASS = 'c'; 68 69 public static final int ANNOTATION = '@'; 70 71 public static final int ARRAY = '['; 72 73 public static final int PRIMITIVE_INT = 'I'; 74 75 public static final int PRIMITIVE_BYTE = 'B'; 76 77 public static final int PRIMITIVE_CHAR = 'C'; 78 79 public static final int PRIMITIVE_DOUBLE = 'D'; 80 81 public static final int PRIMITIVE_FLOAT = 'F'; 82 83 public static final int PRIMITIVE_LONG = 'J'; 84 85 public static final int PRIMITIVE_SHORT = 'S'; 86 87 public static final int PRIMITIVE_BOOLEAN = 'Z'; 88 89 public static ElementValueGen readElementValue(final DataInput dis, 90 final ConstantPoolGen cpGen) throws IOException 91 { 92 final int type = dis.readUnsignedByte(); 93 switch (type) 94 { 95 case 'B': // byte 96 return new SimpleElementValueGen(PRIMITIVE_BYTE, dis 97 .readUnsignedShort(), cpGen); 98 case 'C': // char 99 return new SimpleElementValueGen(PRIMITIVE_CHAR, dis 100 .readUnsignedShort(), cpGen); 101 case 'D': // double 102 return new SimpleElementValueGen(PRIMITIVE_DOUBLE, dis 103 .readUnsignedShort(), cpGen); 104 case 'F': // float 105 return new SimpleElementValueGen(PRIMITIVE_FLOAT, dis 106 .readUnsignedShort(), cpGen); 107 case 'I': // int 108 return new SimpleElementValueGen(PRIMITIVE_INT, dis 109 .readUnsignedShort(), cpGen); 110 case 'J': // long 111 return new SimpleElementValueGen(PRIMITIVE_LONG, dis 112 .readUnsignedShort(), cpGen); 113 case 'S': // short 114 return new SimpleElementValueGen(PRIMITIVE_SHORT, dis 115 .readUnsignedShort(), cpGen); 116 case 'Z': // boolean 117 return new SimpleElementValueGen(PRIMITIVE_BOOLEAN, dis 118 .readUnsignedShort(), cpGen); 119 case 's': // String 120 return new SimpleElementValueGen(STRING, dis.readUnsignedShort(), 121 cpGen); 122 case 'e': // Enum constant 123 return new EnumElementValueGen(dis.readUnsignedShort(), dis 124 .readUnsignedShort(), cpGen); 125 case 'c': // Class 126 return new ClassElementValueGen(dis.readUnsignedShort(), cpGen); 127 case '@': // Annotation 128 // TODO: isRuntimeVisible ?????????? 129 // FIXME 130 return new AnnotationElementValueGen(ANNOTATION, 131 new AnnotationEntryGen(AnnotationEntry.read(dis, cpGen 132 .getConstantPool(), true), cpGen, false), cpGen); 133 case '[': // Array 134 final int numArrayVals = dis.readUnsignedShort(); 135 final ElementValue[] evalues = new ElementValue[numArrayVals]; 136 for (int j = 0; j < numArrayVals; j++) 137 { 138 evalues[j] = ElementValue.readElementValue(dis, cpGen 139 .getConstantPool()); 140 } 141 return new ArrayElementValueGen(ARRAY, evalues, cpGen); 142 default: 143 throw new RuntimeException("Unexpected element value kind in annotation: " + type); 144 } 145 } 146 147 protected ConstantPoolGen getConstantPool() 148 { 149 return cpGen; 150 } 151 152 /** 153 * Creates an (modifiable) ElementValueGen copy of an (immutable) 154 * ElementValue - constant pool is assumed correct. 155 */ 156 public static ElementValueGen copy(final ElementValue value, 157 final ConstantPoolGen cpool, final boolean copyPoolEntries) 158 { 159 switch (value.getElementValueType()) 160 { 161 case 'B': // byte 162 case 'C': // char 163 case 'D': // double 164 case 'F': // float 165 case 'I': // int 166 case 'J': // long 167 case 'S': // short 168 case 'Z': // boolean 169 case 's': // String 170 return new SimpleElementValueGen((SimpleElementValue) value, cpool, 171 copyPoolEntries); 172 case 'e': // Enum constant 173 return new EnumElementValueGen((EnumElementValue) value, cpool, 174 copyPoolEntries); 175 case '@': // Annotation 176 return new AnnotationElementValueGen( 177 (AnnotationElementValue) value, cpool, copyPoolEntries); 178 case '[': // Array 179 return new ArrayElementValueGen((ArrayElementValue) value, cpool, 180 copyPoolEntries); 181 case 'c': // Class 182 return new ClassElementValueGen((ClassElementValue) value, cpool, 183 copyPoolEntries); 184 default: 185 throw new RuntimeException("Not implemented yet! (" + value.getElementValueType() + ")"); 186 } 187 } 188} 189