| 1 2 12 package com.versant.core.compiler; 13 14 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 34 public static String getClassName(byte[] bytecode) { 35 int magic = getU4(bytecode, 0); 36 if (magic != 0xCAFEBABE) { 37 throw new IllegalArgumentException ( 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 62 private static String getConstantPoolString(byte[] bytecode, 63 int[] cpOffset, int i) { 64 int offset = cpOffset[i - 1]; 65 if (bytecode[offset] != CONSTANT_Utf8) { 66 throw new IllegalArgumentException ("Not a UTF8 pool entry " + i + 67 " at offset " + offset); 68 } 69 int len = getU2(bytecode, offset + 1); 70 return new String (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 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 ("Unknown constant pool entry type " + 112 tag + " at " + Integer.toHexString(offset)); 113 } 114 115 } 116 | Popular Tags |