package cn.xl.jvm.loader;
import java.io.UnsupportedEncodingException;
import cn.xl.jvm.clz.AccessFlag;
import cn.xl.jvm.clz.ClassFile;
import cn.xl.jvm.clz.ClassIndex;
import cn.xl.jvm.constant.ClassInfo;
import cn.xl.jvm.constant.ConstantPool;
import cn.xl.jvm.constant.FieldRefInfo;
import cn.xl.jvm.constant.MethodRefInfo;
import cn.xl.jvm.constant.NameAndTypeInfo;
import cn.xl.jvm.constant.NullConstantInfo;
import cn.xl.jvm.constant.StringInfo;
import cn.xl.jvm.constant.UTF8Info;
public class ClassFileParser {
public ClassFile parse(byte[] codes) {
ClassFile classFile = new ClassFile();
ByteCodeIterator iter = new ByteCodeIterator(codes);
if(!"cafebabe".equals(iter.nextU4ToHexString())){
return null;
}
classFile.setMinorVersion(iter.nextU2ToInt());
classFile.setMajorVersion(iter.nextU2ToInt());
classFile.setAccessFlag(this.parseAccessFlag(iter));
classFile.setClassIndex(this.parseClassIndex(iter));
classFile.setConstPool(this.parseConstantPool(iter));
return classFile;
}
private AccessFlag parseAccessFlag(ByteCodeIterator iter) {
/*AccessFlag accessFlag = new AccessFlag(iter.nextU2ToInt());
return accessFlag;*/
return null;
}
private ClassIndex parseClassIndex(ByteCodeIterator iter) {
return null;
}
private ConstantPool parseConstantPool(ByteCodeIterator iter) {
int constantCount = iter.nextU2ToInt();
System.out.println("constantPool count:"+constantCount);
ConstantPool constantPool = new ConstantPool();
constantPool.addConstantInfo(new NullConstantInfo());
for(int i = 0; i < constantCount; i++){
int tag = iter.nextU1ToInt();
if(tag == 7){
int utf8Index = iter.nextU2ToInt();
ClassInfo classInfo = new ClassInfo(constantPool);
classInfo.setUtf8Index(utf8Index);
constantPool.addConstantInfo(classInfo);
}else if(tag == 1){
int length = iter.nextU2ToInt();
UTF8Info utf8Info = new UTF8Info(constantPool);
utf8Info.setLength(length);
byte[] b = iter.nextLenBytes(length);
String strValue = null;
try {
strValue = new String(b,"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
utf8Info.setValue(strValue);
constantPool.addConstantInfo(utf8Info);
}else if(tag == 8){
int index = iter.nextU2ToInt();
StringInfo stringInfo = new StringInfo(constantPool);
stringInfo.setIndex(index);
constantPool.addConstantInfo(stringInfo);
}else if(tag == 9){
int classInfoindex = iter.nextU2ToInt();
int nameTypeIndex = iter.nextU2ToInt();
FieldRefInfo filedRefInfo = new FieldRefInfo(constantPool);
filedRefInfo.setClassInfoIndex(classInfoindex);
filedRefInfo.setNameAndTypeIndex(nameTypeIndex);
constantPool.addConstantInfo(filedRefInfo);
}else if(tag == 10){
int classInfoindex = iter.nextU2ToInt();
int nameTypeIndex = iter.nextU2ToInt();
MethodRefInfo methodRefInfo = new MethodRefInfo(constantPool);
methodRefInfo.setClassInfoIndex(classInfoindex);
methodRefInfo.setNameAndTypeIndex(nameTypeIndex);
constantPool.addConstantInfo(methodRefInfo);
}else if(tag == 12){
int nameIndex = iter.nextU2ToInt();
int descIndex = iter.nextU2ToInt();
NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(constantPool);
nameAndTypeInfo.setIndex1(nameIndex);
nameAndTypeInfo.setIndex2(descIndex);
constantPool.addConstantInfo(nameAndTypeInfo);
}else{
//throw new RuntimeException("the constant Pool tag "+tag+" has not been implement yet!");
}
}
return constantPool;
}
}