
com.packenius.datadivider.javaclass.ConstantPool Maven / Gradle / Ivy
package com.packenius.datadivider.javaclass;
import java.util.ArrayList;
import java.util.List;
import com.packenius.datadivider.javaclass.cp.ConstantPoolEntry;
import com.packenius.datadivider.javaclass.cp.ConstantPoolEntryWithMethodRef;
import com.packenius.datadivider.javaclass.cp.CpClass;
import com.packenius.datadivider.javaclass.cp.CpDouble;
import com.packenius.datadivider.javaclass.cp.CpFieldRef;
import com.packenius.datadivider.javaclass.cp.CpFloat;
import com.packenius.datadivider.javaclass.cp.CpInteger;
import com.packenius.datadivider.javaclass.cp.CpInterfaceMethodRef;
import com.packenius.datadivider.javaclass.cp.CpInvokeDynamic;
import com.packenius.datadivider.javaclass.cp.CpLong;
import com.packenius.datadivider.javaclass.cp.CpMethodHandle;
import com.packenius.datadivider.javaclass.cp.CpMethodRef;
import com.packenius.datadivider.javaclass.cp.CpMethodType;
import com.packenius.datadivider.javaclass.cp.CpNameAndType;
import com.packenius.datadivider.javaclass.cp.CpString;
import com.packenius.datadivider.javaclass.cp.CpUtf8;
import com.packenius.dumpapi.DumpBlock;
import com.packenius.dumpapi.DumpReader;
/**
* Konstantenpool einer Klasse.
* @author Christian Packenius, 2016.
*/
public class ConstantPool extends DumpBlock {
/**
* Sämtliche Einträge des Konstantenpools.
*/
private final List content = new ArrayList<>();
/**
* Konstruktor.
*/
public ConstantPool(DumpReader reader) {
super(reader);
// Das Objekt mit dem Index 0 ist immer null.
content.add(null);
// Konstantenpool im ersten Schritt einlesen.
// Mag ungewöhnlich sein, aber wir beginnen bei Eintrag 1, nicht 0.
int constantPoolCount = reader.readBigEndianU2("Entries count: ##DEC##").value;
while (content.size() < constantPoolCount) {
ConstantPoolEntry cpEntry = readNextEntry(reader, content.size());
add(cpEntry);
}
setEndAddress(reader);
}
/**
* Fügt dem Konstantenpool einen neuen Eintrag hinzu.
* @param cpEntry Neuer CP-Eintrag.
* @return ID des CP-Eintrages.
*/
private int add(ConstantPoolEntry cpEntry) {
int id = content.size();
content.add(cpEntry);
// Long- und Double-Einträge werden idiotischerweise gedoppelt.
if (cpEntry instanceof CpDouble || cpEntry instanceof CpLong) {
content.add(cpEntry);
}
return id;
}
/**
* Liest den nächsten Eintrag aus dem Konstantenpool.
* @param cpID Nummer innerhalb des Konstantenpools (ab 1 aufsteigend, bei Long
* und Double zwei Nummern).
*/
private ConstantPoolEntry readNextEntry(DumpReader reader, int cpID) {
// Vorab das Tag lesen, damit wir wissen, welche Art von CP-Eintrag wir
// lesen müssen.
short tag = reader.readU1("Tag id: ##DEC##").value;
reader.deltaIndex(-1);
switch (tag) {
case 1:
return new CpUtf8(reader, cpID, this);
case 3:
return new CpInteger(reader, cpID);
case 4:
return new CpFloat(reader, cpID);
case 5:
return new CpLong(reader, cpID);
case 6:
return new CpDouble(reader, cpID);
case 7:
return new CpClass(reader, cpID);
case 8:
return new CpString(reader, cpID, this);
case 9:
return new CpFieldRef(reader, cpID, this);
case 10:
return new CpMethodRef(reader, cpID, this);
case 11:
return new CpInterfaceMethodRef(reader, cpID, this);
case 12:
return new CpNameAndType(reader, cpID);
case 15:
return new CpMethodHandle(reader, cpID, this);
case 16:
return new CpMethodType(reader, cpID, this);
case 18:
return new CpInvokeDynamic(reader, cpID, this);
default:
throw new IllegalArgumentException("Eintrag unbekannten Typs [" + tag + "] im Konstantenpool!");
}
}
/**
* Ermittelt einen beliebigen Eintrag aus dem Konstantenpool.
* @param index Index des Eintrags.
* @return Eigentlicher Eintrag.
*/
public ConstantPoolEntry getEntry(int index) {
return content.get(index);
}
/**
* Ermittelt einen UTF8-Eintrag.
* @param index Index auf den gewünschten Eintrag.
* @return Geforderter UTF8-Eintrag.
*/
public CpUtf8 getUtf8Entry(int index) {
return content.get(index).asUtf8();
}
/**
* Ermittelt einen Class-Eintrag.
* @param index Index auf den gewünschten Eintrag.
* @return Geforderter Class-Eintrag.
*/
public CpClass getClassEntry(int index) {
return (CpClass) content.get(index);
}
/**
* Ermittelt einen NameAndType-Eintrag.
* @param index Index auf den gewünschten Eintrag.
* @return Geforderter NameAndType-Eintrag.
*/
public CpNameAndType getNameAndTypeEntry(int index) {
return (CpNameAndType) content.get(index);
}
/**
* Ermittelt einen InterfaceMethod-Eintrag.
* @param index Index auf den gewünschten Eintrag.
* @return Geforderter InterfaceMethod-Eintrag.
*/
public CpInterfaceMethodRef getInterfaceMethodEntry(int index) {
return (CpInterfaceMethodRef) content.get(index);
}
/**
* @param index
* @return MethodRef oder InterfaceMethodRef.
*/
public ConstantPoolEntryWithMethodRef getEntryWithMethodRef(int index) {
return (ConstantPoolEntryWithMethodRef) content.get(index);
}
public CpFieldRef getFieldRefEntry(int index) {
return (CpFieldRef) content.get(index);
}
public ConstantPoolEntryWithMethodRef getMethodRefEntry(int index) {
return (ConstantPoolEntryWithMethodRef) content.get(index);
}
@Override
public String toString() {
return "Constant Pool [" + content.size() + " entries]";
}
@Override
public String getDescription() {
return "Constant pool of this java class file, containing all types of constants used within the class file. Each entry in " //
+ "the constant pool table must begin with a 1-byte tag indicating " //
+ "the kind of constant denoted by the entry.\r\nHINT:\r\nIndex #0 is never used, for this the count is +1 larger than the real number of entries.";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy