KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > alt > jiapi > file > ConstantPool


1 package alt.jiapi.file;
2
3 import java.io.DataOutputStream JavaDoc;
4 import java.io.IOException JavaDoc;
5
6 import java.util.ArrayList JavaDoc;
7 import java.util.List JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.Properties JavaDoc;
10
11 /**
12  * Class ConstantPool.
13  *
14  * @author Mika Riekkinen
15  */

16 public class ConstantPool {
17     private static String JavaDoc REUSE_ENTRIES = "alt.jiapi.file.reuse-constantpool-entries";
18     private static Configuration config = new Configuration();
19
20     /**
21      * Constant, that represents a class_ref tag in constant pool
22      */

23     public static final byte CONSTANT_Class = 7;
24     /**
25      * Constant, that represents a field_ref tag in constant pool
26      */

27     public static final byte CONSTANT_Fieldref = 9;
28     /**
29      * Constant, that represents a method_ref tag in constant pool
30      */

31     public static final byte CONSTANT_Methodref = 10;
32     /**
33      * Constant, that represents a interfacemethod_ref tag in constant pool
34      */

35     public static final byte CONSTANT_InterfaceMethodref = 11;
36     /**
37      * Constant, that represents a string tag in constant pool
38      */

39     public static final byte CONSTANT_String = 8;
40     /**
41      * Constant, that represents a integer tag in constant pool
42      */

43     public static final byte CONSTANT_Integer = 3;
44     /**
45      * Constant, that represents a float tag in constant pool
46      */

47     public static final byte CONSTANT_Float = 4;
48     /**
49      * Constant, that represents a long tag in constant pool
50      */

51     public static final byte CONSTANT_Long = 5;
52     /**
53      * Constant, that represents a double tag in constant pool
54      */

55     public static final byte CONSTANT_Double = 6;
56     /**
57      * Constant, that represents a nameAndType tag in constant pool
58      */

59     public static final byte CONSTANT_NameAndType = 12;
60     /**
61      * Constant, that represents a Utf8 tag in constant pool
62      */

63     public static final byte CONSTANT_Utf8 = 1;
64     
65
66     private ArrayList JavaDoc cp;
67
68     ConstantPool(int size) {
69         cp = new ArrayList JavaDoc(size);
70     }
71
72     /**
73      * Creates an empty constant pool.
74      */

75     public ConstantPool() {
76         cp = new ArrayList JavaDoc();
77     }
78     
79
80     /**
81      * Adds an entry to this constant pool.
82      * If entry has sub-entries, those are added also.
83      */

84     public short add(ConstantPool.Entry entry) {
85         if (entry instanceof ClassInfo) {
86             return addClassInfo(((ClassInfo)entry).getName()).getEntryIndex();
87         }
88         else if (entry instanceof FieldRefInfo) {
89             FieldRefInfo fri = (FieldRefInfo)entry;
90             short ciIdx = add(fri.getClassInfo());
91
92             return addFieldRefInfo((ClassInfo)get(ciIdx),
93                                    fri.getNameAndTypeInfo().getName(),
94                                    fri.getNameAndTypeInfo().getDescriptor()).getEntryIndex();
95         }
96         else if (entry instanceof MethodRefInfo) {
97             MethodRefInfo mri = (MethodRefInfo)entry;
98             short ciIdx = add(mri.getClassInfo());
99
100             return addMethodRefInfo((ClassInfo)get(ciIdx),
101                                     mri.getNameAndTypeInfo().getName(),
102                                     mri.getNameAndTypeInfo().getDescriptor()).getEntryIndex();
103         }
104         else if (entry instanceof InterfaceMethodRefInfo) {
105             InterfaceMethodRefInfo imri = (InterfaceMethodRefInfo)entry;
106             short ciIdx = add(imri.getClassInfo());
107
108             return addInterfaceMethodRefInfo((ClassInfo)get(ciIdx), imri.getNameAndTypeInfo().getName(), imri.getNameAndTypeInfo().getDescriptor()).getEntryIndex();
109         }
110         else if (entry instanceof StringInfo) {
111             StringInfo si = (StringInfo)entry;
112             return addStringInfo(si.stringValue()).getEntryIndex();
113         }
114         else if (entry instanceof IntegerInfo ||
115                  entry instanceof FloatInfo) {
116             cp.add(entry);
117
118             return (short)cp.size();
119         }
120         else if (entry instanceof LongInfo ||
121                  entry instanceof DoubleInfo) {
122             cp.add(entry);
123             cp.add(new NullEntry());
124             return (short)(cp.size() - 1);
125         }
126         else if (entry instanceof NameAndTypeInfo) {
127             NameAndTypeInfo nti = (NameAndTypeInfo)entry;
128             return addNameAndTypeInfo(nti.getName(), nti.getDescriptor()).getEntryIndex();
129         }
130         else if (entry instanceof Utf8Info) {
131             Utf8Info utf8 = (Utf8Info)entry;
132             return addUtf8Info(utf8.stringValue()).getEntryIndex();
133         }
134         else {
135             System.out.println("ERROR: " + entry + " not converted");
136         }
137
138         return 0;
139     }
140
141
142     short addClassInfo(short nameIndex) {
143         if (nameIndex <= 0) {
144             throw new ParseException("Adding class_info, but name_index does not points to 0", this);
145         }
146
147         if (nameIndex <= cp.size()) {
148             Entry e = get(nameIndex);
149
150             if (!(e instanceof Utf8Info)) {
151                 throw new ParseException("Adding class_info, but name_index does not point to Utf8Info; index=" + nameIndex + ", " + e, this);
152             }
153         }
154
155         ClassInfo ci = new ClassInfo(nameIndex);
156         cp.add(ci);
157
158         return (short)(cp.size());
159     }
160
161     /**
162      * Adds a new ClassInfo.
163      *
164      * @param className a fully qualified class name
165      * @return ClassInfo
166      */

167     public ClassInfo addClassInfo(String JavaDoc className) {
168         String JavaDoc internalName = className.replace('.', '/');
169
170         if (config.getBoolean(REUSE_ENTRIES, true)) {
171             short idx = findClassInfo(0, internalName);
172             if (idx != -1) {
173                 return (ClassInfo)cp.get(idx);
174             }
175         }
176
177         Utf8Info u8 = addUtf8Info(internalName);
178         ClassInfo ci = new ClassInfo(u8.getEntryIndex());
179         cp.add(ci);
180         
181         return ci;
182     }
183
184
185     /**
186      * Adds a new FieldRefInfo.
187      *
188      * @param ci ClassInfo, that is supposed to contain created field
189      * reference
190      * @param name Name of the field
191      * @param desc descriptor of the field
192      * @return FieldRefInfo
193      */

194     public FieldRefInfo addFieldRefInfo(ClassInfo ci, String JavaDoc name, String JavaDoc desc) {
195         if (config.getBoolean(REUSE_ENTRIES, true)) {
196             FieldRefInfo __fi = findFieldRefInfo(0, ci, name, desc);
197             if (__fi != null) {
198                 return __fi;
199             }
200         }
201
202         short classIndex = ci.getEntryIndex();
203         short nameAndTypeIndex =addNameAndTypeInfo(name, desc).getEntryIndex();
204
205         FieldRefInfo fi = new FieldRefInfo(classIndex, nameAndTypeIndex);
206         cp.add(fi);
207
208         return fi;
209     }
210
211     short addFieldRefInfo(short classIndex, short nameAndTypeIndex) {
212         if (classIndex <= 0 || nameAndTypeIndex <=0) {
213             throw new ParseException("Adding fieldRef_info, but class_index or nameAndType_index is 0", this);
214         }
215
216         if (classIndex <= cp.size()) {
217             Entry e = get(classIndex);
218
219             if (!(e instanceof ClassInfo)) {
220                 throw new ParseException("Adding fieldRef_info, but class_index does not point to classInfo; index=" + classIndex + ", " + e, this);
221             }
222         }
223
224         FieldRefInfo fi = new FieldRefInfo(classIndex,
225                                            nameAndTypeIndex);
226         cp.add(fi);
227
228         return (short)(cp.size());
229     }
230
231     /**
232      * Adds a new MethodRefInfo.
233      *
234      * @param ci ClassInfo, that is supposed to contain created method
235      * reference
236      * @param name Name of the method
237      * @param desc descriptor of the method
238      * @return MethodRefInfo
239      */

240     public MethodRefInfo addMethodRefInfo(ClassInfo ci, String JavaDoc name, String JavaDoc desc) {
241         if (config.getBoolean(REUSE_ENTRIES, true)) {
242             MethodRefInfo __mi = findMethodRefInfo(0, ci, name, desc);
243             if (__mi != null) {
244                 return __mi;
245             }
246         }
247
248         short classIndex = ci.getEntryIndex();
249         short nameAndTypeIndex = addNameAndTypeInfo(name, desc).getEntryIndex();
250
251         MethodRefInfo mi = new MethodRefInfo(classIndex, nameAndTypeIndex);
252         cp.add(mi);
253
254         return mi;
255     }
256
257     short addMethodRefInfo(short classIndex, short nameAndTypeIndex) {
258         if (classIndex <= 0 || nameAndTypeIndex <=0) {
259             throw new ParseException("Adding methodRef_info, but class_index or nameAndType_index is 0", this);
260         }
261
262         if (classIndex <= cp.size()) {
263             Entry e = get(classIndex);
264
265             if (!(e instanceof ClassInfo)) {
266                 throw new ParseException("Adding methodRef_info, but class_index does not point to classInfo; index=" + classIndex + ", " + e, this);
267             }
268         }
269
270         MethodRefInfo mi = new MethodRefInfo(classIndex, nameAndTypeIndex);
271         cp.add(mi);
272
273         return (short)(cp.size());
274     }
275
276
277     /**
278      * Adds a new InterfaceMethodRefInfo.
279      *
280      * @param ci ClassInfo, that is supposed to contain created interface
281      * method reference
282      * @param name Name of the method
283      * @param desc descriptor of the method
284      * @return InterfaceMethodRefInfo
285      */

286     public InterfaceMethodRefInfo addInterfaceMethodRefInfo(ClassInfo ci, String JavaDoc name, String JavaDoc desc) {
287         short classIndex = ci.getEntryIndex();
288         short nameAndTypeIndex = addNameAndTypeInfo(name, desc).getEntryIndex();
289
290         InterfaceMethodRefInfo imi = new InterfaceMethodRefInfo(classIndex, nameAndTypeIndex);
291         cp.add(imi);
292
293         return imi;
294     }
295
296     short addInterfaceMethodRefInfo(short classIndex, short nameAndTypeIndex) {
297         if (classIndex <= 0 || nameAndTypeIndex <=0) {
298             throw new ParseException("Adding interfaceMethodRef_info, but class_index or nameAndType_index is 0", this);
299         }
300
301         if (classIndex <= cp.size()) {
302             Entry e = get(classIndex);
303
304             if (!(e instanceof ClassInfo)) {
305                 throw new ParseException("Adding interfaceMethodRef_info, but class_index does not point to classInfo; index=" + classIndex + ", " + e, this);
306             }
307         }
308
309         InterfaceMethodRefInfo imi = new InterfaceMethodRefInfo(classIndex, nameAndTypeIndex);
310         cp.add(imi);
311
312         return (short)(cp.size());
313     }
314
315
316     /**
317      * Adds a new StringInfo.
318      *
319      * @param s String constant to add
320      * @return StringInfo
321      */

322     public StringInfo addStringInfo(String JavaDoc s) {
323         if (config.getBoolean(REUSE_ENTRIES, true)) {
324             StringInfo __si = findStringInfo(0, s);
325             if (__si != null) {
326                 return __si;
327             }
328         }
329
330         Utf8Info u8 = addUtf8Info(s);
331         StringInfo si = new StringInfo(u8.getEntryIndex());
332         cp.add(si);
333         
334         return si;
335     }
336
337     short addString_info(short stringIndex) {
338         if (stringIndex <= 0) {
339             throw new ParseException("Adding string_info, but string_index is 0", this);
340         }
341
342         if (stringIndex <= cp.size()) {
343             Entry e = get(stringIndex);
344
345             if (!(e instanceof Utf8Info)) {
346                 throw new ParseException("Adding string_info, but string_index does not point to Utf8Info; index=" + stringIndex + ", " + e, this);
347             }
348         }
349
350         StringInfo si = new StringInfo(stringIndex);
351         cp.add(si);
352
353         return (short)(cp.size());
354     }
355
356
357     /**
358      * Adds a new IntegerInfo.
359      *
360      * @param bytes integer constant
361      * @return IntegerInfo
362      */

363     public IntegerInfo addIntegerInfo(int bytes) {
364         IntegerInfo ii = new IntegerInfo(bytes);
365         cp.add(ii);
366
367         return ii;
368     }
369
370     short addInteger_info(int bytes) {
371         IntegerInfo ii = new IntegerInfo(bytes);
372         cp.add(ii);
373
374         return (short)(cp.size());
375     }
376
377     /**
378      * Adds a new FloatInfo.
379      *
380      * @param bytes float constant
381      * @return FloatInfo
382      */

383     public FloatInfo addFloatInfo(int bytes) {
384         FloatInfo fi = new FloatInfo(bytes);
385         cp.add(fi);
386
387         return fi;
388     }
389
390     short addFloat_info(int bytes) {
391         FloatInfo fi = new FloatInfo(bytes);
392         cp.add(fi);
393
394         return (short)(cp.size());
395     }
396
397
398     /**
399      * Adds a new LongInfo.
400      *
401      * @param highBytes long constant
402      * @param lowBytes long constant
403      * @return LongInfo
404      */

405     public LongInfo addLongInfo(int highBytes, int lowBytes) {
406         LongInfo li = new LongInfo(highBytes, lowBytes);
407         cp.add(li);
408
409         return li;
410     }
411
412     short addLong_info(int highBytes, int lowBytes) {
413         LongInfo fi = new LongInfo(highBytes, lowBytes);
414         cp.add(fi);
415         cp.add(new NullEntry()); // long/double takes 2 entries in cp
416

417         return (short)(cp.size() - 1);
418     }
419
420     /**
421      * Adds a new DoubleInfo.
422      *
423      * @param highBytes double constant
424      * @param lowBytes double constant
425      * @return DoubleInfo
426      */

427     public DoubleInfo addDoubleInfo(int highBytes, int lowBytes) {
428         DoubleInfo di = new DoubleInfo(highBytes, lowBytes);
429         cp.add(di);
430
431         return di;
432     }
433
434     short addDouble_info(int highBytes, int lowBytes) {
435         DoubleInfo fi = new DoubleInfo(highBytes, lowBytes);
436         cp.add(fi);
437         cp.add(new NullEntry()); // long/double takes 2 entries in cp
438

439         return (short)(cp.size() - 1);
440     }
441
442
443     /**
444      * Adds a new NameAndTypeInfo.
445      *
446      * @param name Name to add
447      * @param descriptor descriptor to add
448      * @return NameAndTypeInfo
449      */

450     public NameAndTypeInfo addNameAndTypeInfo(String JavaDoc name, String JavaDoc descriptor) {
451         if (config.getBoolean(REUSE_ENTRIES, true)) {
452             NameAndTypeInfo ni= findNameAndTypeInfo(0, name, descriptor);
453             if (ni != null) {
454                 return ni;
455             }
456         }
457
458         short nameIndex = addUtf8Info(name).getEntryIndex();
459         short descriptorIndex = addUtf8Info(descriptor).getEntryIndex();
460
461         NameAndTypeInfo fi = new NameAndTypeInfo(nameIndex, descriptorIndex);
462         cp.add(fi);
463
464         return fi;
465     }
466
467     short addNameAndTypeInfo(short nameIndex, short descriptorIndex) {
468         if (nameIndex <= 0 || descriptorIndex <=0) {
469             throw new ParseException("Adding nameAndType_info, but name_index or descriptor_index is 0", this);
470         }
471
472         if (nameIndex <= cp.size()) {
473             Entry e = get(nameIndex);
474
475             if (!(e instanceof Utf8Info)) {
476                 throw new ParseException("Adding nameAndType_info, but name_index does not point to Utf8Info; index=" + nameIndex + ", " + e, this);
477             }
478         }
479         if (descriptorIndex <= cp.size()) {
480             Entry e = get(descriptorIndex);
481
482             if (!(e instanceof Utf8Info)) {
483                 throw new ParseException("Adding nameAndType_info, but descriptor_index does not point to Utf8Info; name_index=" + nameIndex + ", descriptor_index=" + descriptorIndex + ", " + e,this);
484             }
485         }
486
487         NameAndTypeInfo fi = new NameAndTypeInfo(nameIndex, descriptorIndex);
488         cp.add(fi);
489
490         return (short)(cp.size());
491     }
492
493
494
495     /**
496      * Adds a new Utf8Info.
497      *
498      * @param s String to add
499      * @return Utf8Info
500      */

501     public Utf8Info addUtf8Info(String JavaDoc s) {
502         if (config.getBoolean(REUSE_ENTRIES, true)) {
503             Utf8Info u8 = findUtf8Info(0, s);
504             if (u8 != null) {
505                 return u8;
506             }
507         }
508
509         return (Utf8Info)cp.get(addUtf8_info(s.getBytes()) - 1);
510     }
511
512     short addUtf8_info(byte[] bytes) {
513         Utf8Info ui = new Utf8Info(bytes);
514         cp.add(ui);
515
516         return (short)(cp.size());
517     }
518
519
520     /**
521      * Gets an entry from constant pool. Indexing starts from 1.
522      *
523      * @param index index into constant pool
524      * @return An instance of Entry
525      */

526     public Entry get(int index) {
527         return (Entry)cp.get(index - 1);
528     }
529
530
531     /**
532      * Gets a String at given constant pool index.
533      * index must point to a Utf8Info.
534      *
535      * @param index index into constant pool
536      * @return An instance of Entry
537      * @exception IllegalArgumentException is throw, if entry at
538      * given index does not point into Utf8Info
539      */

540     public String JavaDoc getUtf8(short index) {
541         ConstantPool.Entry utf8 = get(index);
542
543         if (utf8 instanceof ConstantPool.Utf8Info) {
544             byte[] bytes = ((ConstantPool.Utf8Info)utf8).getBytes();
545             return new String JavaDoc(bytes);
546         }
547         else {
548             throw new IllegalArgumentException JavaDoc("index does not point to utf8_info structure: index " + index + " -> " + utf8);
549         }
550     }
551
552
553
554     /**
555      * Gets a String at given constant pool index.
556      * index must point to a StringInfo or Utf8Info.
557      *
558      * @param index index into constant pool
559      * @return a String
560      * @exception IllegalArgumentException is throw, if entry at
561      * given index does not point into StringInfo or utf8Info
562      */

563     public String JavaDoc getStringValue(short index) {
564         ConstantPool.Entry str = get(index);
565
566         if (str instanceof ConstantPool.StringInfo) {
567             String JavaDoc s = ((ConstantPool.StringInfo)str).stringValue();
568             return s;
569         }
570         else if (str instanceof ConstantPool.Utf8Info) {
571             byte[] bytes = ((ConstantPool.Utf8Info)str).getBytes();
572             return new String JavaDoc(bytes);
573         }
574         else {
575             throw new IllegalArgumentException JavaDoc("index does not point to string_info structure: index " + index + " -> " + str);
576         }
577     }
578
579
580     /**
581      * Index must point to a Class_info structure in Constant pool
582      *
583      * @param index index to ClassInfo in constant pool.
584      * @return an internal representation of classname,
585      * like <b>java/lang/Object</b>
586      * @exception IllegalArgumentException is throw, if entry at
587      * given index does not point into ClassInfo, or
588      * ClassInfo.getNameIndex() does not point to Utf8Info
589      */

590     public String JavaDoc getClassName(short index) {
591         // NOTE: This should be package protected
592
// @see JiapiMethod for its usage relating to exceptions
593
ConstantPool.Entry ci = get(index);
594         if (ci instanceof ConstantPool.ClassInfo) {
595             short nameIndex = ((ConstantPool.ClassInfo)ci).getNameIndex();
596
597             return getUtf8(nameIndex).replace('/', '.');
598         }
599         else {
600             throw new IllegalArgumentException JavaDoc("index does not point to Class_info structure: index " + index + " -> " + ci);
601         }
602     }
603
604
605     /**
606      * Base class for entries in ConstantPool.
607      */

608     public abstract class Entry {
609         private byte tag;
610         private short entryIndex;
611
612         // For NullEntry
613
private Entry() {
614         }
615
616         /**
617          * Constructor.
618          *
619          * @param tag One of CONSTANT_XXX defined in ConstantPool
620          */

621         public Entry(byte tag) {
622             this.entryIndex = (short)(cp.size() + 1);
623             this.tag = tag;
624         }
625
626         /**
627          * Gets the tag related to this entry.
628          *
629          * @return tag
630          */

631         public byte getTag() {
632             return tag;
633         }
634
635         /**
636          * Get the index in the constant pool.
637          *
638          * @return constant pool index of this entry
639          */

640         public short getEntryIndex() {
641             return entryIndex;
642         }
643
644         /**
645          * Writes this Entry to DataOutputStream given.
646          *
647          * @param dos DataOutputStream used
648          */

649         public abstract void writeData(DataOutputStream JavaDoc dos) throws IOException JavaDoc;
650     }
651
652     /**
653      */

654     public class NullEntry extends Entry {
655         public NullEntry() {
656         }
657
658         public void writeData(DataOutputStream JavaDoc dos) {
659         }
660     }
661
662
663     /**
664      * Represents a CONSTANT_Class_info in constant pool
665      *
666      * @see Java Virtual Machine Specification, 2nd edition, ch. 4.4.1
667      */

668     public class ClassInfo extends Entry {
669         private short nameIndex;
670
671         ClassInfo(short nameIndex) {
672             super(CONSTANT_Class);
673             this.nameIndex = nameIndex;
674         }
675
676         /**
677          * Gets an index in constant pool, that points to Utf8_info,
678          * representing name of this ClassInfo
679          */

680         short getNameIndex() {
681             return nameIndex;
682         }
683
684         /**
685          * Gets a name, that is represented by this ClassInfo
686          */

687         public String JavaDoc getName() {
688             return getUtf8(nameIndex);
689         }
690
691         public String JavaDoc toString() {
692             return "Class_info:\n " + get(nameIndex);
693         }
694
695         public void writeData(DataOutputStream JavaDoc dos) throws IOException JavaDoc {
696             dos.writeShort(nameIndex);
697         }
698     }
699
700
701     /**
702      * Represents a CONSTANT_FieldRef in constant pool
703      *
704      * @see Java Virtual Machine Specification, 2nd edition, ch. 4.4.2
705      */

706     public class FieldRefInfo extends Entry {
707         private short classIndex;
708         private short nameAndTypeIndex;
709
710         FieldRefInfo(short classIndex, short nameAndTypeIndex) {
711             super(CONSTANT_Fieldref);
712             this.classIndex = classIndex;
713             this.nameAndTypeIndex = nameAndTypeIndex;
714         }
715
716         short getClassIndex() {
717             return classIndex;
718         }
719
720         public ClassInfo getClassInfo() {
721             return (ClassInfo)get(classIndex);
722         }
723
724         short getNameAndTypeIndex() {
725             return nameAndTypeIndex;
726         }
727
728         public NameAndTypeInfo getNameAndTypeInfo() {
729             return (NameAndTypeInfo)get(nameAndTypeIndex);
730         }
731
732         /**
733          * Gets the name of the field referenced by this FieldRefInfo
734          */

735         public String JavaDoc getFieldName() {
736             NameAndTypeInfo nti = (NameAndTypeInfo)get(nameAndTypeIndex);
737             return getUtf8(nti.getNameIndex());
738         }
739
740
741         /**
742          * Get Fields descriptor
743          */

744         public String JavaDoc getDescriptor() {
745             NameAndTypeInfo nti = (NameAndTypeInfo)get(nameAndTypeIndex);
746             return getUtf8(nti.getDescriptorIndex());
747         }
748
749         public String JavaDoc toString() {
750             return "fieldref_info:\n " + get(classIndex) + "\n " +
751                 get(nameAndTypeIndex);
752         }
753
754         public void writeData(DataOutputStream JavaDoc dos) throws IOException JavaDoc {
755             dos.writeShort(classIndex);
756             dos.writeShort(nameAndTypeIndex);
757         }
758     }
759
760
761     /**
762      * Represents a CONSTANT_MethodRef in constant pool
763      *
764      * @see Java Virtual Machine Specification, 2nd edition, ch. 4.4.2
765      */

766     public class MethodRefInfo extends Entry {
767         private short classIndex;
768         private short nameAndTypeIndex;
769
770         MethodRefInfo(short classIndex, short nameAndTypeIndex) {
771             super(CONSTANT_Methodref);
772             this.classIndex = classIndex;
773             this.nameAndTypeIndex = nameAndTypeIndex;
774         }
775
776         short getClassIndex() {
777             return classIndex;
778         }
779
780         public ClassInfo getClassInfo() {
781             return (ClassInfo)get(classIndex);
782         }
783
784         short getNameAndTypeIndex() {
785             return nameAndTypeIndex;
786         }
787
788         public NameAndTypeInfo getNameAndTypeInfo() {
789             return (NameAndTypeInfo)get(nameAndTypeIndex);
790         }
791
792         /**
793          * Gets the name of the method referenced by this MethodRefInfo
794          */

795         public String JavaDoc getMethodName() {
796             NameAndTypeInfo nti = (NameAndTypeInfo)get(nameAndTypeIndex);
797             return getUtf8(nti.getNameIndex());
798         }
799
800         /**
801          * Get methods descriptor
802          */

803         public String JavaDoc getDescriptor() {
804             NameAndTypeInfo nti = (NameAndTypeInfo)get(nameAndTypeIndex);
805             return getUtf8(nti.getDescriptorIndex());
806         }
807
808         public String JavaDoc toString() {
809             return "methodref_info:\n " + get(classIndex) + "(" + classIndex+
810                 ")\n " + get(nameAndTypeIndex);
811         }
812
813         public void writeData(DataOutputStream JavaDoc dos) throws IOException JavaDoc {
814             dos.writeShort(classIndex);
815             dos.writeShort(nameAndTypeIndex);
816         }
817     }
818
819
820
821     /**
822      * Represents a CONSTANT_InterfaceMethodRef in constant pool
823      *
824      * @see Java Virtual Machine Specification, 2nd edition, ch. 4.4.2
825      */

826     public class InterfaceMethodRefInfo extends Entry {
827         private short classIndex;
828         private short nameAndTypeIndex;
829
830         InterfaceMethodRefInfo(short classIndex, short nameAndTypeIndex) {
831             super(CONSTANT_InterfaceMethodref);
832             this.classIndex = classIndex;
833             this.nameAndTypeIndex = nameAndTypeIndex;
834         }
835
836         short getClassIndex() {
837             return classIndex;
838         }
839
840         public ClassInfo getClassInfo() {
841             return (ClassInfo)get(classIndex);
842         }
843
844         short getNameAndTypeIndex() {
845             return nameAndTypeIndex;
846         }
847
848         public NameAndTypeInfo getNameAndTypeInfo() {
849             return (NameAndTypeInfo)get(nameAndTypeIndex);
850         }
851
852
853         /**
854          * Gets the name of the method referenced by this MethodRefInfo
855          */

856         public String JavaDoc getMethodName() {
857             NameAndTypeInfo nti = (NameAndTypeInfo)get(nameAndTypeIndex);
858             return getUtf8(nti.getNameIndex());
859         }
860
861         /**
862          * Get methods descriptor
863          */

864         public String JavaDoc getDescriptor() {
865             NameAndTypeInfo nti = (NameAndTypeInfo)get(nameAndTypeIndex);
866             return getUtf8(nti.getDescriptorIndex());
867         }
868
869         public String JavaDoc toString() {
870             return "interfacemethodref_info:\n " + get(classIndex) + "\n " +
871                 get(nameAndTypeIndex);
872         }
873
874         public void writeData(DataOutputStream JavaDoc dos) throws IOException JavaDoc {
875             dos.writeShort(classIndex);
876             dos.writeShort(nameAndTypeIndex);
877         }
878     }
879
880     public class StringInfo extends Entry {
881         private short stringIndex;
882
883         StringInfo(short stringIndex) {
884             super(CONSTANT_String);
885             this.stringIndex = stringIndex;
886         }
887
888         short getStringIndex() {
889             return stringIndex;
890         }
891
892         public String JavaDoc stringValue() {
893             Utf8Info u8 = (Utf8Info)get(stringIndex);
894             return u8.stringValue();
895         }
896
897         public String JavaDoc toString() {
898             return "string_info:\n " + get(stringIndex);
899         }
900
901         public void writeData(DataOutputStream JavaDoc dos) throws IOException JavaDoc {
902             dos.writeShort(stringIndex);
903         }
904     }
905
906     public class IntegerInfo extends Entry {
907         private int bytes;
908
909         IntegerInfo(int bytes) {
910             super(CONSTANT_Integer);
911             this.bytes = bytes;
912         }
913
914         public int getBytes() {
915             return bytes;
916         }
917
918         public String JavaDoc toString() {
919             return "integer_info: " + bytes;
920         }
921
922         public void writeData(DataOutputStream JavaDoc dos) throws IOException JavaDoc {
923             dos.writeInt(bytes);
924         }
925     }
926
927
928     public class FloatInfo extends Entry {
929         private int bytes;
930
931         FloatInfo(int bytes) {
932             super(CONSTANT_Float);
933             this.bytes = bytes;
934         }
935
936         public int getBytes() {
937             return bytes;
938         }
939
940         public String JavaDoc toString() {
941             return "float_info: " + bytes;
942         }
943
944         public void writeData(DataOutputStream JavaDoc dos) throws IOException JavaDoc {
945             dos.writeInt(bytes);
946         }
947     }
948
949     public class LongInfo extends Entry {
950         private int highBytes;
951         private int lowBytes;
952
953         LongInfo(int highBytes, int lowBytes) {
954             super(CONSTANT_Long);
955             this.highBytes = highBytes;
956             this.lowBytes = lowBytes;
957         }
958
959         public int getHighBytes() {
960             return highBytes;
961         }
962
963         public int getLowBytes() {
964             return lowBytes;
965         }
966
967         public String JavaDoc toString() {
968             return "long_info: " + highBytes + " " + lowBytes;
969         }
970
971         public void writeData(DataOutputStream JavaDoc dos) throws IOException JavaDoc {
972             dos.writeInt(highBytes);
973             dos.writeInt(lowBytes);
974         }
975     }
976
977     public class DoubleInfo extends Entry {
978         private int highBytes;
979         private int lowBytes;
980
981         DoubleInfo(int highBytes, int lowBytes) {
982             super(CONSTANT_Double);
983             this.highBytes = highBytes;
984             this.lowBytes = lowBytes;
985         }
986
987         public int getHighBytes() {
988             return highBytes;
989         }
990
991         public int getLowBytes() {
992             return lowBytes;
993         }
994
995         public String JavaDoc toString() {
996             return "double_info: " + highBytes + " " + lowBytes;
997         }
998
999         public void writeData(DataOutputStream JavaDoc dos) throws IOException JavaDoc {
1000            dos.writeInt(highBytes);
1001            dos.writeInt(lowBytes);
1002        }
1003    }
1004
1005    /**
1006     * Represents a CONSTANT_NameAndType in constant pool
1007     *
1008     * @see Java Virtual Machine Specification, 2nd edition, ch. 4.4.6
1009     */

1010    public class NameAndTypeInfo extends Entry {
1011        private short nameIndex;
1012        private short descriptorIndex;
1013
1014        NameAndTypeInfo(short nameIndex, short descriptorIndex) {
1015            super(CONSTANT_NameAndType);
1016            this.nameIndex = nameIndex;
1017            this.descriptorIndex = descriptorIndex;
1018        }
1019
1020        short getNameIndex() {
1021            return nameIndex;
1022        }
1023
1024        public String JavaDoc getName() {
1025            return getUtf8(nameIndex);
1026        }
1027
1028        short getDescriptorIndex() {
1029            return descriptorIndex;
1030        }
1031
1032        public String JavaDoc getDescriptor() {
1033            return getUtf8(descriptorIndex);
1034        }
1035
1036        public String JavaDoc toString() {
1037            return "nameandtype_info:\n " + get(nameIndex) + "\n " +
1038                get(descriptorIndex);
1039        }
1040
1041
1042        public void writeData(DataOutputStream JavaDoc dos) throws IOException JavaDoc {
1043            dos.writeShort(nameIndex);
1044            dos.writeShort(descriptorIndex);
1045        }
1046    }
1047
1048
1049    public class Utf8Info extends Entry {
1050        private byte[] bytes;
1051
1052        Utf8Info(byte[] bytes) {
1053            super(CONSTANT_Utf8);
1054            this.bytes = bytes;
1055        }
1056
1057        public byte[] getBytes() {
1058            return bytes;
1059        }
1060
1061        public String JavaDoc stringValue() {
1062            return new String JavaDoc(bytes);
1063        }
1064
1065        public String JavaDoc toString() {
1066            return "utf8_info: " + new String JavaDoc(bytes);
1067        }
1068
1069        public void writeData(DataOutputStream JavaDoc dos) throws IOException JavaDoc {
1070            dos.writeShort(bytes.length);
1071            for (int i = 0; i < bytes.length; i++) {
1072                dos.writeByte(bytes[i]);
1073            }
1074        }
1075    }
1076
1077
1078    /**
1079     * Get the size of this ConstantPool.
1080     *
1081     * @return number of entries in constant-pool
1082     */

1083    public int size() {
1084        return cp.size();
1085    }
1086
1087
1088    List JavaDoc getList() {
1089        cp.trimToSize();
1090        return cp;
1091    }
1092
1093    public String JavaDoc toString() {
1094        StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1095        int idx = 1;
1096
1097        Iterator JavaDoc i = cp.iterator();
1098        while(i.hasNext()) {
1099            sb.append(idx);
1100            sb.append(": ");
1101            sb.append(i.next());
1102            if (i.hasNext()) {
1103                sb.append('\n');
1104            }
1105            idx++;
1106        }
1107
1108        return sb.toString();
1109    }
1110
1111    public byte[] toBytes() {
1112        if (true) {
1113            throw new RuntimeException JavaDoc("NOT IMPLEMENTED"); // needed???
1114
}
1115
1116        return null;
1117    }
1118
1119
1120
1121    short findClassInfo(int start, String JavaDoc s) {
1122        for (int i = start; i < cp.size(); i++) {
1123            Entry e = (Entry)cp.get(i);
1124            
1125            if (e instanceof ClassInfo) {
1126                ClassInfo ci = (ClassInfo)e;
1127
1128                if (ci.getName().equals(s)) {
1129                    return (short)(i);
1130                }
1131            }
1132        }
1133        
1134        return -1;
1135    }
1136
1137
1138    MethodRefInfo findMethodRefInfo(int start, ClassInfo ci, String JavaDoc name, String JavaDoc desc){
1139        for (int i = start; i < cp.size(); i++) {
1140            Entry e = (Entry)cp.get(i);
1141            
1142            if (e instanceof MethodRefInfo) {
1143                MethodRefInfo mi = (MethodRefInfo)e;
1144
1145                if (mi.getMethodName().equals(name) &&
1146                    mi.getDescriptor().equals(desc)) {
1147                    ClassInfo __ci = mi.getClassInfo();
1148
1149                    if (__ci.getEntryIndex() == ci.getEntryIndex()) {
1150                        return mi;
1151                    }
1152                }
1153            }
1154        }
1155        
1156        return null;
1157    }
1158
1159
1160
1161    FieldRefInfo findFieldRefInfo(int start, ClassInfo ci, String JavaDoc name, String JavaDoc desc){
1162        for (int i = start; i < cp.size(); i++) {
1163            Entry e = (Entry)cp.get(i);
1164            
1165            if (e instanceof FieldRefInfo) {
1166                FieldRefInfo fi = (FieldRefInfo)e;
1167
1168                if (fi.getFieldName().equals(name) &&
1169                    fi.getDescriptor().equals(desc)) {
1170                    ClassInfo __ci = fi.getClassInfo();
1171
1172                    if (__ci.getEntryIndex() == ci.getEntryIndex()) {
1173                        return fi;
1174                    }
1175                }
1176            }
1177        }
1178        
1179        return null;
1180    }
1181
1182
1183    NameAndTypeInfo findNameAndTypeInfo(int start, String JavaDoc name, String JavaDoc desc) {
1184        for (int i = start; i < cp.size(); i++) {
1185            Entry e = (Entry)cp.get(i);
1186            
1187            if (e instanceof NameAndTypeInfo) {
1188                NameAndTypeInfo ni = (NameAndTypeInfo)e;
1189
1190                if (ni.getName().equals(name) &&
1191                    ni.getDescriptor().equals(desc)) {
1192                    return ni;
1193                }
1194            }
1195        }
1196        
1197        return null;
1198    }
1199
1200
1201    StringInfo findStringInfo(int start, String JavaDoc s) {
1202        for (int i = start; i < cp.size(); i++) {
1203            Entry e = (Entry)cp.get(i);
1204            
1205            if (e instanceof StringInfo) {
1206                StringInfo si = (StringInfo)e;
1207
1208                if (si.stringValue().equals(s)) {
1209                    return si;
1210                }
1211            }
1212        }
1213        
1214        return null;
1215    }
1216
1217
1218    Utf8Info findUtf8Info(int start, String JavaDoc s) {
1219        for (int i = start; i < cp.size(); i++) {
1220            Entry e = (Entry)cp.get(i);
1221            
1222            if (e instanceof Utf8Info) {
1223                Utf8Info u8 = (Utf8Info)e;
1224
1225                if (u8.stringValue().equals(s)) {
1226                    return u8;
1227                }
1228            }
1229        }
1230        
1231        return null;
1232    }
1233
1234
1235    /**
1236     * Verifies this ConstantPool
1237     */

1238    void verify() {
1239        Iterator JavaDoc i = cp.iterator();
1240        while(i.hasNext()) {
1241            Entry e = (Entry)i.next();
1242
1243            if (e instanceof ClassInfo) {
1244                ClassInfo ci = (ClassInfo)e;
1245                if (ci.getNameIndex() <= cp.size()) {
1246                    Entry e2 = get(ci.getNameIndex());
1247                    
1248                    if (!(e2 instanceof Utf8Info)) {
1249                        throw new ParseException("Invalid class_info; name_index does not point to Utf8Info; index=" + ci.getNameIndex() + ", " + e2, this);
1250                    }
1251                }
1252            }
1253        }
1254    }
1255}
1256
Popular Tags