KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > bytecode > Attribute


1 // Copyright (c) 1997 Per M.A. Bothner.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.bytecode;
5 import java.io.*;
6
7 /**
8   * Represents an Attribute of an AttrContainer.
9   * <p>
10   * Various sub-classses are used for standard attributes,
11   * or you can use MiscAttr for a generic attribute.
12   * @author Per Bothner
13   */

14
15 public abstract class Attribute
16 {
17   /** Every Attribute belongs to some AttrContainer object. */
18   AttrContainer container;
19   /** Return the Attribute container that contains this Attribute. */
20   public final AttrContainer getContainer() { return container; }
21   public final void setContainer(AttrContainer container)
22   { this.container = container; }
23
24   Attribute next;
25   /** Get the next Attribute belonging to getContainer(). */
26   public final Attribute getNext() { return next; }
27   /** Set the next Attribute in the chain belonging to getContainer(). */
28   public final void setNext(Attribute next) { this.next = next; }
29
30   /** Add this to (the front of) of the specified attribute container. */
31   public void addToFrontOf(AttrContainer container)
32   {
33     setContainer(container);
34     setNext(container.getAttributes());
35     container.setAttributes(this);
36   }
37
38   String JavaDoc name; // This is an interned string.
39

40   // If > 0, the constant-pool index of name.
41
// If -1, means attribute should be skipped on output.
42
int name_index;
43
44   /** Returns true if this attribute should be skipped on output. */
45   public final boolean isSkipped() { return name_index < 0; }
46
47   /** Iff skip, cause this attributed to be skipped on output. */
48   public final void setSkipped(boolean skip) { name_index = skip ? -1 : 0; }
49
50   /** Cause this attributed to be skipped on output. */
51   public final void setSkipped() { name_index = -1; }
52
53   public final String JavaDoc getName() { return name; }
54   public final void setName(String JavaDoc name) { this.name = name.intern(); }
55
56   public final int getNameIndex() { return name_index; }
57   public final void setNameIndex(int index) { name_index = index; }
58
59   /** Create a new Attribute.
60     * @param name - an interned String that names the Attribute. */

61   public Attribute (String JavaDoc name)
62   {
63     this.name = name;
64   }
65
66   /** Find an Attribute by name, in an attribute cointainer.
67     * @param container the attribute container to search
68     * @param name the (interned) name of the attribute we are seeking
69     * @return the matching Attribute, or null if the search failed.
70     */

71   public static Attribute get (AttrContainer container, String JavaDoc name)
72   {
73     for (Attribute attr = container.getAttributes();
74      attr != null; attr = attr.next)
75       {
76     if (attr.getName() == name)
77       return attr;
78       }
79     return null;
80   }
81
82   /** Add any needed constant pool entries for this Attribute.
83     * Overridden by sub-classes.
84     * Do any other cleanup needed before writing out a .class file. */

85   public void assignConstants (ClassType cl)
86   {
87     if (name_index == 0)
88       name_index = cl.getConstants().addUtf8(name).getIndex();
89   }
90
91   /** Add any needed constant pool entries for all attributes in a container.
92     * Do any other cleanup needed before writing out a .class file. */

93   public static void assignConstants (AttrContainer container, ClassType cl)
94   {
95     for (Attribute attr = container.getAttributes();
96      attr != null; attr = attr.next)
97       {
98     if (! attr.isSkipped())
99       attr.assignConstants(cl);
100       }
101   }
102
103   /** Return the length of the attribute in bytes.
104     * Does not include the 6-byte header (for the name_index and the length).*/

105   abstract public int getLength();
106
107   /** Return the length of all the attributes (with headers) in bytes. */
108   public static int getLengthAll (AttrContainer container)
109   {
110     int length = 0;
111     for (Attribute attr = container.getAttributes();
112      attr != null; attr = attr.next)
113       {
114     if (! attr.isSkipped())
115       length += 6 + attr.getLength();
116       }
117     return length;
118   }
119
120   /** Write out the contents of the Attribute.
121     * Does not write the 6-byte attribute header. */

122   abstract public void write (DataOutputStream dstr)
123     throws java.io.IOException JavaDoc;
124
125   public static int count (AttrContainer container)
126   {
127     int count = 0;
128     for (Attribute attr = container.getAttributes();
129      attr != null; attr = attr.next)
130       {
131     if (!attr.isSkipped())
132       count++;
133       }
134     return count;
135   }
136
137   public static void writeAll (AttrContainer container, DataOutputStream dstr)
138     throws java.io.IOException JavaDoc
139   {
140     int count = count(container);
141     dstr.writeShort(count);
142     for (Attribute attr = container.getAttributes();
143      attr != null; attr = attr.next)
144       {
145     if (attr.isSkipped())
146       continue;
147     if (attr.name_index == 0)
148       throw new Error JavaDoc("Attribute.writeAll called without assignConstants");
149     dstr.writeShort(attr.name_index);
150     dstr.writeInt(attr.getLength());
151     attr.write(dstr);
152       }
153   }
154
155   public void print (ClassTypeWriter dst)
156   {
157     dst.print("Attribute \"");
158     dst.print(getName());
159     dst.print("\", length:");
160     dst.println(getLength());
161   }
162
163 };
164
Popular Tags