Source code: com/chaoswg/xtc4y/classdesc/CodeAttribute.java
1 //$Header: /cvsroot/xtc4y/xtc4y/src/com/chaoswg/xtc4y/classdesc/CodeAttribute.java,v 1.4 2003/09/08 21:09:54 toggm Exp $
2 /******************************************************************************
3 * XTC4y - eXtreme Testing Collection 4 you *
4 * -------------------------------------------------------------------------- *
5 * URL: http://www.chaoswg.com/xtc4y *
6 * Author: Mike Toggweiler (2.dog@gmx.ch) *
7 * *
8 * Last Updated: $Date: 2003/09/08 21:09:54 $, by $Author: toggm $ *
9 * Version: $Revision: 1.4 $ *
10 * -------------------------------------------------------------------------- *
11 * COPYRIGHT: (c) 2003 by Mike Toggweiler *
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 *****************************************************************************/
18 package com.chaoswg.xtc4y.classdesc;
19
20 import java.util.Vector;
21
22 import java.io.DataInputStream;
23 import java.io.DataOutputStream;
24 import java.io.IOException;
25
26 import com.chaoswg.xtc4y.classdesc.code.Code;
27
28 /**
29 * This class describes the information for a code attribute ($4.7.3)
30 * TBD: replace the byte array representing the code by a code class thorugh
31 * which easily the code may be changed an extended and all the indices
32 * may be checked (as with the constant pool)
33 * @author Mike Toggweiler
34 **/
35 public class CodeAttribute extends Attribute {
36
37 private short maxStack;
38 private short maxLocals;
39 private Code code;
40 private Vector exceptions;
41
42 private Vector attributes;
43
44 public static final String NAME = "Code";
45 private static final short DEFAULT_MAX_STACK = 10;
46 private static final short DEFAULT_MAX_LOCALS = 10;
47
48 /**
49 * Creates a CodeAttribute and initializes it from a DataInputStream
50 * The attribute name and length
51 * of the attribute information was already read.
52 * @param dis the DataInputStream to read from
53 * @param cp the constant pool to resolve indices
54 * @param length the length of the attribute information provided
55 * on the DataInputStream
56 **/
57 protected CodeAttribute(DataInputStream dis, ConstantPool cp,
58 int length)
59 throws IOException {
60 super(dis, cp, length);
61 exceptions = new Vector();
62 attributes = new Vector();
63
64 if (!getName().equals(NAME)) {
65 throw new ClassFormatError("Attribute name does not match");
66 }
67 maxStack = (short)dis.readUnsignedShort();
68 maxLocals = (short)dis.readUnsignedShort();
69 int codeLength = dis.readInt();
70 code = new Code(dis, cp, codeLength);
71 int exLength = dis.readUnsignedShort();
72 for (int i=0; i<exLength; ++i) {
73 exceptions.add(new ExceptionInfo(dis, cp, code));
74 }
75 int attrLength = dis.readUnsignedShort();
76 for (int i=0; i<attrLength; ++i) {
77 AttributeInfo ai = new AttributeInfo(dis, cp);
78 Attribute attr = ai.getAttribute();
79 if (attr instanceof CodeCompatible) {
80 ((CodeCompatible)attr).resolveIndices(code);
81 }
82 attributes.add(ai);
83 }
84 }
85
86 /**
87 * Construct a new code attribute with default values except the code
88 * part. The exceptions and attributes are initializes to be empty
89 * @param code the instructions as code
90 **/
91 public CodeAttribute(Code code) {
92 maxStack = DEFAULT_MAX_STACK;
93 maxLocals = DEFAULT_MAX_LOCALS;
94 this.code = code;
95 exceptions = new Vector();
96 attributes = new Vector();
97 }
98
99 /**
100 * Write the attribute information onto the DataOutputStream, using the
101 * constant pool to register variables. The Attribute name and the
102 * length of the information will already be written. A specific
103 * attribute implementation should overwrite this method.
104 * @param dos the DataOutputStream to write on
105 * @param cp The constant pool to register variables
106 **/
107 protected void writeAttribute(DataOutputStream dos, ConstantPool cp)
108 throws IOException {
109 dos.writeShort(maxStack);
110 dos.writeShort(maxLocals);
111 dos.writeInt(code.getLength());
112 code.write(dos, cp);
113 //write exceptions
114 dos.writeShort(exceptions.size());
115 for (int i=0; i<exceptions.size(); ++i) {
116 ((ExceptionInfo)exceptions.elementAt(i)).write(dos, cp, code);
117 }
118 //write attributes
119 dos.writeShort(attributes.size());
120 for (int i=0; i<attributes.size(); ++i) {
121 AttributeInfo ai = (AttributeInfo)attributes.elementAt(i);
122 Attribute attr = ai.getAttribute();
123 if (attr instanceof CodeCompatible) {
124 ((CodeCompatible)attr).readIndices(code);
125 }
126 ai.write(dos, cp);
127 }
128 }
129
130 /**
131 * @return the max stack
132 **/
133 public short getMaxStack() {
134 return maxStack;
135 }
136
137 /**
138 * @return the max locals
139 **/
140 public short getMaxLocals() {
141 return maxLocals;
142 }
143
144 /**
145 * @return the code array in bytes, for further information see $4.8
146 **/
147 public Code getCode() {
148 return code;
149 }
150
151 /**
152 * @return an array of exceptions
153 **/
154 public ExceptionInfo[] getExceptions() {
155 return ((ExceptionInfo[])
156 exceptions.toArray(new ExceptionInfo[exceptions.size()]));
157 }
158
159 /**
160 * Add an exception
161 * @param exception to add
162 **/
163 public void addException(ExceptionInfo exception) {
164 exceptions.add(exception);
165 }
166
167 /**
168 * Remove an exception
169 * @param exception to remove
170 **/
171 public void removeException(ExceptionInfo exception) {
172 exceptions.remove(exception);
173 }
174
175 /**
176 * @return an array of attributes
177 **/
178 public AttributeInfo[] getAttributes() {
179 return ((AttributeInfo[])
180 attributes.toArray(new AttributeInfo[attributes.size()]));
181 }
182
183 /**
184 * Add an attribute
185 * @param attribute to add
186 **/
187 public void addAttribute(AttributeInfo attribute) {
188 attributes.add(attribute);
189 }
190
191 /**
192 * Remove an attribute
193 * @param attribute to remove
194 **/
195 public void removeAttribute(AttributeInfo attribute) {
196 attributes.remove(attribute);
197 }
198
199 /**
200 * Set the new max stack
201 * @param maxStack
202 **/
203 public void setMaxStack(short maxStack) {
204 this.maxStack = maxStack;
205 }
206
207 /**
208 * Set the new max locals
209 * @param maxLocals
210 **/
211 public void setMaxLocals(short maxLocals) {
212 this.maxLocals = maxLocals;
213 }
214
215 /**
216 * Set the new byte array of code
217 * @param code
218 **/
219 public void setCode(Code code) {
220 this.code = code;
221 }
222
223 /**
224 * @return the name of the attribute
225 **/
226 public String getName() {
227 return NAME;
228 }
229
230 /**
231 * Write in a readable way
232 **/
233 public String toString() {
234 String ret = super.toString() + "\n";
235 ret += "MaxStack: " + maxStack + "\n";
236 ret += "MaxLocals: " + maxLocals + "\n";
237 ret += "Code: " + code + "\n";
238 ret += "Exceptions: \n";
239 for (int i=0; i<exceptions.size(); ++i) {
240 ret += " " + i + " " + exceptions.elementAt(i) + "\n";
241 }
242 ret += "Attributes: \n";
243 for (int i=0; i<attributes.size(); ++i) {
244 ret += " " + i + " " + attributes.elementAt(i) + "\n";
245 }
246 return ret;
247 }
248 }