1
3 package jminusminus;
4
5 import java.io.EOFException;
6 import java.io.IOException;
7 import java.io.DataInputStream;
8 import java.io.InputStream;
9 import java.util.ArrayList;
10 import static jminusminus.CLConstants.*;
11
12
17
18 public class CLAbsorber {
19
20
21 private CLFile classFile;
22
23
24 private boolean errorHasOccurred;
25
26
27 private String className;
28
29
37
38 private void reportWarning(String message, Object... args) {
39 System.err.printf("CLAbsorber Warning: " + message + "\n", args);
40 }
41
42
51
52 private void reportError(String message, Object... args) {
53 System.err.printf("CLAbsorber Error: " + message + "\n", args);
54 errorHasOccurred = true;
55 }
56
57
65
66 private CLConstantPool readConstantPool(CLInputStream in) {
67 CLConstantPool cp = new CLConstantPool();
68 try {
69 for (int i = 1; i < classFile.constantPoolCount; i++) {
70 int tag = in.readUnsignedByte();
71 switch (tag) {
72 case CONSTANT_Class:
73 cp
74 .addCPItem(new CLConstantClassInfo(in
75 .readUnsignedShort()));
76 break;
77 case CONSTANT_Fieldref:
78 cp.addCPItem(new CLConstantFieldRefInfo(in
79 .readUnsignedShort(), in.readUnsignedShort()));
80 break;
81 case CONSTANT_Methodref:
82 cp.addCPItem(new CLConstantMethodRefInfo(in
83 .readUnsignedShort(), in.readUnsignedShort()));
84 break;
85 case CONSTANT_InterfaceMethodref:
86 cp.addCPItem(new CLConstantInterfaceMethodRefInfo(in
87 .readUnsignedShort(), in.readUnsignedShort()));
88 break;
89 case CONSTANT_String:
90 cp.addCPItem(new CLConstantStringInfo(in
91 .readUnsignedShort()));
92 break;
93 case CONSTANT_Integer:
94 cp.addCPItem(new CLConstantIntegerInfo(in.readInt()));
95 break;
96 case CONSTANT_Float:
97 cp.addCPItem(new CLConstantFloatInfo(in.readFloat()));
98 break;
99 case CONSTANT_Long:
100 cp.addCPItem(new CLConstantLongInfo(in.readLong()));
101 i++;
102 break;
103 case CONSTANT_Double:
104 cp.addCPItem(new CLConstantDoubleInfo(in.readDouble()));
105 i++;
106 break;
107 case CONSTANT_NameAndType:
108 cp.addCPItem(new CLConstantNameAndTypeInfo(in
109 .readUnsignedShort(), in.readUnsignedShort()));
110 break;
111 case CONSTANT_Utf8:
112 int length = in.readUnsignedShort();
113 byte[] b = new byte[length];
114 in.read(b);
115 cp.addCPItem(new CLConstantUtf8Info(b));
116 break;
117 default:
118 reportError("Unknown cp_info tag '%d'", tag);
119 return cp;
120 }
121 }
122 } catch (IOException e) {
123 reportError("Error reading constant pool from file %s", className);
124 }
125 return cp;
126 }
127
128
137
138 private ArrayList<CLFieldInfo> readFields(CLInputStream in, int fieldsCount) {
139 ArrayList<CLFieldInfo> fields = new ArrayList<CLFieldInfo>();
140 try {
141 for (int i = 0; i < fieldsCount; i++) {
142 int accessFlags = in.readUnsignedShort();
143 int nameIndex = in.readUnsignedShort();
144 int descriptorIndex = in.readUnsignedShort();
145 int attributesCount = in.readUnsignedShort();
146 fields.add(new CLFieldInfo(accessFlags, nameIndex,
147 descriptorIndex, attributesCount, readAttributes(in,
148 attributesCount)));
149 }
150 } catch (IOException e) {
151 reportError("Error reading fields from file %s", className);
152 }
153 return fields;
154 }
155
156
165
166 private ArrayList<CLMethodInfo> readMethods(CLInputStream in,
167 int methodsCount) {
168 ArrayList<CLMethodInfo> methods = new ArrayList<CLMethodInfo>();
169 try {
170 for (int i = 0; i < methodsCount; i++) {
171 int accessFlags = in.readUnsignedShort();
172 int nameIndex = in.readUnsignedShort();
173 int descriptorIndex = in.readUnsignedShort();
174 int attributesCount = in.readUnsignedShort();
175 methods.add(new CLMethodInfo(accessFlags, nameIndex,
176 descriptorIndex, attributesCount, readAttributes(in,
177 attributesCount)));
178 }
179 } catch (IOException e) {
180 reportError("Error reading methods from file %s", className);
181 }
182 return methods;
183 }
184
185
194
195 private ArrayList<CLAttributeInfo> readAttributes(CLInputStream in,
196 int attributesCount) {
197 ArrayList<CLAttributeInfo> attributes = new ArrayList<CLAttributeInfo>();
198 try {
199 CLConstantPool cp = classFile.constantPool;
200 for (int i = 0; i < attributesCount; i++) {
201 int attributeNameIndex = in.readUnsignedShort();
202 long attributeLength = in.readUnsignedInt();
203 CLAttributeInfo attributeInfo = null;
204 String attributeName = new String(((CLConstantUtf8Info) cp
205 .cpItem(attributeNameIndex)).b);
206 if (attributeName.equals(ATT_CONSTANT_VALUE)) {
207 attributeInfo = readConstantValueAttribute(in,
208 attributeNameIndex, attributeLength);
209 } else if (attributeName.equals(ATT_CODE)) {
210 attributeInfo = readCodeAttribute(in, attributeNameIndex,
211 attributeLength);
212 } else if (attributeName.equals(ATT_EXCEPTIONS)) {
213 attributeInfo = readExceptionsAttribute(in,
214 attributeNameIndex, attributeLength);
215 } else if (attributeName.equals(ATT_INNER_CLASSES)) {
216 attributeInfo = readInnerClassesAttribute(in,
217 attributeNameIndex, attributeLength);
218 } else if (attributeName.equals(ATT_ENCLOSING_METHOD)) {
219 attributeInfo = readEnclosingMethodAttribute(in,
220 attributeNameIndex, attributeLength);
221 } else if (attributeName.equals(ATT_SYNTHETIC)) {
222 attributeInfo = readSyntheticAttribute(in,
223 attributeNameIndex, attributeLength);
224 } else if (attributeName.equals(ATT_SIGNATURE)) {
225 attributeInfo = readSignatureAttribute(in,
226 attributeNameIndex, attributeLength);
227 } else if (attributeName.equals(ATT_SOURCE_FILE)) {
228 attributeInfo = readSourceFileAttribute(in,
229 attributeNameIndex, attributeLength);
230 } else if (attributeName.equals(ATT_SOURCE_DEBUG_EXTENSION)) {
231 attributeInfo = readSourceDebugExtensionAttribute(in,
232 attributeNameIndex, attributeLength);
233 } else if (attributeName.equals(ATT_LINE_NUMBER_TABLE)) {
234 attributeInfo = readLineNumberTableAttribute(in,
235 attributeNameIndex, attributeLength);
236 } else if (attributeName.equals(ATT_LOCAL_VARIABLE_TABLE)) {
237 attributeInfo = readLocalVariableTableAttribute(in,
238 attributeNameIndex, attributeLength);
239 } else if (attributeName.equals(ATT_LOCAL_VARIABLE_TYPE_TABLE)) {
240 attributeInfo = readLocalVariableTypeTableAttribute(in,
241 attributeNameIndex, attributeLength);
242 } else if (attributeName.equals(ATT_DEPRECATED)) {
243 attributeInfo = readDeprecatedAttribute(in,
244 attributeNameIndex, attributeLength);
245 } else if (attributeName
246 .equals(ATT_RUNTIME_VISIBLE_ANNOTATIONS)) {
247 attributeInfo = readRuntimeVisibleAnnotationsAttribute(in,
248 attributeNameIndex, attributeLength);
249 } else if (attributeName
250 .equals(ATT_RUNTIME_INVISIBLE_ANNOTATIONS)) {
251 attributeInfo = readRuntimeInvisibleAnnotationsAttribute(
252 in, attributeNameIndex, attributeLength);
253 } else if (attributeName
254 .equals(ATT_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS)) {
255 attributeInfo = readRuntimeVisibleParameterAnnotationsAttribute(
256 in, attributeNameIndex, attributeLength);
257 } else if (attributeName
258 .equals(ATT_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS)) {
259 attributeInfo = readRuntimeInvisibleParameterAnnotationsAttribute(
260 in, attributeNameIndex, attributeLength);
261 } else if (attributeName.equals(ATT_ANNOTATION_DEFAULT)) {
262 attributeInfo = readAnnotationDefaultAttribute(in,
263 attributeNameIndex, attributeLength);
264 } else {
265 reportWarning("Unknown attribute '%s'", attributeName,
266 className);
267 for (long j = 0; j < attributeLength; j++) {
268 in.readUnsignedByte();
269 }
270 }
271 if (attributeInfo != null) {
272 attributes.add(attributeInfo);
273 }
274 }
275 } catch (IOException e) {
276 reportError("Error reading attributes from file %s", className);
277 }
278 return attributes;
279 }
280
281
293
294 private CLConstantValueAttribute readConstantValueAttribute(
295 CLInputStream in, int attributeNameIndex, long attributeLength) {
296 CLConstantValueAttribute attribute = null;
297 try {
298 attribute = new CLConstantValueAttribute(attributeNameIndex,
299 attributeLength, in.readUnsignedShort());
300 } catch (IOException e) {
301 reportError("Error reading ConstantValue_attribute from file %s",
302 className);
303 }
304 return attribute;
305 }
306
307
318
319 private CLCodeAttribute readCodeAttribute(CLInputStream in,
320 int attributeNameIndex, long attributeLength) {
321 CLCodeAttribute attribute = null;
322 try {
323 int maxStack = in.readUnsignedShort();
324 int maxLocals = in.readUnsignedShort();
325 ArrayList<Integer> code = new ArrayList<Integer>();
326 long codeLength = in.readUnsignedInt();
327 for (long l = 0; l < codeLength; l++) {
328 code.add(in.readUnsignedByte());
329 }
330 int exceptionTableLength = in.readUnsignedShort();
331 ArrayList<CLExceptionInfo> exceptionTable = new ArrayList<CLExceptionInfo>();
332 for (int l = 0; l < exceptionTableLength; l++) {
333 int startPC = in.readUnsignedShort();
334 int endPC = in.readUnsignedShort();
335 int handlerPC = in.readUnsignedShort();
336 int catchType = in.readUnsignedShort();
337 exceptionTable.add(new CLExceptionInfo(startPC, endPC,
338 handlerPC, catchType));
339 }
340 int codeAttrAttributesCount = in.readUnsignedShort();
341 ArrayList<CLAttributeInfo> codeAttrAttributes = readAttributes(in,
342 codeAttrAttributesCount);
343 attribute = new CLCodeAttribute(attributeNameIndex,
344 attributeLength, maxStack, maxLocals, codeLength, code,
345 exceptionTableLength, exceptionTable,
346 codeAttrAttributesCount, codeAttrAttributes);
347 } catch (IOException e) {
348 reportError("Error reading Code_attribute from file %s", className);
349 }
350 return attribute;
351 }
352
353
365
366 private CLExceptionsAttribute readExceptionsAttribute(CLInputStream in,
367 int attributeNameIndex, long attributeLength) {
368 CLExceptionsAttribute attribute = null;
369 try {
370 int numberOfExceptions = in.readUnsignedShort();
371 ArrayList<Integer> exceptionIndexTable = new ArrayList<Integer>();
372 for (int l = 0; l < numberOfExceptions; l++) {
373 exceptionIndexTable.add(in.readUnsignedShort());
374 }
375 attribute = new CLExceptionsAttribute(attributeNameIndex,
376 attributeLength, numberOfExceptions, exceptionIndexTable);
377 } catch (IOException e) {
378 reportError("Error reading Exceptions_attribute from file %s",
379 className);
380 }
381 return attribute;
382 }
383
384
396
397 private CLInnerClassesAttribute readInnerClassesAttribute(CLInputStream in,
398 int attributeNameIndex, long attributeLength) {
399 CLInnerClassesAttribute attribute = null;
400 try {
401 int numberOfClasses = in.readUnsignedShort();
402 ArrayList<CLInnerClassInfo> classes = new ArrayList<CLInnerClassInfo>();
403 for (int m = 0; m < numberOfClasses; m++) {
404 classes.add(new CLInnerClassInfo(in.readUnsignedShort(), in
405 .readUnsignedShort(), in.readUnsignedShort(), in
406 .readUnsignedShort()));
407 }
408 attribute = new CLInnerClassesAttribute(attributeNameIndex,
409 attributeLength, numberOfClasses, classes);
410
411 } catch (IOException e) {
412 reportError("Error reading InnerClasses_attribute from file %s",
413 className);
414 }
415 return attribute;
416 }
417
418
430
431 private CLEnclosingMethodAttribute readEnclosingMethodAttribute(
432 CLInputStream in, int attributeNameIndex, long attributeLength) {
433 CLEnclosingMethodAttribute attribute = null;
434 try {
435 attribute = new CLEnclosingMethodAttribute(attributeNameIndex,
436 attributeLength, in.readUnsignedShort(), in
437 .readUnsignedShort());
438 } catch (IOException e) {
439 reportError("Error reading EnclosingMethod_attribute from file %s",
440 className);
441 }
442 return attribute;
443 }
444
445
457
458 private CLSyntheticAttribute readSyntheticAttribute(CLInputStream in,
459 int attributeNameIndex, long attributeLength) {
460 return new CLSyntheticAttribute(attributeNameIndex, attributeLength);
461 }
462
463
475
476 private CLSignatureAttribute readSignatureAttribute(CLInputStream in,
477 int attributeNameIndex, long attributeLength) {
478 CLSignatureAttribute attribute = null;
479 try {
480 attribute = new CLSignatureAttribute(attributeNameIndex,
481 attributeLength, in.readUnsignedShort());
482 } catch (IOException e) {
483 reportError("Error reading Signature_attribute from file %s",
484 className);
485 }
486 return attribute;
487 }
488
489
501
502 private CLSourceFileAttribute readSourceFileAttribute(CLInputStream in,
503 int attributeNameIndex, long attributeLength) {
504 CLSourceFileAttribute attribute = null;
505 try {
506 attribute = new CLSourceFileAttribute(attributeNameIndex,
507 attributeLength, in.readUnsignedShort());
508 } catch (IOException e) {
509 reportError("Error reading SourceFile_attribute from file %s",
510 className);
511 }
512 return attribute;
513 }
514
515
527
528 private CLSourceDebugExtensionAttribute readSourceDebugExtensionAttribute(
529 CLInputStream in, int attributeNameIndex, long attributeLength) {
530 CLSourceDebugExtensionAttribute attribute = null;
531 try {
532 byte[] b = new byte[(int) attributeLength];
533
534 in.read(b);
535 attribute = new CLSourceDebugExtensionAttribute(attributeNameIndex,
536 attributeLength, b);
537 } catch (IOException e) {
538 reportError("Error reading SourceDebugExtension_attribute "
539 + "from file %s", className);
540 }
541 return attribute;
542 }
543
544
556
557 private CLLineNumberTableAttribute readLineNumberTableAttribute(
558 CLInputStream in, int attributeNameIndex, long attributeLength) {
559 CLLineNumberTableAttribute attribute = null;
560 try {
561 int lineNumberTableLength = in.readUnsignedShort();
562 ArrayList<CLLineNumberInfo> lineNumberTable = new ArrayList<CLLineNumberInfo>();
563 for (int m = 0; m < lineNumberTableLength; m++) {
564 lineNumberTable.add(new CLLineNumberInfo(
565 in.readUnsignedShort(), in.readUnsignedShort()));
566 }
567 attribute = new CLLineNumberTableAttribute(attributeNameIndex,
568 attributeLength, lineNumberTableLength, lineNumberTable);
569 } catch (IOException e) {
570 reportError("Error reading LineNumberTable_attribute from file %s",
571 className);
572 }
573 return attribute;
574 }
575
576
588
589 private CLLocalVariableTableAttribute readLocalVariableTableAttribute(
590 CLInputStream in, int attributeNameIndex, long attributeLength) {
591 CLLocalVariableTableAttribute attribute = null;
592 try {
593 int localVariableTableLength = in.readUnsignedShort();
594 ArrayList<CLLocalVariableInfo> localVariableTable = new ArrayList<CLLocalVariableInfo>();
595 for (int m = 0; m < localVariableTableLength; m++) {
596 localVariableTable.add(new CLLocalVariableInfo(in
597 .readUnsignedShort(), in.readUnsignedShort(), in
598 .readUnsignedShort(), in.readUnsignedShort(), in
599 .readUnsignedShort()));
600 }
601 attribute = new CLLocalVariableTableAttribute(attributeNameIndex,
602 attributeLength, localVariableTableLength,
603 localVariableTable);
604 } catch (IOException e) {
605 reportError("Error reading LocalVariableTable_attribute "
606 + "from file %s", className);
607 }
608 return attribute;
609 }
610
611
623
624 private CLLocalVariableTypeTableAttribute readLocalVariableTypeTableAttribute(
625 CLInputStream in, int attributeNameIndex, long attributeLength) {
626 CLLocalVariableTypeTableAttribute attribute = null;
627 try {
628 int localVariableTypeTableLength = in.readUnsignedShort();
629 ArrayList<CLLocalVariableTypeInfo> localVariableTypeTable = new ArrayList<CLLocalVariableTypeInfo>();
630 for (int m = 0; m < localVariableTypeTableLength; m++) {
631 localVariableTypeTable.add(new CLLocalVariableTypeInfo(in
632 .readUnsignedShort(), in.readUnsignedShort(), in
633 .readUnsignedShort(), in.readUnsignedShort(), in
634 .readUnsignedShort()));
635 }
636 attribute = new CLLocalVariableTypeTableAttribute(
637 attributeNameIndex, attributeLength,
638 localVariableTypeTableLength, localVariableTypeTable);
639 } catch (IOException e) {
640 reportError("Error reading LocalVariableTypeTable_attribute"
641 + "file %s", className);
642 }
643 return attribute;
644 }
645
646
658
659 private CLDeprecatedAttribute readDeprecatedAttribute(CLInputStream in,
660 int attributeNameIndex, long attributeLength) {
661 return new CLDeprecatedAttribute(attributeNameIndex, attributeLength);
662 }
663
664
676
677 private CLRuntimeVisibleAnnotationsAttribute readRuntimeVisibleAnnotationsAttribute(
678 CLInputStream in, int attributeNameIndex, long attributeLength) {
679 CLRuntimeVisibleAnnotationsAttribute attribute = null;
680 try {
681 int numAnnotations = in.readUnsignedShort();
682 ArrayList<CLAnnotation> annotations = new ArrayList<CLAnnotation>();
683 for (int i = 0; i < numAnnotations; i++) {
684 CLAnnotation annotation = readAnnotation(in);
685 annotations.add(annotation);
686 }
687 attribute = new CLRuntimeVisibleAnnotationsAttribute(
688 attributeNameIndex, attributeLength, numAnnotations,
689 annotations);
690 } catch (IOException e) {
691 reportError("Error reading RuntimeVisibleAnnotations_attribute"
692 + "from file %s", className);
693 }
694 return attribute;
695 }
696
697
709
710 private CLRuntimeInvisibleAnnotationsAttribute readRuntimeInvisibleAnnotationsAttribute(
711 CLInputStream in, int attributeNameIndex, long attributeLength) {
712 CLRuntimeInvisibleAnnotationsAttribute attribute = null;
713 try {
714 int numAnnotations = in.readUnsignedShort();
715 ArrayList<CLAnnotation> annotations = new ArrayList<CLAnnotation>();
716 for (int i = 0; i < numAnnotations; i++) {
717 CLAnnotation annotation = readAnnotation(in);
718 annotations.add(annotation);
719 }
720 attribute = new CLRuntimeInvisibleAnnotationsAttribute(
721 attributeNameIndex, attributeLength, numAnnotations,
722 annotations);
723 } catch (IOException e) {
724 reportError("Error reading RuntimeInvisibleAnnotations_attribute"
725 + "from file %s", className);
726 }
727 return attribute;
728 }
729
730
742
743 private CLRuntimeVisibleParameterAnnotationsAttribute readRuntimeVisibleParameterAnnotationsAttribute(
744 CLInputStream in, int attributeNameIndex, long attributeLength) {
745 CLRuntimeVisibleParameterAnnotationsAttribute attribute = null;
746 try {
747 int numParameters = in.readUnsignedByte();
748 ArrayList<CLParameterAnnotationInfo> parameterAnnotations = new ArrayList<CLParameterAnnotationInfo>();
749 for (int i = 0; i < numParameters; i++) {
750 int numAnnotations = in.readUnsignedShort();
751 ArrayList<CLAnnotation> annotations = new ArrayList<CLAnnotation>();
752 for (int j = 0; j < numAnnotations; j++) {
753 CLAnnotation annotation = readAnnotation(in);
754 annotations.add(annotation);
755 }
756 parameterAnnotations.add(new CLParameterAnnotationInfo(
757 numAnnotations, annotations));
758 }
759 attribute = new CLRuntimeVisibleParameterAnnotationsAttribute(
760 attributeNameIndex, attributeLength, (short) numParameters,
761 parameterAnnotations);
762 } catch (IOException e) {
763 reportError("Error reading "
764 + "RuntimeVisibleParameterAnnotations_attribute"
765 + " from file %s", className);
766 }
767 return attribute;
768 }
769
770
782
783 private CLRuntimeInvisibleParameterAnnotationsAttribute readRuntimeInvisibleParameterAnnotationsAttribute(
784 CLInputStream in, int attributeNameIndex, long attributeLength) {
785 CLRuntimeInvisibleParameterAnnotationsAttribute attribute = null;
786 try {
787 int numParameters = in.readUnsignedByte();
788 ArrayList<CLParameterAnnotationInfo> parameterAnnotations = new ArrayList<CLParameterAnnotationInfo>();
789 for (int i = 0; i < numParameters; i++) {
790 int numAnnotations = in.readUnsignedShort();
791 ArrayList<CLAnnotation> annotations = new ArrayList<CLAnnotation>();
792 for (int j = 0; j < numAnnotations; j++) {
793 CLAnnotation annotation = readAnnotation(in);
794 annotations.add(annotation);
795 }
796 parameterAnnotations.add(new CLParameterAnnotationInfo(
797 numAnnotations, annotations));
798 }
799 attribute = new CLRuntimeInvisibleParameterAnnotationsAttribute(
800 attributeNameIndex, attributeLength, (short) numParameters,
801 parameterAnnotations);
802 } catch (IOException e) {
803 reportError("Error reading "
804 + "RuntimeInvisibleParameterAnnotations_attribute"
805 + " from file %s", className);
806 }
807 return attribute;
808 }
809
810
822
823 private CLAnnotationDefaultAttribute readAnnotationDefaultAttribute(
824 CLInputStream in, int attributeNameIndex, long attributeLength) {
825 return new CLAnnotationDefaultAttribute(attributeNameIndex,
826 attributeLength, readElementValue(in));
827 }
828
829
836
837 private CLElementValue readElementValue(CLInputStream in) {
838 CLElementValue elementValue = null;
839 try {
840 int tag = in.readUnsignedByte();
841 switch (tag) {
842 case ELT_B:
843 case ELT_C:
844 case ELT_D:
845 case ELT_F:
846 case ELT_I:
847 case ELT_J:
848 case ELT_S:
849 case ELT_Z:
850 case ELT_s:
851 elementValue = new CLElementValue((short) tag, in
852 .readUnsignedShort());
853 break;
854 case ELT_e:
855 elementValue = new CLElementValue(in.readUnsignedShort(), in
856 .readUnsignedShort());
857 break;
858 case ELT_c:
859 elementValue = new CLElementValue(in.readUnsignedShort());
860 break;
861 case ELT_ANNOTATION:
862 elementValue = new CLElementValue(readAnnotation(in));
863 break;
864 case ELT_ARRAY:
865 int numValues = in.readUnsignedShort();
866 ArrayList<CLElementValue> values = new ArrayList<CLElementValue>();
867 for (int i = 0; i < numValues; i++) {
868 values.add(readElementValue(in));
869 }
870 elementValue = new CLElementValue(numValues, values);
871 }
872 } catch (IOException e) {
873 reportError("Error reading AnnotationDefault_attribute "
874 + "from file %s", className);
875 }
876 return elementValue;
877 }
878
879
886
887 private CLAnnotation readAnnotation(CLInputStream in) {
888 CLAnnotation annotation = null;
889 try {
890 int typeIndex = in.readUnsignedShort();
891 int numElementValuePairs = in.readUnsignedShort();
892 ArrayList<CLElementValuePair> elementValuePairs = new ArrayList<CLElementValuePair>();
893 for (int i = 0; i < numElementValuePairs; i++) {
894 int elementNameIndex = in.readUnsignedShort();
895 CLElementValue value = readElementValue(in);
896 elementValuePairs.add(new CLElementValuePair(elementNameIndex,
897 value));
898 }
899 annotation = new CLAnnotation(typeIndex, numElementValuePairs,
900 elementValuePairs);
901 } catch (IOException e) {
902 reportError("Error reading Annotation from file %s", className);
903 }
904 return annotation;
905 }
906
907
914
915 public CLAbsorber(String className) {
916 try {
917 this.className = className;
918 CLPath classPath = new CLPath();
919 CLInputStream in = classPath.loadClass(className);
920 errorHasOccurred = false;
921 if (in == null) {
922 reportError("Error loading %s", className);
923 return;
924 }
925 classFile = new CLFile();
926
927 long magic = in.readUnsignedInt();
929 if (magic != MAGIC) {
930 reportWarning("%s has an invalid magic number", className);
931 return;
932 }
933 classFile.magic = magic;
934
935 classFile.minorVersion = in.readUnsignedShort();
937 classFile.majorVersion = in.readUnsignedShort();
938
939 classFile.constantPoolCount = in.readUnsignedShort();
941 classFile.constantPool = readConstantPool(in);
942 if (errorHasOccurred()) {
943 return;
944 }
945
946 classFile.accessFlags = in.readUnsignedShort();
948
949 classFile.thisClass = in.readUnsignedShort();
951
952 classFile.superClass = in.readUnsignedShort();
954
955 int interfacesCount = in.readUnsignedShort();
959 ArrayList<Integer> interfaces = new ArrayList<Integer>();
960 classFile.interfacesCount = interfacesCount;
961 for (int i = 0; i < interfacesCount; i++) {
962 interfaces.add(in.readUnsignedShort());
963 }
964 classFile.interfaces = interfaces;
965
966 classFile.fieldsCount = in.readUnsignedShort();
968 classFile.fields = readFields(in, classFile.fieldsCount);
969 if (errorHasOccurred()) {
970 return;
971 }
972
973 classFile.methodsCount = in.readUnsignedShort();
975 classFile.methods = readMethods(in, classFile.methodsCount);
976 if (errorHasOccurred()) {
977 return;
978 }
979
980 classFile.attributesCount = in.readUnsignedShort();
982 classFile.attributes = readAttributes(in, classFile.attributesCount);
983 } catch (EOFException e) {
984 reportError("Unexpected end of file %s", className);
985 } catch (IOException e) {
986 reportError("Error reading file %s", className);
987 }
988 }
989
990
995
996 public CLFile classFile() {
997 return classFile;
998 }
999
1000
1006
1007 public boolean errorHasOccurred() {
1008 return errorHasOccurred;
1009 }
1010
1011
1017
1018 public static void main(String[] args) {
1019 String classFile = "";
1020 if (args.length == 1) {
1021 classFile = args[0];
1022 } else {
1023 String usage = "Usage: java jminusminus.CLAbsorber <class name>\n"
1024 + "Where the class name must be fully qualified; "
1025 + "eg, java/util/ArrayList";
1026 System.out.println(usage);
1027 System.exit(0);
1028 }
1029 CLAbsorber r = new CLAbsorber(classFile);
1030 if (!r.errorHasOccurred()) {
1031 CLFile c = r.classFile();
1032 c.writeToStdOut();
1033 }
1034 }
1035
1036}
1037
1038
1043
1044class CLInputStream extends DataInputStream {
1045
1046
1052
1053 public CLInputStream(InputStream in) {
1054 super(in);
1055 }
1056
1057
1075
1076 public final long readUnsignedInt() throws IOException {
1077 byte[] b = new byte[4];
1078 long mask = 0xFF, l;
1079 in.read(b);
1080 l = ((b[0] & mask) << 24) | ((b[1] & mask) << 16)
1081 | ((b[2] & mask) << 8) | (b[3] & mask);
1082 return l;
1083 }
1084
1085}
1086