/Users/lyon/j4p/src/javassist/bytecode/ExceptionsAttribute.java

1    /* 
2     * Javassist, a Java-bytecode translator toolkit. 
3     * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved. 
4     * 
5     * The contents of this file are subject to the Mozilla Public License Version 
6     * 1.1 (the "License"); you may not use this file except in compliance with 
7     * the License.  Alternatively, the contents of this file may be used under 
8     * the terms of the GNU Lesser General Public License Version 2.1 or later. 
9     * 
10    * Software distributed under the License is distributed on an "AS IS" basis, 
11    * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
12    * for the specific language governing rights and limitations under the 
13    * License. 
14    */ 
15    
16   package javassist.bytecode; 
17    
18   import java.io.DataInputStream; 
19   import java.io.IOException; 
20   import java.util.Map; 
21    
22   /** 
23    * <code>Exceptions_attribute</code>. 
24    */ 
25   public class ExceptionsAttribute extends AttributeInfo { 
26       /** 
27        * The name of this attribute <code>"Exceptions"</code>. 
28        */ 
29       public static final String tag = "Exceptions"; 
30    
31       ExceptionsAttribute(ConstPool cp, int n, DataInputStream in) 
32               throws IOException { 
33           super(cp, n, in); 
34       } 
35    
36       /** 
37        * Constructs a copy of an exceptions attribute. 
38        * 
39        * @param cp                constant pool table. 
40        * @param src               source attribute. 
41        */ 
42       private ExceptionsAttribute(ConstPool cp, ExceptionsAttribute src, 
43                                   Map classnames) { 
44           super(cp, tag); 
45           copyFrom(src, classnames); 
46       } 
47    
48       /** 
49        * Constructs a new exceptions attribute. 
50        * 
51        * @param cp                constant pool table. 
52        */ 
53       public ExceptionsAttribute(ConstPool cp) { 
54           super(cp, tag); 
55           byte[] data = new byte[2]; 
56           data[0] = data[1] = 0;  // empty 
57           this.info = data; 
58       } 
59    
60       /** 
61        * Makes a copy.  Class names are replaced according to the 
62        * given <code>Map</code> object. 
63        * 
64        * @param newCp     the constant pool table used by the new copy. 
65        * @param classnames        pairs of replaced and substituted 
66        *                          class names. 
67        */ 
68       public AttributeInfo copy(ConstPool newCp, Map classnames) { 
69           return new ExceptionsAttribute(newCp, this, classnames); 
70       } 
71    
72       /** 
73        * Copies the contents from a source attribute. 
74        * Specified class names are replaced during the copy. 
75        * 
76        * @param srcAttr           source Exceptions attribute 
77        * @param classnames        pairs of replaced and substituted 
78        *                          class names. 
79        */ 
80       private void copyFrom(ExceptionsAttribute srcAttr, Map classnames) { 
81           ConstPool srcCp = srcAttr.constPool; 
82           ConstPool destCp = this.constPool; 
83           byte[] src = srcAttr.info; 
84           int num = src.length; 
85           byte[] dest = new byte[num]; 
86           dest[0] = src[0]; 
87           dest[1] = src[1];       // the number of elements. 
88           for (int i = 2; i < num; i += 2) { 
89               int index = ByteArray.readU16bit(src, i); 
90               ByteArray.write16bit(srcCp.copy(index, destCp, classnames), 
91                       dest, i); 
92           } 
93    
94           this.info = dest; 
95       } 
96    
97       /** 
98        * Returns <code>exception_index_table[]</code>. 
99        */ 
100      public int[] getExceptionIndexes() { 
101          byte[] blist = info; 
102          int n = blist.length; 
103          if (n <= 2) 
104              return null; 
105   
106          int[] elist = new int[n / 2 - 1]; 
107          int k = 0; 
108          for (int j = 2; j < n; j += 2) 
109              elist[k++] = ((blist[j] & 0xff) << 8) | (blist[j + 1] & 0xff); 
110   
111          return elist; 
112      } 
113   
114      /** 
115       * Returns the names of exceptions that the method may throw. 
116       */ 
117      public String[] getExceptions() { 
118          byte[] blist = info; 
119          int n = blist.length; 
120          if (n <= 2) 
121              return null; 
122   
123          String[] elist = new String[n / 2 - 1]; 
124          int k = 0; 
125          for (int j = 2; j < n; j += 2) { 
126              int index = ((blist[j] & 0xff) << 8) | (blist[j + 1] & 0xff); 
127              elist[k++] = constPool.getClassInfo(index); 
128          } 
129   
130          return elist; 
131      } 
132   
133      /** 
134       * Sets <code>exception_index_table[]</code>. 
135       */ 
136      public void setExceptionIndexes(int[] elist) { 
137          int n = elist.length; 
138          byte[] blist = new byte[n * 2 + 2]; 
139          ByteArray.write16bit(n, blist, 0); 
140          for (int i = 0; i < n; ++i) 
141              ByteArray.write16bit(elist[i], blist, i * 2 + 2); 
142   
143          info = blist; 
144      } 
145   
146      /** 
147       * Sets the names of exceptions that the method may throw. 
148       */ 
149      public void setExceptions(String[] elist) { 
150          int n = elist.length; 
151          byte[] blist = new byte[n * 2 + 2]; 
152          ByteArray.write16bit(n, blist, 0); 
153          for (int i = 0; i < n; ++i) 
154              ByteArray.write16bit(constPool.addClassInfo(elist[i]), 
155                      blist, i * 2 + 2); 
156   
157          info = blist; 
158      } 
159   
160      /** 
161       * Returns <code>number_of_exceptions</code>. 
162       */ 
163      public int length() { 
164          return info.length / 2 - 1; 
165      } 
166   
167      /** 
168       * Returns the value of <code>exception_index_table[nth]</code>. 
169       */ 
170      public int getException(int nth) { 
171          int index = nth * 2 + 2;        // nth >= 0 
172          return ((info[index] & 0xff) << 8) | (info[index + 1] & 0xff); 
173      } 
174  } 
175