001: /*
002: This library is free software; you can redistribute it and/or
003: modify it under the terms of the GNU General Public
004: License as published by the Free Software Foundation; either
005: version 2 of the license, or (at your option) any later version.
006: */
007:
008: package org.gjt.jclasslib.structures.attributes;
009:
010: import org.gjt.jclasslib.structures.AttributeInfo;
011: import org.gjt.jclasslib.structures.InvalidByteCodeException;
012:
013: import java.io.*;
014:
015: /**
016: Describes a <tt>Code</tt> attribute structure.
017:
018: @author <a href="mailto:jclasslib@ej-technologies.com">Ingo Kegel</a>
019: @version $Revision: 1.4 $ $Date: 2003/08/18 07:52:05 $
020: */
021: public class CodeAttribute extends AttributeInfo {
022:
023: /** Name of the attribute as in the corresponding constant pool entry. */
024: public static final String ATTRIBUTE_NAME = "Code";
025:
026: private static final int INITIAL_LENGTH = 12;
027:
028: private int maxStack;
029: private int maxLocals;
030: private byte[] code;
031: private ExceptionTableEntry[] exceptionTable;
032:
033: /**
034: Get the maximum stack depth of this code attribute.
035: @return the stack depth
036: */
037: public int getMaxStack() {
038: return maxStack;
039: }
040:
041: /**
042: Set the maximum stack depth of this code attribute.
043: @param maxStack the stack depth
044: */
045: public void setMaxStack(int maxStack) {
046: this .maxStack = maxStack;
047: }
048:
049: /**
050: Get the maximum number of local variables of this code attribute.
051: @return the maximum number
052: */
053: public int getMaxLocals() {
054: return maxLocals;
055: }
056:
057: /**
058: Set the maximum number of local variables of this code attribute.
059: @param maxLocals the maximum number
060: */
061: public void setMaxLocals(int maxLocals) {
062: this .maxLocals = maxLocals;
063: }
064:
065: /**
066: Get the code of this code attribute as an array of bytes .
067: @return the array
068: */
069: public byte[] getCode() {
070: return code;
071: }
072:
073: /**
074: Set the code of this code attribute as an array of bytes .
075: @param code the array
076: */
077: public void setCode(byte[] code) {
078: this .code = code;
079: }
080:
081: /**
082: Get the exception table of this code attribute as an array of
083: <tt>ExceptionTableEntry</tt> elements.
084: @return the array
085: */
086: public ExceptionTableEntry[] getExceptionTable() {
087: return exceptionTable;
088: }
089:
090: /**
091: Set the exception table of this code attribute as an array of
092: <tt>ExceptionTableEntry</tt> elements.
093: @param exceptionTable the array
094: */
095: public void setExceptionTable(ExceptionTableEntry[] exceptionTable) {
096: this .exceptionTable = exceptionTable;
097: }
098:
099: public void read(DataInput in) throws InvalidByteCodeException,
100: IOException {
101:
102: maxStack = in.readUnsignedShort();
103: maxLocals = in.readUnsignedShort();
104: int codeLength = in.readInt();
105: code = new byte[codeLength];
106: in.readFully(code);
107:
108: readExceptionTable(in);
109: readAttributes(in);
110: if (debug)
111: debug("read ");
112: }
113:
114: public void write(DataOutput out) throws InvalidByteCodeException,
115: IOException {
116:
117: super .write(out);
118: out.writeShort(maxStack);
119: out.writeShort(maxLocals);
120: out.writeInt(getLength(code));
121: out.write(code);
122:
123: writeExceptionTable(out);
124: writeAttributes(out);
125:
126: if (debug)
127: debug("wrote ");
128: }
129:
130: private void readExceptionTable(DataInput in)
131: throws InvalidByteCodeException, IOException {
132:
133: int exceptionTableLength = in.readUnsignedShort();
134: exceptionTable = new ExceptionTableEntry[exceptionTableLength];
135: for (int i = 0; i < exceptionTableLength; i++) {
136: exceptionTable[i] = ExceptionTableEntry.create(in,
137: classFile);
138: }
139:
140: }
141:
142: private void writeExceptionTable(DataOutput out)
143: throws InvalidByteCodeException, IOException {
144:
145: int exceptionTableLength = getLength(exceptionTable);
146:
147: out.writeShort(exceptionTableLength);
148: for (int i = 0; i < exceptionTableLength; i++) {
149: exceptionTable[i].write(out);
150: }
151:
152: }
153:
154: public int getAttributeLength() {
155: return INITIAL_LENGTH + getLength(code)
156: + getLength(exceptionTable)
157: * ExceptionTableEntry.LENGTH + 6
158: * getLength(attributes) + getTotalAttributesLength();
159: }
160:
161: protected void debug(String message) {
162: super .debug(message + "Code attribute with max_stack "
163: + maxStack + ", max_locals " + maxLocals
164: + ", code_length " + getLength(code));
165: }
166:
167: }
|