Home | History | Annotate | Download | only in editor
      1 /*
      2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
      3  *             of Java bytecode.
      4  *
      5  * Copyright (c) 2002-2009 Eric Lafortune (eric (at) graphics.cornell.edu)
      6  *
      7  * This program is free software; you can redistribute it and/or modify it
      8  * under the terms of the GNU General Public License as published by the Free
      9  * Software Foundation; either version 2 of the License, or (at your option)
     10  * any later version.
     11  *
     12  * This program is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
     15  * more details.
     16  *
     17  * You should have received a copy of the GNU General Public License along
     18  * with this program; if not, write to the Free Software Foundation, Inc.,
     19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20  */
     21 package proguard.classfile.editor;
     22 
     23 import proguard.classfile.*;
     24 import proguard.classfile.attribute.*;
     25 
     26 import java.util.Arrays;
     27 
     28 /**
     29  * This class can add and delete interfaces to and from classes. References to
     30  * the constant pool must be filled out beforehand.
     31  *
     32  * @author Eric Lafortune
     33  */
     34 public class InterfacesEditor
     35 {
     36     private final ProgramClass targetClass;
     37 
     38 
     39     /**
     40      * Creates a new InterfacesEditor that will edit interfaces in the given
     41      * target class.
     42      */
     43     public InterfacesEditor(ProgramClass targetClass)
     44     {
     45         this.targetClass = targetClass;
     46     }
     47 
     48 
     49     /**
     50      * Adds the specified interface to the target class, if it isn't present yet.
     51      */
     52     public void addInterface(int interfaceConstantIndex)
     53     {
     54         // Is the interface not yet present?
     55         if (findInterfaceIndex(interfaceConstantIndex) < 0)
     56         {
     57             int   interfacesCount = targetClass.u2interfacesCount++;
     58             int[] interfaces      = targetClass.u2interfaces;
     59 
     60             // Is the array too small to contain the additional interface?
     61             if (interfaces.length <= interfacesCount)
     62             {
     63                 // Create a new array and copy the interfaces into it.
     64                 int[] newinterfaces = new int[interfacesCount + 1];
     65                 System.arraycopy(interfaces, 0, newinterfaces, 0, interfacesCount);
     66                 interfaces = newinterfaces;
     67 
     68                 targetClass.u2interfaces = interfaces;
     69             }
     70 
     71             // Append the interface.
     72             interfaces[interfacesCount] = interfaceConstantIndex;
     73         }
     74     }
     75 
     76 
     77     /**
     78      * Deletes the given interface from the target class, if it is present.
     79      */
     80     public void deleteInterface(int interfaceConstantIndex)
     81     {
     82         // Is the interface already present?
     83         int interfaceIndex = findInterfaceIndex(interfaceConstantIndex);
     84         if (interfaceIndex >= 0)
     85         {
     86             int   interfacesCount = --targetClass.u2interfacesCount;
     87             int[] interfaces      = targetClass.u2interfaces;
     88 
     89             // Shift the other interfaces in the array.
     90             for (int index = interfaceIndex; index < interfacesCount; index++)
     91             {
     92                 interfaces[index] = interfaces[index + 1];
     93             }
     94 
     95             // Clear the remaining entry in the array.
     96             interfaces[interfacesCount] = 0;
     97         }
     98     }
     99 
    100 
    101     // Small utility methods.
    102 
    103     /**
    104      * Finds the index of the specified interface in the list of interfaces of
    105      * the target class.
    106      */
    107     private int findInterfaceIndex(int interfaceConstantIndex)
    108     {
    109         int   interfacesCount = targetClass.u2interfacesCount;
    110         int[] interfaces      = targetClass.u2interfaces;
    111 
    112         for (int index = 0; index < interfacesCount; index++)
    113         {
    114             if (interfaces[index] == interfaceConstantIndex)
    115               {
    116                   return index;
    117               }
    118         }
    119 
    120         return -1;
    121     }
    122 }