1 19 20 package jode.bytecode; 21 import java.io.DataInputStream ; 22 import java.io.IOException ; 23 24 29 public class ConstantPool { 30 public final static int CLASS = 7; 31 public final static int FIELDREF = 9; 32 public final static int METHODREF = 10; 33 public final static int INTERFACEMETHODREF = 11; 34 public final static int STRING = 8; 35 public final static int INTEGER = 3; 36 public final static int FLOAT = 4; 37 public final static int LONG = 5; 38 public final static int DOUBLE = 6; 39 public final static int NAMEANDTYPE = 12; 40 public final static int UTF8 = 1; 41 42 int count; 43 int[] tags; 44 int[] indices1, indices2; 45 46 Object [] constants; 47 48 public ConstantPool () { 49 } 50 51 public void read(DataInputStream stream) 52 throws IOException { 53 count = stream.readUnsignedShort(); 54 tags = new int[count]; 55 indices1 = new int[count]; 56 indices2 = new int[count]; 57 constants = new Object [count]; 58 59 for (int i=1; i< count; i++) { 60 int tag = stream.readUnsignedByte(); 61 tags[i] = tag; 62 switch (tag) { 63 case CLASS: 64 indices1[i] = stream.readUnsignedShort(); 65 break; 66 case FIELDREF: 67 case METHODREF: 68 case INTERFACEMETHODREF: 69 indices1[i] = stream.readUnsignedShort(); 70 indices2[i] = stream.readUnsignedShort(); 71 break; 72 case STRING: 73 indices1[i] = stream.readUnsignedShort(); 74 break; 75 case INTEGER: 76 constants[i] = new Integer (stream.readInt()); 77 break; 78 case FLOAT: 79 constants[i] = new Float (stream.readFloat()); 80 break; 81 case LONG: 82 constants[i] = new Long (stream.readLong()); 83 tags[++i] = -LONG; 84 break; 85 case DOUBLE: 86 constants[i] = new Double (stream.readDouble()); 87 tags[++i] = -DOUBLE; 88 break; 89 case NAMEANDTYPE: 90 indices1[i] = stream.readUnsignedShort(); 91 indices2[i] = stream.readUnsignedShort(); 92 break; 93 case UTF8: 94 constants[i] = stream.readUTF().intern(); 95 break; 96 default: 97 throw new ClassFormatException("unknown constant tag"); 98 } 99 } 100 } 101 102 public int getTag(int i) throws ClassFormatException { 103 if (i == 0) 104 throw new ClassFormatException("null tag"); 105 return tags[i]; 106 } 107 108 public String getUTF8(int i) throws ClassFormatException { 109 if (i == 0) 110 return null; 111 if (tags[i] != UTF8) 112 throw new ClassFormatException("Tag mismatch"); 113 return (String )constants[i]; 114 } 115 116 public Reference getRef(int i) throws ClassFormatException { 117 if (i == 0) 118 return null; 119 if (tags[i] != FIELDREF 120 && tags[i] != METHODREF && tags[i] != INTERFACEMETHODREF) 121 throw new ClassFormatException("Tag mismatch"); 122 if (constants[i] == null) { 123 int classIndex = indices1[i]; 124 int nameTypeIndex = indices2[i]; 125 if (tags[nameTypeIndex] != NAMEANDTYPE) 126 throw new ClassFormatException("Tag mismatch"); 127 String type = getUTF8(indices2[nameTypeIndex]); 128 try { 129 if (tags[i] == FIELDREF) 130 TypeSignature.checkTypeSig(type); 131 else 132 TypeSignature.checkMethodTypeSig(type); 133 } catch (IllegalArgumentException ex) { 134 throw new ClassFormatException(ex.getMessage()); 135 } 136 String clName = getClassType(classIndex); 137 constants[i] = Reference.getReference 138 (clName, getUTF8(indices1[nameTypeIndex]), type); 139 } 140 return (Reference) constants[i]; 141 } 142 143 public Object getConstant(int i) throws ClassFormatException { 144 if (i == 0) 145 throw new ClassFormatException("null constant"); 146 switch (tags[i]) { 147 case ConstantPool.INTEGER: 148 case ConstantPool.FLOAT: 149 case ConstantPool.LONG: 150 case ConstantPool.DOUBLE: 151 return constants[i]; 152 case ConstantPool.STRING: 153 return getUTF8(indices1[i]); 154 } 155 throw new ClassFormatException("Tag mismatch: "+tags[i]); 156 } 157 158 public String getClassType(int i) throws ClassFormatException { 159 if (i == 0) 160 return null; 161 if (tags[i] != CLASS) 162 throw new ClassFormatException("Tag mismatch"); 163 String clName = getUTF8(indices1[i]); 164 if (clName.charAt(0) != '[') { 165 clName = ("L"+clName+';').intern(); 166 } 167 try { 168 TypeSignature.checkTypeSig(clName); 169 } catch (IllegalArgumentException ex) { 170 throw new ClassFormatException(ex.getMessage()); 171 } 172 173 return clName; 174 } 175 176 public String getClassName(int i) throws ClassFormatException { 177 if (i == 0) 178 return null; 179 if (tags[i] != CLASS) 180 throw new ClassFormatException("Tag mismatch"); 181 String clName = getUTF8(indices1[i]); 182 try { 183 TypeSignature.checkTypeSig("L"+clName+";"); 184 } catch (IllegalArgumentException ex) { 185 throw new ClassFormatException(ex.getMessage()); 186 } 187 return clName.replace('/','.').intern(); 188 } 189 190 public String toString(int i) { 191 switch (tags[i]) { 192 case CLASS: 193 return "Class "+toString(indices1[i]); 194 case STRING: 195 return "String \""+toString(indices1[i])+"\""; 196 case INTEGER: 197 return "Int "+constants[i].toString(); 198 case FLOAT: 199 return "Float "+constants[i].toString(); 200 case LONG: 201 return "Long "+constants[i].toString(); 202 case DOUBLE: 203 return "Double "+constants[i].toString(); 204 case UTF8: 205 return constants[i].toString(); 206 case FIELDREF: 207 return "Fieldref: "+toString(indices1[i])+"; " 208 + toString(indices2[i]); 209 case METHODREF: 210 return "Methodref: "+toString(indices1[i])+"; " 211 + toString(indices2[i]); 212 case INTERFACEMETHODREF: 213 return "Interfaceref: "+toString(indices1[i])+"; " 214 + toString(indices2[i]); 215 case NAMEANDTYPE: 216 return "Name "+toString(indices1[i]) 217 +"; Type "+toString(indices2[i]); 218 default: 219 return "unknown tag: "+tags[i]; 220 } 221 } 222 223 public int size() { 224 return count; 225 } 226 227 public String toString() { 228 StringBuffer result = new StringBuffer ("[ null"); 229 for (int i=1; i< count; i++) { 230 result.append(", ").append(i).append(" = ").append(toString(i)); 231 } 232 result.append(" ]"); 233 return result.toString(); 234 } 235 } 236 | Popular Tags |