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.DataInput;
021    import java.io.DataOutputStream;
022    import java.io.IOException;
023    import java.io.Serializable;
024    
025    import org.apache.bcel.Constants;
026    
027    /**
028     * This class represents an entry in the exception table of the <em>Code</em>
029     * attribute and is used only there. It contains a range in which a
030     * particular exception handler is active.
031     *
032     * @version $Id: CodeException.java 1152072 2011-07-29 01:54:05Z dbrosius $
033     * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
034     * @see     Code
035     */
036    public final class CodeException implements Cloneable, Constants, Node, Serializable {
037    
038        private static final long serialVersionUID = 2972500041254967221L;
039        private int start_pc; // Range in the code the exception handler is
040        private int end_pc; // active. start_pc is inclusive, end_pc exclusive
041        private int handler_pc; /* Starting address of exception handler, i.e.,
042         * an offset from start of code.
043         */
044        private int catch_type; /* If this is zero the handler catches any
045         * exception, otherwise it points to the
046         * exception class which is to be caught.
047         */
048    
049    
050        /**
051         * Initialize from another object.
052         */
053        public CodeException(CodeException c) {
054            this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType());
055        }
056    
057    
058        /**
059         * Construct object from file stream.
060         * @param file Input stream
061         * @throws IOException
062         */
063        CodeException(DataInput file) throws IOException {
064            this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file
065                    .readUnsignedShort());
066        }
067    
068    
069        /**
070         * @param start_pc Range in the code the exception handler is active,
071         * start_pc is inclusive while
072         * @param end_pc is exclusive
073         * @param handler_pc Starting address of exception handler, i.e.,
074         * an offset from start of code.
075         * @param catch_type If zero the handler catches any 
076         * exception, otherwise it points to the exception class which is 
077         * to be caught.
078         */
079        public CodeException(int start_pc, int end_pc, int handler_pc, int catch_type) {
080            this.start_pc = start_pc;
081            this.end_pc = end_pc;
082            this.handler_pc = handler_pc;
083            this.catch_type = catch_type;
084        }
085    
086    
087        /**
088         * Called by objects that are traversing the nodes of the tree implicitely
089         * defined by the contents of a Java class. I.e., the hierarchy of methods,
090         * fields, attributes, etc. spawns a tree of objects.
091         *
092         * @param v Visitor object
093         */
094        public void accept( Visitor v ) {
095            v.visitCodeException(this);
096        }
097    
098    
099        /**
100         * Dump code exception to file stream in binary format.
101         *
102         * @param file Output file stream
103         * @throws IOException
104         */
105        public final void dump( DataOutputStream file ) throws IOException {
106            file.writeShort(start_pc);
107            file.writeShort(end_pc);
108            file.writeShort(handler_pc);
109            file.writeShort(catch_type);
110        }
111    
112    
113        /**
114         * @return 0, if the handler catches any exception, otherwise it points to
115         * the exception class which is to be caught.
116         */
117        public final int getCatchType() {
118            return catch_type;
119        }
120    
121    
122        /**
123         * @return Exclusive end index of the region where the handler is active.
124         */
125        public final int getEndPC() {
126            return end_pc;
127        }
128    
129    
130        /**
131         * @return Starting address of exception handler, relative to the code.
132         */
133        public final int getHandlerPC() {
134            return handler_pc;
135        }
136    
137    
138        /**
139         * @return Inclusive start index of the region where the handler is active.
140         */
141        public final int getStartPC() {
142            return start_pc;
143        }
144    
145    
146        /**
147         * @param catch_type the type of exception that is caught
148         */
149        public final void setCatchType( int catch_type ) {
150            this.catch_type = catch_type;
151        }
152    
153    
154        /**
155         * @param end_pc end of handled block
156         */
157        public final void setEndPC( int end_pc ) {
158            this.end_pc = end_pc;
159        }
160    
161    
162        /**
163         * @param handler_pc where the actual code is
164         */
165        public final void setHandlerPC( int handler_pc ) {
166            this.handler_pc = handler_pc;
167        }
168    
169    
170        /**
171         * @param start_pc start of handled block
172         */
173        public final void setStartPC( int start_pc ) {
174            this.start_pc = start_pc;
175        }
176    
177    
178        /**
179         * @return String representation.
180         */
181        @Override
182        public final String toString() {
183            return "CodeException(start_pc = " + start_pc + ", end_pc = " + end_pc + ", handler_pc = "
184                    + handler_pc + ", catch_type = " + catch_type + ")";
185        }
186    
187    
188        /**
189         * @return String representation.
190         */
191        public final String toString( ConstantPool cp, boolean verbose ) {
192            String str;
193            if (catch_type == 0) {
194                str = "<Any exception>(0)";
195            } else {
196                str = Utility.compactClassName(cp.getConstantString(catch_type, CONSTANT_Class), false)
197                        + (verbose ? "(" + catch_type + ")" : "");
198            }
199            return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str;
200        }
201    
202    
203        public final String toString( ConstantPool cp ) {
204            return toString(cp, true);
205        }
206    
207    
208        /**
209         * @return deep copy of this object
210         */
211        public CodeException copy() {
212            try {
213                return (CodeException) clone();
214            } catch (CloneNotSupportedException e) {
215            }
216            return null;
217        }
218    }