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