/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