• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Javassist, a Java-bytecode translator toolkit.
3  * Copyright (C) 1999-2007 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 
ExceptionsAttribute(ConstPool cp, int n, DataInputStream in)31     ExceptionsAttribute(ConstPool cp, int n, DataInputStream in)
32         throws IOException
33     {
34         super(cp, n, in);
35     }
36 
37     /**
38      * Constructs a copy of an exceptions attribute.
39      *
40      * @param cp                constant pool table.
41      * @param src               source attribute.
42      */
ExceptionsAttribute(ConstPool cp, ExceptionsAttribute src, Map classnames)43     private ExceptionsAttribute(ConstPool cp, ExceptionsAttribute src,
44                                 Map classnames) {
45         super(cp, tag);
46         copyFrom(src, classnames);
47     }
48 
49     /**
50      * Constructs a new exceptions attribute.
51      *
52      * @param cp                constant pool table.
53      */
ExceptionsAttribute(ConstPool cp)54     public ExceptionsAttribute(ConstPool cp) {
55         super(cp, tag);
56         byte[] data = new byte[2];
57         data[0] = data[1] = 0;  // empty
58         this.info = data;
59     }
60 
61     /**
62      * Makes a copy.  Class names are replaced according to the
63      * given <code>Map</code> object.
64      *
65      * @param newCp     the constant pool table used by the new copy.
66      * @param classnames        pairs of replaced and substituted
67      *                          class names.  It can be <code>null</code>.
68      */
copy(ConstPool newCp, Map classnames)69     public AttributeInfo copy(ConstPool newCp, Map classnames) {
70         return new ExceptionsAttribute(newCp, this, classnames);
71     }
72 
73     /**
74      * Copies the contents from a source attribute.
75      * Specified class names are replaced during the copy.
76      *
77      * @param srcAttr           source Exceptions attribute
78      * @param classnames        pairs of replaced and substituted
79      *                          class names.
80      */
copyFrom(ExceptionsAttribute srcAttr, Map classnames)81     private void copyFrom(ExceptionsAttribute srcAttr, Map classnames) {
82         ConstPool srcCp = srcAttr.constPool;
83         ConstPool destCp = this.constPool;
84         byte[] src = srcAttr.info;
85         int num = src.length;
86         byte[] dest = new byte[num];
87         dest[0] = src[0];
88         dest[1] = src[1];       // the number of elements.
89         for (int i = 2; i < num; i += 2) {
90             int index = ByteArray.readU16bit(src, i);
91             ByteArray.write16bit(srcCp.copy(index, destCp, classnames),
92                                  dest, i);
93         }
94 
95         this.info = dest;
96     }
97 
98     /**
99      * Returns <code>exception_index_table[]</code>.
100      */
getExceptionIndexes()101     public int[] getExceptionIndexes() {
102         byte[] blist = info;
103         int n = blist.length;
104         if (n <= 2)
105             return null;
106 
107         int[] elist = new int[n / 2 - 1];
108         int k = 0;
109         for (int j = 2; j < n; j += 2)
110             elist[k++] = ((blist[j] & 0xff) << 8) | (blist[j + 1] & 0xff);
111 
112         return elist;
113     }
114 
115     /**
116      * Returns the names of exceptions that the method may throw.
117      */
getExceptions()118     public String[] getExceptions() {
119         byte[] blist = info;
120         int n = blist.length;
121         if (n <= 2)
122             return null;
123 
124         String[] elist = new String[n / 2 - 1];
125         int k = 0;
126         for (int j = 2; j < n; j += 2) {
127             int index = ((blist[j] & 0xff) << 8) | (blist[j + 1] & 0xff);
128             elist[k++] = constPool.getClassInfo(index);
129         }
130 
131         return elist;
132     }
133 
134     /**
135      * Sets <code>exception_index_table[]</code>.
136      */
setExceptionIndexes(int[] elist)137     public void setExceptionIndexes(int[] elist) {
138         int n = elist.length;
139         byte[] blist = new byte[n * 2 + 2];
140         ByteArray.write16bit(n, blist, 0);
141         for (int i = 0; i < n; ++i)
142             ByteArray.write16bit(elist[i], blist, i * 2 + 2);
143 
144         info = blist;
145     }
146 
147     /**
148      * Sets the names of exceptions that the method may throw.
149      */
setExceptions(String[] elist)150     public void setExceptions(String[] elist) {
151         int n = elist.length;
152         byte[] blist = new byte[n * 2 + 2];
153         ByteArray.write16bit(n, blist, 0);
154         for (int i = 0; i < n; ++i)
155             ByteArray.write16bit(constPool.addClassInfo(elist[i]),
156                                  blist, i * 2 + 2);
157 
158         info = blist;
159     }
160 
161     /**
162      * Returns <code>number_of_exceptions</code>.
163      */
tableLength()164     public int tableLength() { return info.length / 2 - 1; }
165 
166     /**
167      * Returns the value of <code>exception_index_table[nth]</code>.
168      */
getException(int nth)169     public int getException(int nth) {
170         int index = nth * 2 + 2;        // nth >= 0
171         return ((info[index] & 0xff) << 8) | (info[index + 1] & 0xff);
172     }
173 }
174