KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jbet > FieldInfo


1 /*
2  * JBET - Java Binary Enhancement Tool
3  * Copyright (c) 2003 Networks Associates Technology, Inc.
4  *
5  * This software was developed under DARPA/SPAWAR contract
6  * N66001-00-C-8602 "SPMA" as part of the
7  * DARPA OASIS research program.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */

30
31 /**
32  * This class represents a field (i.e., data member) of a class.
33  *
34  * @author Lee Badger
35  * @author Larry D'Anna
36  * @version 0.1
37  * @since JDK 1.1.8
38  */

39
40 package jbet;
41 import java.io.*;
42 import java.util.*;
43
44 public final class FieldInfo {
45
46     public static String JavaDoc JbetLogFacility = "field";
47
48     public int accessFlags;
49
50     public String JavaDoc name;
51     public Type type;
52
53     Vector attrHints;
54     public boolean synthetic, deprecated;
55     public Object JavaDoc value;
56
57
58     public ClassInfo cr;
59
60     /* read/write stuff */
61     int nameIndex;
62     int typeIndex;
63     Vector attributes;
64     int valueIndex;
65
66     /** Access to the type's relocate method.
67      * @param subs Hashtable
68      */

69     void relocate (Hashtable subs) {
70     type = type.relocate_new(subs);
71     }
72
73     /** Constructor.
74      */

75     FieldInfo() {
76     attrHints = new Vector();
77     }
78
79     /** disassemble
80      * @param out print stream
81      * @param prefix output prefix
82      */

83     public void disassemble (LineWriter out, String JavaDoc prefix) {
84     out.print(prefix + ".field " + Util.flags2str(accessFlags) + " " + name
85           + " " + type );
86     if (synthetic || deprecated || value != null) {
87         out.print( " { " );
88         boolean first = true;
89         if (synthetic) {
90         out.print(".synthetic");
91         first = false;
92         }
93         if (deprecated) {
94         if (!first) out.print("; ");
95         out.print(".deprecated");
96         first = false;
97         }
98         if (value != null) {
99         if (!first) out.print("; ");
100         first = false;
101         out.print( ".value ");
102         if (type.equals(Type.STRING))
103             out.print("\"" + Util.quoteString((String JavaDoc) value) + "\"");
104         else
105             switch(type.vmType()) {
106             case Type.VM_INT:
107             case Type.VM_LONG:
108             out.print( value );
109             break;
110             default:
111             throw new RuntimeException JavaDoc("not implemented");
112             }
113         }
114         out.print(" }");
115     }
116     out.println();
117     }
118
119     /** Constructor.
120      * @param lexer a Lexer instance
121      */

122     public FieldInfo (Lexer lexer) {
123     this();
124     lexer.push(Lexer.ST_ASM);
125     if (!lexer.match(Token.TAG).text.equals(".field"))
126         lexer.unexpected(lexer.justread());
127     accessFlags = lexer.parse_flags(ACC_ALL_FFLAGS);
128     name = lexer.match(Token.TAG).text;
129     type = lexer.parse_type();
130     if (lexer.peek().type != ';' && lexer.peek().type != Token.EOF) {
131         lexer.match('{');
132         //lexer.push(Lexer.ST_ASM);
133
while (true) {
134         lexer.state = Lexer.ST_ASM;
135         while ( lexer.peek().type == ';' ) lexer.read();
136         Token tok = lexer.peek();
137         lexer.state = Lexer.ST_ASM_ARG;
138         if (tok.type == Token.TAG) {
139             if (tok.text.equals(".synthetic")) {
140             lexer.read();
141             lexer.term();
142             synthetic = true;
143             continue;
144             }
145             if (tok.text.equals(".deprecated")) {
146             lexer.read();
147             lexer.term();
148             deprecated = true;
149             continue;
150             }
151             if (tok.text.equals(".flags")) {
152             lexer.read();
153             int flags = lexer.parse_flags(ACC_ALL_FFLAGS);
154             lexer.term();
155             accessFlags = flags;
156             continue;
157             }
158             if (tok.text.equals(".value")) {
159             lexer.read();
160             if (type.equals(Type.STRING)) {
161                 value = lexer.parse_string();
162             } else
163                 switch(type.vmType()) {
164                 case Type.VM_INT:
165                 value = new Integer JavaDoc( lexer.parse_int() );
166                 break;
167                 case Type.VM_LONG:
168                 value = new Long JavaDoc( lexer.parse_long() );
169                 break;
170                 default:
171                 throw new RuntimeException JavaDoc("not implemented");
172                 }
173             lexer.term();
174             continue;
175             }
176             lexer.unexpected(tok);
177         }
178         if (tok.type == '}')
179             break;
180         lexer.unexpected(tok);
181         }
182         lexer.match('}');
183     }
184     lexer.pop();
185     }
186
187     /** Copy Constructor.
188      * @param fi another instance of FieldInfo
189      */

190     public FieldInfo(FieldInfo fi) {
191     accessFlags = fi.accessFlags;
192     name = fi.name;
193     type = fi.type;
194     value = fi.value;
195     synthetic = fi.synthetic;
196     deprecated = fi.deprecated;
197     attrHints = new Vector();
198     }
199
200     /** Constructor
201      * @param n name
202      * @param t type
203      */

204     public FieldInfo (String JavaDoc n, Type t) {
205     name = n;
206     type = t;
207     accessFlags = 0;
208     attrHints = new Vector();
209     }
210
211     /** Constructor
212      * @param n name
213      * @param t type
214      * @param a access flags
215      */

216     public FieldInfo (String JavaDoc n, Type t, int a) {
217     name = n;
218     type = t;
219     accessFlags = a;
220     attrHints = new Vector();
221     }
222
223     /** Return a printable string: flags name value
224      * @return printable string
225      */

226     public String JavaDoc recString() {
227     StringBuffer JavaDoc ret = new StringBuffer JavaDoc();
228     String JavaDoc f = flags2str(accessFlags);
229     if (!f.equals("")) ret.append( f + " " );
230     
231     if (synthetic)
232         ret.append( "synthetic " );
233     if (deprecated)
234         ret.append( "deprecated " );
235
236     ret.append(name + " " + type.toString() );
237
238     if (value != null)
239         if (value instanceof String JavaDoc)
240         ret.append( " = \"" + value.toString() + "\"");
241         else
242         ret.append( " = " + value.toString() );
243
244     return ret.toString();
245     }
246     
247     /** return an AttributeWriter class that writes the valueIndex
248      * @return an AttributeWriter class
249      */

250     AttributeWriter valueWriter() {
251     return new AttributeWriter() {
252         public void write(DataOutputStream dataOut)
253             throws IOException, RuntimeException JavaDoc {
254             dataOut.writeShort( valueIndex );
255         }
256         public int size() { return 2; }
257         };
258     }
259
260     public void resolveConstants () {
261     resolveConstants(cr.constantPool);
262     }
263
264     /** resolveConstants
265      * @param constantPool constant pool
266      */

267     void resolveConstants (ConstantPool constantPool) {
268     nameIndex = constantPool.internUtf8 (name);
269     typeIndex = constantPool.internUtf8( type.toString() );
270
271     
272     Vector outAttrs = new Vector();
273
274     if (synthetic)
275         outAttrs.addElement(new GenericAttribute("Synthetic", constantPool).nodata());
276
277     if (deprecated)
278         outAttrs.addElement(new GenericAttribute("Deprecated", constantPool).nodata());
279
280     if (value != null) {
281         GenericAttribute attr = new GenericAttribute("ConstantValue", constantPool);
282         attr.writer = valueWriter();
283         if (value instanceof Long JavaDoc)
284         valueIndex = constantPool.internLong( ((Long JavaDoc)value).longValue() ) ;
285         else if (value instanceof Float JavaDoc)
286         valueIndex = constantPool.internFloat( ((Float JavaDoc)value).floatValue() ) ;
287         else if (value instanceof Double JavaDoc)
288         valueIndex = constantPool.internDouble( ((Double JavaDoc)value).doubleValue());
289         else if (value instanceof Integer JavaDoc)
290         valueIndex = constantPool.internInteger( ((Integer JavaDoc)value).intValue());
291         else if (value instanceof String JavaDoc)
292         valueIndex = constantPool.internString( (String JavaDoc) value ) ;
293         outAttrs.addElement (attr);
294     }
295     
296     attributes = new Vector ();
297     GenericAttribute.permute(attrHints, outAttrs, attributes);
298     }
299
300     /** Write flags, name index, type index, and attributes.
301      * @param dataOut output stream
302      */

303     void writeFile(DataOutputStream dataOut) throws IOException {
304     dataOut.writeShort (accessFlags);
305     dataOut.writeShort (nameIndex);
306     dataOut.writeShort (typeIndex);
307     
308     dataOut.writeShort (attributes.size());
309     for (int i = 0; i < attributes.size(); i++)
310         ((GenericAttribute)attributes.elementAt(i)).writeAll(dataOut);
311     }
312     
313     /** Constructor given an input file.
314      * @param dataIn input stream
315      * @param constantPool constant pool
316      */

317     public FieldInfo (DataInputStream dataIn, ConstantPool constantPool)
318     throws IOException, ClassFileException {
319
320     value = null;
321
322     accessFlags = dataIn.readUnsignedShort();
323
324     nameIndex = dataIn.readUnsignedShort();
325     name = constantPool.utf8At(nameIndex);
326
327     typeIndex = dataIn.readUnsignedShort();
328     String JavaDoc typeString = constantPool.utf8At(typeIndex);
329     type = new Type (typeString);
330
331     int attributesCount = dataIn.readUnsignedShort();
332     attrHints = new Vector (attributesCount);
333     for (int i = 0; i < attributesCount; i++) {
334         int nameindex = dataIn.readUnsignedShort();
335         String JavaDoc attrname = constantPool.utf8At(nameindex);
336         int length = dataIn.readInt();
337         
338         GenericAttribute item = new GenericAttribute (attrname, nameindex);
339         
340         if (attrname.equals("Synthetic")) {
341         synthetic = true;
342         item.nodata();
343         } else if (attrname.equals("Deprecated")) {
344         deprecated = true;
345         item.nodata();
346         } else if (attrname.equals("ConstantValue")) {
347         valueIndex = dataIn.readUnsignedShort();
348         item.writer = valueWriter();
349         switch ( constantPool.tagAt(valueIndex) ) {
350         case ConstantPool.CONSTANT_Long:
351             long l = constantPool.longAt(valueIndex);
352             value = new Long JavaDoc (l); break;
353         case ConstantPool.CONSTANT_Float:
354             float f = constantPool.floatAt(valueIndex);
355             value = new Float JavaDoc (f); break;
356         case ConstantPool.CONSTANT_Double:
357             double d = constantPool.doubleAt(valueIndex);
358             value = new Double JavaDoc (d); break;
359         case ConstantPool.CONSTANT_Integer:
360             int I = constantPool.integerAt(valueIndex);
361             value = new Integer JavaDoc (I); break;
362         case ConstantPool.CONSTANT_String:
363             value = constantPool.stringAt(valueIndex); break;
364         default:
365             throw new ClassFileException ("bad index for ConstantValue");
366         }
367         } else {
368         Jbet.warn.println ("Warning: unrecognised field attribute " + attrname);
369         item.read (length, dataIn);
370         }
371         attrHints.addElement(item);
372     }
373
374     attributes = attrHints;
375
376     }
377
378     /** test if a field is static.
379      * @return TRUE if static
380      */

381     public boolean isStatic() {
382     return (accessFlags & ACC_STATIC) != 0;
383     }
384
385     /** convert access flags to string
386      * @return printable access flags
387      */

388     public static String JavaDoc flags2str (int accessFlags) {
389     return Util.flags2str(accessFlags);
390     }
391     
392     public static final int ACC_PUBLIC = Util.ACC_PUBLIC;
393     public static final int ACC_PRIVATE = Util.ACC_PRIVATE;
394     public static final int ACC_PROTECTED = Util.ACC_PROTECTED;
395     public static final int ACC_STATIC = Util.ACC_STATIC;
396     public static final int ACC_FINAL = Util.ACC_FINAL;
397     public static final int ACC_VOLATILE = Util.ACC_VOLATILE;
398     public static final int ACC_TRANSIENT = Util.ACC_TRANSIENT;
399
400     public static final int ACC_ALL_FFLAGS = ACC_PUBLIC | ACC_PRIVATE |
401     ACC_PROTECTED | ACC_STATIC | ACC_FINAL | ACC_VOLATILE |
402     ACC_TRANSIENT;
403
404     /** Override equals, make it EQ.
405      * @param o another FieldInfo instance
406      * @return TRUE if same object
407      */

408     public boolean equals(Object JavaDoc o) {
409     return this == o;
410     }
411
412     public String JavaDoc qualifiedName() {
413     return cr.thisClass + "." + name;
414     }
415 }
416
Popular Tags