• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: Attribute_info.java,v 1.1.1.1 2004/05/09 16:57:47 vlad_r Exp $
8  */
9 package com.vladium.jcd.cls.attribute;
10 
11 import java.io.IOException;
12 
13 import com.vladium.jcd.cls.ClassDef;
14 import com.vladium.jcd.cls.IConstantCollection;
15 import com.vladium.jcd.cls.constant.*;
16 import com.vladium.jcd.compiler.IClassFormatOutput;
17 import com.vladium.jcd.lib.UDataInputStream;
18 import com.vladium.jcd.lib.UDataOutputStream;
19 
20 // ----------------------------------------------------------------------------
21 /**
22  * Abstract base for all XXXAttribute_info structures. It also works in conjunction
23  * with {@link GenericAttribute_info} class to process all unrecognized attributes.<P>
24  *
25  * Attributes are used in the {@link com.vladium.jcd.cls.ClassDef}, {@link com.vladium.jcd.cls.Field_info},
26  * {@link com.vladium.jcd.cls.Method_info}, and {@link CodeAttribute_info}
27  * structures of the .class file format. All attributes have the following
28  * general format:
29  * <PRE>
30  *  attribute_info {
31  *          u2 attribute_name_index;
32  *          u4 attribute_length;
33  *          u1 info[attribute_length];
34  *  }
35  * </PRE>
36  *
37  * For all attributes, the attribute_name_index must be a valid unsigned 16-bit
38  * index into the constant pool of the class. The constant pool entry at
39  * attribute_name_index must be a {@link com.vladium.jcd.cls.constant.CONSTANT_Utf8_info}
40  * string representing the name of the attribute. The value of the attribute_length
41  * item indicates the length of the subsequent information in bytes. The length
42  * does not include the initial six bytes that contain the attribute_name_index
43  * and attribute_length items.
44  *
45  * @see GenericAttribute_info
46  *
47  * @author (C) 2001, Vlad Roubtsov
48  */
49 public
50 abstract class Attribute_info implements Cloneable, IClassFormatOutput
51 {
52     // public: ................................................................
53 
54     public static final String ATTRIBUTE_CODE               = "Code";
55     public static final String ATTRIBUTE_CONSTANT_VALUE     = "ConstantValue";
56     public static final String ATTRIBUTE_LINE_NUMBER_TABLE  = "LineNumberTable";
57     public static final String ATTRIBUTE_EXCEPTIONS         = "Exceptions";
58     public static final String ATTRIBUTE_SYNTHETIC          = "Synthetic";
59     public static final String ATTRIBUTE_BRIDGE             = "Bridge";
60     public static final String ATTRIBUTE_SOURCEFILE         = "SourceFile";
61     public static final String ATTRIBUTE_INNERCLASSES       = "InnerClasses";
62 
63     /**
64      * Constant pool index for {@link com.vladium.jcd.cls.constant.CONSTANT_Utf8_info}
65      * string representing the name of this attribute [always positive].
66      */
67     public int m_name_index;
68 
69     /**
70      * Returns the name for this attribute within the constant pool context of 'cls'
71      * class definition.
72      *
73      * @param cls class that contains this attribute
74      * @return attribute name
75      */
getName(final ClassDef cls)76     public String getName (final ClassDef cls)
77     {
78         return ((CONSTANT_Utf8_info) cls.getConstants ().get (m_name_index)).m_value;
79     }
80 
81     /**
82      * Returns the total length of this attribute when converted to
83      * .class format [including the 6-byte header]
84      */
length()85     public abstract long length (); // including the 6-byte header
86 
87     // Visitor:
88 
accept(IAttributeVisitor visitor, Object ctx)89     public abstract void accept (IAttributeVisitor visitor, Object ctx);
90 
toString()91     public abstract String toString ();
92 
93     // TODO: use a hashmap lookup in this method + control which set of attrs get mapped to generic
94     /**
95      * Parses out a single Attribute_info element out of .class data in
96      * 'bytes'.
97      *
98      * @param constants constant pool for the parent class [may not be null; not validated]
99      * @param bytes input .class data stream [may not be null; not validated]
100      *
101      * @return a single parsed attribute
102      *
103      * @throws IOException on input errors
104      */
new_Attribute_info(final IConstantCollection constants, final UDataInputStream bytes)105     public static Attribute_info new_Attribute_info (final IConstantCollection constants,
106                                                      final UDataInputStream bytes)
107         throws IOException
108     {
109         final int attribute_name_index = bytes.readU2 ();
110         final long attribute_length = bytes.readU4 ();
111 
112         final CONSTANT_Utf8_info attribute_name = (CONSTANT_Utf8_info) constants.get (attribute_name_index);
113         final String name = attribute_name.m_value;
114 
115         if (ATTRIBUTE_CODE.equals (name))
116         {
117             return new CodeAttribute_info (constants, attribute_name_index, attribute_length, bytes);
118         }
119         else if (ATTRIBUTE_CONSTANT_VALUE.equals (name))
120         {
121             return new ConstantValueAttribute_info (attribute_name_index, attribute_length, bytes);
122         }
123         else if (ATTRIBUTE_EXCEPTIONS.equals (name))
124         {
125             return new ExceptionsAttribute_info (attribute_name_index, attribute_length, bytes);
126         }
127         else if (ATTRIBUTE_INNERCLASSES.equals (name))
128         {
129             return new InnerClassesAttribute_info (attribute_name_index, attribute_length, bytes);
130         }
131         else if (ATTRIBUTE_SYNTHETIC.equals (name))
132         {
133             return new SyntheticAttribute_info (attribute_name_index, attribute_length);
134         }
135         else if (ATTRIBUTE_BRIDGE.equals (name))
136         {
137             return new BridgeAttribute_info (attribute_name_index, attribute_length);
138         }
139         else if (ATTRIBUTE_LINE_NUMBER_TABLE.equals (name))
140         {
141             return new LineNumberTableAttribute_info (attribute_name_index, attribute_length, bytes);
142         }
143         else if (ATTRIBUTE_SOURCEFILE.equals (name))
144         {
145             return new SourceFileAttribute_info (attribute_name_index, attribute_length, bytes);
146         }
147         else
148         {
149             // default:
150             return new GenericAttribute_info (attribute_name_index, attribute_length, bytes);
151         }
152     }
153 
154     // Cloneable:
155 
156     /**
157      * Chains to super.clone() and removes CloneNotSupportedException
158      * from the method signature.
159      */
clone()160     public Object clone ()
161     {
162         try
163         {
164             return super.clone ();
165         }
166         catch (CloneNotSupportedException e)
167         {
168             throw new InternalError (e.toString ());
169         }
170     }
171 
172     // IClassFormatOutput:
173 
writeInClassFormat(UDataOutputStream out)174     public void writeInClassFormat (UDataOutputStream out) throws IOException
175     {
176         out.writeU2 (m_name_index);
177         out.writeU4 (length () - 6); // don't use m_attribute_length
178     }
179 
180     // protected: .............................................................
181 
182     /*
183     protected Attribute_info (UDataInputStream bytes) throws IOException
184     {
185         //m_name_index = bytes.readU2 ();
186         //m_attribute_length = bytes.readU4 ();
187     }
188     */
189 
Attribute_info(final int attribute_name_index, final long attribute_length)190     protected Attribute_info (final int attribute_name_index, final long attribute_length)
191     {
192         m_name_index = attribute_name_index;
193         m_attribute_length = attribute_length;
194     }
195 
196     // TODO: remove this field as it is invalidated easily by most attribute mutations
197     protected long m_attribute_length; // excluding the 6-byte header
198 
199     // package: ...............................................................
200 
201     // private: ...............................................................
202 
203 } // end of class
204 // ----------------------------------------------------------------------------
205