📄 classutil.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.util;import proguard.classfile.*;import java.util.*;/** * Utility methods for converting between internal and external representations * of names and descriptions. * * @author Eric Lafortune */public class ClassUtil{ private static final String EMPTY_STRING = ""; private static final InternalTypeEnumeration internalTypeEnumeration = new InternalTypeEnumeration(); private static final ExternalTypeEnumeration externalTypeEnumeration = new ExternalTypeEnumeration(); /** * Checks whether the given class magic number is correct. * @param magicNumber the magic number. * @throws UnsupportedOperationException when the magic number is incorrect. */ public static void checkMagicNumber(int magicNumber) throws UnsupportedOperationException { if (magicNumber != ClassConstants.MAGIC) { throw new UnsupportedOperationException("Invalid magic number ["+Integer.toHexString(magicNumber)+"] in class"); } } /** * Returns the combined class version number. * @param majorVersion the major part of the class version number. * @param minorVersion the minor part of the class version number. * @return the combined class version number. */ public static int internalClassVersion(int majorVersion, int minorVersion) { return (majorVersion << 16) | minorVersion; } /** * Returns the major part of the given class version number. * @param classVersion the combined class version number. * @return the major part of the class version number. */ public static int internalMajorClassVersion(int classVersion) { return classVersion >>> 16; } /** * Returns the internal class version number. * @param classVersion the external class version number. * @return the internal class version number. */ public static int internalMinorClassVersion(int classVersion) { return classVersion & 0xffff; } /** * Returns the internal class version number. * @param classVersion the external class version number. * @return the internal class version number. */ public static int internalClassVersion(String classVersion) { return classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_0) || classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_1) ? ClassConstants.INTERNAL_CLASS_VERSION_1_0 : classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_2) ? ClassConstants.INTERNAL_CLASS_VERSION_1_2 : classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_3) ? ClassConstants.INTERNAL_CLASS_VERSION_1_3 : classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_4) ? ClassConstants.INTERNAL_CLASS_VERSION_1_4 : classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_5_ALIAS) || classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_5) ? ClassConstants.INTERNAL_CLASS_VERSION_1_5 : classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_6_ALIAS) || classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_6) ? ClassConstants.INTERNAL_CLASS_VERSION_1_6 : 0; } /** * Returns the minor part of the given class version number. * @param classVersion the combined class version number. * @return the minor part of the class version number. */ public static String externalClassVersion(int classVersion) { switch (classVersion) { case ClassConstants.INTERNAL_CLASS_VERSION_1_0: return ClassConstants.EXTERNAL_CLASS_VERSION_1_0; case ClassConstants.INTERNAL_CLASS_VERSION_1_2: return ClassConstants.EXTERNAL_CLASS_VERSION_1_2; case ClassConstants.INTERNAL_CLASS_VERSION_1_3: return ClassConstants.EXTERNAL_CLASS_VERSION_1_3; case ClassConstants.INTERNAL_CLASS_VERSION_1_4: return ClassConstants.EXTERNAL_CLASS_VERSION_1_4; case ClassConstants.INTERNAL_CLASS_VERSION_1_5: return ClassConstants.EXTERNAL_CLASS_VERSION_1_5; case ClassConstants.INTERNAL_CLASS_VERSION_1_6: return ClassConstants.EXTERNAL_CLASS_VERSION_1_6; default: return null; } } /** * Checks whether the given class version number is supported. * @param classVersion the combined class version number. * @throws UnsupportedOperationException when the version is not supported. */ public static void checkVersionNumbers(int classVersion) throws UnsupportedOperationException { if (classVersion < ClassConstants.INTERNAL_CLASS_VERSION_1_0 || classVersion > ClassConstants.INTERNAL_CLASS_VERSION_1_6) { throw new UnsupportedOperationException("Unsupported version number ["+ internalMajorClassVersion(classVersion)+"."+ internalMinorClassVersion(classVersion)+"] for class format"); } } /** * Converts an external class name into an internal class name. * @param externalClassName the external class name, * e.g. "<code>java.lang.Object</code>" * @return the internal class name, * e.g. "<code>java/lang/Object</code>". */ public static String internalClassName(String externalClassName) { return externalClassName.replace(ClassConstants.EXTERNAL_PACKAGE_SEPARATOR, ClassConstants.INTERNAL_PACKAGE_SEPARATOR); } /** * Converts an internal class description into an external class description. * @param accessFlags the access flags of the class. * @param internalClassName the internal class name, * e.g. "<code>java/lang/Object</code>". * @return the external class description, * e.g. "<code>public java.lang.Object</code>". */ public static String externalFullClassDescription(int accessFlags, String internalClassName) { return externalClassAccessFlags(accessFlags) + externalClassName(internalClassName); } /** * Converts an internal class name into an external class name. * @param internalClassName the internal class name, * e.g. "<code>java/lang/Object</code>". * @return the external class name, * e.g. "<code>java.lang.Object</code>". */ public static String externalClassName(String internalClassName) { return //internalClassName.startsWith(ClassConstants.INTERNAL_PACKAGE_JAVA_LANG) && //internalClassName.indexOf(ClassConstants.INTERNAL_PACKAGE_SEPARATOR, ClassConstants.INTERNAL_PACKAGE_JAVA_LANG.length() + 1) < 0 ? //internalClassName.substring(ClassConstants.INTERNAL_PACKAGE_JAVA_LANG.length()) : internalClassName.replace(ClassConstants.INTERNAL_PACKAGE_SEPARATOR, ClassConstants.EXTERNAL_PACKAGE_SEPARATOR); } /** * Converts an internal class name into an external short class name, without * package specification. * @param externalClassName the external class name, * e.g. "<code>java.lang.Object</code>" * @return the external short class name, * e.g. "<code>Object</code>". */ public static String externalShortClassName(String externalClassName) { int index = externalClassName.lastIndexOf(ClassConstants.EXTERNAL_PACKAGE_SEPARATOR); return externalClassName.substring(index+1); } /** * Returns whether the given internal type is an array type. * @param internalType the internal type, * e.g. "<code>[[Ljava/lang/Object;</code>". * @return <code>true</code> if the given type is an array type, * <code>false</code> otherwise. */ public static boolean isInternalArrayType(String internalType) { return internalType.length() > 1 && internalType.charAt(0) == ClassConstants.INTERNAL_TYPE_ARRAY; } /** * Returns the number of dimensions of the given internal type. * @param internalType the internal type, * e.g. "<code>[[Ljava/lang/Object;</code>". * @return the number of dimensions, e.g. 2. */ public static int internalArrayTypeDimensionCount(String internalType) { int dimensions = 0; while (internalType.charAt(dimensions) == ClassConstants.INTERNAL_TYPE_ARRAY) { dimensions++; } return dimensions; } /** * Returns whether the given internal class name is one of the interfaces * that is implemented by all array types. These class names are * "<code>java/lang/Object</code>", "<code>java/lang/Cloneable</code>", and * "<code>java/io/Serializable</code>" * @param internalClassName the internal class name, * e.g. "<code>java/lang/Object</code>". * @return <code>true</code> if the given type is an array interface name, * <code>false</code> otherwise. */ public static boolean isInternalArrayInterfaceName(String internalClassName) { return ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT.equals(internalClassName) || ClassConstants.INTERNAL_NAME_JAVA_LANG_CLONEABLE.equals(internalClassName) || ClassConstants.INTERNAL_NAME_JAVA_IO_SERIALIZABLE.equals(internalClassName); } /** * Returns whether the given internal type is a plain primitive type * (not void). * @param internalType the internal type, * e.g. "<code>I</code>". * @return <code>true</code> if the given type is a class type, * <code>false</code> otherwise. */ public static boolean isInternalPrimitiveType(char internalType) { return internalType == ClassConstants.INTERNAL_TYPE_BOOLEAN || internalType == ClassConstants.INTERNAL_TYPE_BYTE || internalType == ClassConstants.INTERNAL_TYPE_CHAR || internalType == ClassConstants.INTERNAL_TYPE_SHORT || internalType == ClassConstants.INTERNAL_TYPE_INT || internalType == ClassConstants.INTERNAL_TYPE_FLOAT || internalType == ClassConstants.INTERNAL_TYPE_LONG || internalType == ClassConstants.INTERNAL_TYPE_DOUBLE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -