Files
Brainstorm/Class File Services/src/com/de22/javabytecode/CodeAttribute.java
2014-05-30 10:31:51 -07:00

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//