1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.bcel.classfile;
21
22 import java.io.DataInput;
23 import java.io.DataOutputStream;
24 import java.io.IOException;
25
26 import org.apache.bcel.Const;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public abstract class ElementValue {
54
55 public static final byte STRING = 's';
56 public static final byte ENUM_CONSTANT = 'e';
57 public static final byte CLASS = 'c';
58 public static final byte ANNOTATION = '@';
59 public static final byte ARRAY = '[';
60 public static final byte PRIMITIVE_INT = 'I';
61 public static final byte PRIMITIVE_BYTE = 'B';
62 public static final byte PRIMITIVE_CHAR = 'C';
63 public static final byte PRIMITIVE_DOUBLE = 'D';
64 public static final byte PRIMITIVE_FLOAT = 'F';
65 public static final byte PRIMITIVE_LONG = 'J';
66 public static final byte PRIMITIVE_SHORT = 'S';
67 public static final byte PRIMITIVE_BOOLEAN = 'Z';
68 static final ElementValue[] EMPTY_ARRAY = {};
69
70
71
72
73
74
75
76
77
78 public static ElementValue readElementValue(final DataInput input, final ConstantPool cpool) throws IOException {
79 return readElementValue(input, cpool, 0);
80 }
81
82
83
84
85
86
87
88
89
90
91
92 public static ElementValue readElementValue(final DataInput input, final ConstantPool cpool, int arrayNesting)
93 throws IOException {
94 final byte tag = input.readByte();
95 switch (tag) {
96 case PRIMITIVE_BYTE:
97 case PRIMITIVE_CHAR:
98 case PRIMITIVE_DOUBLE:
99 case PRIMITIVE_FLOAT:
100 case PRIMITIVE_INT:
101 case PRIMITIVE_LONG:
102 case PRIMITIVE_SHORT:
103 case PRIMITIVE_BOOLEAN:
104 case STRING:
105 return new SimpleElementValue(tag, input.readUnsignedShort(), cpool);
106
107 case ENUM_CONSTANT:
108 return new EnumElementValue(ENUM_CONSTANT, input.readUnsignedShort(), input.readUnsignedShort(), cpool);
109
110 case CLASS:
111 return new ClassElementValue(CLASS, input.readUnsignedShort(), cpool);
112
113 case ANNOTATION:
114
115 return new AnnotationElementValue(ANNOTATION, AnnotationEntry.read(input, cpool, false), cpool);
116
117 case ARRAY:
118 arrayNesting++;
119 if (arrayNesting > Const.MAX_ARRAY_DIMENSIONS) {
120
121 throw new ClassFormatException(String.format("Arrays are only valid if they represent %,d or fewer dimensions.", Const.MAX_ARRAY_DIMENSIONS));
122 }
123 final int numArrayVals = input.readUnsignedShort();
124 final ElementValue[] evalues = new ElementValue[numArrayVals];
125 for (int j = 0; j < numArrayVals; j++) {
126 evalues[j] = readElementValue(input, cpool, arrayNesting);
127 }
128 return new ArrayElementValue(ARRAY, evalues, cpool);
129
130 default:
131 throw new ClassFormatException("Unexpected element value tag in annotation: " + tag);
132 }
133 }
134
135
136
137
138 @java.lang.Deprecated
139 protected int type;
140
141
142
143 @java.lang.Deprecated
144 protected ConstantPool cpool;
145
146 protected ElementValue(final int type, final ConstantPool cpool) {
147 this.type = type;
148 this.cpool = cpool;
149 }
150
151 public abstract void dump(DataOutputStream dos) throws IOException;
152
153
154 final ConstantPool getConstantPool() {
155 return cpool;
156 }
157
158 public int getElementValueType() {
159 return type;
160 }
161
162
163 final int getType() {
164 return type;
165 }
166
167 public abstract String stringifyValue();
168
169 public String toShortString() {
170 return stringifyValue();
171 }
172
173 @Override
174 public String toString() {
175 return stringifyValue();
176 }
177 }