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