diff -r 3392f250c784 -r ecbd252fd3a7 javap/src/main/java/org/apidesign/javap/ClassData.java --- a/javap/src/main/java/org/apidesign/javap/ClassData.java Fri Mar 22 16:59:47 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,713 +0,0 @@ -/* - * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - -package org.apidesign.javap; - -import java.io.*; - -/** - * Central data repository of the Java Disassembler. - * Stores all the information in java class file. - * - * @author Sucheta Dambalkar (Adopted code from jdis) - */ -public final class ClassData implements RuntimeConstants { - - private int magic; - private int minor_version; - private int major_version; - private int cpool_count; - private Object cpool[]; - private int access; - private int this_class = 0;; - private int super_class; - private int interfaces_count; - private int[] interfaces = new int[0];; - private int fields_count; - private FieldData[] fields; - private int methods_count; - private MethodData[] methods; - private InnerClassData[] innerClasses; - private int attributes_count; - private AttrData[] attrs; - private String classname; - private String superclassname; - private int source_cpx=0; - private byte tags[]; - private Hashtable indexHashAscii = new Hashtable(); - private String pkgPrefix=""; - private int pkgPrefixLen=0; - - /** - * Read classfile to disassemble. - */ - public ClassData(InputStream infile) throws IOException { - this.read(new DataInputStream(infile)); - } - - /** - * Reads and stores class file information. - */ - public void read(DataInputStream in) throws IOException { - // Read the header - magic = in.readInt(); - if (magic != JAVA_MAGIC) { - throw new ClassFormatError("wrong magic: " + - toHex(magic) + ", expected " + - toHex(JAVA_MAGIC)); - } - minor_version = in.readShort(); - major_version = in.readShort(); - if (major_version != JAVA_VERSION) { - } - - // Read the constant pool - readCP(in); - access = in.readUnsignedShort(); - this_class = in.readUnsignedShort(); - super_class = in.readUnsignedShort(); - - //Read interfaces. - interfaces_count = in.readUnsignedShort(); - if(interfaces_count > 0){ - interfaces = new int[interfaces_count]; - } - for (int i = 0; i < interfaces_count; i++) { - interfaces[i]=in.readShort(); - } - - // Read the fields - readFields(in); - - // Read the methods - readMethods(in); - - // Read the attributes - attributes_count = in.readUnsignedShort(); - attrs=new AttrData[attributes_count]; - for (int k = 0; k < attributes_count; k++) { - int name_cpx=in.readUnsignedShort(); - if (getTag(name_cpx)==CONSTANT_UTF8 - && getString(name_cpx).equals("SourceFile") - ){ if (in.readInt()!=2) - throw new ClassFormatError("invalid attr length"); - source_cpx=in.readUnsignedShort(); - AttrData attr=new AttrData(this); - attr.read(name_cpx); - attrs[k]=attr; - - } else if (getTag(name_cpx)==CONSTANT_UTF8 - && getString(name_cpx).equals("InnerClasses") - ){ int length=in.readInt(); - int num=in.readUnsignedShort(); - if (2+num*8 != length) - throw new ClassFormatError("invalid attr length"); - innerClasses=new InnerClassData[num]; - for (int j = 0; j < num; j++) { - InnerClassData innerClass=new InnerClassData(this); - innerClass.read(in); - innerClasses[j]=innerClass; - } - AttrData attr=new AttrData(this); - attr.read(name_cpx); - attrs[k]=attr; - } else { - AttrData attr=new AttrData(this); - attr.read(name_cpx, in); - attrs[k]=attr; - } - } - in.close(); - } // end ClassData.read() - - /** - * Reads and stores constant pool info. - */ - void readCP(DataInputStream in) throws IOException { - cpool_count = in.readUnsignedShort(); - tags = new byte[cpool_count]; - cpool = new Object[cpool_count]; - for (int i = 1; i < cpool_count; i++) { - byte tag = in.readByte(); - - switch(tags[i] = tag) { - case CONSTANT_UTF8: - String str=in.readUTF(); - indexHashAscii.put(cpool[i] = str, new Integer(i)); - break; - case CONSTANT_INTEGER: - cpool[i] = new Integer(in.readInt()); - break; - case CONSTANT_FLOAT: - cpool[i] = new Float(in.readFloat()); - break; - case CONSTANT_LONG: - cpool[i++] = new Long(in.readLong()); - break; - case CONSTANT_DOUBLE: - cpool[i++] = new Double(in.readDouble()); - break; - case CONSTANT_CLASS: - case CONSTANT_STRING: - cpool[i] = new CPX(in.readUnsignedShort()); - break; - - case CONSTANT_FIELD: - case CONSTANT_METHOD: - case CONSTANT_INTERFACEMETHOD: - case CONSTANT_NAMEANDTYPE: - cpool[i] = new CPX2(in.readUnsignedShort(), in.readUnsignedShort()); - break; - - case 0: - default: - throw new ClassFormatError("invalid constant type: " + (int)tags[i]); - } - } - } - - /** - * Reads and strores field info. - */ - protected void readFields(DataInputStream in) throws IOException { - int fields_count = in.readUnsignedShort(); - fields=new FieldData[fields_count]; - for (int k = 0; k < fields_count; k++) { - FieldData field=new FieldData(this); - field.read(in); - fields[k]=field; - } - } - - /** - * Reads and strores Method info. - */ - protected void readMethods(DataInputStream in) throws IOException { - int methods_count = in.readUnsignedShort(); - methods=new MethodData[methods_count]; - for (int k = 0; k < methods_count ; k++) { - MethodData method=new MethodData(this); - method.read(in); - methods[k]=method; - } - } - - /** - * get a string - */ - public String getString(int n) { - if (n == 0) { - return null; - } else { - return (String)cpool[n]; - } - } - - /** - * get the type of constant given an index - */ - public byte getTag(int n) { - try{ - return tags[n]; - } catch (ArrayIndexOutOfBoundsException e) { - return (byte)100; - } - } - - static final String hexString="0123456789ABCDEF"; - - public static char hexTable[]=hexString.toCharArray(); - - static String toHex(long val, int width) { - StringBuffer s = new StringBuffer(); - for (int i=width-1; i>=0; i--) - s.append(hexTable[((int)(val>>(4*i)))&0xF]); - return "0x"+s.toString(); - } - - static String toHex(long val) { - int width; - for (width=16; width>0; width--) { - if ((val>>(width-1)*4)!=0) break; - } - return toHex(val, width); - } - - static String toHex(int val) { - int width; - for (width=8; width>0; width--) { - if ((val>>(width-1)*4)!=0) break; - } - return toHex(val, width); - } - - /** - * Returns the name of this class. - */ - public String getClassName() { - String res=null; - if (this_class==0) { - return res; - } - int tcpx; - try { - if (tags[this_class]!=CONSTANT_CLASS) { - return res; //" "; - } - tcpx=((CPX)cpool[this_class]).cpx; - } catch (ArrayIndexOutOfBoundsException e) { - return res; // "#"+cpx+"// invalid constant pool index"; - } catch (Throwable e) { - return res; // "#"+cpx+"// ERROR IN DISASSEMBLER"; - } - - try { - return (String)(cpool[tcpx]); - } catch (ArrayIndexOutOfBoundsException e) { - return res; // "class #"+scpx+"// invalid constant pool index"; - } catch (ClassCastException e) { - return res; // "class #"+scpx+"// invalid constant pool reference"; - } catch (Throwable e) { - return res; // "#"+cpx+"// ERROR IN DISASSEMBLER"; - } - - } - - /** - * Returns the name of class at perticular index. - */ - public String getClassName(int cpx) { - String res="#"+cpx; - if (cpx==0) { - return res; - } - int scpx; - try { - if (tags[cpx]!=CONSTANT_CLASS) { - return res; //" "; - } - scpx=((CPX)cpool[cpx]).cpx; - } catch (ArrayIndexOutOfBoundsException e) { - return res; // "#"+cpx+"// invalid constant pool index"; - } catch (Throwable e) { - return res; // "#"+cpx+"// ERROR IN DISASSEMBLER"; - } - res="#"+scpx; - try { - return (String)(cpool[scpx]); - } catch (ArrayIndexOutOfBoundsException e) { - return res; // "class #"+scpx+"// invalid constant pool index"; - } catch (ClassCastException e) { - return res; // "class #"+scpx+"// invalid constant pool reference"; - } catch (Throwable e) { - return res; // "#"+cpx+"// ERROR IN DISASSEMBLER"; - } - } - - public int getAccessFlags() { - return access; - } - - /** - * Returns true if it is a class - */ - public boolean isClass() { - if((access & ACC_INTERFACE) == 0) return true; - return false; - } - - /** - * Returns true if it is a interface. - */ - public boolean isInterface(){ - if((access & ACC_INTERFACE) != 0) return true; - return false; - } - - /** - * Returns true if this member is public, false otherwise. - */ - public boolean isPublic(){ - return (access & ACC_PUBLIC) != 0; - } - - /** - * Returns the access of this class or interface. - */ - public String[] getAccess(){ - Vector v = new Vector(); - if ((access & ACC_PUBLIC) !=0) v.addElement("public"); - if ((access & ACC_FINAL) !=0) v.addElement("final"); - if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract"); - String[] accflags = new String[v.size()]; - v.copyInto(accflags); - return accflags; - } - - /** - * Returns list of innerclasses. - */ - public InnerClassData[] getInnerClasses(){ - return innerClasses; - } - - /** - * Returns list of attributes. - */ - final AttrData[] getAttributes(){ - return attrs; - } - - public byte[] findAnnotationData(boolean classRetention) { - String n = classRetention ? - "RuntimeInvisibleAnnotations" : // NOI18N - "RuntimeVisibleAnnotations"; // NOI18N - return findAttr(n, attrs); - } - - /** - * Returns true if superbit is set. - */ - public boolean isSuperSet(){ - if ((access & ACC_SUPER) !=0) return true; - return false; - } - - /** - * Returns super class name. - */ - public String getSuperClassName(){ - String res=null; - if (super_class==0) { - return res; - } - int scpx; - try { - if (tags[super_class]!=CONSTANT_CLASS) { - return res; //" "; - } - scpx=((CPX)cpool[super_class]).cpx; - } catch (ArrayIndexOutOfBoundsException e) { - return res; // "#"+cpx+"// invalid constant pool index"; - } catch (Throwable e) { - return res; // "#"+cpx+"// ERROR IN DISASSEMBLER"; - } - - try { - return (String)(cpool[scpx]); - } catch (ArrayIndexOutOfBoundsException e) { - return res; // "class #"+scpx+"// invalid constant pool index"; - } catch (ClassCastException e) { - return res; // "class #"+scpx+"// invalid constant pool reference"; - } catch (Throwable e) { - return res; // "#"+cpx+"// ERROR IN DISASSEMBLER"; - } - } - - /** - * Returns list of super interfaces. - */ - public String[] getSuperInterfaces(){ - String interfacenames[] = new String[interfaces.length]; - int interfacecpx = -1; - for(int i = 0; i < interfaces.length; i++){ - interfacecpx=((CPX)cpool[interfaces[i]]).cpx; - interfacenames[i] = (String)(cpool[interfacecpx]); - } - return interfacenames; - } - - /** - * Returns string at prticular constant pool index. - */ - public String getStringValue(int cpoolx) { - try { - return ((String)cpool[cpoolx]); - } catch (ArrayIndexOutOfBoundsException e) { - return "//invalid constant pool index:"+cpoolx; - } catch (ClassCastException e) { - return "//invalid constant pool ref:"+cpoolx; - } - } - - /** - * Returns list of field info. - */ - public FieldData[] getFields(){ - return fields; - } - - /** - * Returns list of method info. - */ - public MethodData[] getMethods(){ - return methods; - } - - /** - * Returns constant pool entry at that index. - */ - public CPX2 getCpoolEntry(int cpx){ - return ((CPX2)(cpool[cpx])); - } - - public Object getCpoolEntryobj(int cpx){ - return (cpool[cpx]); - } - - /** - * Returns index of this class. - */ - public int getthis_cpx(){ - return this_class; - } - - /** - * Returns string at that index. - */ - public String StringValue(int cpx) { - return stringValue(cpx, false); - } - public String stringValue(int cpx, boolean textual) { - return stringValue(cpx, textual, null); - } - public String stringValue(int cpx, String[] classRefs) { - return stringValue(cpx, true, classRefs); - } - private String stringValue(int cpx, boolean textual, String[] refs) { - if (cpx==0) return "#0"; - int tag; - Object x; - String suffix=""; - try { - tag=tags[cpx]; - x=cpool[cpx]; - } catch (IndexOutOfBoundsException e) { - return ""; - } - - if (x==null) return ""; - switch (tag) { - case CONSTANT_UTF8: { - if (!textual) { - return (String)x; - } - StringBuilder sb=new StringBuilder(); - String s=(String)x; - for (int k=0; k"; - } catch (ClassCastException e) { - return ""; - } - } - - /** - * Returns unqualified class name. - */ - public String getShortClassName(int cpx) { - String classname=javaName(getClassName(cpx)); - pkgPrefixLen=classname.lastIndexOf("/")+1; - if (pkgPrefixLen!=0) { - pkgPrefix=classname.substring(0,pkgPrefixLen); - if (classname.startsWith(pkgPrefix)) { - return classname.substring(pkgPrefixLen); - } - } - return classname; - } - - /** - * Returns source file name. - */ - public String getSourceName(){ - return getName(source_cpx); - } - - /** - * Returns package name. - */ - public String getPkgName(){ - String classname=getClassName(this_class); - pkgPrefixLen=classname.lastIndexOf("/")+1; - if (pkgPrefixLen!=0) { - pkgPrefix=classname.substring(0,pkgPrefixLen); - return("package "+pkgPrefix.substring(0,pkgPrefixLen-1)+";\n"); - }else return null; - } - - /** - * Returns total constant pool entry count. - */ - public int getCpoolCount(){ - return cpool_count; - } - - /** - * Returns minor version of class file. - */ - public int getMinor_version(){ - return minor_version; - } - - /** - * Returns major version of class file. - */ - public int getMajor_version(){ - return major_version; - } - - private boolean isJavaIdentifierStart(int cp) { - return ('a' <= cp && cp <= 'z') || ('A' <= cp && cp <= 'Z'); - } - - private boolean isJavaIdentifierPart(int cp) { - return isJavaIdentifierStart(cp) || ('0' <= cp && cp <= '9'); - } - - public String[] getNameAndType(int indx) { - return getNameAndType(indx, 0, new String[2]); - } - - private String[] getNameAndType(int indx, int at, String[] arr) { - CPX2 c2 = getCpoolEntry(indx); - arr[at] = StringValue(c2.cpx1); - arr[at + 1] = StringValue(c2.cpx2); - return arr; - } - - public String[] getFieldInfoName(int indx) { - CPX2 c2 = getCpoolEntry(indx); - String[] arr = new String[3]; - arr[0] = getClassName(c2.cpx1); - return getNameAndType(c2.cpx2, 1, arr); - } - - static byte[] findAttr(String n, AttrData[] attrs) { - for (AttrData ad : attrs) { - if (n.equals(ad.getAttrName())) { - return ad.getData(); - } - } - return null; - } -}