1 30 package com.genimen.djeneric.util; 31 32 import java.io.BufferedInputStream ; 33 import java.io.File ; 34 import java.io.FileInputStream ; 35 import java.io.IOException ; 36 import java.util.ArrayList ; 37 38 import com.genimen.djeneric.language.Messages; 39 import com.genimen.djeneric.repository.exceptions.DjenericException; 40 41 public class DjClassInspector 42 { 43 final static int CONSTANT_Utf8 = 1; 44 final static int CONSTANT_Integer = 3; 45 final static int CONSTANT_Float = 4; 46 final static int CONSTANT_Long = 5; 47 final static int CONSTANT_Double = 6; 48 final static int CONSTANT_Class = 7; 49 final static int CONSTANT_String = 8; 50 final static int CONSTANT_Fieldref = 9; 51 final static int CONSTANT_Methodref = 10; 52 final static int CONSTANT_InterfaceMethodref = 11; 53 final static int CONSTANT_NameAndType = 12; 54 55 private byte[] _classDefinition; 56 57 public DjClassInspector() 58 { 59 } 60 61 public DjClassInspector(byte[] classBytes) 62 { 63 setClassDefinition(classBytes); 64 } 65 66 public static byte[] readclass(String fileName) throws IOException 67 { 68 File infile = new File (fileName); 69 long size = infile.length(); 70 71 FileInputStream fis = new FileInputStream (infile); 72 BufferedInputStream bis = new BufferedInputStream (fis); 73 74 byte[] buffer = new byte[(int) size]; 75 int offset = 0; 76 int totalRead = 0; 77 while (totalRead < size) 78 { 79 totalRead += bis.read(buffer, offset, (int) (size - totalRead)); 80 } 81 bis.close(); 82 return buffer; 83 } 84 85 int asInt(byte b) 86 { 87 if ((b & 0x80) != 0) return (b & 0x7f) | 0x80; 88 return b; 89 90 } 91 92 long asLong(byte b) 93 { 94 if ((b & 0x80) != 0) return (b & 0x7f) | 0x80; 95 return b; 96 } 97 98 int asInt(byte[] buffer, int offset) 99 { 100 return asInt(buffer[offset]) << 8 | asInt(buffer[offset + 1]); 101 } 102 103 long asLong(byte[] buffer, int offset) 104 { 105 return asLong(buffer[offset]) << 24 | asLong(buffer[offset + 1]) << 16 | asLong(buffer[offset + 2]) << 8 106 | asLong(buffer[offset + 3]); 107 } 108 109 public boolean isValidClass() 110 { 111 byte[] clz = getClassDefinition(); 112 113 if (clz == null) return false; 114 115 return asLong(clz, 0) == 0xcafebabeL; 116 } 117 118 public String getClassName() throws DjenericException 119 { 120 byte[] clz = getClassDefinition(); 121 122 if (clz == null) return null; 123 124 int numConstPoolEntries = asInt(clz, 8); 127 128 if (!isValidClass()) 129 { 130 throw new DjenericException(Messages.getString("DjClassInspector.NotAClassFile")); 131 } 132 133 136 ArrayList names = new ArrayList (); 137 138 IndexInfo indexInfo = new IndexInfo(); 139 indexInfo.idx = 10; 140 indexInfo.poolSize = numConstPoolEntries - 1; 141 142 int i = 0; 143 while (i < indexInfo.poolSize) 144 { 145 readConstant(clz, names, indexInfo); 146 i++; 147 } 148 149 indexInfo.idx += 2; 151 152 int ident = asInt(clz, indexInfo.idx) - 1; 153 int classIdx = Integer.parseInt(names.get(ident).toString()); 154 155 return names.get(classIdx - 1).toString(); 156 } 157 158 private void readConstant(byte[] clz, ArrayList names, IndexInfo indexInfo) 159 { 160 byte tag = clz[indexInfo.idx++]; 161 162 if (tag == CONSTANT_Utf8) 163 { 164 int length = asInt(clz, indexInfo.idx); 165 indexInfo.idx += 2; 166 String name = new String (clz, indexInfo.idx, length); 167 names.add(name); 168 indexInfo.idx += length; 169 } 170 else if (tag == CONSTANT_Class) 171 { 172 int subscript = asInt(clz, indexInfo.idx); 173 indexInfo.idx += 2; 174 names.add(String.valueOf(subscript)); 175 } 176 else if (tag == CONSTANT_String) 177 { 178 names.add("S" + asInt(clz, indexInfo.idx)); 179 indexInfo.idx += 2; 180 } 181 else if (tag == CONSTANT_Fieldref || tag == CONSTANT_Methodref || tag == CONSTANT_InterfaceMethodref 182 || tag == CONSTANT_NameAndType || tag == CONSTANT_Integer || tag == CONSTANT_Float) 183 { 184 indexInfo.idx += 4; 185 names.add("R" + asLong(clz, indexInfo.idx)); 186 } 187 else if (tag == CONSTANT_Long || tag == CONSTANT_Double) 188 { 189 names.add("L"); 190 indexInfo.idx += 8; 191 indexInfo.poolSize--; 192 } 193 } 194 195 public byte[] getClassDefinition() 196 { 197 return _classDefinition; 198 } 199 200 public void setClassDefinition(byte[] bs) 201 { 202 _classDefinition = bs; 203 } 204 205 class IndexInfo 206 { 207 public int idx; 208 public int poolSize; 209 210 } 211 } | Popular Tags |