00001 package de.fub.bytecode.classfile;
00002
00003 import de.fub.bytecode.Constants;
00004 import java.io.*;
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 public abstract class Attribute implements Cloneable
00028 {
00029 protected int name_index;
00030 protected int length;
00031 protected byte tag;
00032 protected ConstantPool constant_pool;
00033
00034 Attribute(byte tag, int name_index, int length, ConstantPool constant_pool) {
00035 this.tag = tag;
00036 this.name_index = name_index;
00037 this.length = length;
00038 this.constant_pool = constant_pool;
00039 }
00040
00041
00042
00043
00044
00045
00046
00047 public abstract void accept(Visitor v);
00048
00049
00050
00051
00052
00053
00054 public Object clone() {
00055 Object o = null;
00056
00057 try {
00058 o = super.clone();
00059 } catch(CloneNotSupportedException e) {
00060 e.printStackTrace();
00061 }
00062
00063 return o;
00064 }
00065
00066
00067
00068 public abstract Attribute copy(ConstantPool constant_pool);
00069
00070
00071
00072
00073
00074
00075 public void dump(DataOutputStream file) throws IOException
00076 {
00077 file.writeShort(name_index);
00078 file.writeInt(length);
00079 }
00080
00081
00082
00083
00084 public final ConstantPool getConstantPool() { return constant_pool; }
00085
00086
00087
00088 public final int getLength() { return length; }
00089
00090
00091
00092 public final int getNameIndex() { return name_index; }
00093
00094
00095
00096
00097 public final byte getTag() { return tag; }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 static final Attribute readAttribute(DataInputStream file,
00114 ConstantPool constant_pool)
00115 throws IOException, ClassFormatError, InternalError
00116 {
00117 ConstantUtf8 c;
00118 String name;
00119 int name_index;
00120 int length;
00121 byte tag = Constants.ATTR_UNKNOWN;
00122
00123
00124 name_index = (int)(file.readUnsignedShort());
00125 c = (ConstantUtf8)constant_pool.getConstant(name_index,
00126 Constants.CONSTANT_Utf8);
00127 name = c.getBytes();
00128
00129
00130 length = file.readInt();
00131
00132
00133 for(byte i=0; i < Constants.KNOWN_ATTRIBUTES; i++) {
00134 if(name.equals(Constants.ATTRIBUTE_NAMES[i])) {
00135 tag = i;
00136 break;
00137 }
00138 }
00139
00140
00141 switch(tag) {
00142 case Constants.ATTR_UNKNOWN:
00143 return new Unknown(name_index, length, file, constant_pool);
00144
00145 case Constants.ATTR_CONSTANT_VALUE:
00146 return new ConstantValue(name_index, length, file, constant_pool);
00147
00148 case Constants.ATTR_SOURCE_FILE:
00149 return new SourceFile(name_index, length, file, constant_pool);
00150
00151 case Constants.ATTR_CODE:
00152 return new Code(name_index, length, file, constant_pool);
00153
00154 case Constants.ATTR_EXCEPTIONS:
00155 return new ExceptionTable(name_index, length, file, constant_pool);
00156
00157 case Constants.ATTR_LINE_NUMBER_TABLE:
00158 return new LineNumberTable(name_index, length, file, constant_pool);
00159
00160 case Constants.ATTR_LOCAL_VARIABLE_TABLE:
00161 return new LocalVariableTable(name_index, length, file, constant_pool);
00162
00163 case Constants.ATTR_INNER_CLASSES:
00164 return new InnerClasses(name_index, length, file, constant_pool);
00165
00166 case Constants.ATTR_SYNTHETIC:
00167 return new Synthetic(name_index, length, file, constant_pool);
00168
00169 case Constants.ATTR_DEPRECATED:
00170 return new Deprecated(name_index, length, file, constant_pool);
00171
00172 case Constants.ATTR_PMG:
00173 return new PMGClass(name_index, length, file, constant_pool);
00174
00175 case Constants.ATTR_SIGNATURE:
00176 return new Signature(name_index, length, file, constant_pool);
00177
00178 default:
00179 throw new InternalError("Ooops! default case reached.");
00180 }
00181 }
00182
00183
00184
00185
00186 public final void setConstantPool(ConstantPool constant_pool) {
00187 this.constant_pool = constant_pool;
00188 }
00189
00190
00191
00192 public final void setLength(int length) {
00193 this.length = length;
00194 }
00195
00196
00197
00198 public final void setNameIndex(int name_index) {
00199 this.name_index = name_index;
00200 }
00201
00202
00203
00204 public String toString() {
00205 return Constants.ATTRIBUTE_NAMES[tag];
00206 }
00207 }