2022-03-07 09:34:54 +00:00
|
|
|
package lombok.bytecode;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.List;
|
2022-03-17 08:17:49 +00:00
|
|
|
/* loaded from: com.discord-119106.apk:lombok/bytecode/ClassFileMetaData.SCL.lombok */
|
2022-03-07 09:34:54 +00:00
|
|
|
public class ClassFileMetaData {
|
|
|
|
private static final byte UTF8 = 1;
|
|
|
|
private static final byte INTEGER = 3;
|
|
|
|
private static final byte FLOAT = 4;
|
|
|
|
private static final byte LONG = 5;
|
|
|
|
private static final byte DOUBLE = 6;
|
|
|
|
private static final byte CLASS = 7;
|
|
|
|
private static final byte STRING = 8;
|
|
|
|
private static final byte FIELD = 9;
|
|
|
|
private static final byte METHOD = 10;
|
|
|
|
private static final byte INTERFACE_METHOD = 11;
|
|
|
|
private static final byte NAME_TYPE = 12;
|
|
|
|
private static final byte METHOD_HANDLE = 15;
|
|
|
|
private static final byte METHOD_TYPE = 16;
|
|
|
|
private static final byte DYNAMIC = 17;
|
|
|
|
private static final byte INVOKE_DYNAMIC = 18;
|
|
|
|
private static final byte MODULE = 19;
|
|
|
|
private static final byte PACKAGE = 20;
|
|
|
|
private static final int NOT_FOUND = -1;
|
|
|
|
private static final int START_OF_CONSTANT_POOL = 8;
|
|
|
|
private final byte[] byteCode;
|
|
|
|
private final int maxPoolSize = readValue(8);
|
|
|
|
private final int[] offsets = new int[this.maxPoolSize];
|
|
|
|
private final byte[] types = new byte[this.maxPoolSize];
|
|
|
|
private final String[] utf8s = new String[this.maxPoolSize];
|
|
|
|
private final int endOfPool;
|
|
|
|
|
|
|
|
public ClassFileMetaData(byte[] bArr) {
|
|
|
|
this.byteCode = bArr;
|
|
|
|
int i = 10;
|
|
|
|
int i2 = 1;
|
|
|
|
while (i2 < this.maxPoolSize) {
|
|
|
|
byte b2 = bArr[i];
|
|
|
|
this.types[i2] = b2;
|
|
|
|
i++;
|
|
|
|
this.offsets[i2] = i;
|
|
|
|
switch (b2) {
|
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
int readValue = readValue(i);
|
|
|
|
int i3 = i + 2;
|
|
|
|
this.utf8s[i2] = decodeString(i3, readValue);
|
|
|
|
i = i3 + readValue;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
case 13:
|
|
|
|
case 14:
|
|
|
|
default:
|
|
|
|
throw new AssertionError("Unknown constant pool type " + ((int) b2));
|
|
|
|
case 3:
|
|
|
|
case 4:
|
|
|
|
case 9:
|
|
|
|
case 10:
|
|
|
|
case 11:
|
|
|
|
case 12:
|
|
|
|
case 17:
|
|
|
|
case 18:
|
|
|
|
i += 4;
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
case 6:
|
|
|
|
i += 8;
|
|
|
|
i2++;
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
case 8:
|
|
|
|
case 16:
|
|
|
|
case 19:
|
|
|
|
case 20:
|
|
|
|
i += 2;
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
i += 3;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
i2++;
|
|
|
|
}
|
|
|
|
this.endOfPool = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
private String decodeString(int i, int i2) {
|
|
|
|
int i3 = i + i2;
|
|
|
|
char[] cArr = new char[i2];
|
|
|
|
int i4 = 0;
|
|
|
|
while (i < i3) {
|
|
|
|
i++;
|
|
|
|
int i5 = this.byteCode[i] & 255;
|
|
|
|
if (i5 < 128) {
|
|
|
|
i4++;
|
|
|
|
cArr[i4] = (char) i5;
|
|
|
|
} else if ((i5 & 224) == 192) {
|
|
|
|
i++;
|
|
|
|
i4++;
|
|
|
|
cArr[i4] = (char) (((i5 & 31) << 6) | (this.byteCode[i] & 63));
|
|
|
|
} else {
|
|
|
|
int i6 = (i5 & 15) << 12;
|
|
|
|
int i7 = i + 1;
|
|
|
|
int i8 = (this.byteCode[i] & 63) << 6;
|
|
|
|
i = i7 + 1;
|
|
|
|
i4++;
|
|
|
|
cArr[i4] = (char) (i6 | i8 | (this.byteCode[i7] & 63));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return new String(cArr, 0, i4);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean containsUtf8(String str) {
|
|
|
|
return findUtf8(str) != -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean usesClass(String str) {
|
|
|
|
return findClass(str) != -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean usesField(String str, String str2) {
|
|
|
|
int findUtf8;
|
|
|
|
int findClass = findClass(str);
|
|
|
|
if (findClass == -1 || (findUtf8 = findUtf8(str2)) == -1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
for (int i = 1; i < this.maxPoolSize; i++) {
|
|
|
|
if (this.types[i] == 9 && readValue(this.offsets[i]) == findClass) {
|
|
|
|
if (readValue(this.offsets[readValue(this.offsets[i] + 2)]) == findUtf8) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean usesMethod(String str, String str2) {
|
|
|
|
int findUtf8;
|
|
|
|
int findClass = findClass(str);
|
|
|
|
if (findClass == -1 || (findUtf8 = findUtf8(str2)) == -1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
for (int i = 1; i < this.maxPoolSize; i++) {
|
|
|
|
if (isMethod(i) && readValue(this.offsets[i]) == findClass) {
|
|
|
|
if (readValue(this.offsets[readValue(this.offsets[i] + 2)]) == findUtf8) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean usesMethod(String str, String str2, String str3) {
|
|
|
|
int findNameAndType;
|
|
|
|
int findClass = findClass(str);
|
|
|
|
if (findClass == -1 || (findNameAndType = findNameAndType(str2, str3)) == -1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
for (int i = 1; i < this.maxPoolSize; i++) {
|
|
|
|
if (isMethod(i) && readValue(this.offsets[i]) == findClass && readValue(this.offsets[i] + 2) == findNameAndType) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean containsStringConstant(String str) {
|
|
|
|
int findUtf8 = findUtf8(str);
|
|
|
|
if (findUtf8 == -1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
for (int i = 1; i < this.maxPoolSize; i++) {
|
|
|
|
if (this.types[i] == 8 && readValue(this.offsets[i]) == findUtf8) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean containsLong(long j) {
|
|
|
|
for (int i = 1; i < this.maxPoolSize; i++) {
|
|
|
|
if (this.types[i] == 5 && readLong(i) == j) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean containsDouble(double d) {
|
|
|
|
boolean isNaN = Double.isNaN(d);
|
|
|
|
for (int i = 1; i < this.maxPoolSize; i++) {
|
|
|
|
if (this.types[i] == 6) {
|
|
|
|
double readDouble = readDouble(i);
|
|
|
|
if (readDouble == d) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (isNaN && Double.isNaN(readDouble)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean containsInteger(int i) {
|
|
|
|
for (int i2 = 1; i2 < this.maxPoolSize; i2++) {
|
|
|
|
if (this.types[i2] == 3 && readInteger(i2) == i) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean containsFloat(float f) {
|
|
|
|
boolean isNaN = Float.isNaN(f);
|
|
|
|
for (int i = 1; i < this.maxPoolSize; i++) {
|
|
|
|
if (this.types[i] == 4) {
|
|
|
|
float readFloat = readFloat(i);
|
|
|
|
if (readFloat == f) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (isNaN && Float.isNaN(readFloat)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
private long readLong(int i) {
|
|
|
|
int i2 = this.offsets[i];
|
|
|
|
return (read32(i2) << 32) | (read32(i2 + 4) & 4294967295L);
|
|
|
|
}
|
|
|
|
|
|
|
|
private double readDouble(int i) {
|
|
|
|
return Double.longBitsToDouble(readLong(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
private int readInteger(int i) {
|
|
|
|
return read32(this.offsets[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
private float readFloat(int i) {
|
|
|
|
return Float.intBitsToFloat(readInteger(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
private int read32(int i) {
|
|
|
|
return ((this.byteCode[i] & 255) << 24) | ((this.byteCode[i + 1] & 255) << 16) | ((this.byteCode[i + 2] & 255) << 8) | (this.byteCode[i + 3] & 255);
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getClassName() {
|
|
|
|
return getClassName(readValue(this.endOfPool + 2));
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getSuperClassName() {
|
|
|
|
return getClassName(readValue(this.endOfPool + 4));
|
|
|
|
}
|
|
|
|
|
|
|
|
public List<String> getInterfaces() {
|
|
|
|
int readValue = readValue(this.endOfPool + 6);
|
|
|
|
if (readValue == 0) {
|
|
|
|
return Collections.emptyList();
|
|
|
|
}
|
|
|
|
ArrayList arrayList = new ArrayList();
|
|
|
|
for (int i = 0; i < readValue; i++) {
|
|
|
|
arrayList.add(getClassName(readValue(this.endOfPool + 8 + (i * 2))));
|
|
|
|
}
|
|
|
|
return arrayList;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String poolContent() {
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
for (int i = 1; i < this.maxPoolSize; i++) {
|
|
|
|
sb.append(String.format("#%02x: ", Integer.valueOf(i)));
|
|
|
|
int i2 = this.offsets[i];
|
|
|
|
switch (this.types[i]) {
|
|
|
|
case 0:
|
|
|
|
sb.append("(cont.)");
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
sb.append("Utf8 ").append(this.utf8s[i]);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
sb.append("int ").append(readInteger(i));
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
sb.append("float ").append(readFloat(i));
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
sb.append("long ").append(readLong(i));
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
sb.append("double ").append(readDouble(i));
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
sb.append("Class ").append(getClassName(i));
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
sb.append("String \"").append(this.utf8s[readValue(i2)]).append("\"");
|
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
appendAccess(sb.append("Field "), i);
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
case 11:
|
|
|
|
appendAccess(sb.append("Method "), i);
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
appendNameAndType(sb.append("Name&Type "), i);
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
sb.append("MethodHandle...");
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
sb.append("MethodType...");
|
|
|
|
break;
|
|
|
|
case 17:
|
|
|
|
sb.append("Dynamic...");
|
|
|
|
break;
|
|
|
|
case 18:
|
|
|
|
sb.append("InvokeDynamic...");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
sb.append("\n");
|
|
|
|
}
|
|
|
|
return sb.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void appendAccess(StringBuilder sb, int i) {
|
|
|
|
int i2 = this.offsets[i];
|
|
|
|
sb.append(getClassName(readValue(i2))).append(".");
|
|
|
|
appendNameAndType(sb, readValue(i2 + 2));
|
|
|
|
}
|
|
|
|
|
|
|
|
private void appendNameAndType(StringBuilder sb, int i) {
|
|
|
|
int i2 = this.offsets[i];
|
|
|
|
sb.append(this.utf8s[readValue(i2)]).append(":").append(this.utf8s[readValue(i2 + 2)]);
|
|
|
|
}
|
|
|
|
|
|
|
|
private String getClassName(int i) {
|
|
|
|
if (i < 1) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return this.utf8s[readValue(this.offsets[i])];
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean isMethod(int i) {
|
|
|
|
byte b2 = this.types[i];
|
|
|
|
return b2 == 10 || b2 == 11;
|
|
|
|
}
|
|
|
|
|
|
|
|
private int findNameAndType(String str, String str2) {
|
|
|
|
int findUtf8;
|
|
|
|
int findUtf82 = findUtf8(str);
|
|
|
|
if (findUtf82 == -1 || (findUtf8 = findUtf8(str2)) == -1) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
for (int i = 1; i < this.maxPoolSize; i++) {
|
|
|
|
if (this.types[i] == 12 && readValue(this.offsets[i]) == findUtf82 && readValue(this.offsets[i] + 2) == findUtf8) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
private int findUtf8(String str) {
|
|
|
|
for (int i = 1; i < this.maxPoolSize; i++) {
|
|
|
|
if (str.equals(this.utf8s[i])) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
private int findClass(String str) {
|
|
|
|
int findUtf8 = findUtf8(str);
|
|
|
|
if (findUtf8 == -1) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
for (int i = 1; i < this.maxPoolSize; i++) {
|
|
|
|
if (this.types[i] == 7 && readValue(this.offsets[i]) == findUtf8) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
private int readValue(int i) {
|
|
|
|
return ((this.byteCode[i] & 255) << 8) | (this.byteCode[i + 1] & 255);
|
|
|
|
}
|
|
|
|
}
|