📄 programclasswriter.java
字号:
/* * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package proguard.classfile.io;import proguard.classfile.*;import proguard.classfile.attribute.*;import proguard.classfile.attribute.annotation.*;import proguard.classfile.attribute.annotation.visitor.*;import proguard.classfile.attribute.preverification.*;import proguard.classfile.attribute.preverification.visitor.*;import proguard.classfile.attribute.visitor.*;import proguard.classfile.constant.*;import proguard.classfile.constant.visitor.ConstantVisitor;import proguard.classfile.util.*;import proguard.classfile.visitor.*;import java.io.*;/** * This ClassVisitor writes out the ProgramClass objects that it visits to the * given DataOutput object. * * @author Eric Lafortune */public class ProgramClassWriterextends SimplifiedVisitorimplements ClassVisitor, MemberVisitor, ConstantVisitor, AttributeVisitor{ private RuntimeDataOutput dataOutput; private ConstantBodyWriter constantBodyWriter = new ConstantBodyWriter(); private AttributeBodyWriter attributeBodyWriter = new AttributeBodyWriter(); private StackMapFrameBodyWriter stackMapFrameBodyWriter = new StackMapFrameBodyWriter(); private VerificationTypeBodyWriter verificationTypeBodyWriter = new VerificationTypeBodyWriter(); private ElementValueBodyWriter elementValueBodyWriter = new ElementValueBodyWriter(); /** * Creates a new ProgramClassWriter for reading from the given DataOutput. */ public ProgramClassWriter(DataOutput dataOutput) { this.dataOutput = new RuntimeDataOutput(dataOutput); } // Implementations for ClassVisitor. public void visitProgramClass(ProgramClass programClass) { // Write the magic number. dataOutput.writeInt(programClass.u4magic); // Write the version numbers. dataOutput.writeShort(ClassUtil.internalMinorClassVersion(programClass.u4version)); dataOutput.writeShort(ClassUtil.internalMajorClassVersion(programClass.u4version)); // Write the constant pool. dataOutput.writeShort(programClass.u2constantPoolCount); programClass.constantPoolEntriesAccept(this); // Write the general class information. dataOutput.writeShort(programClass.u2accessFlags); dataOutput.writeShort(programClass.u2thisClass); dataOutput.writeShort(programClass.u2superClass); // Write the interfaces. dataOutput.writeShort(programClass.u2interfacesCount); for (int index = 0; index < programClass.u2interfacesCount; index++) { dataOutput.writeShort(programClass.u2interfaces[index]); } // Write the fields. dataOutput.writeShort(programClass.u2fieldsCount); programClass.fieldsAccept(this); // Write the methods. dataOutput.writeShort(programClass.u2methodsCount); programClass.methodsAccept(this); // Write the class attributes. dataOutput.writeShort(programClass.u2attributesCount); programClass.attributesAccept(this); } public void visitLibraryClass(LibraryClass libraryClass) { } // Implementations for MemberVisitor. public void visitProgramField(ProgramClass programClass, ProgramField programField) { // Write the general field information. dataOutput.writeShort(programField.u2accessFlags); dataOutput.writeShort(programField.u2nameIndex); dataOutput.writeShort(programField.u2descriptorIndex); // Write the field attributes. dataOutput.writeShort(programField.u2attributesCount); programField.attributesAccept(programClass, this); } public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) { // Write the general method information. dataOutput.writeShort(programMethod.u2accessFlags); dataOutput.writeShort(programMethod.u2nameIndex); dataOutput.writeShort(programMethod.u2descriptorIndex); // Write the method attributes. dataOutput.writeShort(programMethod.u2attributesCount); programMethod.attributesAccept(programClass, this); } public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember) { } // Implementations for ConstantVisitor. public void visitAnyConstant(Clazz clazz, Constant constant) { // Write the tag. dataOutput.writeByte(constant.getTag()); // Write the actual body. constant.accept(clazz, constantBodyWriter); } private class ConstantBodyWriter extends SimplifiedVisitor implements ConstantVisitor { // Implementations for ConstantVisitor. public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant) { dataOutput.writeInt(integerConstant.u4value); } public void visitLongConstant(Clazz clazz, LongConstant longConstant) { dataOutput.writeLong(longConstant.u8value); } public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant) { dataOutput.writeFloat(floatConstant.f4value); } public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) { dataOutput.writeDouble(doubleConstant.f8value); } public void visitStringConstant(Clazz clazz, StringConstant stringConstant) { dataOutput.writeShort(stringConstant.u2stringIndex); } public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) { byte[] bytes = utf8Constant.getBytes(); dataOutput.writeShort(bytes.length); dataOutput.write(bytes); } public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant) { dataOutput.writeShort(refConstant.u2classIndex); dataOutput.writeShort(refConstant.u2nameAndTypeIndex); } public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { dataOutput.writeShort(classConstant.u2nameIndex); } public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) { dataOutput.writeShort(nameAndTypeConstant.u2nameIndex); dataOutput.writeShort(nameAndTypeConstant.u2descriptorIndex); } } // Implementations for AttributeVisitor. public void visitAnyAttribute(Clazz clazz, Attribute attribute) { // Write the attribute name index. dataOutput.writeShort(attribute.u2attributeNameIndex); // We'll write the attribute body into an array first, so we can // automatically figure out its length. ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // Temporarily replace the current data output. RuntimeDataOutput oldDataOutput = dataOutput; dataOutput = new RuntimeDataOutput(new DataOutputStream(byteArrayOutputStream)); // Write the attribute body into the array. Note that the // accept method with two dummy null arguments never throws // an UnsupportedOperationException. attribute.accept(clazz, null, null, attributeBodyWriter); // Restore the original data output. dataOutput = oldDataOutput; // Write the attribute length and body. byte[] info = byteArrayOutputStream.toByteArray(); dataOutput.writeInt(info.length); dataOutput.write(info); } private class AttributeBodyWriter extends SimplifiedVisitor implements AttributeVisitor, InnerClassesInfoVisitor, ExceptionInfoVisitor, StackMapFrameVisitor, VerificationTypeVisitor, LineNumberInfoVisitor, LocalVariableInfoVisitor, LocalVariableTypeInfoVisitor, AnnotationVisitor, ElementValueVisitor { // Implementations for AttributeVisitor. public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute) { // Write the unknown information. byte[] info = new byte[unknownAttribute.u4attributeLength]; dataOutput.write(info); unknownAttribute.info = info; } public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute) { dataOutput.writeShort(sourceFileAttribute.u2sourceFileIndex); } public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute) { dataOutput.writeShort(sourceDirAttribute.u2sourceDirIndex); } public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute) { // Write the inner classes. dataOutput.writeShort(innerClassesAttribute.u2classesCount); innerClassesAttribute.innerClassEntriesAccept(clazz, this); } public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute) { dataOutput.writeShort(enclosingMethodAttribute.u2classIndex); dataOutput.writeShort(enclosingMethodAttribute.u2nameAndTypeIndex); } public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute) { // This attribute does not contain any additional information. } public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute) { // This attribute does not contain any additional information. } public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute) { dataOutput.writeShort(signatureAttribute.u2signatureIndex); } public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute) { dataOutput.writeShort(constantValueAttribute.u2constantValueIndex); } public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute) { // Write the exceptions. dataOutput.writeShort(exceptionsAttribute.u2exceptionIndexTableLength); for (int index = 0; index < exceptionsAttribute.u2exceptionIndexTableLength; index++) { dataOutput.writeShort(exceptionsAttribute.u2exceptionIndexTable[index]); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -