📄 classparser.java
字号:
null, "I", // 3: CONSTANT_Integer "F", // 4: CONSTANT_Float "L", // 5: CONSTANT_Long "D", // 6: CONSTANT_Double "i", // 7: CONSTANT_Class "i", // 8: CONSTANT_String "ii", // 9: CONSTANT_Fieldref "ii", // 10: CONSTANT_Methodref "ii", // 11: CONSTANT_InterfaceMethodref "ii", // 12: CONSTANT_NameAndType }; /** * Read a constant from the constant pool. * * @return a Constant * @throws InvalidClassFileFormatException * @throws IOException */ private Constant readConstant() throws InvalidClassFileFormatException, IOException { int tag = in.readUnsignedByte(); if (tag < 0 || tag >= CONSTANT_FORMAT_MAP.length || CONSTANT_FORMAT_MAP[tag] == null) { throw new InvalidClassFileFormatException(expectedClassDescriptor, codeBaseEntry); } String format = CONSTANT_FORMAT_MAP[tag]; Object[] data = new Object[format.length()]; for (int i = 0; i < format.length(); i++) { char spec = format.charAt(i); switch (spec) { case '8': data[i] = in.readUTF(); break; case 'I': data[i] = (Integer)in.readInt(); break; case 'F': data[i] = new Float(in.readFloat()); break; case 'L': data[i] = (Long)in.readLong(); break; case 'D': data[i] = new Double(in.readDouble()); break; case 'i': data[i] = (Integer)in.readUnsignedShort(); break; default: throw new IllegalStateException(); } } return new Constant(tag, data); } /** * Get a class name from a CONSTANT_Class. * Note that this may be an array (e.g., "[Ljava/lang/String;"). * * @param index index of the constant * @return the class name * @throws InvalidClassFileFormatException */ private String getClassName(int index) throws InvalidClassFileFormatException { if (index == 0) { return null; } checkConstantPoolIndex(index); Constant constant = constantPool[index]; checkConstantTag(constant, IClassConstants.CONSTANT_Class); int refIndex = ((Integer)constant.data[0]).intValue(); String stringValue = getUtf8String(refIndex); return stringValue; } /** * Get the ClassDescriptor of a class referenced in the constant pool. * * @param index index of the referenced class in the constant pool * @return the ClassDescriptor of the referenced calss * @throws InvalidClassFileFormatException */ private ClassDescriptor getClassDescriptor(int index) throws InvalidClassFileFormatException { String className = getClassName(index); return className != null ? new ClassDescriptor(className) : null; } /** * Get the UTF-8 string constant at given constant pool index. * * @param refIndex the constant pool index * @return the String at that index * @throws InvalidClassFileFormatException */ private String getUtf8String(int refIndex) throws InvalidClassFileFormatException { checkConstantPoolIndex(refIndex); Constant refConstant = constantPool[refIndex]; checkConstantTag(refConstant, IClassConstants.CONSTANT_Utf8); return (String) refConstant.data[0]; } /** * Check that a constant pool index is valid. * * @param expectedClassDescriptor class descriptor * @param constantPool the constant pool * @param index the index to check * @throws InvalidClassFileFormatException if the index is not valid */ private void checkConstantPoolIndex(int index) throws InvalidClassFileFormatException { if (index < 0 || index >= constantPool.length || constantPool[index] == null) { throw new InvalidClassFileFormatException(expectedClassDescriptor, codeBaseEntry); } } /** * Check that a constant has the expected tag. * * @param constant the constant to check * @param expectedTag the expected constant tag * @throws InvalidClassFileFormatException if the constant's tag does not match the expected tag */ private void checkConstantTag(Constant constant, int expectedTag) throws InvalidClassFileFormatException { if (constant.tag != expectedTag) { throw new InvalidClassFileFormatException(expectedClassDescriptor, codeBaseEntry); } } interface FieldOrMethodDescriptorCreator<E> { public E create(String className, String name, String signature, int accessFlags); } /** * Read field_info, return FieldDescriptor. * * @param thisClassDescriptor the ClassDescriptor of this class (being parsed) * @return the FieldDescriptor * @throws IOException * @throws InvalidClassFileFormatException */ private FieldDescriptor readField(ClassDescriptor thisClassDescriptor) throws IOException, InvalidClassFileFormatException { return readFieldOrMethod(thisClassDescriptor, new FieldOrMethodDescriptorCreator<FieldDescriptor>() { /* (non-Javadoc) * @see edu.umd.cs.findbugs.classfile.engine.ClassParser.FieldOrMethodDescriptorCreator#create(java.lang.String, java.lang.String, java.lang.String, int) */ public FieldDescriptor create(String className, String name, String signature, int accessFlags) { return new FieldDescriptor(className, name, signature, (accessFlags & IClassConstants.ACC_STATIC) != 0); } }); } /** * Read method_info, read method descriptor. * * @param thisClassDescriptor * @return * @throws IOException * @throws InvalidClassFileFormatException */ private MethodDescriptor readMethod(ClassDescriptor thisClassDescriptor) throws InvalidClassFileFormatException, IOException { return readFieldOrMethod(thisClassDescriptor, new FieldOrMethodDescriptorCreator<MethodDescriptor>(){ /* (non-Javadoc) * @see edu.umd.cs.findbugs.classfile.engine.ClassParser.FieldOrMethodDescriptorCreator#create(java.lang.String, java.lang.String, java.lang.String, int) */ public MethodDescriptor create(String className, String name, String signature, int accessFlags) { return new MethodDescriptor(className, name, signature, (accessFlags & IClassConstants.ACC_STATIC) != 0); } }); } /** * Read field_info or method_info. * They have the same format. * * @param <E> descriptor type to return * @param thisClassDescriptor class descriptor of class being parsed * @param creator callback to create the FieldDescriptor or MethodDescriptor * @return the parsed descriptor * @throws IOException * @throws InvalidClassFileFormatException */ private<E> E readFieldOrMethod( ClassDescriptor thisClassDescriptor, FieldOrMethodDescriptorCreator<E> creator) throws IOException, InvalidClassFileFormatException { int access_flags = in.readUnsignedShort(); int name_index = in.readUnsignedShort(); int descriptor_index = in.readUnsignedShort(); int attributes_count = in.readUnsignedShort(); String name = getUtf8String(name_index); String signature = getUtf8String(descriptor_index); if (attributes_count < 0) { throw new InvalidClassFileFormatException(expectedClassDescriptor, codeBaseEntry); } for (int i = 0; i < attributes_count; i++) { readAttribute(); } return creator.create( thisClassDescriptor.getClassName(), name, signature, access_flags); } /** * Read an attribute. * * @throws IOException * @throws InvalidClassFileFormatException */ private void readAttribute() throws IOException, InvalidClassFileFormatException { int attribute_name_index = in.readUnsignedShort(); int attribute_length = in.readInt(); if (attribute_length < 0) { throw new InvalidClassFileFormatException(expectedClassDescriptor, codeBaseEntry); } byte[] buf = new byte[attribute_length]; in.readFully(buf); } /** * Get the signature from a CONSTANT_NameAndType. * * @param index the index of the CONSTANT_NameAndType * @return the signature * @throws InvalidClassFileFormatException */ private String getSignatureFromNameAndType(int index) throws InvalidClassFileFormatException { checkConstantPoolIndex(index); Constant constant = constantPool[index]; checkConstantTag(constant, IClassConstants.CONSTANT_NameAndType); return getUtf8String((Integer) constant.data[1]); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -