001: /*
002: * Copyright 2000-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: *
016: */
017: package org.apache.bcel.classfile;
018:
019: import java.io.DataInputStream;
020: import java.io.DataOutputStream;
021: import java.io.IOException;
022: import java.io.Serializable;
023: import org.apache.bcel.Constants;
024:
025: /**
026: * This class represents an entry in the exception table of the <em>Code</em>
027: * attribute and is used only there. It contains a range in which a
028: * particular exception handler is active.
029: *
030: * @version $Id: CodeException.java 386056 2006-03-15 11:31:56Z tcurdt $
031: * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
032: * @see Code
033: */
034: public final class CodeException implements Cloneable, Constants, Node,
035: Serializable {
036:
037: private int start_pc; // Range in the code the exception handler is
038: private int end_pc; // active. start_pc is inclusive, end_pc exclusive
039: private int handler_pc; /* Starting address of exception handler, i.e.,
040: * an offset from start of code.
041: */
042: private int catch_type; /* If this is zero the handler catches any
043: * exception, otherwise it points to the
044: * exception class which is to be caught.
045: */
046:
047: /**
048: * Initialize from another object.
049: */
050: public CodeException(CodeException c) {
051: this (c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c
052: .getCatchType());
053: }
054:
055: /**
056: * Construct object from file stream.
057: * @param file Input stream
058: * @throws IOException
059: */
060: CodeException(DataInputStream file) throws IOException {
061: this (file.readUnsignedShort(), file.readUnsignedShort(), file
062: .readUnsignedShort(), file.readUnsignedShort());
063: }
064:
065: /**
066: * @param start_pc Range in the code the exception handler is active,
067: * start_pc is inclusive while
068: * @param end_pc is exclusive
069: * @param handler_pc Starting address of exception handler, i.e.,
070: * an offset from start of code.
071: * @param catch_type If zero the handler catches any
072: * exception, otherwise it points to the exception class which is
073: * to be caught.
074: */
075: public CodeException(int start_pc, int end_pc, int handler_pc,
076: int catch_type) {
077: this .start_pc = start_pc;
078: this .end_pc = end_pc;
079: this .handler_pc = handler_pc;
080: this .catch_type = catch_type;
081: }
082:
083: /**
084: * Called by objects that are traversing the nodes of the tree implicitely
085: * defined by the contents of a Java class. I.e., the hierarchy of methods,
086: * fields, attributes, etc. spawns a tree of objects.
087: *
088: * @param v Visitor object
089: */
090: public void accept(Visitor v) {
091: v.visitCodeException(this );
092: }
093:
094: /**
095: * Dump code exception to file stream in binary format.
096: *
097: * @param file Output file stream
098: * @throws IOException
099: */
100: public final void dump(DataOutputStream file) throws IOException {
101: file.writeShort(start_pc);
102: file.writeShort(end_pc);
103: file.writeShort(handler_pc);
104: file.writeShort(catch_type);
105: }
106:
107: /**
108: * @return 0, if the handler catches any exception, otherwise it points to
109: * the exception class which is to be caught.
110: */
111: public final int getCatchType() {
112: return catch_type;
113: }
114:
115: /**
116: * @return Exclusive end index of the region where the handler is active.
117: */
118: public final int getEndPC() {
119: return end_pc;
120: }
121:
122: /**
123: * @return Starting address of exception handler, relative to the code.
124: */
125: public final int getHandlerPC() {
126: return handler_pc;
127: }
128:
129: /**
130: * @return Inclusive start index of the region where the handler is active.
131: */
132: public final int getStartPC() {
133: return start_pc;
134: }
135:
136: /**
137: * @param catch_type the type of exception that is caught
138: */
139: public final void setCatchType(int catch_type) {
140: this .catch_type = catch_type;
141: }
142:
143: /**
144: * @param end_pc end of handled block
145: */
146: public final void setEndPC(int end_pc) {
147: this .end_pc = end_pc;
148: }
149:
150: /**
151: * @param handler_pc where the actual code is
152: */
153: public final void setHandlerPC(int handler_pc) {
154: this .handler_pc = handler_pc;
155: }
156:
157: /**
158: * @param start_pc start of handled block
159: */
160: public final void setStartPC(int start_pc) {
161: this .start_pc = start_pc;
162: }
163:
164: /**
165: * @return String representation.
166: */
167: public final String toString() {
168: return "CodeException(start_pc = " + start_pc + ", end_pc = "
169: + end_pc + ", handler_pc = " + handler_pc
170: + ", catch_type = " + catch_type + ")";
171: }
172:
173: /**
174: * @return String representation.
175: */
176: public final String toString(ConstantPool cp, boolean verbose) {
177: String str;
178: if (catch_type == 0) {
179: str = "<Any exception>(0)";
180: } else {
181: str = Utility.compactClassName(cp.getConstantString(
182: catch_type, CONSTANT_Class), false)
183: + (verbose ? "(" + catch_type + ")" : "");
184: }
185: return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t"
186: + str;
187: }
188:
189: public final String toString(ConstantPool cp) {
190: return toString(cp, true);
191: }
192:
193: /**
194: * @return deep copy of this object
195: */
196: public CodeException copy() {
197: try {
198: return (CodeException) clone();
199: } catch (CloneNotSupportedException e) {
200: }
201: return null;
202: }
203: }
|