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 
  22 package com.sun.org.apache.bcel.internal.classfile;
  23 
  24 import java.io.DataInput;
  25 import java.io.DataOutputStream;
  26 import java.io.IOException;
  27 
  28 import 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  */
  39 public 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 }