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