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