1 cananian 1.1.2.2 // Attribute.java, created Mon Jan 18 22:44:33 1999 by cananian
 2 cananian 1.1.2.1 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
 3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
 4 cananian 1.1.2.1 package harpoon.IR.RawClass;
 5 cananian 1.1.2.1 
 6 cananian 1.1.2.1 /**
 7 cananian 1.1.2.1  * Attributes are used in the <code>ClassFile</code>,
 8 cananian 1.1.2.1  * <code>field_info</code>, <code>method_info</code>, and
 9 cananian 1.1.2.1  * <code>Code_attribute</code> structures of the <code>class</code> file
10 cananian 1.1.2.1  * format.  <code>Attribute</code> is the superclass of the different
11 cananian 1.1.2.1  * types of attribute information classes.
12 cananian 1.1.2.1  *
13 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
14 cananian 1.4      * @version $Id: Attribute.java,v 1.4 2003/09/05 21:45:15 cananian Exp $
15 cananian 1.1.2.1  * @see "The Java Virtual Machine Specification, section 4.7"
16 cananian 1.1.2.1  * @see ClassFile
17 cananian 1.1.2.1  * @see FieldInfo
18 cananian 1.1.2.1  * @see MethodInfo
19 cananian 1.1.2.1  * @see AttributeCode
20 cananian 1.1.2.1  */
21 cananian 1.1.2.1 public abstract class Attribute {
22 cananian 1.1.2.1   /** ClassFile in which this attribute information is found. */
23 cananian 1.1.2.1   protected ClassFile parent;
24 cananian 1.1.2.1 
25 cananian 1.1.2.1   /** The <code>attribute_name_index</code> must be a valid unsigned
26 cananian 1.1.2.1       16-bit index into the constant pool of the class.  The
27 cananian 1.1.2.1       <code>constant_pool</code> entry at
28 cananian 1.1.2.1       <code>attribute_name_index</code> must be a
29 cananian 1.1.2.1       <code>CONSTANT_Utf8</code> string representing the name of the
30 cananian 1.1.2.1       attribute. */
31 cananian 1.1.2.1   public int attribute_name_index;
32 cananian 1.1.2.1   /** The value of the <code>attribute_length</code> item indicates
33 cananian 1.1.2.1    *  the length of the attribute, excluding the initial six bytes. 
34 cananian 1.1.2.1    */ 
35 cananian 1.1.2.1   public abstract long attribute_length();
36 cananian 1.1.2.1 
37 cananian 1.1.2.1   /** Constructor.  Meant for use only by subclasses. */
38 cananian 1.1.2.1   protected Attribute(ClassFile p, int attribute_name_index) {
39 cananian 1.1.2.1     this.parent = p;
40 cananian 1.1.2.1     this.attribute_name_index = attribute_name_index;
41 cananian 1.1.2.1   }
42 cananian 1.1.2.1 
43 cananian 1.1.2.1   /** Read an Attribute from a ClassDataInputStream. */
44 cananian 1.1.2.1   public static Attribute read(ClassFile parent, ClassDataInputStream in)
45 cananian 1.1.2.1        throws java.io.IOException {
46 cananian 1.1.2.1     int attribute_name_index = in.read_u2();
47 cananian 1.1.2.1     String attribute_name = 
48 cananian 1.1.2.1       ((ConstantUtf8) parent.constant_pool[attribute_name_index]).val;
49 cananian 1.1.2.1 
50 cananian 1.4         if (attribute_name.equals(AttributeSourceFile.ATTRIBUTE_NAME))
51 cananian 1.1.2.1       return new AttributeSourceFile(parent, in, attribute_name_index);
52 cananian 1.4         if (attribute_name.equals(AttributeConstantValue.ATTRIBUTE_NAME))
53 cananian 1.1.2.1       return new AttributeConstantValue(parent, in, attribute_name_index);
54 cananian 1.4         if (attribute_name.equals(AttributeCode.ATTRIBUTE_NAME))
55 cananian 1.1.2.1       return new AttributeCode(parent, in, attribute_name_index);
56 cananian 1.4         if (attribute_name.equals(AttributeExceptions.ATTRIBUTE_NAME))
57 cananian 1.1.2.1       return new AttributeExceptions(parent, in, attribute_name_index);
58 cananian 1.4         if (attribute_name.equals(AttributeLineNumberTable.ATTRIBUTE_NAME))
59 cananian 1.1.2.1       return new AttributeLineNumberTable(parent, in, attribute_name_index);
60 cananian 1.4         if (attribute_name.equals(AttributeLocalVariableTable.ATTRIBUTE_NAME))
61 cananian 1.1.2.1       return new AttributeLocalVariableTable(parent, in, attribute_name_index);
62 cananian 1.4         if (attribute_name.equals(AttributeInnerClasses.ATTRIBUTE_NAME))
63 cananian 1.1.2.1       return new AttributeInnerClasses(parent, in, attribute_name_index);
64 cananian 1.4         if (attribute_name.equals(AttributeSynthetic.ATTRIBUTE_NAME))
65 cananian 1.1.2.1       return new AttributeSynthetic(parent, in, attribute_name_index);
66 cananian 1.4         if (attribute_name.equals(AttributeSignature.ATTRIBUTE_NAME))
67 cananian 1.2.2.1         return new AttributeSignature(parent, in, attribute_name_index);
68 cananian 1.1.2.1     // Unknown attribute type.
69 cananian 1.1.2.1     return new AttributeUnknown(parent, in, attribute_name_index);
70 cananian 1.1.2.1   }
71 cananian 1.1.2.1 
72 cananian 1.1.2.1   /** Write Attribute to bytecode file. */
73 cananian 1.1.2.1   public abstract void write(ClassDataOutputStream out) 
74 cananian 1.1.2.1     throws java.io.IOException;
75 cananian 1.1.2.1   
76 cananian 1.1.2.1   // convenience functions.
77 cananian 1.1.2.1   public ConstantUtf8 attribute_name_index()
78 cananian 1.1.2.1   { return (ConstantUtf8) parent.constant_pool[attribute_name_index]; }
79 cananian 1.1.2.1   public String attribute_name() { return attribute_name_index().val; }
80 cananian 1.1.2.1 
81 cananian 1.1.2.1   /** Create a human-readable representation for the Attribute. */
82 cananian 1.1.2.1   public String toString()
83 cananian 1.1.2.1   { return "("+attribute_name()+" Attribute["+attribute_length()+"])"; }
84 cananian 1.1.2.1 
85 cananian 1.1.2.1   /** Pretty-print this attribute structure. */
86 cananian 1.1.2.1   public void print(java.io.PrintWriter pw, int indent) {
87 cananian 1.1.2.1     indent(pw, indent, toString());
88 cananian 1.1.2.1   }
89 cananian 1.1.2.1   static void indent(java.io.PrintWriter pw, int indent, String s) {
90 cananian 1.1.2.1     ClassFile.indent(pw,indent,s);
91 cananian 1.1.2.1   }
92 cananian 1.2     }