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