Path: blob/master/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ConstantPool.java
41161 views
/*1* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.tools.classfile;2627import java.io.DataOutputStream;28import java.io.IOException;29import java.io.OutputStream;30import java.util.Iterator;3132/**33* See JVMS, section 4.5.34*35* <p><b>This is NOT part of any supported API.36* If you write code that depends on this, you do so at your own risk.37* This code and its internal interfaces are subject to change or38* deletion without notice.</b>39*/40public class ConstantPool {4142public static class InvalidIndex extends ConstantPoolException {43private static final long serialVersionUID = -4350294289300939730L;44InvalidIndex(int index) {45super(index);46}4748@Override49public String getMessage() {50// i18n51return "invalid index #" + index;52}53}5455public static class UnexpectedEntry extends ConstantPoolException {56private static final long serialVersionUID = 6986335935377933211L;57UnexpectedEntry(int index, int expected_tag, int found_tag) {58super(index);59this.expected_tag = expected_tag;60this.found_tag = found_tag;61}6263@Override64public String getMessage() {65// i18n?66return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag;67}6869public final int expected_tag;70public final int found_tag;71}7273public static class InvalidEntry extends ConstantPoolException {74private static final long serialVersionUID = 1000087545585204447L;75InvalidEntry(int index, int tag) {76super(index);77this.tag = tag;78}7980@Override81public String getMessage() {82// i18n?83return "unexpected tag at #" + index + ": " + tag;84}8586public final int tag;87}8889public static class EntryNotFound extends ConstantPoolException {90private static final long serialVersionUID = 2885537606468581850L;91EntryNotFound(Object value) {92super(-1);93this.value = value;94}9596@Override97public String getMessage() {98// i18n?99return "value not found: " + value;100}101102public final Object value;103}104105public static final int CONSTANT_Utf8 = 1;106public static final int CONSTANT_Integer = 3;107public static final int CONSTANT_Float = 4;108public static final int CONSTANT_Long = 5;109public static final int CONSTANT_Double = 6;110public static final int CONSTANT_Class = 7;111public static final int CONSTANT_String = 8;112public static final int CONSTANT_Fieldref = 9;113public static final int CONSTANT_Methodref = 10;114public static final int CONSTANT_InterfaceMethodref = 11;115public static final int CONSTANT_NameAndType = 12;116public static final int CONSTANT_MethodHandle = 15;117public static final int CONSTANT_MethodType = 16;118public static final int CONSTANT_Dynamic = 17;119public static final int CONSTANT_InvokeDynamic = 18;120public static final int CONSTANT_Module = 19;121public static final int CONSTANT_Package = 20;122123public static enum RefKind {124REF_getField(1),125REF_getStatic(2),126REF_putField(3),127REF_putStatic(4),128REF_invokeVirtual(5),129REF_invokeStatic(6),130REF_invokeSpecial(7),131REF_newInvokeSpecial(8),132REF_invokeInterface(9);133134public final int tag;135136RefKind(int tag) {137this.tag = tag;138}139140static RefKind getRefkind(int tag) {141switch(tag) {142case 1:143return REF_getField;144case 2:145return REF_getStatic;146case 3:147return REF_putField;148case 4:149return REF_putStatic;150case 5:151return REF_invokeVirtual;152case 6:153return REF_invokeStatic;154case 7:155return REF_invokeSpecial;156case 8:157return REF_newInvokeSpecial;158case 9:159return REF_invokeInterface;160default:161return null;162}163}164}165166ConstantPool(ClassReader cr) throws IOException, InvalidEntry {167int count = cr.readUnsignedShort();168pool = new CPInfo[count];169for (int i = 1; i < count; i++) {170int tag = cr.readUnsignedByte();171switch (tag) {172case CONSTANT_Class:173pool[i] = new CONSTANT_Class_info(this, cr);174break;175176case CONSTANT_Double:177pool[i] = new CONSTANT_Double_info(cr);178i++;179break;180181case CONSTANT_Fieldref:182pool[i] = new CONSTANT_Fieldref_info(this, cr);183break;184185case CONSTANT_Float:186pool[i] = new CONSTANT_Float_info(cr);187break;188189case CONSTANT_Integer:190pool[i] = new CONSTANT_Integer_info(cr);191break;192193case CONSTANT_InterfaceMethodref:194pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);195break;196197case CONSTANT_InvokeDynamic:198pool[i] = new CONSTANT_InvokeDynamic_info(this, cr);199break;200201case CONSTANT_Dynamic:202pool[i] = new CONSTANT_Dynamic_info(this, cr);203break;204205case CONSTANT_Long:206pool[i] = new CONSTANT_Long_info(cr);207i++;208break;209210case CONSTANT_MethodHandle:211pool[i] = new CONSTANT_MethodHandle_info(this, cr);212break;213214case CONSTANT_MethodType:215pool[i] = new CONSTANT_MethodType_info(this, cr);216break;217218case CONSTANT_Methodref:219pool[i] = new CONSTANT_Methodref_info(this, cr);220break;221222case CONSTANT_Module:223pool[i] = new CONSTANT_Module_info(this, cr);224break;225226case CONSTANT_NameAndType:227pool[i] = new CONSTANT_NameAndType_info(this, cr);228break;229230case CONSTANT_Package:231pool[i] = new CONSTANT_Package_info(this, cr);232break;233234case CONSTANT_String:235pool[i] = new CONSTANT_String_info(this, cr);236break;237238case CONSTANT_Utf8:239pool[i] = new CONSTANT_Utf8_info(cr);240break;241242default:243throw new InvalidEntry(i, tag);244}245}246}247248public ConstantPool(CPInfo[] pool) {249this.pool = pool;250}251252public int size() {253return pool.length;254}255256public int byteLength() {257int length = 2;258for (int i = 1; i < size(); ) {259CPInfo cpInfo = pool[i];260length += cpInfo.byteLength();261i += cpInfo.size();262}263return length;264}265266public CPInfo get(int index) throws InvalidIndex {267if (index <= 0 || index >= pool.length)268throw new InvalidIndex(index);269CPInfo info = pool[index];270if (info == null) {271// this occurs for indices referencing the "second half" of an272// 8 byte constant, such as CONSTANT_Double or CONSTANT_Long273throw new InvalidIndex(index);274}275return pool[index];276}277278private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry {279CPInfo info = get(index);280if (info.getTag() != expected_type)281throw new UnexpectedEntry(index, expected_type, info.getTag());282return info;283}284285public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry {286return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8));287}288289public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry {290return ((CONSTANT_Class_info) get(index, CONSTANT_Class));291}292293public CONSTANT_Module_info getModuleInfo(int index) throws InvalidIndex, UnexpectedEntry {294return ((CONSTANT_Module_info) get(index, CONSTANT_Module));295}296297public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {298return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));299}300301public CONSTANT_Package_info getPackageInfo(int index) throws InvalidIndex, UnexpectedEntry {302return ((CONSTANT_Package_info) get(index, CONSTANT_Package));303}304305public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry {306return getUTF8Info(index).value;307}308309public int getUTF8Index(String value) throws EntryNotFound {310for (int i = 1; i < pool.length; i++) {311CPInfo info = pool[i];312if (info instanceof CONSTANT_Utf8_info &&313((CONSTANT_Utf8_info) info).value.equals(value))314return i;315}316throw new EntryNotFound(value);317}318319public Iterable<CPInfo> entries() {320return () -> new Iterator<CPInfo>() {321322public boolean hasNext() {323return next < pool.length;324}325326public CPInfo next() {327current = pool[next];328switch (current.getTag()) {329case CONSTANT_Double:330case CONSTANT_Long:331next += 2;332break;333default:334next += 1;335}336return current;337}338339public void remove() {340throw new UnsupportedOperationException();341}342343private CPInfo current;344private int next = 1;345346};347}348349private CPInfo[] pool;350351public interface Visitor<R,P> {352R visitClass(CONSTANT_Class_info info, P p);353R visitDouble(CONSTANT_Double_info info, P p);354R visitFieldref(CONSTANT_Fieldref_info info, P p);355R visitFloat(CONSTANT_Float_info info, P p);356R visitInteger(CONSTANT_Integer_info info, P p);357R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);358R visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, P p);359R visitDynamicConstant(CONSTANT_Dynamic_info info, P p);360R visitLong(CONSTANT_Long_info info, P p);361R visitMethodref(CONSTANT_Methodref_info info, P p);362R visitMethodHandle(CONSTANT_MethodHandle_info info, P p);363R visitMethodType(CONSTANT_MethodType_info info, P p);364R visitModule(CONSTANT_Module_info info, P p);365R visitNameAndType(CONSTANT_NameAndType_info info, P p);366R visitPackage(CONSTANT_Package_info info, P p);367R visitString(CONSTANT_String_info info, P p);368R visitUtf8(CONSTANT_Utf8_info info, P p);369}370371public static abstract class CPInfo {372CPInfo() {373this.cp = null;374}375376CPInfo(ConstantPool cp) {377this.cp = cp;378}379380public abstract int getTag();381382/** The number of slots in the constant pool used by this entry.383* 2 for CONSTANT_Double and CONSTANT_Long; 1 for everything else. */384public int size() {385return 1;386}387388public abstract int byteLength();389390public abstract <R,D> R accept(Visitor<R,D> visitor, D data);391392protected final ConstantPool cp;393}394395public static abstract class CPRefInfo extends CPInfo {396protected CPRefInfo(ConstantPool cp, ClassReader cr, int tag) throws IOException {397super(cp);398this.tag = tag;399class_index = cr.readUnsignedShort();400name_and_type_index = cr.readUnsignedShort();401}402403protected CPRefInfo(ConstantPool cp, int tag, int class_index, int name_and_type_index) {404super(cp);405this.tag = tag;406this.class_index = class_index;407this.name_and_type_index = name_and_type_index;408}409410public int getTag() {411return tag;412}413414public int byteLength() {415return 5;416}417418public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {419return cp.getClassInfo(class_index);420}421422public String getClassName() throws ConstantPoolException {423return cp.getClassInfo(class_index).getName();424}425426public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {427return cp.getNameAndTypeInfo(name_and_type_index);428}429430public final int tag;431public final int class_index;432public final int name_and_type_index;433}434435public static class CONSTANT_Class_info extends CPInfo {436CONSTANT_Class_info(ConstantPool cp, ClassReader cr) throws IOException {437super(cp);438name_index = cr.readUnsignedShort();439}440441public CONSTANT_Class_info(ConstantPool cp, int name_index) {442super(cp);443this.name_index = name_index;444}445446public int getTag() {447return CONSTANT_Class;448}449450public int byteLength() {451return 3;452}453454/**455* Get the raw value of the class referenced by this constant pool entry.456* This will either be the name of the class, in internal form, or a457* descriptor for an array class.458* @return the raw value of the class459*/460public String getName() throws ConstantPoolException {461return cp.getUTF8Value(name_index);462}463464/**465* If this constant pool entry identifies either a class or interface type,466* or a possibly multi-dimensional array of a class of interface type,467* return the name of the class or interface in internal form. Otherwise,468* (i.e. if this is a possibly multi-dimensional array of a primitive type),469* return null.470* @return the base class or interface name471*/472public String getBaseName() throws ConstantPoolException {473String name = getName();474if (name.startsWith("[")) {475int index = name.indexOf("[L");476if (index == -1)477return null;478return name.substring(index + 2, name.length() - 1);479} else480return name;481}482483public int getDimensionCount() throws ConstantPoolException {484String name = getName();485int count = 0;486while (name.charAt(count) == '[')487count++;488return count;489}490491@Override492public String toString() {493return "CONSTANT_Class_info[name_index: " + name_index + "]";494}495496public <R, D> R accept(Visitor<R, D> visitor, D data) {497return visitor.visitClass(this, data);498}499500public final int name_index;501}502503public static class CONSTANT_Double_info extends CPInfo {504CONSTANT_Double_info(ClassReader cr) throws IOException {505value = cr.readDouble();506}507508public CONSTANT_Double_info(double value) {509this.value = value;510}511512public int getTag() {513return CONSTANT_Double;514}515516public int byteLength() {517return 9;518}519520@Override521public int size() {522return 2;523}524525@Override526public String toString() {527return "CONSTANT_Double_info[value: " + value + "]";528}529530public <R, D> R accept(Visitor<R, D> visitor, D data) {531return visitor.visitDouble(this, data);532}533534public final double value;535}536537public static class CONSTANT_Fieldref_info extends CPRefInfo {538CONSTANT_Fieldref_info(ConstantPool cp, ClassReader cr) throws IOException {539super(cp, cr, CONSTANT_Fieldref);540}541542public CONSTANT_Fieldref_info(ConstantPool cp, int class_index, int name_and_type_index) {543super(cp, CONSTANT_Fieldref, class_index, name_and_type_index);544}545546@Override547public String toString() {548return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";549}550551public <R, D> R accept(Visitor<R, D> visitor, D data) {552return visitor.visitFieldref(this, data);553}554}555556public static class CONSTANT_Float_info extends CPInfo {557CONSTANT_Float_info(ClassReader cr) throws IOException {558value = cr.readFloat();559}560561public CONSTANT_Float_info(float value) {562this.value = value;563}564565public int getTag() {566return CONSTANT_Float;567}568569public int byteLength() {570return 5;571}572573@Override574public String toString() {575return "CONSTANT_Float_info[value: " + value + "]";576}577578public <R, D> R accept(Visitor<R, D> visitor, D data) {579return visitor.visitFloat(this, data);580}581582public final float value;583}584585public static class CONSTANT_Integer_info extends CPInfo {586CONSTANT_Integer_info(ClassReader cr) throws IOException {587value = cr.readInt();588}589590public CONSTANT_Integer_info(int value) {591this.value = value;592}593594public int getTag() {595return CONSTANT_Integer;596}597598public int byteLength() {599return 5;600}601602@Override603public String toString() {604return "CONSTANT_Integer_info[value: " + value + "]";605}606607public <R, D> R accept(Visitor<R, D> visitor, D data) {608return visitor.visitInteger(this, data);609}610611public final int value;612}613614public static class CONSTANT_InterfaceMethodref_info extends CPRefInfo {615CONSTANT_InterfaceMethodref_info(ConstantPool cp, ClassReader cr) throws IOException {616super(cp, cr, CONSTANT_InterfaceMethodref);617}618619public CONSTANT_InterfaceMethodref_info(ConstantPool cp, int class_index, int name_and_type_index) {620super(cp, CONSTANT_InterfaceMethodref, class_index, name_and_type_index);621}622623@Override624public String toString() {625return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";626}627628public <R, D> R accept(Visitor<R, D> visitor, D data) {629return visitor.visitInterfaceMethodref(this, data);630}631}632633public static class CONSTANT_InvokeDynamic_info extends CPInfo {634CONSTANT_InvokeDynamic_info(ConstantPool cp, ClassReader cr) throws IOException {635super(cp);636bootstrap_method_attr_index = cr.readUnsignedShort();637name_and_type_index = cr.readUnsignedShort();638}639640public CONSTANT_InvokeDynamic_info(ConstantPool cp, int bootstrap_method_index, int name_and_type_index) {641super(cp);642this.bootstrap_method_attr_index = bootstrap_method_index;643this.name_and_type_index = name_and_type_index;644}645646public int getTag() {647return CONSTANT_InvokeDynamic;648}649650public int byteLength() {651return 5;652}653654@Override655public String toString() {656return "CONSTANT_InvokeDynamic_info[bootstrap_method_index: " + bootstrap_method_attr_index + ", name_and_type_index: " + name_and_type_index + "]";657}658659public <R, D> R accept(Visitor<R, D> visitor, D data) {660return visitor.visitInvokeDynamic(this, data);661}662663public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {664return cp.getNameAndTypeInfo(name_and_type_index);665}666667public final int bootstrap_method_attr_index;668public final int name_and_type_index;669}670671public static class CONSTANT_Long_info extends CPInfo {672CONSTANT_Long_info(ClassReader cr) throws IOException {673value = cr.readLong();674}675676public CONSTANT_Long_info(long value) {677this.value = value;678}679680public int getTag() {681return CONSTANT_Long;682}683684@Override685public int size() {686return 2;687}688689public int byteLength() {690return 9;691}692693@Override694public String toString() {695return "CONSTANT_Long_info[value: " + value + "]";696}697698public <R, D> R accept(Visitor<R, D> visitor, D data) {699return visitor.visitLong(this, data);700}701702public final long value;703}704705public static class CONSTANT_MethodHandle_info extends CPInfo {706CONSTANT_MethodHandle_info(ConstantPool cp, ClassReader cr) throws IOException {707super(cp);708reference_kind = RefKind.getRefkind(cr.readUnsignedByte());709reference_index = cr.readUnsignedShort();710}711712public CONSTANT_MethodHandle_info(ConstantPool cp, RefKind ref_kind, int member_index) {713super(cp);714this.reference_kind = ref_kind;715this.reference_index = member_index;716}717718public int getTag() {719return CONSTANT_MethodHandle;720}721722public int byteLength() {723return 4;724}725726@Override727public String toString() {728return "CONSTANT_MethodHandle_info[ref_kind: " + reference_kind + ", member_index: " + reference_index + "]";729}730731public <R, D> R accept(Visitor<R, D> visitor, D data) {732return visitor.visitMethodHandle(this, data);733}734735public CPRefInfo getCPRefInfo() throws ConstantPoolException {736int expected = CONSTANT_Methodref;737int actual = cp.get(reference_index).getTag();738// allow these tag types also:739switch (actual) {740case CONSTANT_Fieldref:741case CONSTANT_InterfaceMethodref:742expected = actual;743}744return (CPRefInfo) cp.get(reference_index, expected);745}746747public final RefKind reference_kind;748public final int reference_index;749}750751public static class CONSTANT_MethodType_info extends CPInfo {752CONSTANT_MethodType_info(ConstantPool cp, ClassReader cr) throws IOException {753super(cp);754descriptor_index = cr.readUnsignedShort();755}756757public CONSTANT_MethodType_info(ConstantPool cp, int signature_index) {758super(cp);759this.descriptor_index = signature_index;760}761762public int getTag() {763return CONSTANT_MethodType;764}765766public int byteLength() {767return 3;768}769770@Override771public String toString() {772return "CONSTANT_MethodType_info[signature_index: " + descriptor_index + "]";773}774775public <R, D> R accept(Visitor<R, D> visitor, D data) {776return visitor.visitMethodType(this, data);777}778779public String getType() throws ConstantPoolException {780return cp.getUTF8Value(descriptor_index);781}782783public final int descriptor_index;784}785786public static class CONSTANT_Methodref_info extends CPRefInfo {787CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {788super(cp, cr, CONSTANT_Methodref);789}790791public CONSTANT_Methodref_info(ConstantPool cp, int class_index, int name_and_type_index) {792super(cp, CONSTANT_Methodref, class_index, name_and_type_index);793}794795@Override796public String toString() {797return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";798}799800public <R, D> R accept(Visitor<R, D> visitor, D data) {801return visitor.visitMethodref(this, data);802}803}804805public static class CONSTANT_Module_info extends CPInfo {806CONSTANT_Module_info(ConstantPool cp, ClassReader cr) throws IOException {807super(cp);808name_index = cr.readUnsignedShort();809}810811public CONSTANT_Module_info(ConstantPool cp, int name_index) {812super(cp);813this.name_index = name_index;814}815816public int getTag() {817return CONSTANT_Module;818}819820public int byteLength() {821return 3;822}823824/**825* Get the raw value of the module name referenced by this constant pool entry.826* This will be the name of the module.827* @return the raw value of the module name828*/829public String getName() throws ConstantPoolException {830return cp.getUTF8Value(name_index);831}832833@Override834public String toString() {835return "CONSTANT_Module_info[name_index: " + name_index + "]";836}837838public <R, D> R accept(Visitor<R, D> visitor, D data) {839return visitor.visitModule(this, data);840}841842public final int name_index;843}844845public static class CONSTANT_NameAndType_info extends CPInfo {846CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException {847super(cp);848name_index = cr.readUnsignedShort();849type_index = cr.readUnsignedShort();850}851852public CONSTANT_NameAndType_info(ConstantPool cp, int name_index, int type_index) {853super(cp);854this.name_index = name_index;855this.type_index = type_index;856}857858public int getTag() {859return CONSTANT_NameAndType;860}861862public int byteLength() {863return 5;864}865866public String getName() throws ConstantPoolException {867return cp.getUTF8Value(name_index);868}869870public String getType() throws ConstantPoolException {871return cp.getUTF8Value(type_index);872}873874public <R, D> R accept(Visitor<R, D> visitor, D data) {875return visitor.visitNameAndType(this, data);876}877878@Override879public String toString() {880return "CONSTANT_NameAndType_info[name_index: " + name_index + ", type_index: " + type_index + "]";881}882883public final int name_index;884public final int type_index;885}886887public static class CONSTANT_Dynamic_info extends CPInfo {888CONSTANT_Dynamic_info(ConstantPool cp, ClassReader cr) throws IOException {889super(cp);890bootstrap_method_attr_index = cr.readUnsignedShort();891name_and_type_index = cr.readUnsignedShort();892}893894public CONSTANT_Dynamic_info(ConstantPool cp, int bootstrap_method_index, int name_and_type_index) {895super(cp);896this.bootstrap_method_attr_index = bootstrap_method_index;897this.name_and_type_index = name_and_type_index;898}899900public int getTag() {901return CONSTANT_Dynamic;902}903904public int byteLength() {905return 5;906}907908@Override909public String toString() {910return "CONSTANT_Dynamic_info[bootstrap_method_index: " + bootstrap_method_attr_index + ", name_and_type_index: " + name_and_type_index + "]";911}912913public <R, D> R accept(Visitor<R, D> visitor, D data) {914return visitor.visitDynamicConstant(this, data);915}916917public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {918return cp.getNameAndTypeInfo(name_and_type_index);919}920921public final int bootstrap_method_attr_index;922public final int name_and_type_index;923}924925public static class CONSTANT_Package_info extends CPInfo {926CONSTANT_Package_info(ConstantPool cp, ClassReader cr) throws IOException {927super(cp);928name_index = cr.readUnsignedShort();929}930931public CONSTANT_Package_info(ConstantPool cp, int name_index) {932super(cp);933this.name_index = name_index;934}935936public int getTag() {937return CONSTANT_Package;938}939940public int byteLength() {941return 3;942}943944/**945* Get the raw value of the package name referenced by this constant pool entry.946* This will be the name of the package, in internal form.947* @return the raw value of the module name948*/949public String getName() throws ConstantPoolException {950return cp.getUTF8Value(name_index);951}952953@Override954public String toString() {955return "CONSTANT_Package_info[name_index: " + name_index + "]";956}957958public <R, D> R accept(Visitor<R, D> visitor, D data) {959return visitor.visitPackage(this, data);960}961962public final int name_index;963}964965public static class CONSTANT_String_info extends CPInfo {966CONSTANT_String_info(ConstantPool cp, ClassReader cr) throws IOException {967super(cp);968string_index = cr.readUnsignedShort();969}970971public CONSTANT_String_info(ConstantPool cp, int string_index) {972super(cp);973this.string_index = string_index;974}975976public int getTag() {977return CONSTANT_String;978}979980public int byteLength() {981return 3;982}983984public String getString() throws ConstantPoolException {985return cp.getUTF8Value(string_index);986}987988public <R, D> R accept(Visitor<R, D> visitor, D data) {989return visitor.visitString(this, data);990}991992@Override993public String toString() {994return "CONSTANT_String_info[class_index: " + string_index + "]";995}996997public final int string_index;998}9991000public static class CONSTANT_Utf8_info extends CPInfo {1001CONSTANT_Utf8_info(ClassReader cr) throws IOException {1002value = cr.readUTF();1003}10041005public CONSTANT_Utf8_info(String value) {1006this.value = value;1007}10081009public int getTag() {1010return CONSTANT_Utf8;1011}10121013public int byteLength() {1014class SizeOutputStream extends OutputStream {1015@Override1016public void write(int b) {1017size++;1018}1019int size;1020}1021SizeOutputStream sizeOut = new SizeOutputStream();1022DataOutputStream out = new DataOutputStream(sizeOut);1023try { out.writeUTF(value); } catch (IOException ignore) { }1024return 1 + sizeOut.size;1025}10261027@Override1028public String toString() {1029if (value.length() < 32 && isPrintableAscii(value))1030return "CONSTANT_Utf8_info[value: \"" + value + "\"]";1031else1032return "CONSTANT_Utf8_info[value: (" + value.length() + " chars)]";1033}10341035static boolean isPrintableAscii(String s) {1036for (int i = 0; i < s.length(); i++) {1037char c = s.charAt(i);1038if (c < 32 || c >= 127)1039return false;1040}1041return true;1042}10431044public <R, D> R accept(Visitor<R, D> visitor, D data) {1045return visitor.visitUtf8(this, data);1046}10471048public final String value;1049}10501051}105210531054