1 19 20 package edu.umd.cs.findbugs.ba; 21 22 import java.security.MessageDigest ; 23 import java.security.NoSuchAlgorithmException ; 24 import java.util.Arrays ; 25 26 import org.apache.bcel.classfile.Method; 27 28 29 36 public class MethodHash implements Comparable <MethodHash> { 37 public static final String METHOD_HASH_ELEMENT_NAME = "MethodHash"; 38 39 private byte[] hash; 40 private String methodName; 41 private String methodSig; 42 private boolean isStatic; 43 44 48 public MethodHash() { 49 } 50 51 59 public MethodHash(String methodName, String methodSig, boolean isStatic, byte[] hash) { 60 this.methodName = methodName; 61 this.methodSig = methodSig; 62 this.isStatic = isStatic; 63 this.hash = new byte[hash.length]; 64 System.arraycopy(hash, 0, this.hash, 0, hash.length); 65 } 66 67 70 public String getMethodName() { 71 return methodName; 72 } 73 74 77 public String getMethodSig() { 78 return methodSig; 79 } 80 81 84 public boolean isStatic() { 85 return isStatic; 86 } 87 88 93 public byte[] getMethodHash() { 94 return hash; 95 } 96 97 103 public MethodHash computeHash(Method method) { 104 MessageDigest digest_; 105 try { 106 digest_ = MessageDigest.getInstance("MD5"); 107 } catch (NoSuchAlgorithmException e) { 108 throw new IllegalStateException ("No algorithm for computing method hash", e); 109 } 110 final MessageDigest digest = digest_; 111 112 byte[] code; 113 if (method.getCode() == null || method.getCode().getCode() == null) { 114 code = new byte[0]; 115 } else { 116 code = method.getCode().getCode(); 117 } 118 119 BytecodeScanner.Callback callback = new BytecodeScanner.Callback() { 120 public void handleInstruction(int opcode, int index) { 121 digest.update((byte) opcode); 122 } 123 }; 124 125 BytecodeScanner bytecodeScanner = new BytecodeScanner(); 126 bytecodeScanner.scan(code, callback); 127 128 hash = digest.digest(); 129 130 return this; 131 } 132 133 139 public boolean isSameHash(MethodHash other) { 140 return Arrays.equals(this.hash, other.hash); 141 } 142 143 146 public int compareTo(MethodHash other) { 147 return MethodHash.compareHashes(this.hash, other.hash); 148 } 149 150 public boolean equals(Object o) { 151 if (o instanceof MethodHash) 152 return isSameHash((MethodHash)o); 153 return false; 154 } 155 public int hashCode() { 156 int result = 0; 157 for(byte b : hash) 158 result = result * 17 + b; 159 return result; 160 } 161 public static int compareHashes(byte[] a, byte[] b) { 162 int pfxlen = Math.min(a.length, b.length); 163 for (int i = 0; i < pfxlen; ++i) { 164 int cmp = toUnsigned(a[i]) - toUnsigned(b[i]); 165 if (cmp != 0) 166 return cmp; 167 } 168 return a.length - b.length; 169 } 170 171 177 private static int toUnsigned(byte b) { 178 int value = b & 0x7F; 179 if ((b & 0x80) != 0) { 180 value |= 0x80; 181 } 182 return value; 183 } 184 185 } 186 | Popular Tags |