1 package com.sun.org.apache.bcel.internal.classfile; 2 3 56 57 import com.sun.org.apache.bcel.internal.Constants; 58 import java.io.*; 59 import java.util.zip.*; 60 61 77 public final class ClassParser { 78 private DataInputStream file; 79 private ZipFile zip; 80 private String file_name; 81 private int class_name_index, superclass_name_index; 82 private int major, minor; private int access_flags; private int[] interfaces; private ConstantPool constant_pool; private Field[] fields; private Method[] methods; private Attribute[] attributes; private boolean is_zip; 91 private static final int BUFSIZE = 8192; 92 93 99 public ClassParser(InputStream file, String file_name) { 100 this.file_name = file_name; 101 102 String clazz = file.getClass().getName(); is_zip = clazz.startsWith("java.util.zip.") || clazz.startsWith("java.util.jar."); 104 105 if(file instanceof DataInputStream) this.file = (DataInputStream)file; 107 else 108 this.file = new DataInputStream(new BufferedInputStream(file, BUFSIZE)); 109 } 110 111 116 public ClassParser(String file_name) throws IOException 117 { 118 is_zip = false; 119 this.file_name = file_name; 120 file = new DataInputStream(new BufferedInputStream 121 (new FileInputStream(file_name), BUFSIZE)); 122 } 123 124 129 public ClassParser(String zip_file, String file_name) throws IOException 130 { 131 is_zip = true; 132 zip = new ZipFile(zip_file); 133 ZipEntry entry = zip.getEntry(file_name); 134 135 this.file_name = file_name; 136 137 file = new DataInputStream(new BufferedInputStream(zip.getInputStream(entry), 138 BUFSIZE)); 139 } 140 141 152 public JavaClass parse() throws IOException, ClassFormatError 153 { 154 155 readID(); 157 158 readVersion(); 160 161 162 readConstantPool(); 164 165 readClassInfo(); 167 168 readInterfaces(); 170 171 172 readFields(); 174 175 readMethods(); 177 178 readAttributes(); 180 181 186 192 198 file.close(); 200 if(zip != null) 201 zip.close(); 202 203 return new JavaClass(class_name_index, superclass_name_index, 205 file_name, major, minor, access_flags, 206 constant_pool, interfaces, fields, 207 methods, attributes, is_zip? JavaClass.ZIP : JavaClass.FILE); 208 } 209 210 215 private final void readAttributes() throws IOException, ClassFormatError 216 { 217 int attributes_count; 218 219 attributes_count = file.readUnsignedShort(); 220 attributes = new Attribute[attributes_count]; 221 222 for(int i=0; i < attributes_count; i++) 223 attributes[i] = Attribute.readAttribute(file, constant_pool); 224 } 225 226 231 private final void readClassInfo() throws IOException, ClassFormatError 232 { 233 access_flags = file.readUnsignedShort(); 234 235 238 if((access_flags & Constants.ACC_INTERFACE) != 0) 239 access_flags |= Constants.ACC_ABSTRACT; 240 241 if(((access_flags & Constants.ACC_ABSTRACT) != 0) && 242 ((access_flags & Constants.ACC_FINAL) != 0 )) 243 throw new ClassFormatError ("Class can't be both final and abstract"); 244 245 class_name_index = file.readUnsignedShort(); 246 superclass_name_index = file.readUnsignedShort(); 247 } 248 253 private final void readConstantPool() throws IOException, ClassFormatError 254 { 255 constant_pool = new ConstantPool(file); 256 } 257 258 263 private final void readFields() throws IOException, ClassFormatError 264 { 265 int fields_count; 266 267 fields_count = file.readUnsignedShort(); 268 fields = new Field[fields_count]; 269 270 for(int i=0; i < fields_count; i++) 271 fields[i] = new Field(file, constant_pool); 272 } 273 274 275 276 282 private final void readID() throws IOException, ClassFormatError 283 { 284 int magic = 0xCAFEBABE; 285 286 if(file.readInt() != magic) 287 throw new ClassFormatError (file_name + " is not a Java .class file"); 288 } 289 294 private final void readInterfaces() throws IOException, ClassFormatError 295 { 296 int interfaces_count; 297 298 interfaces_count = file.readUnsignedShort(); 299 interfaces = new int[interfaces_count]; 300 301 for(int i=0; i < interfaces_count; i++) 302 interfaces[i] = file.readUnsignedShort(); 303 } 304 309 private final void readMethods() throws IOException, ClassFormatError 310 { 311 int methods_count; 312 313 methods_count = file.readUnsignedShort(); 314 methods = new Method[methods_count]; 315 316 for(int i=0; i < methods_count; i++) 317 methods[i] = new Method(file, constant_pool); 318 } 319 324 private final void readVersion() throws IOException, ClassFormatError 325 { 326 minor = file.readUnsignedShort(); 327 major = file.readUnsignedShort(); 328 } 329 } 330 | Popular Tags |