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 }