package org.tinylcy.attributeinfo;
import org.tinylcy.basictype.U1;
import org.tinylcy.basictype.U2;
import org.tinylcy.basictype.U4;
import org.tinylcy.constantpool.ConstantPool;
import org.tinylcy.constantpool.ConstantUtf8Info;
import java.io.InputStream;
import java.util.Arrays;
/**
* Created by chenyangli.
*/
public class Code extends BasicAttributeInfo {
private short maxStack;
private short maxLocals;
private long codeLength;
private byte[] code;
private short exceptionTableLength;
private ExceptionInfo[] exceptionTable;
private short attributesCount;
private BasicAttributeInfo[] attributes;
public Code(ConstantPool constantPool, short attributeNameIndex) {
super(constantPool);
setAttributeNameIndex(attributeNameIndex);
}
@Override
public void read(InputStream inputStream) {
U4 attributeLengthU4 = U4.read(inputStream);
U2 maxStackU2 = U2.read(inputStream);
U2 maxLocalsU2 = U2.read(inputStream);
U4 codeLengthU4 = U4.read(inputStream);
setAttributeLength(attributeLengthU4.getValue());
maxStack = maxStackU2.getValue();
maxLocals = maxLocalsU2.getValue();
codeLength = codeLengthU4.getValue();
code = new byte[(int) codeLength];
for (int i = 0; i < codeLength; i++) {
U1 codeU1 = U1.read(inputStream);
code[i] = codeU1.getValue();
}
U2 exceptionTableLengthU2 = U2.read(inputStream);
exceptionTableLength = exceptionTableLengthU2.getValue();
exceptionTable = new ExceptionInfo[exceptionTableLength];
for (int i = 0; i < exceptionTableLengthU2.getValue(); i++) {
ExceptionInfo exceptionInfo = new ExceptionInfo();
exceptionInfo.read(inputStream);
exceptionTable[i] = exceptionInfo;
}
U2 attributesCountU2 = U2.read(inputStream);
attributesCount = attributesCountU2.getValue();
attributes = new BasicAttributeInfo[attributesCount];
for (int i = 0; i < attributesCountU2.getValue(); i++) {
short attributeNameIndex = U2.read(inputStream).getValue();
BasicAttributeInfo attributeInfo = BasicAttributeInfo.newAttributeInfo(constantPool,
attributeNameIndex);
attributeInfo.read(inputStream);
attributes[i] = attributeInfo;
}
}
@Override
public String toString() {
return "Code{" +
"attributeNameIndex=" + getAttributeNameIndex() +
" [attribute name = " + ((ConstantUtf8Info) (constantPool.getCpInfo()[getAttributeNameIndex() - 1])).getValue() + "]" +
", attributeLength=" + getAttributeLength() +
", maxStack=" + maxStack +
", maxLocals=" + maxLocals +
", codeLength=" + codeLength +
", code=" + Arrays.toString(code) +
", exceptionTableLength=" + exceptionTableLength +
", exceptionTable=" + Arrays.toString(exceptionTable) +
", attributesCount=" + attributesCount +
", attributes=" + Arrays.toString(attributes) +
'}';
}
private class ExceptionInfo {
public short startPc;
public short endPc;
public short handlerPc;
public short catchType;
public void read(InputStream inputStream) {
U2 startPcU2 = U2.read(inputStream);
U2 endPcU2 = U2.read(inputStream);
U2 handlerPcU2 = U2.read(inputStream);
U2 catchTypeU2 = U2.read(inputStream);
this.startPc = startPcU2.getValue();
this.endPc = endPcU2.getValue();
this.handlerPc = handlerPcU2.getValue();
this.catchType = catchTypeU2.getValue();
}
@Override
public String toString() {
return "ExceptionInfo{" +
"startPc=" + startPc +
", endPc=" + endPc +
", handlerPc=" + handlerPc +
", catchType=" + catchType +
'}';
}
}
}