|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
package com.sun.org.apache.bcel.internal.classfile; |
|
|
|
import java.io.DataInput; |
|
import java.io.DataInputStream; |
|
import java.io.DataOutputStream; |
|
import java.io.IOException; |
|
import java.util.HashMap; |
|
import java.util.Map; |
|
|
|
import com.sun.org.apache.bcel.internal.Const; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public abstract class Attribute implements Cloneable, Node { |
|
|
|
private int name_index; |
|
private int length; |
|
private final byte tag; |
|
private ConstantPool constant_pool; |
|
|
|
protected Attribute(final byte tag, final int name_index, final int length, final ConstantPool constant_pool) { |
|
this.tag = tag; |
|
this.name_index = name_index; |
|
this.length = length; |
|
this.constant_pool = constant_pool; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
@Override |
|
public abstract void accept(Visitor v); |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void dump(final DataOutputStream file) throws IOException { |
|
file.writeShort(name_index); |
|
file.writeInt(length); |
|
} |
|
|
|
private static final Map<String, Object> readers = new HashMap<>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static void addAttributeReader(final String name, final UnknownAttributeReader r) { |
|
readers.put(name, r); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static void removeAttributeReader(final String name) { |
|
readers.remove(name); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static Attribute readAttribute(final DataInputStream file, final ConstantPool constant_pool) |
|
throws IOException, ClassFormatException { |
|
return readAttribute((DataInput) file, constant_pool); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static Attribute readAttribute(final DataInput file, final ConstantPool constant_pool) |
|
throws IOException, ClassFormatException { |
|
byte tag = Const.ATTR_UNKNOWN; |
|
|
|
final int name_index = file.readUnsignedShort(); |
|
final ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); |
|
final String name = c.getBytes(); |
|
|
|
|
|
final int length = file.readInt(); |
|
|
|
|
|
for (byte i = 0; i < Const.KNOWN_ATTRIBUTES; i++) { |
|
if (name.equals(Const.getAttributeName(i))) { |
|
tag = i; |
|
break; |
|
} |
|
} |
|
|
|
|
|
switch (tag) { |
|
case Const.ATTR_UNKNOWN: |
|
final Object r = readers.get(name); |
|
if (r instanceof UnknownAttributeReader) { |
|
return ((UnknownAttributeReader) r).createAttribute(name_index, length, file, constant_pool); |
|
} |
|
return new Unknown(name_index, length, file, constant_pool); |
|
case Const.ATTR_CONSTANT_VALUE: |
|
return new ConstantValue(name_index, length, file, constant_pool); |
|
case Const.ATTR_SOURCE_FILE: |
|
return new SourceFile(name_index, length, file, constant_pool); |
|
case Const.ATTR_CODE: |
|
return new Code(name_index, length, file, constant_pool); |
|
case Const.ATTR_EXCEPTIONS: |
|
return new ExceptionTable(name_index, length, file, constant_pool); |
|
case Const.ATTR_LINE_NUMBER_TABLE: |
|
return new LineNumberTable(name_index, length, file, constant_pool); |
|
case Const.ATTR_LOCAL_VARIABLE_TABLE: |
|
return new LocalVariableTable(name_index, length, file, constant_pool); |
|
case Const.ATTR_INNER_CLASSES: |
|
return new InnerClasses(name_index, length, file, constant_pool); |
|
case Const.ATTR_SYNTHETIC: |
|
return new Synthetic(name_index, length, file, constant_pool); |
|
case Const.ATTR_DEPRECATED: |
|
return new Deprecated(name_index, length, file, constant_pool); |
|
case Const.ATTR_PMG: |
|
return new PMGClass(name_index, length, file, constant_pool); |
|
case Const.ATTR_SIGNATURE: |
|
return new Signature(name_index, length, file, constant_pool); |
|
case Const.ATTR_STACK_MAP: |
|
return new StackMap(name_index, length, file, constant_pool); |
|
case Const.ATTR_RUNTIME_VISIBLE_ANNOTATIONS: |
|
return new RuntimeVisibleAnnotations(name_index, length, file, constant_pool); |
|
case Const.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS: |
|
return new RuntimeInvisibleAnnotations(name_index, length, file, constant_pool); |
|
case Const.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: |
|
return new RuntimeVisibleParameterAnnotations(name_index, length, file, constant_pool); |
|
case Const.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: |
|
return new RuntimeInvisibleParameterAnnotations(name_index, length, file, constant_pool); |
|
case Const.ATTR_ANNOTATION_DEFAULT: |
|
return new AnnotationDefault(name_index, length, file, constant_pool); |
|
case Const.ATTR_LOCAL_VARIABLE_TYPE_TABLE: |
|
return new LocalVariableTypeTable(name_index, length, file, constant_pool); |
|
case Const.ATTR_ENCLOSING_METHOD: |
|
return new EnclosingMethod(name_index, length, file, constant_pool); |
|
case Const.ATTR_STACK_MAP_TABLE: |
|
return new StackMap(name_index, length, file, constant_pool); |
|
case Const.ATTR_BOOTSTRAP_METHODS: |
|
return new BootstrapMethods(name_index, length, file, constant_pool); |
|
case Const.ATTR_METHOD_PARAMETERS: |
|
return new MethodParameters(name_index, length, file, constant_pool); |
|
default: |
|
|
|
throw new IllegalStateException("Unrecognized attribute type tag parsed: " + tag); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public String getName() { |
|
final ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); |
|
return c.getBytes(); |
|
} |
|
|
|
|
|
|
|
*/ |
|
public final int getLength() { |
|
return length; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public final void setLength(final int length) { |
|
this.length = length; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public final void setNameIndex(final int name_index) { |
|
this.name_index = name_index; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public final int getNameIndex() { |
|
return name_index; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public final byte getTag() { |
|
return tag; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public final ConstantPool getConstantPool() { |
|
return constant_pool; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public final void setConstantPool(final ConstantPool constant_pool) { |
|
this.constant_pool = constant_pool; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
@Override |
|
public Object clone() { |
|
Attribute attr = null; |
|
try { |
|
attr = (Attribute) super.clone(); |
|
} catch (final CloneNotSupportedException e) { |
|
throw new Error("Clone Not Supported"); |
|
} |
|
return attr; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public abstract Attribute copy(ConstantPool _constant_pool); |
|
|
|
|
|
|
|
*/ |
|
@Override |
|
public String toString() { |
|
return Const.getAttributeName(tag); |
|
} |
|
} |