KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > compiler > ClassFileUtils


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.compiler;
13
14 /**
15  * Utility methods for getting info from a class file.
16  */

17 public class ClassFileUtils {
18
19     private static final int CONSTANT_Class = 7;
20     private static final int CONSTANT_Fieldref = 9;
21     private static final int CONSTANT_Methodref = 10;
22     private static final int CONSTANT_InterfaceMethodref = 11;
23     private static final int CONSTANT_String = 8;
24     private static final int CONSTANT_Integer = 3;
25     private static final int CONSTANT_Float = 4;
26     private static final int CONSTANT_Long = 5;
27     private static final int CONSTANT_Double = 6;
28     private static final int CONSTANT_NameAndType = 12;
29     private static final int CONSTANT_Utf8 = 1;
30
31     /**
32      * Get the name of the class represented by bytecode.
33      */

34     public static String JavaDoc getClassName(byte[] bytecode) {
35         int magic = getU4(bytecode, 0);
36         if (magic != 0xCAFEBABE) {
37             throw new IllegalArgumentException JavaDoc(
38                     "Not a class file: Magic 0xCAFEBABE bad: " +
39                     Integer.toHexString(magic));
40         }
41         int constantPoolCount = getU2(bytecode, 8);
42         int[] cpOffset = new int[constantPoolCount - 1];
43         int offset = 10;
44         for (int i = 0; i < constantPoolCount - 1; i++) {
45             cpOffset[i] = offset;
46             int tag = bytecode[offset] & 0xFF;
47             if (tag == CONSTANT_Long || tag == CONSTANT_Double) {
48                 ++i;
49             }
50             offset += getConstantPoolEntryLength(bytecode, offset);
51         }
52         offset += 2;
53         int thisClass = getU2(bytecode, offset);
54         int nameCpIndex = getU2(bytecode, cpOffset[thisClass - 1] + 1);
55         return getConstantPoolString(bytecode, cpOffset, nameCpIndex);
56     }
57
58     /**
59      * Get the constant pool entry number i which is must be a UTF8
60      * string.
61      */

62     private static String JavaDoc getConstantPoolString(byte[] bytecode,
63             int[] cpOffset, int i) {
64         int offset = cpOffset[i - 1];
65         if (bytecode[offset] != CONSTANT_Utf8) {
66             throw new IllegalArgumentException JavaDoc("Not a UTF8 pool entry " + i +
67                     " at offset " + offset);
68         }
69         int len = getU2(bytecode, offset + 1);
70         return new String JavaDoc(bytecode, offset + 3, len);
71     }
72
73     private static int getU4(byte[] bytecode, int offset) {
74         int b0 = (bytecode[offset] & 0xFF);
75         int b1 = (bytecode[offset + 1] & 0xFF);
76         int b2 = (bytecode[offset + 2] & 0xFF);
77         int b3 = (bytecode[offset + 3] & 0xFF);
78         return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;
79     }
80
81     private static int getU2(byte[] bytecode, int offset) {
82         int b0 = (bytecode[offset] & 0xFF);
83         int b1 = (bytecode[offset + 1] & 0xFF);
84         return (b0 << 8) + b1;
85     }
86
87     /**
88      * Get the length in bytes of an entry in the constant pool.
89      */

90     private static int getConstantPoolEntryLength(byte[] bytecode, int offset) {
91         int tag = bytecode[offset] & 0xFF;
92         switch (tag) {
93             case CONSTANT_Class:
94             case CONSTANT_String:
95                 return 3;
96             case CONSTANT_Fieldref:
97             case CONSTANT_Methodref:
98             case CONSTANT_InterfaceMethodref:
99             case CONSTANT_Integer:
100             case CONSTANT_Float:
101             case CONSTANT_NameAndType:
102                 return 5;
103             case CONSTANT_Long:
104             case CONSTANT_Double:
105                 return 9;
106             case CONSTANT_Utf8:
107                 return 3 + getU2(bytecode, offset + 1);
108             case 0:
109                 return 0;
110         }
111         throw new IllegalArgumentException JavaDoc("Unknown constant pool entry type " +
112                 tag + " at " + Integer.toHexString(offset));
113     }
114
115 }
116
Popular Tags