package com.coderising.jvm.test;
import java.io.UnsupportedEncodingException;
import javax.management.RuntimeErrorException;
import com.coderising.jvm.clz.AccessFlag;
import com.coderising.jvm.clz.ClassFile;
import com.coderising.jvm.clz.ClassIndex;
import com.coderising.jvm.constant.ClassInfo;
import com.coderising.jvm.constant.ConstantPool;
import com.coderising.jvm.constant.FieldRefInfo;
import com.coderising.jvm.constant.MethodRefInfo;
import com.coderising.jvm.constant.NameAndTypeInfo;
import com.coderising.jvm.constant.NullConstantInfo;
import com.coderising.jvm.constant.StringInfo;
import com.coderising.jvm.constant.UTF8Info;
public class ClassFileParser {
public ClassFile parse(byte[] codes) {
ClassFile clzFile = new ClassFile();
ByteCodeIterator iter = new ByteCodeIterator(codes);
String magicNumber = iter.nextU4ToHexString();
if(!"cafebabe".equals(magicNumber)){
return null;
}
//读版本号
clzFile.setMinorVersion(iter.nextU2ToInt());
clzFile.setMajorVersion(iter.nextU2ToInt());
//读常量池
ConstantPool pool = parseConstantPool(iter);
clzFile.setConstPool(pool);
return clzFile;
}
private AccessFlag parseAccessFlag(ByteCodeIterator iter) {
return null;
}
private ClassIndex parseClassInfex(ByteCodeIterator iter) {
return null;
}
private ConstantPool parseConstantPool(ByteCodeIterator iter) {
//取出常量池的个数
int constPoolCount = iter.nextU2ToInt();
System.out.println("Constant pool Count:"+constPoolCount);
//定义一个常量池
ConstantPool pool = new ConstantPool();
//因为数组的第零项是无效的,数组从0开始,但是JVM确从1开始
pool.addConstantInfo(new NullConstantInfo());
for(int i = 1;i<=constPoolCount-1;i++){
int tag = iter.nextU1ToInt();
if(tag == 7){
//class Info
int utf8Index = iter.nextU2ToInt();
ClassInfo clzInfo = new ClassInfo(pool);
clzInfo.setUtf8Index(utf8Index);
//把classInfo加入到常量池中
pool.addConstantInfo(clzInfo);
}else if(tag == 1){
int len = iter.nextU2ToInt();
byte[] data = iter.getBytes(len);
String value = null;
try {
value = new String(data,"UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
UTF8Info utf8str = new UTF8Info(pool);
utf8str.setLength(len);
utf8str.setValue(value);
pool.addConstantInfo(utf8str);
}
else if(tag == 8){
StringInfo info = new StringInfo(pool);
info.setIndex(iter.nextU2ToInt());
pool.addConstantInfo(info);
}else if(tag == 9){
FieldRefInfo field = new FieldRefInfo(pool);
field.setClassInfoIndex(iter.nextU2ToInt());
field.setNameAndTypeIndex(iter.nextU2ToInt());
pool.addConstantInfo(field);
}else if (tag == 10) {
MethodRefInfo method = new MethodRefInfo(pool);
method.setClassInfoIndex(iter.nextU2ToInt());
method.setNameAndTypeIndex(iter.nextU2ToInt());
pool.addConstantInfo(method);
}else if(tag == 12){
NameAndTypeInfo nameType = new NameAndTypeInfo(pool);
nameType.setIndex1(iter.nextU2ToInt());
nameType.setIndex2(iter.nextU2ToInt());
pool.addConstantInfo(nameType);
}else{
throw new RuntimeErrorException(null, "the constant pool tag"+tag+"has not been implemented yet ");
}
}
System.out.println("Finshed reading Constant pool");
return pool;
}
}