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 a stack map attribute used for
  32  * preverification of Java classes for the <a
  33  * href="http://java.sun.com/j2me/"> Java 2 Micro Edition</a>
  34  * (J2ME). This attribute is used by the <a
  35  * href="http://java.sun.com/products/cldc/">KVM</a> and contained
  36  * within the Code attribute of a method. See CLDC specification
  37  * 5.3.1.2
  38  *
  39  * @version $Id$
  40  * @see     Code
  41  * @see     StackMapEntry
  42  * @see     StackMapType
  43  */
  44 public final class StackMap extends Attribute {
  45 
  46     private StackMapEntry[] map; // Table of stack map entries
  47 
  48 
  49     /*
  50      * @param name_index Index of name
  51      * @param length Content length in bytes
  52      * @param map Table of stack map entries
  53      * @param constant_pool Array of constants
  54      */
  55     public StackMap(final int name_index, final int length, final StackMapEntry[] map, final ConstantPool constant_pool) {
  56         super(Const.ATTR_STACK_MAP, name_index, length, constant_pool);
  57         this.map = map;
  58     }
  59 
  60 
  61     /**
  62      * Construct object from input stream.
  63      *
  64      * @param name_index Index of name
  65      * @param length Content length in bytes
  66      * @param input Input stream
  67      * @param constant_pool Array of constants
  68      * @throws IOException
  69      */
  70     StackMap(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException {
  71         this(name_index, length, (StackMapEntry[]) null, constant_pool);
  72         final int map_length = input.readUnsignedShort();
  73         map = new StackMapEntry[map_length];
  74         for (int i = 0; i < map_length; i++) {
  75             map[i] = new StackMapEntry(input, constant_pool);
  76         }
  77     }
  78 
  79 
  80     /**
  81      * Dump stack map table attribute to file stream in binary format.
  82      *
  83      * @param file Output file stream
  84      * @throws IOException
  85      */
  86     @Override
  87     public final void dump( final DataOutputStream file ) throws IOException {
  88         super.dump(file);
  89         file.writeShort(map.length);
  90         for (final StackMapEntry entry : map) {
  91             entry.dump(file);
  92         }
  93     }
  94 
  95 
  96     /**
  97      * @return Array of stack map entries
  98      */
  99     public final StackMapEntry[] getStackMap() {
 100         return map;
 101     }
 102 
 103 
 104     /**
 105      * @param map Array of stack map entries
 106      */
 107     public final void setStackMap( final StackMapEntry[] map ) {
 108         this.map = map;
 109         int len = 2; // Length of 'number_of_entries' field prior to the array of stack maps
 110         for (final StackMapEntry element : map) {
 111             len += element.getMapEntrySize();
 112         }
 113         setLength(len);
 114     }
 115 
 116 
 117     /**
 118      * @return String representation.
 119      */
 120     @Override
 121     public final String toString() {
 122         final StringBuilder buf = new StringBuilder("StackMap(");
 123         for (int i = 0; i < map.length; i++) {
 124             buf.append(map[i]);
 125             if (i < map.length - 1) {
 126                 buf.append(", ");
 127             }
 128         }
 129         buf.append(')');
 130         return buf.toString();
 131     }
 132 
 133 
 134     /**
 135      * @return deep copy of this attribute
 136      */
 137     @Override
 138     public Attribute copy( final ConstantPool _constant_pool ) {
 139         final StackMap c = (StackMap) clone();
 140         c.map = new StackMapEntry[map.length];
 141         for (int i = 0; i < map.length; i++) {
 142             c.map[i] = map[i].copy();
 143         }
 144         c.setConstantPool(_constant_pool);
 145         return c;
 146     }
 147 
 148 
 149     /**
 150      * Called by objects that are traversing the nodes of the tree implicitely
 151      * defined by the contents of a Java class. I.e., the hierarchy of methods,
 152      * fields, attributes, etc. spawns a tree of objects.
 153      *
 154      * @param v Visitor object
 155      */
 156     @Override
 157     public void accept( final Visitor v ) {
 158         v.visitStackMap(this);
 159     }
 160 
 161 
 162     public final int getMapLength() {
 163         return map == null ? 0 : map.length;
 164     }
 165 }