Initial commit from SVN.
This commit is contained in:
123
Class File Services/src/com/de22/javabytecode/CodeAttribute.java
Normal file
123
Class File Services/src/com/de22/javabytecode/CodeAttribute.java
Normal file
@@ -0,0 +1,123 @@
|
||||
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//
|
||||
Reference in New Issue
Block a user