View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   *
17   */
18  package org.apache.bcel.classfile;
19  
20  import java.io.DataInput;
21  import java.io.DataOutputStream;
22  import java.io.IOException;
23  
24  import org.apache.bcel.Const;
25  import org.apache.bcel.Constants;
26  
27  /**
28   * This class represents an entry in the exception table of the <em>Code</em>
29   * attribute and is used only there. It contains a range in which a
30   * particular exception handler is active.
31   *
32   * @version $Id: CodeException.html 1018313 2017-09-18 09:03:04Z britter $
33   * @see     Code
34   */
35  public final class CodeException implements Cloneable, Node, Constants {
36  
37      private int start_pc; // Range in the code the exception handler is
38      private int end_pc; // active. start_pc is inclusive, end_pc exclusive
39      private int handler_pc; /* Starting address of exception handler, i.e.,
40       * an offset from start of code.
41       */
42      private int catch_type; /* If this is zero the handler catches any
43       * exception, otherwise it points to the
44       * exception class which is to be caught.
45       */
46  
47  
48      /**
49       * Initialize from another object.
50       */
51      public CodeException(final CodeException c) {
52          this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType());
53      }
54  
55  
56      /**
57       * Construct object from file stream.
58       * @param file Input stream
59       * @throws IOException
60       */
61      CodeException(final DataInput file) throws IOException {
62          this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file
63                  .readUnsignedShort());
64      }
65  
66  
67      /**
68       * @param start_pc Range in the code the exception handler is active,
69       * start_pc is inclusive while
70       * @param end_pc is exclusive
71       * @param handler_pc Starting address of exception handler, i.e.,
72       * an offset from start of code.
73       * @param catch_type If zero the handler catches any
74       * exception, otherwise it points to the exception class which is
75       * to be caught.
76       */
77      public CodeException(final int start_pc, final int end_pc, final int handler_pc, final int catch_type) {
78          this.start_pc = start_pc;
79          this.end_pc = end_pc;
80          this.handler_pc = handler_pc;
81          this.catch_type = catch_type;
82      }
83  
84  
85      /**
86       * Called by objects that are traversing the nodes of the tree implicitely
87       * defined by the contents of a Java class. I.e., the hierarchy of methods,
88       * fields, attributes, etc. spawns a tree of objects.
89       *
90       * @param v Visitor object
91       */
92      @Override
93      public void accept( final Visitor v ) {
94          v.visitCodeException(this);
95      }
96  
97  
98      /**
99       * Dump code exception to file stream in binary format.
100      *
101      * @param file Output file stream
102      * @throws IOException
103      */
104     public final void dump( final DataOutputStream file ) throws IOException {
105         file.writeShort(start_pc);
106         file.writeShort(end_pc);
107         file.writeShort(handler_pc);
108         file.writeShort(catch_type);
109     }
110 
111 
112     /**
113      * @return 0, if the handler catches any exception, otherwise it points to
114      * the exception class which is to be caught.
115      */
116     public final int getCatchType() {
117         return catch_type;
118     }
119 
120 
121     /**
122      * @return Exclusive end index of the region where the handler is active.
123      */
124     public final int getEndPC() {
125         return end_pc;
126     }
127 
128 
129     /**
130      * @return Starting address of exception handler, relative to the code.
131      */
132     public final int getHandlerPC() {
133         return handler_pc;
134     }
135 
136 
137     /**
138      * @return Inclusive start index of the region where the handler is active.
139      */
140     public final int getStartPC() {
141         return start_pc;
142     }
143 
144 
145     /**
146      * @param catch_type the type of exception that is caught
147      */
148     public final void setCatchType( final int catch_type ) {
149         this.catch_type = catch_type;
150     }
151 
152 
153     /**
154      * @param end_pc end of handled block
155      */
156     public final void setEndPC( final int end_pc ) {
157         this.end_pc = end_pc;
158     }
159 
160 
161     /**
162      * @param handler_pc where the actual code is
163      */
164     public final void setHandlerPC( final int handler_pc ) { // TODO unused
165         this.handler_pc = handler_pc;
166     }
167 
168 
169     /**
170      * @param start_pc start of handled block
171      */
172     public final void setStartPC( final int start_pc ) { // TODO unused
173         this.start_pc = start_pc;
174     }
175 
176 
177     /**
178      * @return String representation.
179      */
180     @Override
181     public final String toString() {
182         return "CodeException(start_pc = " + start_pc + ", end_pc = " + end_pc + ", handler_pc = "
183                 + handler_pc + ", catch_type = " + catch_type + ")";
184     }
185 
186 
187     /**
188      * @return String representation.
189      */
190     public final String toString( final ConstantPool cp, final boolean verbose ) {
191         String str;
192         if (catch_type == 0) {
193             str = "<Any exception>(0)";
194         } else {
195             str = Utility.compactClassName(cp.getConstantString(catch_type, Const.CONSTANT_Class), false)
196                     + (verbose ? "(" + catch_type + ")" : "");
197         }
198         return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str;
199     }
200 
201 
202     public final String toString( final ConstantPool cp ) {
203         return toString(cp, true);
204     }
205 
206 
207     /**
208      * @return deep copy of this object
209      */
210     public CodeException copy() {
211         try {
212             return (CodeException) clone();
213         } catch (final CloneNotSupportedException e) {
214             // TODO should this throw?
215         }
216         return null;
217     }
218 }