package parse; import clz.AccessFlag; import clz.ClassFile; import clz.ClassIndex; import com.sun.corba.se.impl.orbutil.closure.Constant; import constant.*; import field.Field; import iterator.ByteCodeIterator; import method.Method; import util.Util; import java.util.List; /** * Created by william on 2017/4/11. */ public class ClassFilePaser { private ClassFile classFile; public ClassFile parse(byte[] codes) { classFile = new ClassFile(); ByteCodeIterator iterator = new ByteCodeIterator(codes); String magic = iterator.nextU4ToHexString(); if (!"cafebabe".equals(magic)) return null; classFile.setMinorVersion(iterator.nextU2ToInt()); classFile.setMajorVersion(iterator.nextU2ToInt()); ConstantPool constantPool = parseConstantPool(iterator); classFile.setConstPool(constantPool); AccessFlag accessFlag = parseAccessFlag(iterator); classFile.setAccessFlag(accessFlag); ClassIndex classIndex = parseClassIndex(iterator); classFile.setClassIndex(classIndex); iterator.nextU2ToInt();//没有接口直接读取两个字节 int fieldCount = iterator.nextU2ToInt(); for (int i = 0; i < fieldCount; i++) { Field field = parseField(iterator, constantPool); classFile.addField(field); } int methodCount = iterator.nextU2ToInt(); for (int i = 0; i < methodCount; i++) { Method method = parseMethod(iterator, classFile); classFile.addMethod(method); } return classFile; } private Method parseMethod(ByteCodeIterator iterator, ClassFile classFile) { return Method.parse(classFile,iterator); } private Field parseField(ByteCodeIterator iterator, ConstantPool constantPool) { return Field.parse(constantPool, iterator); } private ClassIndex parseClassIndex(ByteCodeIterator iterator) { ClassIndex classIndex = new ClassIndex(); classIndex.setThisClassIndex(iterator.nextU2ToInt()); classIndex.setSuperClassIndex(iterator.nextU2ToInt()); return classIndex; } private AccessFlag parseAccessFlag(ByteCodeIterator iterator) { AccessFlag accessFlag = new AccessFlag(iterator.nextU2ToInt()); return accessFlag; } private ConstantPool parseConstantPool(ByteCodeIterator iterator) { int poolSize = iterator.nextU2ToInt(); System.out.println("constant pool size = " + (poolSize - 1)); ConstantPool constantPool = new ConstantPool(); constantPool.addConstantInfo(new NullConstantInfo()); for (int i = 1; i < poolSize; i++) { int tag = iterator.nextU1ToInt(); if (tag == ConstantInfo.CLASS_INFO) { ClassInfo classInfo = new ClassInfo(constantPool); classInfo.setUtf8Index(iterator.nextU2ToInt()); constantPool.addConstantInfo(classInfo); } else if (tag == ConstantInfo.METHOD_INFO) { MethodRefInfo methodRefInfo = new MethodRefInfo(constantPool); methodRefInfo.setClassInfoIndex(iterator.nextU2ToInt()); methodRefInfo.setNameAndTypeIndex(iterator.nextU2ToInt()); constantPool.addConstantInfo(methodRefInfo); } else if (tag == ConstantInfo.FIELD_INFO) { FieldRefInfo fieldRefInfo = new FieldRefInfo(constantPool); fieldRefInfo.setClassInfoIndex(iterator.nextU2ToInt()); fieldRefInfo.setNameAndTypeIndex(iterator.nextU2ToInt()); constantPool.addConstantInfo(fieldRefInfo); } else if (tag == ConstantInfo.STRING_INFO) { StringInfo stringInfo = new StringInfo(constantPool); stringInfo.setIndex(iterator.nextU2ToInt()); constantPool.addConstantInfo(stringInfo); } else if (tag == ConstantInfo.NAME_AND_TYPE_INFO) { NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(constantPool); nameAndTypeInfo.setIndex1(iterator.nextU2ToInt()); nameAndTypeInfo.setIndex2(iterator.nextU2ToInt()); constantPool.addConstantInfo(nameAndTypeInfo); } else if (tag == ConstantInfo.UTF8_INFO) { UTF8Info utf8Info = new UTF8Info(constantPool); int length = iterator.nextU2ToInt(); utf8Info.setLength(length); utf8Info.setValue(new String(iterator.nextLengthBytes(length))); constantPool.addConstantInfo(utf8Info); } else { System.out.println("other class info "); } } return constantPool; } }