1 23 24 25 package com.sun.jdo.api.persistence.enhancer.classfile; 26 27 import java.util.Vector ; 28 import java.util.Hashtable ; 29 import java.io.*; 30 31 35 36 public class ConstantPool implements VMConstants { 37 38 39 private Vector pool = new Vector (); 40 41 42 private boolean hashed = false; 43 private Hashtable utfTable = new Hashtable (11); 44 private Hashtable unicodeTable = new Hashtable (3); 45 private Hashtable stringTable = new Hashtable (11); 46 private Hashtable classTable = new Hashtable (11); 47 private Hashtable intTable = new Hashtable (3); 48 private Hashtable floatTable = new Hashtable (3); 49 private Hashtable longTable = new Hashtable (3); 50 private Hashtable doubleTable = new Hashtable (3); 51 52 private Vector methodRefTable = new Vector (); 53 private Vector fieldRefTable = new Vector (); 54 private Vector ifaceMethodRefTable = new Vector (); 55 private Vector nameAndTypeTable = new Vector (); 56 57 58 59 62 public int nEntries() { 63 return pool.size(); 64 } 65 66 69 public ConstBasic constantAt (int index) { 70 return (ConstBasic) pool.elementAt(index); 71 } 72 73 76 public ConstClass addClass (String className) { 77 hashConstants(); 78 ConstClass c = (ConstClass) classTable.get(className); 79 if (c == null) { 80 c = new ConstClass(addUtf8(className)); 81 internConstant(c); 82 } 83 return c; 84 } 85 86 89 public ConstFieldRef addFieldRef (String className, String fieldName, 90 String type) { 91 hashConstants(); 92 ConstFieldRef f = (ConstFieldRef) 93 searchTable(fieldRefTable, className, fieldName, type); 94 95 if (f == null) { 96 f = new ConstFieldRef (addClass(className), 97 addNameAndType(fieldName, type)); 98 internConstant(f); 99 } 100 return f; 101 } 102 103 106 public ConstMethodRef addMethodRef (String className, String methodName, 107 String type) { 108 hashConstants(); 109 ConstMethodRef m = (ConstMethodRef) 110 searchTable(methodRefTable, className, methodName, type); 111 if (m == null) { 112 m = new ConstMethodRef (addClass(className), 113 addNameAndType(methodName, type)); 114 internConstant(m); 115 } 116 return m; 117 } 118 119 122 public ConstInterfaceMethodRef addInterfaceMethodRef (String className, 123 String methodName, String type) { 124 hashConstants(); 125 ConstInterfaceMethodRef m = (ConstInterfaceMethodRef) 126 searchTable(ifaceMethodRefTable, className, methodName, type); 127 if (m == null) { 128 m = new ConstInterfaceMethodRef (addClass(className), 129 addNameAndType(methodName, type)); 130 internConstant(m); 131 } 132 return m; 133 } 134 135 138 public ConstString addString (String s) { 139 hashConstants(); 140 ConstString cs = (ConstString) stringTable.get(s); 141 if (cs == null) { 142 cs = new ConstString(addUtf8(s)); 143 internConstant(cs); 144 } 145 return cs; 146 } 147 148 151 public ConstInteger addInteger (int i) { 152 hashConstants(); 153 Integer io = new Integer (i); 154 ConstInteger ci = (ConstInteger) intTable.get(io); 155 if (ci == null) { 156 ci = new ConstInteger(i); 157 internConstant(ci); 158 } 159 return ci; 160 } 161 162 165 public ConstFloat addFloat (float f) { 166 hashConstants(); 167 Float fo = new Float (f); 168 ConstFloat cf = (ConstFloat) floatTable.get(fo); 169 if (cf == null) { 170 cf = new ConstFloat(f); 171 internConstant(cf); 172 } 173 return cf; 174 } 175 176 179 public ConstLong addLong (long l) { 180 hashConstants(); 181 Long lo = new Long (l); 182 ConstLong cl = (ConstLong) longTable.get(lo); 183 if (cl == null) { 184 cl = new ConstLong(l); 185 internConstant(cl); 186 internConstant(null); 187 } 188 return cl; 189 } 190 191 194 public ConstDouble addDouble (double d) { 195 hashConstants(); 196 Double dobj = new Double (d); 197 ConstDouble cd = (ConstDouble) doubleTable.get(dobj); 198 if (cd == null) { 199 cd = new ConstDouble(d); 200 internConstant(cd); 201 internConstant(null); 202 } 203 return cd; 204 } 205 206 209 public ConstNameAndType addNameAndType (String name, String type) { 210 hashConstants(); 211 for (int i=0; i<nameAndTypeTable.size(); i++) { 212 ConstNameAndType nt = (ConstNameAndType) nameAndTypeTable.elementAt(i); 213 if (nt.name().asString().equals(name) && 214 nt.signature().asString().equals(type)) 215 return nt; 216 } 217 218 ConstNameAndType nt = 219 new ConstNameAndType(addUtf8(name), addUtf8(type)); 220 internConstant(nt); 221 return nt; 222 } 223 224 227 public ConstUtf8 addUtf8 (String s) { 228 hashConstants(); 229 ConstUtf8 u = (ConstUtf8) utfTable.get(s); 230 if (u == null) { 231 u = new ConstUtf8(s); 232 internConstant(u); 233 } 234 return u; 235 } 236 237 241 public ConstUnicode addUnicode (String s) { 242 hashConstants(); 243 ConstUnicode u = (ConstUnicode) unicodeTable.get(s); 244 if (u == null) { 245 u = new ConstUnicode(s); 246 internConstant(u); 247 } 248 return u; 249 } 250 251 252 253 ConstantPool() { 254 pool.addElement(null); 255 } 256 257 ConstantPool(DataInputStream input) throws IOException { 258 pool.addElement(null); 259 int nconstants = input.readUnsignedShort()-1; 260 while (nconstants > 0) 261 nconstants -= readConstant(input); 262 263 resolvePool(); 264 } 265 266 void print (PrintStream out) { 267 for (int i=0; i<pool.size(); i++) { 268 ConstBasic c = constantAt(i); 269 if (c != null) { 270 out.print (i); 271 out.print (": "); out.println (c.toString()); 273 } 274 } 275 } 276 277 void summarize () { 278 int stringSize = 0; 279 int nStrings = 0; 280 for (int i=0; i<pool.size(); i++) { 281 ConstBasic c = constantAt(i); 282 if (c != null && c.tag() == CONSTANTUtf8) { 283 ConstUtf8 utf8 = (ConstUtf8) c; 284 stringSize += utf8.asString().length(); 285 nStrings++; 286 } 287 } 288 System.out.println(" " + nStrings + " strings totalling " + stringSize + " bytes"); } 291 292 void write (DataOutputStream buff) throws IOException { 293 buff.writeShort(pool.size()); 294 for (int i=1; i<pool.size(); i++) { 295 ConstBasic cb = (ConstBasic) pool.elementAt(i); 296 if (cb != null) { 297 buff.writeByte((byte) cb.tag()); 298 cb.formatData(buff); 299 } 300 } 301 } 302 303 304 305 private void resolvePool() { 306 307 for (int i=0; i<pool.size(); i++) { 308 ConstBasic c = constantAt(i); 309 if (c != null) { 310 c.setIndex(i); 311 c.resolve(this); 312 } 313 } 314 } 315 316 private void hashConstants() { 317 if (hashed) 318 return; 319 320 321 for (int j=0; j<pool.size(); j++) { 322 ConstBasic c = constantAt(j); 323 if (c != null) { 324 recordConstant(c); 325 } 326 } 327 328 hashed = true; 329 } 330 331 332 private int readConstant(DataInputStream input) throws IOException { 333 ConstBasic basic; 334 byte b = input.readByte(); 335 int slots = 1; 336 switch (b) { 337 case CONSTANTUtf8: 338 basic = ConstUtf8.read(input); 339 break; 340 case CONSTANTUnicode: 341 basic = ConstUnicode.read(input); 342 break; 343 case CONSTANTInteger: 344 basic = ConstInteger.read(input); 345 break; 346 case CONSTANTFloat: 347 basic = ConstFloat.read(input); 348 break; 349 case CONSTANTLong: 350 basic = ConstLong.read(input); 351 slots = 2; 352 break; 353 case CONSTANTDouble: 354 basic = ConstDouble.read(input); 355 slots = 2; 356 break; 357 case CONSTANTClass: 358 basic = ConstClass.read(input); 359 break; 360 case CONSTANTString: 361 basic = ConstString.read(input); 362 break; 363 case CONSTANTFieldRef: 364 basic = ConstFieldRef.read(input); 365 break; 366 case CONSTANTMethodRef: 367 basic = ConstMethodRef.read(input); 368 break; 369 case CONSTANTInterfaceMethodRef: 370 basic = ConstInterfaceMethodRef.read(input); 371 break; 372 case CONSTANTNameAndType: 373 basic = ConstNameAndType.read(input); 374 break; 375 default: 376 throw new ClassFormatError ("Don't know this constant type: " + Integer.toString(b)); 378 } 379 380 pool.addElement(basic); 381 if (slots > 1) 382 pool.addElement(null); 383 return slots; 384 } 385 386 private void internConstant (ConstBasic c) { 387 if (c != null) { 388 c.setIndex(pool.size()); 389 recordConstant(c); 390 } 391 pool.addElement(c); 392 } 393 394 private void recordConstant (ConstBasic c) { 395 if (c != null) { 396 switch (c.tag()) { 397 case CONSTANTUtf8: 398 utfTable.put(((ConstUtf8)c).asString(), c); 399 break; 400 case CONSTANTUnicode: 401 unicodeTable.put(((ConstUnicode)c).asString(), c); 402 break; 403 case CONSTANTInteger: 404 intTable.put(new Integer (((ConstInteger)c).value()), c); 405 break; 406 case CONSTANTFloat: 407 floatTable.put(new Float (((ConstFloat)c).value()), c); 408 break; 409 case CONSTANTLong: 410 longTable.put(new Long (((ConstLong)c).value()), c); 411 break; 412 case CONSTANTDouble: 413 doubleTable.put(new Double (((ConstDouble)c).value()), c); 414 break; 415 case CONSTANTClass: 416 classTable.put(((ConstClass)c).asString(), c); 417 break; 418 case CONSTANTString: 419 stringTable.put(((ConstString)c).value().asString(), c); 420 break; 421 case CONSTANTFieldRef: 422 fieldRefTable.addElement(c); 423 break; 424 case CONSTANTMethodRef: 425 methodRefTable.addElement(c); 426 break; 427 case CONSTANTInterfaceMethodRef: 428 ifaceMethodRefTable.addElement(c); 429 break; 430 case CONSTANTNameAndType: 431 nameAndTypeTable.addElement(c); 432 break; 433 } 434 } 435 } 436 437 private ConstBasicMemberRef searchTable(Vector table, String cname, 438 String mname, String sig) { 439 for (int i=0; i<table.size(); i++) { 440 ConstBasicMemberRef memRef = (ConstBasicMemberRef) table.elementAt(i); 441 if (memRef.className().asString().equals(cname) && 442 memRef.nameAndType().name().asString().equals(mname) && 443 memRef.nameAndType().signature().asString().equals(sig)) 444 return memRef; 445 } 446 return null; 447 } 448 449 450 } 451 452 | Popular Tags |