001: /*
002: * Javassist, a Java-bytecode translator toolkit.
003: * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
004: *
005: * The contents of this file are subject to the Mozilla Public License Version
006: * 1.1 (the "License"); you may not use this file except in compliance with
007: * the License. Alternatively, the contents of this file may be used under
008: * the terms of the GNU Lesser General Public License Version 2.1 or later.
009: *
010: * Software distributed under the License is distributed on an "AS IS" basis,
011: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
012: * for the specific language governing rights and limitations under the
013: * License.
014: */
015:
016: package javassist.bytecode;
017:
018: import java.io.DataInputStream;
019: import java.io.IOException;
020: import java.util.Map;
021:
022: /**
023: * <code>Exceptions_attribute</code>.
024: */
025: public class ExceptionsAttribute extends AttributeInfo {
026: /**
027: * The name of this attribute <code>"Exceptions"</code>.
028: */
029: public static final String tag = "Exceptions";
030:
031: ExceptionsAttribute(ConstPool cp, int n, DataInputStream in)
032: throws IOException {
033: super (cp, n, in);
034: }
035:
036: /**
037: * Constructs a copy of an exceptions attribute.
038: *
039: * @param cp constant pool table.
040: * @param src source attribute.
041: */
042: private ExceptionsAttribute(ConstPool cp, ExceptionsAttribute src,
043: Map classnames) {
044: super (cp, tag);
045: copyFrom(src, classnames);
046: }
047:
048: /**
049: * Constructs a new exceptions attribute.
050: *
051: * @param cp constant pool table.
052: */
053: public ExceptionsAttribute(ConstPool cp) {
054: super (cp, tag);
055: byte[] data = new byte[2];
056: data[0] = data[1] = 0; // empty
057: this .info = data;
058: }
059:
060: /**
061: * Makes a copy. Class names are replaced according to the
062: * given <code>Map</code> object.
063: *
064: * @param newCp the constant pool table used by the new copy.
065: * @param classnames pairs of replaced and substituted
066: * class names. It can be <code>null</code>.
067: */
068: public AttributeInfo copy(ConstPool newCp, Map classnames) {
069: return new ExceptionsAttribute(newCp, this , classnames);
070: }
071:
072: /**
073: * Copies the contents from a source attribute.
074: * Specified class names are replaced during the copy.
075: *
076: * @param srcAttr source Exceptions attribute
077: * @param classnames pairs of replaced and substituted
078: * class names.
079: */
080: private void copyFrom(ExceptionsAttribute srcAttr, Map classnames) {
081: ConstPool srcCp = srcAttr.constPool;
082: ConstPool destCp = this .constPool;
083: byte[] src = srcAttr.info;
084: int num = src.length;
085: byte[] dest = new byte[num];
086: dest[0] = src[0];
087: dest[1] = src[1]; // the number of elements.
088: for (int i = 2; i < num; i += 2) {
089: int index = ByteArray.readU16bit(src, i);
090: ByteArray.write16bit(srcCp.copy(index, destCp, classnames),
091: dest, i);
092: }
093:
094: this .info = dest;
095: }
096:
097: /**
098: * Returns <code>exception_index_table[]</code>.
099: */
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)
110: | (blist[j + 1] & 0xff);
111:
112: return elist;
113: }
114:
115: /**
116: * Returns the names of exceptions that the method may throw.
117: */
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)
128: | (blist[j + 1] & 0xff);
129: elist[k++] = constPool.getClassInfo(index);
130: }
131:
132: return elist;
133: }
134:
135: /**
136: * Sets <code>exception_index_table[]</code>.
137: */
138: public void setExceptionIndexes(int[] elist) {
139: int n = elist.length;
140: byte[] blist = new byte[n * 2 + 2];
141: ByteArray.write16bit(n, blist, 0);
142: for (int i = 0; i < n; ++i)
143: ByteArray.write16bit(elist[i], blist, i * 2 + 2);
144:
145: info = blist;
146: }
147:
148: /**
149: * Sets the names of exceptions that the method may throw.
150: */
151: public void setExceptions(String[] elist) {
152: int n = elist.length;
153: byte[] blist = new byte[n * 2 + 2];
154: ByteArray.write16bit(n, blist, 0);
155: for (int i = 0; i < n; ++i)
156: ByteArray.write16bit(constPool.addClassInfo(elist[i]),
157: blist, i * 2 + 2);
158:
159: info = blist;
160: }
161:
162: /**
163: * Returns <code>number_of_exceptions</code>.
164: */
165: public int tableLength() {
166: return info.length / 2 - 1;
167: }
168:
169: /**
170: * Returns the value of <code>exception_index_table[nth]</code>.
171: */
172: public int getException(int nth) {
173: int index = nth * 2 + 2; // nth >= 0
174: return ((info[index] & 0xff) << 8) | (info[index + 1] & 0xff);
175: }
176: }
|