1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.classfile;
18
19 import java.io.DataInputStream;
20 import java.io.DataOutputStream;
21 import java.io.IOException;
22 import org.apache.bcel.Constants;
23
24 /***
25 * This class represents the type of a local variable or item on stack
26 * used in the StackMap entries.
27 *
28 * @version $Id: StackMapType.java 386056 2006-03-15 11:31:56Z tcurdt $
29 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
30 * @see StackMapEntry
31 * @see StackMap
32 * @see Constants
33 */
34 public final class StackMapType implements Cloneable {
35
36 private byte type;
37 private int index = -1;
38 private ConstantPool constant_pool;
39
40
41 /***
42 * Construct object from file stream.
43 * @param file Input stream
44 * @throws IOException
45 */
46 StackMapType(DataInputStream file, ConstantPool constant_pool) throws IOException {
47 this(file.readByte(), -1, constant_pool);
48 if (hasIndex()) {
49 setIndex(file.readShort());
50 }
51 setConstantPool(constant_pool);
52 }
53
54
55 /***
56 * @param type type tag as defined in the Constants interface
57 * @param index index to constant pool, or byte code offset
58 */
59 public StackMapType(byte type, int index, ConstantPool constant_pool) {
60 setType(type);
61 setIndex(index);
62 setConstantPool(constant_pool);
63 }
64
65
66 public void setType( byte t ) {
67 if ((t < Constants.ITEM_Bogus) || (t > Constants.ITEM_NewObject)) {
68 throw new RuntimeException("Illegal type for StackMapType: " + t);
69 }
70 type = t;
71 }
72
73
74 public byte getType() {
75 return type;
76 }
77
78
79 public void setIndex( int t ) {
80 index = t;
81 }
82
83
84 /*** @return index to constant pool if type == ITEM_Object, or offset
85 * in byte code, if type == ITEM_NewObject, and -1 otherwise
86 */
87 public int getIndex() {
88 return index;
89 }
90
91
92 /***
93 * Dump type entries to file.
94 *
95 * @param file Output file stream
96 * @throws IOException
97 */
98 public final void dump( DataOutputStream file ) throws IOException {
99 file.writeByte(type);
100 if (hasIndex()) {
101 file.writeShort(getIndex());
102 }
103 }
104
105
106 /*** @return true, if type is either ITEM_Object or ITEM_NewObject
107 */
108 public final boolean hasIndex() {
109 return ((type == Constants.ITEM_Object) || (type == Constants.ITEM_NewObject));
110 }
111
112
113 private String printIndex() {
114 if (type == Constants.ITEM_Object) {
115 if (index < 0) {
116 return ", class=<unknown>";
117 }
118 return ", class=" + constant_pool.constantToString(index, Constants.CONSTANT_Class);
119 } else if (type == Constants.ITEM_NewObject) {
120 return ", offset=" + index;
121 } else {
122 return "";
123 }
124 }
125
126
127 /***
128 * @return String representation
129 */
130 public final String toString() {
131 return "(type=" + Constants.ITEM_NAMES[type] + printIndex() + ")";
132 }
133
134
135 /***
136 * @return deep copy of this object
137 */
138 public StackMapType copy() {
139 try {
140 return (StackMapType) clone();
141 } catch (CloneNotSupportedException e) {
142 }
143 return null;
144 }
145
146
147 /***
148 * @return Constant pool used by this object.
149 */
150 public final ConstantPool getConstantPool() {
151 return constant_pool;
152 }
153
154
155 /***
156 * @param constant_pool Constant pool to be used for this object.
157 */
158 public final void setConstantPool( ConstantPool constant_pool ) {
159 this.constant_pool = constant_pool;
160 }
161 }