All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.packenius.datadivider.javaclass.cp.ConstantPoolEntry Maven / Gradle / Ivy

package com.packenius.datadivider.javaclass.cp;

import com.packenius.datadivider.javaclass.ConstantPool;
import com.packenius.dumpapi.DumpBlock;
import com.packenius.dumpapi.DumpReader;

/**
 * Eintrag im Konstantenpool.
 * @author Christian Packenius, 2016.
 */
public abstract class ConstantPoolEntry extends DumpBlock {
    /**
     * Typ dieses Eintrages als Tag.
     */
    public final byte tag;

    /**
     * Index dieses Eintrages innerhalb des Konstantenpools.
     */
    public final int id;

    /**
     * Konstruktor.
     * @param reader Klassen-Reader.
     * @param id     Index dieses Eintrages innerhalb des Konstantenpools.
     */
    public ConstantPoolEntry(DumpReader reader, int id) {
        super(reader);
        tag = (byte) reader.readU1("Tag: ##DEC##").value;
        this.id = id;
    }

    /**
     * Erzeugt einen Klartext einer Methodensignatur.
     * @param classIndex
     * @param nameAndTypeIndex
     * @return Klartext der Methodensignatur.
     */
    public String methodHeadFromConstantPoolEntry(int classIndex, int nameAndTypeIndex) {
        ConstantPool constantpool = reader.getUserObject(ConstantPool.class);
        return methodHeadFromConstantPoolEntry(constantpool, classIndex, nameAndTypeIndex);
    }

    /**
     * Erzeugt einen Klartext einer Methodensignatur.
     * @return Klartext der Methodensignatur.
     */
    public static String methodHeadFromConstantPoolEntry(ConstantPool constantpool, int classIndex,
            int nameAndTypeIndex) {
        String cl = constantpool.getClassEntry(classIndex).getClassName();
        CpNameAndType nameAndTypeEntry = constantpool.getNameAndTypeEntry(nameAndTypeIndex);
        String name = constantpool.getEntry(nameAndTypeEntry.nameIndex).asUtf8().string;

        // Der Descriptor muss auseinander genommen werden.
        // Beispiel: Aus "()V" wird "void" und "()".
        String type = constantpool.getEntry(nameAndTypeEntry.descriptorIndex).asUtf8().string;
        String returnType = singleTypeTranslation(type.substring(type.indexOf(')') + 1));
        String parms = parmsListTranslation(type);

        return returnType + " " + cl + "." + name + parms;
    }

    /**
     * Erzeugt aus einer Parameterliste den dazugehörigen Klartext.
     * @return Klartext der Parameterliste, ohne Rückgabewert, aber mit Klammern.
     */
    public static String parmsListTranslation(String type) {
        String parms = "(";
        if (type.charAt(0) != '(') {
            throw new RuntimeException("Methodendescriptor?? " + type);
        }
        type = type.substring(1);
        boolean firstParm = true;
        while (type.charAt(0) != ')') {
            int k = 0;
            while (type.charAt(k) == '[') {
                k++;
            }
            if (type.charAt(k) == 'L') {
                k = type.indexOf(';', k);
            }
            k++;
            parms += firstParm ? "" : ", ";
            firstParm = false;
            parms += singleTypeTranslation(type.substring(0, k));
            type = type.substring(k);
        }
        parms += ")";
        return parms;
    }

    /**
     * Ermittelt die Langform des angegebenen Typs.
     * @param s Einzelner Typ.
     * @return Langform des Typs.
     */
    public static String singleTypeTranslation(String s) {
        String arr = "";
        while (s.charAt(0) == '[') {
            arr += "[]";
            s = s.substring(1);
        }
        final String type;
        switch (s.charAt(0)) {
        case 'B':
            type = "byte";
            break;
        case 'C':
            type = "char";
            break;
        case 'D':
            type = "double";
            break;
        case 'F':
            type = "float";
            break;
        case 'I':
            type = "int";
            break;
        case 'J':
            type = "long";
            break;
        case 'S':
            type = "short";
            break;
        case 'Z':
            type = "boolean";
            break;
        case 'V':
            type = "void";
            break;
        case 'L':
            if (s.charAt(s.length() - 1) != ';') {
                throw new RuntimeException("Class type does not end with ';'! <" + s + ">");
            }
            type = CpClass.normalizeClassName(s.substring(1, s.length() - 1));
            break;
        default:
            throw new RuntimeException("Illegal type: " + s);
        }
        return type + arr;
    }

    @Override
    public String toString() {
        return "#" + id + ": " + getTagName();
    }

    private String getTagName() {
        switch (tag) {
        case 1:
            return "CONSTANT_Utf8";
        case 3:
            return "CONSTANT_Integer";
        case 4:
            return "CONSTANT_Float";
        case 5:
            return "CONSTANT_Long";
        case 6:
            return "CONSTANT_Double";
        case 7:
            return "CONSTANT_Class";
        case 8:
            return "CONSTANT_String";
        case 9:
            return "CONSTANT_Fieldref";
        case 10:
            return "CONSTANT_Methodref";
        case 11:
            return "CONSTANT_InterfaceMethodref";
        case 12:
            return "CONSTANT_NameAndType";
        case 15:
            return "CONSTANT_MethodHandle";
        case 16:
            return "CONSTANT_MethodType";
        case 17:
            return "CONSTANT_Dynamic_info";
        case 18:
            return "CONSTANT_InvokeDynamic_info";
        case 19:
            return "CONSTANT_Module";
        case 20:
            return "CONSTANT_Package";
        }
        throw new RuntimeException("Illegal tag: " + tag);
    }

    public CpUtf8 asUtf8() {
        return (CpUtf8) this;
    }

    public CpClass asClass() {
        return (CpClass) this;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy