1 /* 2 * Copyright (c) 2017, 2020, 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 21 package com.sun.org.apache.bcel.internal.generic; 22 23 import java.io.DataInput; 24 import java.io.DataOutputStream; 25 import java.io.IOException; 26 27 import com.sun.org.apache.bcel.internal.classfile.AnnotationElementValue; 28 import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; 29 import com.sun.org.apache.bcel.internal.classfile.ArrayElementValue; 30 import com.sun.org.apache.bcel.internal.classfile.ClassElementValue; 31 import com.sun.org.apache.bcel.internal.classfile.ElementValue; 32 import com.sun.org.apache.bcel.internal.classfile.EnumElementValue; 33 import com.sun.org.apache.bcel.internal.classfile.SimpleElementValue; 34 35 /** 36 * @since 6.0 37 * @LastModified: Jan 2020 38 */ 39 public abstract class ElementValueGen 40 { 41 private final int type; 42 private final ConstantPoolGen cpGen; 43 44 protected ElementValueGen(final int type, final ConstantPoolGen cpGen) 45 { 46 this.type = type; 47 this.cpGen = cpGen; 48 } 49 50 /** 51 * Subtypes return an immutable variant of the ElementValueGen 52 */ 53 public abstract ElementValue getElementValue(); 54 55 public int getElementValueType() 56 { 57 return type; 58 } 59 60 public abstract String stringifyValue(); 61 62 public abstract void dump(DataOutputStream dos) throws IOException; 63 64 public static final int STRING = 's'; 65 66 public static final int ENUM_CONSTANT = 'e'; 67 68 public static final int CLASS = 'c'; 69 70 public static final int ANNOTATION = '@'; 71 72 public static final int ARRAY = '['; 73 74 public static final int PRIMITIVE_INT = 'I'; 75 76 public static final int PRIMITIVE_BYTE = 'B'; 77 78 public static final int PRIMITIVE_CHAR = 'C'; 79 80 public static final int PRIMITIVE_DOUBLE = 'D'; 81 82 public static final int PRIMITIVE_FLOAT = 'F'; 83 84 public static final int PRIMITIVE_LONG = 'J'; 85 86 public static final int PRIMITIVE_SHORT = 'S'; 87 88 public static final int PRIMITIVE_BOOLEAN = 'Z'; 89 90 public static ElementValueGen readElementValue(final DataInput dis, 91 final ConstantPoolGen cpGen) throws IOException 92 { 93 final int type = dis.readUnsignedByte(); 94 switch (type) 95 { 96 case 'B': // byte 97 return new SimpleElementValueGen(PRIMITIVE_BYTE, dis 98 .readUnsignedShort(), cpGen); 99 case 'C': // char 100 return new SimpleElementValueGen(PRIMITIVE_CHAR, dis 101 .readUnsignedShort(), cpGen); 102 case 'D': // double 103 return new SimpleElementValueGen(PRIMITIVE_DOUBLE, dis 104 .readUnsignedShort(), cpGen); 105 case 'F': // float 106 return new SimpleElementValueGen(PRIMITIVE_FLOAT, dis 107 .readUnsignedShort(), cpGen); 108 case 'I': // int 109 return new SimpleElementValueGen(PRIMITIVE_INT, dis 110 .readUnsignedShort(), cpGen); 111 case 'J': // long 112 return new SimpleElementValueGen(PRIMITIVE_LONG, dis 113 .readUnsignedShort(), cpGen); 114 case 'S': // short 115 return new SimpleElementValueGen(PRIMITIVE_SHORT, dis 116 .readUnsignedShort(), cpGen); 117 case 'Z': // boolean 118 return new SimpleElementValueGen(PRIMITIVE_BOOLEAN, dis 119 .readUnsignedShort(), cpGen); 120 case 's': // String 121 return new SimpleElementValueGen(STRING, dis.readUnsignedShort(), 122 cpGen); 123 case 'e': // Enum constant 124 return new EnumElementValueGen(dis.readUnsignedShort(), dis 125 .readUnsignedShort(), cpGen); 126 case 'c': // Class 127 return new ClassElementValueGen(dis.readUnsignedShort(), cpGen); 128 case '@': // Annotation 129 // TODO: isRuntimeVisible ?????????? 130 // FIXME 131 return new AnnotationElementValueGen(ANNOTATION, 132 new AnnotationEntryGen(AnnotationEntry.read(dis, cpGen 133 .getConstantPool(), true), cpGen, false), cpGen); 134 case '[': // Array 135 final int numArrayVals = dis.readUnsignedShort(); 136 final ElementValue[] evalues = new ElementValue[numArrayVals]; 137 for (int j = 0; j < numArrayVals; j++) 138 { 139 evalues[j] = ElementValue.readElementValue(dis, cpGen 140 .getConstantPool()); 141 } 142 return new ArrayElementValueGen(ARRAY, evalues, cpGen); 143 default: 144 throw new RuntimeException("Unexpected element value kind in annotation: " + type); 145 } 146 } 147 148 protected ConstantPoolGen getConstantPool() 149 { 150 return cpGen; 151 } 152 153 /** 154 * Creates an (modifiable) ElementValueGen copy of an (immutable) 155 * ElementValue - constant pool is assumed correct. 156 */ 157 public static ElementValueGen copy(final ElementValue value, 158 final ConstantPoolGen cpool, final boolean copyPoolEntries) 159 { 160 switch (value.getElementValueType()) 161 { 162 case 'B': // byte 163 case 'C': // char 164 case 'D': // double 165 case 'F': // float 166 case 'I': // int 167 case 'J': // long 168 case 'S': // short 169 case 'Z': // boolean 170 case 's': // String 171 return new SimpleElementValueGen((SimpleElementValue) value, cpool, 172 copyPoolEntries); 173 case 'e': // Enum constant 174 return new EnumElementValueGen((EnumElementValue) value, cpool, 175 copyPoolEntries); 176 case '@': // Annotation 177 return new AnnotationElementValueGen( 178 (AnnotationElementValue) value, cpool, copyPoolEntries); 179 case '[': // Array 180 return new ArrayElementValueGen((ArrayElementValue) value, cpool, 181 copyPoolEntries); 182 case 'c': // Class 183 return new ClassElementValueGen((ClassElementValue) value, cpool, 184 copyPoolEntries); 185 default: 186 throw new RuntimeException("Not implemented yet! (" + value.getElementValueType() + ")"); 187 } 188 } 189 }