Home | History | Annotate | Download | only in bytecode
      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 
     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      */
     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      */
     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      */
     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      */
     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      */
    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      */
    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      */
    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      */
    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      */
    164     public int tableLength() { return info.length / 2 - 1; }
    165 
    166     /**
    167      * Returns the value of <code>exception_index_table[nth]</code>.
    168      */
    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