/* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package proguard.classfile.editor; import proguard.classfile.*; import proguard.classfile.attribute.*; import java.util.Arrays; /** * This class can add and delete interfaces to and from classes. References to * the constant pool must be filled out beforehand. * * @author Eric Lafortune */ public class InterfacesEditor { private final ProgramClass targetClass; /** * Creates a new InterfacesEditor that will edit interfaces in the given * target class. */ public InterfacesEditor(ProgramClass targetClass) { this.targetClass = targetClass; } /** * Adds the specified interface to the target class, if it isn't present yet. */ public void addInterface(int interfaceConstantIndex) { // Is the interface not yet present? if (findInterfaceIndex(interfaceConstantIndex) < 0) { int interfacesCount = targetClass.u2interfacesCount++; int[] interfaces = targetClass.u2interfaces; // Is the array too small to contain the additional interface? if (interfaces.length <= interfacesCount) { // Create a new array and copy the interfaces into it. int[] newinterfaces = new int[interfacesCount + 1]; System.arraycopy(interfaces, 0, newinterfaces, 0, interfacesCount); interfaces = newinterfaces; targetClass.u2interfaces = interfaces; } // Append the interface. interfaces[interfacesCount] = interfaceConstantIndex; } } /** * Deletes the given interface from the target class, if it is present. */ public void deleteInterface(int interfaceConstantIndex) { // Is the interface already present? int interfaceIndex = findInterfaceIndex(interfaceConstantIndex); if (interfaceIndex >= 0) { int interfacesCount = --targetClass.u2interfacesCount; int[] interfaces = targetClass.u2interfaces; // Shift the other interfaces in the array. for (int index = interfaceIndex; index < interfacesCount; index++) { interfaces[index] = interfaces[index + 1]; } // Clear the remaining entry in the array. interfaces[interfacesCount] = 0; } } // Small utility methods. /** * Finds the index of the specified interface in the list of interfaces of * the target class. */ private int findInterfaceIndex(int interfaceConstantIndex) { int interfacesCount = targetClass.u2interfacesCount; int[] interfaces = targetClass.u2interfaces; for (int index = 0; index < interfacesCount; index++) { if (interfaces[index] == interfaceConstantIndex) { return index; } } return -1; } }