/** * Get the first UTF8 byte of a string in the constant pool, or '\0' if the string is null or empty. */ private byte getConstantPoolStringFirstByte(final int cpIdx) { final int constantPoolStringOffset = getConstantPoolStringOffset(cpIdx, /* subFieldIdx = */ 0); if (constantPoolStringOffset == 0) { return '\0'; } final int utfLen = readUnsignedShort(constantPoolStringOffset); if (utfLen == 0) { return '\0'; } return buf[constantPoolStringOffset + 2]; }
/** * Compare a string in the constant pool with a given constant, without constructing the String object. */ private boolean constantPoolStringEquals(final int cpIdx, final String otherString) { final int strOffset = getConstantPoolStringOffset(cpIdx, /* subFieldIdx = */ 0); if (strOffset == 0) { return otherString == null; } final int strLen = readUnsignedShort(strOffset); final int otherLen = otherString.length(); if (strLen != otherLen) { return false; } final int strStart = strOffset + 2; for (int i = 0; i < strLen; i++) { if ((char) (buf[strStart + i] & 0xff) != otherString.charAt(i)) { return false; } } return true; }
/** Read annotation entry from classfile. */ private AnnotationInfo readAnnotation() throws IOException, InterruptedException { // Lcom/xyz/Annotation; -> Lcom.xyz.Annotation; final String annotationClassName = getConstantPoolClassDescriptor(readUnsignedShort()); final int numElementValuePairs = readUnsignedShort(); List<AnnotationParamValue> paramVals = null; if (numElementValuePairs > 0) { paramVals = new ArrayList<>(numElementValuePairs); } for (int i = 0; i < numElementValuePairs; i++) { final String paramName = getConstantPoolString(readUnsignedShort()); // skip(2); // element_name_index final Object paramValue = readAnnotationElementValue(); paramVals.add(new AnnotationParamValue(paramName, paramValue)); } return new AnnotationInfo(annotationClassName, paramVals); }
final int utfLen = readUnsignedShort(strStart); final int utfStart = strStart + 2; final char[] chars = new char[utfLen];
switch (tag) { case 'B': return Byte.valueOf((byte) readInt(offset[readUnsignedShort()])); case 'C': return Character.valueOf((char) readInt(offset[readUnsignedShort()])); case 'D': return Double.valueOf(Double.longBitsToDouble(readLong(offset[readUnsignedShort()]))); case 'F': return Float.valueOf(Float.intBitsToFloat(readInt(offset[readUnsignedShort()]))); case 'I': return Integer.valueOf(readInt(offset[readUnsignedShort()])); case 'J': return Long.valueOf(readLong(offset[readUnsignedShort()])); case 'S': return Short.valueOf((short) readInt(offset[readUnsignedShort()])); case 'Z': return Boolean.valueOf(readInt(offset[readUnsignedShort()]) != 0); case 's': return getConstantPoolString(readUnsignedShort()); case 'e': { final String className = getConstantPoolClassDescriptor(readUnsignedShort()); final String constName = getConstantPoolString(readUnsignedShort()); return new AnnotationEnumValue(className, constName); final String classRefTypeDescriptor = getConstantPoolString(readUnsignedShort()); return new AnnotationClassRef(classRefTypeDescriptor); case '@':
readUnsignedShort(); readUnsignedShort(); final int cpCount = readUnsignedShort(); switch (tag[i]) { case 1: // Modified UTF8 final int strLen = readUnsignedShort(); skip(strLen); break; indirectStringRefs[i] = readUnsignedShort(); break; case 12: // name and type final int nameRef = readUnsignedShort(); final int typeRef = readUnsignedShort(); indirectStringRefs[i] = (nameRef << 16) | typeRef; break; final int classModifierFlags = readUnsignedShort(); final boolean isInterface = (classModifierFlags & 0x0200) != 0; final boolean isAnnotation = (classModifierFlags & 0x2000) != 0; final String classNamePath = getConstantPoolString(readUnsignedShort()); final String className = classNamePath.replace('/', '.'); if ("java.lang.Object".equals(className)) {