123 lines
4.4 KiB
Java
123 lines
4.4 KiB
Java
package com.de22.javabytecode;
|
|
|
|
import com.de22.javabytecode.attribute.*;
|
|
import com.de22.javabytecode.constant.*;
|
|
|
|
/**
|
|
* Copyright Wynne Crisman 1999,2006<p>
|
|
* Defines an attribute in any of the attribute collections.
|
|
* See the JVM specification 4.7.
|
|
* Subclasses of this type will provided additional functionality.
|
|
*/
|
|
public abstract class CodeAttribute extends Component {
|
|
/** The index of the attribute's name in the constant collection. */
|
|
private short nameIndex = -1;
|
|
/**
|
|
* CodeAttribute constructor.
|
|
*/
|
|
public CodeAttribute(Type type) {
|
|
super(type);
|
|
}//CodeAttribute()//
|
|
/**
|
|
* Gets the attribute's default name as it is stored in the class bytes.
|
|
* @return The default name identifying the attribute's type.
|
|
*/
|
|
public abstract String getDefaultName();
|
|
/**
|
|
* Gets the index of the attribute's name in the type's constant pool.
|
|
* @return The index of the attribute name.
|
|
*/
|
|
public short getNameIndex() {
|
|
return nameIndex;
|
|
}//getNameIndex()//
|
|
/* (non-Javadoc)
|
|
* @see com.de22.javabytecode.ITypeComponent#getSize()
|
|
*/
|
|
public abstract int getSize();
|
|
/**
|
|
* Reads an attribute from the given stream.
|
|
* @param type The type object that the attribute will belong to.
|
|
* @param in The input stream to read the attribute from.
|
|
*/
|
|
protected static CodeAttribute readAttribute(Type type, java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException {
|
|
CodeAttribute attribute = null;
|
|
short nameIndex = in.readShort();
|
|
Constant constant = type.getConstant(nameIndex);
|
|
ConstantUtf8 constantUtf8 = constant instanceof ConstantUtf8 ? (ConstantUtf8) constant : constant instanceof ConstantString ? (ConstantUtf8) type.getConstant(((ConstantString) constant).getStringIndex()) : null;
|
|
|
|
//This should never occur, but seems to for some compiled java code (probably due to a bad compiler). We will simply replace the missing string with an empty string.//
|
|
if(constantUtf8 == null) {
|
|
// System.out.println("Null constant found (index = " + nameIndex + ") while reading an unidentified attribute.");
|
|
attribute = new Unidentified(type, "");
|
|
attribute.nameIndex = nameIndex;
|
|
attribute.readExternal(in);
|
|
}//if//
|
|
else {
|
|
String name = constantUtf8.getValue();
|
|
|
|
if(name.equalsIgnoreCase("SourceFile")) {
|
|
attribute = new SourceFile(type);
|
|
}//if//
|
|
else if(name.equalsIgnoreCase("Code")) {
|
|
attribute = new Code(type);
|
|
}//else if//
|
|
else if(name.equalsIgnoreCase("Exceptions")) {
|
|
attribute = new ExceptionIndexes(type);
|
|
}//else if//
|
|
else if(name.equalsIgnoreCase("LineNumberTable")) {
|
|
attribute = new LineNumberTable(type);
|
|
}//else if//
|
|
else if(name.equalsIgnoreCase("LocalVariableTable")) {
|
|
attribute = new LocalVariableTable(type);
|
|
}//else if//
|
|
else if(name.equalsIgnoreCase("InnerClasses")) {
|
|
attribute = new InnerClasses(type);
|
|
}//else if//
|
|
else if(name.equalsIgnoreCase("ConstantValue")) {
|
|
attribute = new ConstantValue(type);
|
|
}//else if//
|
|
else if(name.equalsIgnoreCase("Synthetic")) {
|
|
attribute = new Synthetic(type);
|
|
}//else if//
|
|
else {
|
|
attribute = new Unidentified(type, name);
|
|
}//else//
|
|
|
|
attribute.nameIndex = nameIndex;
|
|
attribute.readExternal(in);
|
|
}//else//
|
|
|
|
return attribute;
|
|
}//readAttribute()//
|
|
/**
|
|
* Reads this object from the given stream.
|
|
* @param in The input stream to read this object from.
|
|
*/
|
|
public void readExternal(java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException {
|
|
if(this.nameIndex == -1) {
|
|
//There is usually no need to read the name index since it is read in the readAttribute(Type, ObjectInput) method.//
|
|
nameIndex = in.readShort();
|
|
}//if//
|
|
|
|
//Note: We leave it to the attribute to read the length of the attribute because some will require this info and most will ignore it.//
|
|
}//readExternal()//
|
|
/**
|
|
* Sets the index of the attribute's name in the type's constant pool.
|
|
* @param nameIndex The index of the attribute name.
|
|
*/
|
|
public void setNameIndex(short nameIndex) {
|
|
this.nameIndex = nameIndex;
|
|
}//setNameIndex()//
|
|
/**
|
|
* Writes this object to the given stream.
|
|
* @param out The output stream to write this object to.
|
|
*/
|
|
public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {
|
|
short nameIndex = getType().getConstantIndex(new ConstantUtf8(getType(), getDefaultName()));
|
|
|
|
//Write the constant index referenceing the attribute name.//
|
|
out.writeShort(nameIndex);
|
|
//Write size in bytes of the attribute.//
|
|
out.writeInt(getSize());
|
|
}//writeExternal()//
|
|
}//CodeAttribute// |