/Users/lyon/j4p/src/classUtils/dumper/ConstantPoolInfo.java

1    package classUtils.dumper; 
2     
3     
4    import java.io.DataInputStream; 
5    import java.io.DataOutputStream; 
6    import java.io.IOException; 
7     
8     
9    /** 
10    
11    * This class defines an entry in the constant pool for a Java class. 
12    
13    * The class file is primarily composed of ConstantPool entries and 
14    
15    * manipulation is done by modifying those entries. 
16    
17    * 
18    
19    * @version     1.5, 16 Aug 1995 
20    
21    * @author  Chuck McManis 
22    
23    * @see     ClassFile 
24    
25    */ 
26    
27    
28   public class ConstantPoolInfo { 
29    
30       int type;           // type of this item 
31    
32       String name;        // String for the type 
33    
34       ConstantPoolInfo arg1;  // index to first argument 
35    
36       ConstantPoolInfo arg2;  // index to second argument 
37    
38       short index1, index2; 
39    
40       String strValue;        // ASCIZ String value 
41    
42       int intValue; 
43    
44       long longValue; 
45    
46       float floatValue; 
47    
48       double doubleValue; 
49    
50    
51       public static final int CLASS = 7; 
52    
53       public static final int FIELDREF = 9; 
54    
55       public static final int METHODREF = 10; 
56    
57       public static final int STRING = 8; 
58    
59       public static final int INTEGER = 3; 
60    
61       public static final int FLOAT = 4; 
62    
63       public static final int LONG = 5; 
64    
65       public static final int DOUBLE = 6; 
66    
67       public static final int INTERFACE = 11; 
68    
69       public static final int NAMEANDTYPE = 12; 
70    
71       public static final int ASCIZ = 1; 
72    
73       public static final int UNICODE = 2; 
74    
75    
76       /** 
77    
78        * Construct a new ConstantPoolInfo object that is of type ASCIZ 
79    
80        */ 
81    
82       public ConstantPoolInfo(String value) { 
83    
84           index1 = -1; 
85    
86           index2 = -1; 
87    
88           arg1 = null; 
89    
90           arg2 = null; 
91    
92           type = ASCIZ; 
93    
94           strValue = value; 
95    
96       } 
97    
98    
99       /** 
100   
101       * Construct a new ConstantPoolInfo object that is of type INTEGER 
102   
103       */ 
104   
105      public ConstantPoolInfo(int value) { 
106   
107          index1 = -1; 
108   
109          index2 = -1; 
110   
111          arg1 = null; 
112   
113          arg2 = null; 
114   
115          type = INTEGER; 
116   
117          intValue = value; 
118   
119      } 
120   
121   
122      /** 
123   
124       * Construct a new ConstantPoolInfo object that is of type FLOAT 
125   
126       */ 
127   
128      public ConstantPoolInfo(float value) { 
129   
130          index1 = -1; 
131   
132          index2 = -1; 
133   
134          arg1 = null; 
135   
136          arg2 = null; 
137   
138          type = FLOAT; 
139   
140          floatValue = value; 
141   
142      } 
143   
144   
145      /** 
146   
147       * Construct a new ConstantPoolInfo object that is of type LONG 
148   
149       */ 
150   
151      public ConstantPoolInfo(long value) { 
152   
153          index1 = -1; 
154   
155          index2 = -1; 
156   
157          arg1 = null; 
158   
159          arg2 = null; 
160   
161          type = LONG; 
162   
163          longValue = value; 
164   
165      } 
166   
167   
168      /** 
169   
170       * Construct a new ConstantPoolInfo object that is of type DOUBLE 
171   
172       */ 
173   
174      public ConstantPoolInfo(double value) { 
175   
176          index1 = -1; 
177   
178          index2 = -1; 
179   
180          arg1 = null; 
181   
182          arg2 = null; 
183   
184          type = DOUBLE; 
185   
186          doubleValue = value; 
187   
188      } 
189   
190   
191      /** 
192   
193       * Generic constructor 
194   
195       */ 
196   
197      public ConstantPoolInfo() { 
198   
199          index1 = -1; 
200   
201          index2 = -1; 
202   
203          arg1 = null; 
204   
205          arg2 = null; 
206   
207          type = -1; 
208   
209      } 
210   
211   
212      /** 
213   
214       * return the type of this constant pool item. 
215   
216       */ 
217   
218      public int isType() { 
219   
220          return (type); 
221   
222      } 
223   
224   
225      public boolean read(DataInputStream dis) 
226   
227              throws IOException { 
228   
229          int len; 
230   
231          char c; 
232   
233   
234          type = dis.readByte(); 
235   
236          switch (type) { 
237   
238              case CLASS: 
239   
240                  name = "Class"; 
241   
242                  index1 = dis.readShort(); 
243   
244                  index2 = -1; 
245   
246                  break; 
247   
248              case FIELDREF: 
249   
250                  name = "Field Reference"; 
251   
252                  index1 = dis.readShort(); 
253   
254                  index2 = dis.readShort(); 
255   
256                  break; 
257   
258              case METHODREF: 
259   
260                  name = "Method Reference"; 
261   
262                  index1 = dis.readShort(); 
263   
264                  index2 = dis.readShort(); 
265   
266                  break; 
267   
268              case INTERFACE: 
269   
270                  name = "Interface Method Reference"; 
271   
272                  index1 = dis.readShort(); 
273   
274                  index2 = dis.readShort(); 
275   
276                  break; 
277   
278              case NAMEANDTYPE: 
279   
280                  name = "Name and Type"; 
281   
282                  index1 = dis.readShort(); 
283   
284                  index2 = dis.readShort(); 
285   
286                  break; 
287   
288              case STRING: 
289   
290                  name = "String"; 
291   
292                  index1 = dis.readShort(); 
293   
294                  index2 = -1; 
295   
296                  break; 
297   
298              case INTEGER: 
299   
300                  name = "Integer"; 
301   
302                  intValue = dis.readInt(); 
303   
304                  break; 
305   
306              case FLOAT: 
307   
308                  name = "Float"; 
309   
310                  floatValue = dis.readFloat(); 
311   
312                  break; 
313   
314              case LONG: 
315   
316                  name = "Long"; 
317   
318                  longValue = dis.readLong(); 
319   
320                  break; 
321   
322              case DOUBLE: 
323   
324                  name = "Double"; 
325   
326                  doubleValue = dis.readDouble(); 
327   
328                  break; 
329   
330              case ASCIZ: 
331   
332              case UNICODE: 
333   
334                  if (type == ASCIZ) 
335   
336                      name = "ASCIZ"; 
337   
338                  else 
339   
340                      name = "UNICODE"; 
341   
342   
343                  StringBuffer xxBuf = new StringBuffer(); 
344   
345   
346                  len = dis.readShort(); 
347   
348                  while (len > 0) { 
349   
350                      c = (char) (dis.readByte()); 
351   
352                      xxBuf.append(c); 
353   
354                      len--; 
355   
356                  } 
357   
358                  strValue = xxBuf.toString(); 
359   
360                  break; 
361   
362              default: 
363   
364                  System.out.println("Warning bad type."); 
365   
366          } 
367   
368          return (true); 
369   
370      } 
371   
372   
373      public void write(DataOutputStream dos, ConstantPoolInfo pool[]) 
374   
375              throws IOException, Exception { 
376   
377          dos.write(type); 
378   
379          switch (type) { 
380   
381              case CLASS: 
382   
383              case STRING: 
384   
385                  dos.writeShort(indexOf(arg1, pool)); 
386   
387                  break; 
388   
389              case FIELDREF: 
390   
391              case METHODREF: 
392   
393              case INTERFACE: 
394   
395              case NAMEANDTYPE: 
396   
397                  dos.writeShort(indexOf(arg1, pool)); 
398   
399                  dos.writeShort(indexOf(arg2, pool)); 
400   
401                  break; 
402   
403              case INTEGER: 
404   
405                  dos.writeInt(intValue); 
406   
407                  break; 
408   
409              case FLOAT: 
410   
411                  dos.writeFloat(floatValue); 
412   
413                  break; 
414   
415              case LONG: 
416   
417                  dos.writeLong(longValue); 
418   
419                  break; 
420   
421              case DOUBLE: 
422   
423                  dos.writeDouble(doubleValue); 
424   
425                  break; 
426   
427              case ASCIZ: 
428   
429              case UNICODE: 
430   
431                  dos.writeShort(strValue.length()); 
432   
433                  dos.writeBytes(strValue); 
434   
435                  break; 
436   
437              default: 
438   
439                  throw new Exception("ConstantPoolInfo::write() - bad type."); 
440   
441          } 
442   
443      } 
444   
445   
446      public String toString() { 
447   
448          StringBuffer s; 
449   
450   
451          if (type == ASCIZ) { 
452   
453              return (strValue); 
454   
455          } 
456   
457   
458          if (type == INTEGER) { 
459   
460              return ("= " + intValue); 
461   
462          } 
463   
464   
465          if (type == LONG) { 
466   
467              return ("= " + longValue); 
468   
469          } 
470   
471   
472          if (type == FLOAT) { 
473   
474              return ("= " + floatValue); 
475   
476          } 
477   
478   
479          if (type == DOUBLE) { 
480   
481              return ("= " + doubleValue); 
482   
483          } 
484   
485   
486          s = new StringBuffer(); 
487   
488          s.append(name); 
489   
490          s.append(":"); 
491   
492          if (arg1 != null) 
493   
494              s.append(arg1.toString()); 
495   
496          else if (index1 != -1) 
497   
498              s.append("I1[" + index1 + "], "); 
499   
500          if (arg2 != null) 
501   
502              s.append(arg2.toString()); 
503   
504          else if (index2 != -1) 
505   
506              s.append("I2[" + index2 + "], "); 
507   
508          return (s.toString()); 
509   
510      } 
511   
512   
513      public static short indexOf(ConstantPoolInfo item, 
514   
515                                  ConstantPoolInfo pool[]) 
516   
517              throws Exception { 
518   
519          for (int i = 0; i < pool.length; i++) { 
520   
521              if (item == pool[i]) 
522   
523                  return (short) i; 
524   
525          } 
526   
527          throw new Exception("ConstantPoolInfo:: indexOf() - item not in pool."); 
528   
529      } 
530   
531   
532      /** 
533   
534       * Returns true if these constant pool items are identical. 
535   
536       */ 
537   
538      public boolean isEqual(ConstantPoolInfo cp) { 
539   
540          if (cp == null) 
541   
542              return false; 
543   
544   
545          if (cp.type != type) 
546   
547              return (false); 
548   
549          switch (cp.type) { 
550   
551              case CLASS: 
552   
553              case STRING: 
554   
555                  return (arg1 == cp.arg1); 
556   
557              case FIELDREF: 
558   
559              case METHODREF: 
560   
561              case INTERFACE: 
562   
563              case NAMEANDTYPE: 
564   
565                  return ((arg1 == cp.arg1) && (arg2 == cp.arg2)); 
566   
567              case INTEGER: 
568   
569                  return (cp.intValue == intValue); 
570   
571              case FLOAT: 
572   
573                  return (cp.floatValue == floatValue); 
574   
575              case LONG: 
576   
577                  return (cp.longValue == longValue); 
578   
579              case DOUBLE: 
580   
581                  return (cp.doubleValue == doubleValue); 
582   
583              case ASCIZ: 
584   
585              case UNICODE: 
586   
587                  return (cp.strValue.compareTo(strValue) == 0); 
588   
589          } 
590   
591          return (false); 
592   
593      } 
594   
595   
596      /** 
597   
598       * Returns the reference to the constant pool item that is 
599   
600       * already in pool, that matches this one. 
601   
602       */ 
603   
604      public ConstantPoolInfo inPool(ConstantPoolInfo pool[]) { 
605   
606          for (int i = 1; i < pool.length; i++) { 
607   
608              if (isEqual(pool[i])) 
609   
610                  return (pool[i]); 
611   
612          } 
613   
614          return null; 
615   
616      } 
617   
618   
619  } 
620   
621