View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
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   * This class represents the type of a local variable or item on stack
28   * used in the StackMap entries.
29   *
30   * @see     StackMapEntry
31   * @see     StackMap
32   * @see     Const
33   */
34  public final class StackMapType implements Cloneable {
35  
36      private byte type;
37      private int index = -1; // Index to CONSTANT_Class or offset
38      private ConstantPool constantPool;
39  
40  
41      /**
42       * Construct object from file stream.
43       * @param file Input stream
44       * @throws IOException
45       */
46      StackMapType(final DataInput file, final ConstantPool constant_pool) throws IOException {
47          this(file.readByte(), -1, constant_pool);
48          if (hasIndex()) {
49              this.index = file.readShort();
50          }
51          this.constantPool = 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(final byte type, final int index, final ConstantPool constant_pool) {
60          if ((type < Const.ITEM_Bogus) || (type > Const.ITEM_NewObject)) {
61              throw new IllegalArgumentException("Illegal type for StackMapType: " + type);
62          }
63          this.type = type;
64          this.index = index;
65          this.constantPool = constant_pool;
66      }
67  
68  
69      public void setType( final byte t ) {
70          if ((t < Const.ITEM_Bogus) || (t > Const.ITEM_NewObject)) {
71              throw new IllegalArgumentException("Illegal type for StackMapType: " + t);
72          }
73          type = t;
74      }
75  
76  
77      public byte getType() {
78          return type;
79      }
80  
81  
82      public void setIndex( final int t ) {
83          index = t;
84      }
85  
86  
87      /** @return index to constant pool if type == ITEM_Object, or offset
88       * in byte code, if type == ITEM_NewObject, and -1 otherwise
89       */
90      public int getIndex() {
91          return index;
92      }
93  
94  
95      /**
96       * Dump type entries to file.
97       *
98       * @param file Output file stream
99       * @throws IOException
100      */
101     public void dump( final DataOutputStream file ) throws IOException {
102         file.writeByte(type);
103         if (hasIndex()) {
104             file.writeShort(getIndex());
105         }
106     }
107 
108 
109     /** @return true, if type is either ITEM_Object or ITEM_NewObject
110      */
111     public boolean hasIndex() {
112         return type == Const.ITEM_Object || type == Const.ITEM_NewObject;
113     }
114 
115 
116     private String printIndex() {
117         if (type == Const.ITEM_Object) {
118             if (index < 0) {
119                 return ", class=<unknown>";
120             }
121             return ", class=" + constantPool.constantToString(index, Const.CONSTANT_Class);
122         } else if (type == Const.ITEM_NewObject) {
123             return ", offset=" + index;
124         } else {
125             return "";
126         }
127     }
128 
129 
130     /**
131      * @return String representation
132      */
133     @Override
134     public String toString() {
135         return "(type=" + Const.getItemName(type) + printIndex() + ")";
136     }
137 
138 
139     /**
140      * @return deep copy of this object
141      */
142     public StackMapType copy() {
143         try {
144             return (StackMapType) clone();
145         } catch (final CloneNotSupportedException e) {
146             // TODO should this throw?
147         }
148         return null;
149     }
150 
151 
152     /**
153      * @return Constant pool used by this object.
154      */
155     public ConstantPool getConstantPool() {
156         return constantPool;
157     }
158 
159 
160     /**
161      * @param constantPool Constant pool to be used for this object.
162      */
163     public void setConstantPool( final ConstantPool constantPool ) {
164         this.constantPool = constantPool;
165     }
166 }