KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > vladium > jcd > parser > ClassDefParser


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: ClassDefParser.java,v 1.1.1.1 2004/05/09 16:57:51 vlad_r Exp $
8  */

9 package com.vladium.jcd.parser;
10
11 import java.io.InputStream JavaDoc;
12 import java.io.IOException JavaDoc;
13
14 import com.vladium.jcd.cls.*;
15 import com.vladium.jcd.cls.attribute.*;
16 import com.vladium.jcd.cls.constant.*;
17 import com.vladium.jcd.lib.UDataInputStream;
18 import com.vladium.util.ByteArrayIStream;
19
20 // ----------------------------------------------------------------------------
21
/**
22  * This class provides an API for parsing a stream or array of bytecodes into a
23  * {@link ClassDef} AST.
24  *
25  * @author (C) 2001, Vlad Roubtsov
26  */

27 public
28 abstract class ClassDefParser
29 {
30     // public: ................................................................
31

32     
33     /**
34      * Parses an array of bytecodes into a {@link ClassDef}.
35      */

36     public static ClassDef parseClass (final byte [] bytes)
37         throws IOException JavaDoc
38     {
39         if (bytes == null) throw new IllegalArgumentException JavaDoc ("null input: bytes");
40         
41         classParser parser = new classParser (new UDataInputStream (new ByteArrayIStream (bytes)));
42         
43         return parser.class_table ();
44     }
45     
46     /**
47      * Parses an array of bytecodes into a {@link ClassDef}.
48      */

49     public static ClassDef parseClass (final byte [] bytes, final int length)
50         throws IOException JavaDoc
51     {
52         if (bytes == null) throw new IllegalArgumentException JavaDoc ("null input: bytes");
53         
54         classParser parser = new classParser (new UDataInputStream (new ByteArrayIStream (bytes, length)));
55         
56         return parser.class_table ();
57     }
58     
59     
60     /**
61      * Parses a stream of bytecodes into a {@link ClassDef}.
62      */

63     public static ClassDef parseClass (final InputStream JavaDoc bytes)
64         throws IOException JavaDoc
65     {
66         if (bytes == null) throw new IllegalArgumentException JavaDoc ("null input: bytes");
67         
68         classParser parser = new classParser (new UDataInputStream (bytes));
69         
70         return parser.class_table ();
71     }
72     
73     // protected: .............................................................
74

75     // package: ...............................................................
76

77
78     static final boolean PARSE_SERIAL_VERSION_UID = true;
79     
80     static final String JavaDoc SERIAL_VERSION_UID_FIELD_NAME = "serialVersionUID";
81     static final int SERIAL_VERSION_UID_FIELD_MASK = IAccessFlags.ACC_STATIC | IAccessFlags.ACC_FINAL;
82
83     // private: ...............................................................
84

85     
86     /**
87      * All the parsing work is done by this class and its class_table method. The
88      * work that needs to be done is not complicated, but is rather monotonous -- see
89      * Chapter 4 of VM spec 1.0 for the class file format.
90      */

91     private static final class classParser
92     {
93         classParser (final UDataInputStream bytes)
94         {
95             m_bytes = bytes;
96         }
97
98         
99         ClassDef class_table () throws IOException JavaDoc
100         {
101             m_table = new ClassDef ();
102             
103             
104             magic ();
105             version ();
106             
107             if (DEBUG) System.out.println (s_line);
108             
109             constant_pool ();
110             
111             if (DEBUG) System.out.println (s_line);
112             
113             access_flags ();
114             this_class ();
115             super_class ();
116             
117             if (DEBUG) System.out.println (s_line);
118             
119             interfaces ();
120             if (DEBUG) System.out.println (s_line);
121             
122             fields ();
123             if (DEBUG) System.out.println (s_line);
124             
125             methods ();
126             if (DEBUG) System.out.println (s_line);
127             
128             attributes ();
129             if (DEBUG) System.out.println (s_line);
130             
131             return m_table;
132         }
133         
134         
135         void magic () throws IOException JavaDoc
136         {
137             final long magic = m_bytes.readU4 ();
138             if (DEBUG) System.out.println ("magic: [" + Long.toHexString (magic) + ']');
139             
140             m_table.setMagic (magic);
141         }
142         
143         
144         void version () throws IOException JavaDoc
145         {
146             final int minor_version = m_bytes.readU2 ();
147             final int major_version = m_bytes.readU2 ();
148             
149             if (DEBUG)
150             {
151                 System.out.println ("major_version: [" + major_version + ']');
152                 System.out.println ("minor_version: [" + minor_version + ']');
153             }
154             
155             m_table.setVersion (new int [] {major_version, minor_version});
156         }
157         
158         
159         void constant_pool () throws IOException JavaDoc
160         {
161             final int constant_pool_count = m_bytes.readU2 ();
162             if (DEBUG) System.out.println ("constant_pool_count = " + constant_pool_count + " [actual number of entries = " + (constant_pool_count - 1) + "]");
163             
164             final IConstantCollection constants = m_table.getConstants();
165             
166             for (int index = 1; index < constant_pool_count; ++ index)
167             {
168                 final CONSTANT_info cp_info = CONSTANT_info.new_CONSTANT_info (m_bytes);
169                 constants.add (cp_info);
170                 
171                 if (DEBUG) System.out.println ("[" + index + "] constant: " + cp_info);
172                 
173                 if ((cp_info instanceof CONSTANT_Long_info) || (cp_info instanceof CONSTANT_Double_info))
174                     index++;
175             }
176         }
177         
178         
179         void access_flags () throws IOException JavaDoc
180         {
181             final int _access_flags = m_bytes.readU2 ();
182             
183             m_table.setAccessFlags (_access_flags);
184         }
185         
186         
187         void this_class () throws IOException JavaDoc
188         {
189             final int _class_index = m_bytes.readU2 ();
190             if (DEBUG) System.out.println ("this_class: [" + _class_index + ']');
191             
192             m_table.setThisClassIndex (_class_index);
193         }
194         
195         
196         void super_class () throws IOException JavaDoc
197         {
198             final int _class_index = m_bytes.readU2 ();
199             if (DEBUG) System.out.println ("super_class: [" + _class_index + ']');
200             
201             m_table.setSuperClassIndex (_class_index);
202         }
203         
204         
205         void interfaces () throws IOException JavaDoc
206         {
207             final int _interfaces_count = m_bytes.readU2 ();
208             if (DEBUG) System.out.println ("interfaces_count = " + _interfaces_count);
209             
210             for (int i = 0; i < _interfaces_count; i++)
211             {
212                 int _interface_index = m_bytes.readU2 ();
213                 if (DEBUG) System.out.println ("[" + i + "] interface: " + _interface_index);
214                 
215                 m_table.getInterfaces().add (_interface_index);
216             }
217         }
218         
219         
220         void fields () throws IOException JavaDoc
221         {
222             final int _fields_count = m_bytes.readU2 ();
223             if (DEBUG) System.out.println ("fields_count = " + _fields_count);
224             
225             final IConstantCollection constantPool = m_table.getConstants ();
226             
227             for (int i = 0; i < _fields_count; i++)
228             {
229                 final Field_info field_info = new Field_info (constantPool, m_bytes);
230                 if (DEBUG)
231                 {
232                     System.out.println ("[" + i + "] field: " + field_info);
233                     System.out.println ();
234                 }
235                 
236                 m_table.getFields().add (field_info);
237                 
238                 if (PARSE_SERIAL_VERSION_UID)
239                 
240                 if (((field_info.getAccessFlags () & SERIAL_VERSION_UID_FIELD_MASK) == SERIAL_VERSION_UID_FIELD_MASK)
241                     && SERIAL_VERSION_UID_FIELD_NAME.equals (field_info.getName (m_table)))
242                 {
243                     final IAttributeCollection attributes = field_info.getAttributes ();
244                     for (int a = 0, aLimit = attributes.size (); a < aLimit; ++ a)
245                     {
246                         final Attribute_info attr_info = attributes.get (a);
247                         
248                         if (attr_info instanceof ConstantValueAttribute_info)
249                         {
250                             final CONSTANT_literal_info constant_value = ((ConstantValueAttribute_info) attr_info).getValue (m_table);
251                             if (constant_value instanceof CONSTANT_Long_info)
252                                 m_table.setDeclaredSUID (((CONSTANT_Long_info) constant_value).m_value);
253                         }
254                     }
255                 }
256             }
257         }
258         
259         
260         void methods () throws IOException JavaDoc
261         {
262             final int _methods_count = m_bytes.readU2 ();
263             if (DEBUG) System.out.println ("methods_count = " + _methods_count);
264             
265             final IConstantCollection constantPool = m_table.getConstants ();
266             
267             for (int i = 0; i < _methods_count; i++)
268             {
269                 final Method_info method_info = new Method_info (constantPool, m_bytes);
270                 if (DEBUG)
271                 {
272                     System.out.println ("[" + i + "] method: " + method_info);
273                     System.out.println ();
274                 }
275                 
276                 m_table.getMethods().add (method_info);
277             }
278         }
279         
280         
281         void attributes () throws IOException JavaDoc
282         {
283             final int _attributes_count = m_bytes.readU2 ();
284             if (DEBUG) System.out.println ("attributes_count = " + _attributes_count);
285             
286             IConstantCollection constantPool = m_table.getConstants ();
287             
288             for (int i = 0; i < _attributes_count; i++)
289             {
290                 Attribute_info attribute_info = Attribute_info.new_Attribute_info (constantPool, m_bytes);
291                 if (DEBUG)
292                 {
293                     System.out.println ("[" + i + "] attribute: " + attribute_info);
294                     System.out.println ();
295                 }
296                 
297                 m_table.getAttributes().add (attribute_info);
298             }
299         }
300         
301         
302         private final UDataInputStream m_bytes;
303         private ClassDef m_table;
304     
305         private static final boolean DEBUG = false;
306         private static final String JavaDoc s_line = "------------------------------------------------------------------------";
307
308     } // end of static class
309

310 } // end of class
311
// ----------------------------------------------------------------------------
312
Popular Tags