| /* |
| * Copyright 2006 ProductiveMe Inc. |
| * Copyright 2013 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.pme.util; |
| |
| import java.io.*; |
| |
| public class ClassFile { |
| private int myMagic; |
| private short myMajorVersion; |
| private short myMinorVersion; |
| private ConstantPoolInfo myConstantPool[]; |
| private short myAccessFlags; |
| private ConstantPoolInfo myThisClass; |
| private ConstantPoolInfo mySuperClass; |
| private ConstantPoolInfo myInterfaces[]; |
| private FieldInfo myFields[]; |
| private MethodInfo myMethods[]; |
| private AttributeInfo myAttributes[]; |
| |
| private void readConstantPool(DataInputStream stream) throws IOException { |
| myConstantPool = new ConstantPoolInfo[stream.readShort()]; |
| myConstantPool[0] = new ConstantPoolInfo(); |
| for (int i = 1; i < myConstantPool.length; i++) { |
| myConstantPool[i] = new ConstantPoolInfo(); |
| myConstantPool[i].read(stream); |
| // These two types take up "two" spots in the table |
| if ((myConstantPool[i].getType() == ConstantPoolInfo.LONG) || |
| (myConstantPool[i].getType() == ConstantPoolInfo.DOUBLE)) |
| i++; |
| } |
| } |
| |
| private void readInterfaces(DataInputStream stream) throws IOException { |
| int count = stream.readShort(); |
| if (count != 0) { |
| myInterfaces = new ConstantPoolInfo[count]; |
| for (int i = 0; i < count; i++) { |
| int index = stream.readShort(); |
| if ((index < 1) || (index > myConstantPool.length - 1)) |
| throw new InvalidClassException("Wrong count for constant pool"); |
| myInterfaces[i] = myConstantPool[index]; |
| } |
| } |
| } |
| |
| private void readFields(DataInputStream stream) throws IOException { |
| int count = stream.readShort(); |
| if (count != 0) { |
| myFields = new FieldInfo[count]; |
| for (int i = 0; i < count; i++) { |
| myFields[i] = new FieldInfo(); |
| myFields[i].read(stream, myConstantPool); |
| } |
| } |
| } |
| |
| private void readMethods(DataInputStream stream) throws IOException { |
| int count = stream.readShort(); |
| if (count != 0) { |
| myMethods = new MethodInfo[count]; |
| for (int i = 0; i < count; i++) { |
| myMethods[i] = new MethodInfo(); |
| myMethods[i].read(stream, myConstantPool); |
| } |
| } |
| } |
| |
| private void readAttributes(DataInputStream stream) throws IOException { |
| int count = stream.readShort(); |
| if (count != 0) { |
| myAttributes = new AttributeInfo[count]; |
| for (int i = 0; i < count; i++) { |
| myAttributes[i] = new AttributeInfo(); |
| myAttributes[i].read(stream, myConstantPool); |
| } |
| } |
| } |
| |
| public static String readClassName(File file) throws IOException { |
| FileInputStream stream = new FileInputStream(file); |
| ClassFile classFile = new ClassFile(); |
| try { |
| classFile.read(stream); |
| return classFile.getSourceName(); |
| } finally{ |
| stream.close(); |
| } |
| } |
| |
| public void read(InputStream in) throws IOException { |
| DataInputStream stream = new DataInputStream(in); |
| myMagic = stream.readInt(); |
| if (myMagic != 0xCAFEBABE) { |
| throw new InvalidClassException("There is no magic number"); |
| } |
| |
| myMajorVersion = stream.readShort(); |
| myMinorVersion = stream.readShort(); |
| |
| readConstantPool(stream); |
| myAccessFlags = stream.readShort(); |
| myThisClass = myConstantPool[stream.readShort()]; |
| mySuperClass = myConstantPool[stream.readShort()]; |
| readInterfaces(stream); |
| readFields(stream); |
| readMethods(stream); |
| readAttributes(stream); |
| } |
| |
| public String getSourceName() { |
| if (myAttributes != null) { |
| for (int i = 0; i < myAttributes.length; i++) { |
| String attrName = myAttributes[i].getName().getStrValue(); |
| if ("SourceFile".compareTo(attrName) == 0) { |
| try { |
| DataInputStream dis = new DataInputStream(new ByteArrayInputStream(myAttributes[i].getData())); |
| ConstantPoolInfo cpi = myConstantPool[dis.readShort()]; |
| return cpi.getStrValue(); |
| } catch (IOException e) { |
| } |
| } |
| } |
| } |
| return null; |
| } |
| } |