001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 */
018 package org.apache.bcel.classfile;
019
020 import java.io.DataInputStream;
021 import java.io.DataOutputStream;
022 import java.io.IOException;
023 import org.apache.bcel.Constants;
024
025 /**
026 * This class represents a stack map attribute used for
027 * preverification of Java classes for the <a
028 * href="http://java.sun.com/j2me/"> Java 2 Micro Edition</a>
029 * (J2ME). This attribute is used by the <a
030 * href="http://java.sun.com/products/cldc/">KVM</a> and contained
031 * within the Code attribute of a method. See CLDC specification
032 * �5.3.1.2
033 *
034 * @version $Id: StackMap.java 1152077 2011-07-29 02:29:42Z dbrosius $
035 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
036 * @see Code
037 * @see StackMapEntry
038 * @see StackMapType
039 */
040 public final class StackMap extends Attribute {
041
042 private static final long serialVersionUID = -6238662431726968495L;
043 private int map_length;
044 private StackMapEntry[] map; // Table of stack map entries
045
046
047 /*
048 * @param name_index Index of name
049 * @param length Content length in bytes
050 * @param map Table of stack map entries
051 * @param constant_pool Array of constants
052 */
053 public StackMap(int name_index, int length, StackMapEntry[] map, ConstantPool constant_pool) {
054 super(Constants.ATTR_STACK_MAP, name_index, length, constant_pool);
055 setStackMap(map);
056 }
057
058
059 /**
060 * Construct object from file stream.
061 * @param name_index Index of name
062 * @param length Content length in bytes
063 * @param file Input stream
064 * @param constant_pool Array of constants
065 * @throws IOException
066 */
067 StackMap(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
068 throws IOException {
069 this(name_index, length, (StackMapEntry[]) null, constant_pool);
070 map_length = file.readUnsignedShort();
071 map = new StackMapEntry[map_length];
072 for (int i = 0; i < map_length; i++) {
073 map[i] = new StackMapEntry(file, constant_pool);
074 }
075 }
076
077
078 /**
079 * Dump line number table attribute to file stream in binary format.
080 *
081 * @param file Output file stream
082 * @throws IOException
083 */
084 @Override
085 public final void dump( DataOutputStream file ) throws IOException {
086 super.dump(file);
087 file.writeShort(map_length);
088 for (int i = 0; i < map_length; i++) {
089 map[i].dump(file);
090 }
091 }
092
093
094 /**
095 * @return Array of stack map entries
096 */
097 public final StackMapEntry[] getStackMap() {
098 return map;
099 }
100
101
102 /**
103 * @param map Array of stack map entries
104 */
105 public final void setStackMap( StackMapEntry[] map ) {
106 this.map = map;
107 map_length = (map == null) ? 0 : map.length;
108 }
109
110
111 /**
112 * @return String representation.
113 */
114 @Override
115 public final String toString() {
116 StringBuilder buf = new StringBuilder("StackMap(");
117 for (int i = 0; i < map_length; i++) {
118 buf.append(map[i].toString());
119 if (i < map_length - 1) {
120 buf.append(", ");
121 }
122 }
123 buf.append(')');
124 return buf.toString();
125 }
126
127
128 /**
129 * @return deep copy of this attribute
130 */
131 @Override
132 public Attribute copy( ConstantPool _constant_pool ) {
133 StackMap c = (StackMap) clone();
134 c.map = new StackMapEntry[map_length];
135 for (int i = 0; i < map_length; i++) {
136 c.map[i] = map[i].copy();
137 }
138 c.constant_pool = _constant_pool;
139 return c;
140 }
141
142
143 /**
144 * Called by objects that are traversing the nodes of the tree implicitely
145 * defined by the contents of a Java class. I.e., the hierarchy of methods,
146 * fields, attributes, etc. spawns a tree of objects.
147 *
148 * @param v Visitor object
149 */
150 @Override
151 public void accept( Visitor v ) {
152 v.visitStackMap(this);
153 }
154
155
156 public final int getMapLength() {
157 return map_length;
158 }
159 }