javap/src/main/java/sun/tools/javap/ClassData.java
author Jaroslav Tulach <jtulach@netbeans.org>
Fri, 09 Nov 2012 21:33:22 +0100
branchjavap
changeset 144 b06660b614db
child 149 32653a09f0db
permissions -rw-r--r--
javap as of revision jdk6-4ab5d66aaf2b
jtulach@144
     1
/*
jtulach@144
     2
 * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved.
jtulach@144
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jtulach@144
     4
 *
jtulach@144
     5
 * This code is free software; you can redistribute it and/or modify it
jtulach@144
     6
 * under the terms of the GNU General Public License version 2 only, as
jtulach@144
     7
 * published by the Free Software Foundation.  Oracle designates this
jtulach@144
     8
 * particular file as subject to the "Classpath" exception as provided
jtulach@144
     9
 * by Oracle in the LICENSE file that accompanied this code.
jtulach@144
    10
 *
jtulach@144
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
jtulach@144
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jtulach@144
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
jtulach@144
    14
 * version 2 for more details (a copy is included in the LICENSE file that
jtulach@144
    15
 * accompanied this code).
jtulach@144
    16
 *
jtulach@144
    17
 * You should have received a copy of the GNU General Public License version
jtulach@144
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
jtulach@144
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jtulach@144
    20
 *
jtulach@144
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jtulach@144
    22
 * or visit www.oracle.com if you need additional information or have any
jtulach@144
    23
 * questions.
jtulach@144
    24
 */
jtulach@144
    25
jtulach@144
    26
jtulach@144
    27
package sun.tools.javap;
jtulach@144
    28
jtulach@144
    29
import java.util.*;
jtulach@144
    30
import java.io.*;
jtulach@144
    31
jtulach@144
    32
/**
jtulach@144
    33
 * Central data repository of the Java Disassembler.
jtulach@144
    34
 * Stores all the information in java class file.
jtulach@144
    35
 *
jtulach@144
    36
 * @author  Sucheta Dambalkar (Adopted code from jdis)
jtulach@144
    37
 */
jtulach@144
    38
public class ClassData implements RuntimeConstants {
jtulach@144
    39
jtulach@144
    40
    private int magic;
jtulach@144
    41
    private int minor_version;
jtulach@144
    42
    private int major_version;
jtulach@144
    43
    private int cpool_count;
jtulach@144
    44
    private Object cpool[];
jtulach@144
    45
    private int access;
jtulach@144
    46
    private int this_class = 0;;
jtulach@144
    47
    private int super_class;
jtulach@144
    48
    private int interfaces_count;
jtulach@144
    49
    private int[] interfaces = new int[0];;
jtulach@144
    50
    private int fields_count;
jtulach@144
    51
    private FieldData[] fields;
jtulach@144
    52
    private int methods_count;
jtulach@144
    53
    private MethodData[] methods;
jtulach@144
    54
    private InnerClassData[] innerClasses;
jtulach@144
    55
    private int attributes_count;
jtulach@144
    56
    private AttrData[] attrs;
jtulach@144
    57
    private String classname;
jtulach@144
    58
    private String superclassname;
jtulach@144
    59
    private int source_cpx=0;
jtulach@144
    60
    private byte tags[];
jtulach@144
    61
    private Hashtable indexHashAscii = new Hashtable();
jtulach@144
    62
    private String pkgPrefix="";
jtulach@144
    63
    private int pkgPrefixLen=0;
jtulach@144
    64
jtulach@144
    65
    /**
jtulach@144
    66
     * Read classfile to disassemble.
jtulach@144
    67
     */
jtulach@144
    68
    public ClassData(InputStream infile){
jtulach@144
    69
        try{
jtulach@144
    70
            this.read(new DataInputStream(infile));
jtulach@144
    71
        }catch (FileNotFoundException ee) {
jtulach@144
    72
            error("cant read file");
jtulach@144
    73
        }catch (Error ee) {
jtulach@144
    74
            ee.printStackTrace();
jtulach@144
    75
            error("fatal error");
jtulach@144
    76
        } catch (Exception ee) {
jtulach@144
    77
            ee.printStackTrace();
jtulach@144
    78
            error("fatal exception");
jtulach@144
    79
        }
jtulach@144
    80
    }
jtulach@144
    81
jtulach@144
    82
    /**
jtulach@144
    83
     * Reads and stores class file information.
jtulach@144
    84
     */
jtulach@144
    85
    public void read(DataInputStream in) throws IOException {
jtulach@144
    86
        // Read the header
jtulach@144
    87
        magic = in.readInt();
jtulach@144
    88
        if (magic != JAVA_MAGIC) {
jtulach@144
    89
            throw new ClassFormatError("wrong magic: " +
jtulach@144
    90
                                       toHex(magic) + ", expected " +
jtulach@144
    91
                                       toHex(JAVA_MAGIC));
jtulach@144
    92
        }
jtulach@144
    93
        minor_version = in.readShort();
jtulach@144
    94
        major_version = in.readShort();
jtulach@144
    95
        if (major_version != JAVA_VERSION) {
jtulach@144
    96
        }
jtulach@144
    97
jtulach@144
    98
        // Read the constant pool
jtulach@144
    99
        readCP(in);
jtulach@144
   100
        access = in.readUnsignedShort();
jtulach@144
   101
        this_class = in.readUnsignedShort();
jtulach@144
   102
        super_class = in.readUnsignedShort();
jtulach@144
   103
jtulach@144
   104
        //Read interfaces.
jtulach@144
   105
        interfaces_count = in.readUnsignedShort();
jtulach@144
   106
        if(interfaces_count > 0){
jtulach@144
   107
            interfaces = new int[interfaces_count];
jtulach@144
   108
        }
jtulach@144
   109
        for (int i = 0; i < interfaces_count; i++) {
jtulach@144
   110
            interfaces[i]=in.readShort();
jtulach@144
   111
        }
jtulach@144
   112
jtulach@144
   113
        // Read the fields
jtulach@144
   114
        readFields(in);
jtulach@144
   115
jtulach@144
   116
        // Read the methods
jtulach@144
   117
        readMethods(in);
jtulach@144
   118
jtulach@144
   119
        // Read the attributes
jtulach@144
   120
        attributes_count = in.readUnsignedShort();
jtulach@144
   121
        attrs=new AttrData[attributes_count];
jtulach@144
   122
        for (int k = 0; k < attributes_count; k++) {
jtulach@144
   123
            int name_cpx=in.readUnsignedShort();
jtulach@144
   124
            if (getTag(name_cpx)==CONSTANT_UTF8
jtulach@144
   125
                && getString(name_cpx).equals("SourceFile")
jtulach@144
   126
                ){      if (in.readInt()!=2)
jtulach@144
   127
                    throw new ClassFormatError("invalid attr length");
jtulach@144
   128
                source_cpx=in.readUnsignedShort();
jtulach@144
   129
                AttrData attr=new AttrData(this);
jtulach@144
   130
                attr.read(name_cpx);
jtulach@144
   131
                attrs[k]=attr;
jtulach@144
   132
jtulach@144
   133
            } else if (getTag(name_cpx)==CONSTANT_UTF8
jtulach@144
   134
                       && getString(name_cpx).equals("InnerClasses")
jtulach@144
   135
                       ){       int length=in.readInt();
jtulach@144
   136
                       int num=in.readUnsignedShort();
jtulach@144
   137
                       if (2+num*8 != length)
jtulach@144
   138
                           throw new ClassFormatError("invalid attr length");
jtulach@144
   139
                       innerClasses=new InnerClassData[num];
jtulach@144
   140
                       for (int j = 0; j < num; j++) {
jtulach@144
   141
                           InnerClassData innerClass=new InnerClassData(this);
jtulach@144
   142
                           innerClass.read(in);
jtulach@144
   143
                           innerClasses[j]=innerClass;
jtulach@144
   144
                       }
jtulach@144
   145
                       AttrData attr=new AttrData(this);
jtulach@144
   146
                       attr.read(name_cpx);
jtulach@144
   147
                       attrs[k]=attr;
jtulach@144
   148
            } else {
jtulach@144
   149
                AttrData attr=new AttrData(this);
jtulach@144
   150
                attr.read(name_cpx, in);
jtulach@144
   151
                attrs[k]=attr;
jtulach@144
   152
            }
jtulach@144
   153
        }
jtulach@144
   154
        in.close();
jtulach@144
   155
    } // end ClassData.read()
jtulach@144
   156
jtulach@144
   157
    /**
jtulach@144
   158
     * Reads and stores constant pool info.
jtulach@144
   159
     */
jtulach@144
   160
    void readCP(DataInputStream in) throws IOException {
jtulach@144
   161
        cpool_count = in.readUnsignedShort();
jtulach@144
   162
        tags = new byte[cpool_count];
jtulach@144
   163
        cpool = new Object[cpool_count];
jtulach@144
   164
        for (int i = 1; i < cpool_count; i++) {
jtulach@144
   165
            byte tag = in.readByte();
jtulach@144
   166
jtulach@144
   167
            switch(tags[i] = tag) {
jtulach@144
   168
            case CONSTANT_UTF8:
jtulach@144
   169
                String str=in.readUTF();
jtulach@144
   170
                indexHashAscii.put(cpool[i] = str, new Integer(i));
jtulach@144
   171
                break;
jtulach@144
   172
            case CONSTANT_INTEGER:
jtulach@144
   173
                cpool[i] = new Integer(in.readInt());
jtulach@144
   174
                break;
jtulach@144
   175
            case CONSTANT_FLOAT:
jtulach@144
   176
                cpool[i] = new Float(in.readFloat());
jtulach@144
   177
                break;
jtulach@144
   178
            case CONSTANT_LONG:
jtulach@144
   179
                cpool[i++] = new Long(in.readLong());
jtulach@144
   180
                break;
jtulach@144
   181
            case CONSTANT_DOUBLE:
jtulach@144
   182
                cpool[i++] = new Double(in.readDouble());
jtulach@144
   183
                break;
jtulach@144
   184
            case CONSTANT_CLASS:
jtulach@144
   185
            case CONSTANT_STRING:
jtulach@144
   186
                cpool[i] = new CPX(in.readUnsignedShort());
jtulach@144
   187
                break;
jtulach@144
   188
jtulach@144
   189
            case CONSTANT_FIELD:
jtulach@144
   190
            case CONSTANT_METHOD:
jtulach@144
   191
            case CONSTANT_INTERFACEMETHOD:
jtulach@144
   192
            case CONSTANT_NAMEANDTYPE:
jtulach@144
   193
                cpool[i] = new CPX2(in.readUnsignedShort(), in.readUnsignedShort());
jtulach@144
   194
                break;
jtulach@144
   195
jtulach@144
   196
            case 0:
jtulach@144
   197
            default:
jtulach@144
   198
                throw new ClassFormatError("invalid constant type: " + (int)tags[i]);
jtulach@144
   199
            }
jtulach@144
   200
        }
jtulach@144
   201
    }
jtulach@144
   202
jtulach@144
   203
    /**
jtulach@144
   204
     * Reads and strores field info.
jtulach@144
   205
     */
jtulach@144
   206
    protected void readFields(DataInputStream in) throws IOException {
jtulach@144
   207
        int fields_count = in.readUnsignedShort();
jtulach@144
   208
        fields=new FieldData[fields_count];
jtulach@144
   209
        for (int k = 0; k < fields_count; k++) {
jtulach@144
   210
            FieldData field=new FieldData(this);
jtulach@144
   211
            field.read(in);
jtulach@144
   212
            fields[k]=field;
jtulach@144
   213
        }
jtulach@144
   214
    }
jtulach@144
   215
jtulach@144
   216
    /**
jtulach@144
   217
     * Reads and strores Method info.
jtulach@144
   218
     */
jtulach@144
   219
    protected void readMethods(DataInputStream in) throws IOException {
jtulach@144
   220
        int methods_count = in.readUnsignedShort();
jtulach@144
   221
        methods=new MethodData[methods_count];
jtulach@144
   222
        for (int k = 0; k < methods_count ; k++) {
jtulach@144
   223
            MethodData method=new MethodData(this);
jtulach@144
   224
            method.read(in);
jtulach@144
   225
            methods[k]=method;
jtulach@144
   226
        }
jtulach@144
   227
    }
jtulach@144
   228
jtulach@144
   229
    /**
jtulach@144
   230
     * get a string
jtulach@144
   231
     */
jtulach@144
   232
    public String getString(int n) {
jtulach@144
   233
        return (n == 0) ? null : (String)cpool[n];
jtulach@144
   234
    }
jtulach@144
   235
jtulach@144
   236
    /**
jtulach@144
   237
     * get the type of constant given an index
jtulach@144
   238
     */
jtulach@144
   239
    public byte getTag(int n) {
jtulach@144
   240
        try{
jtulach@144
   241
            return tags[n];
jtulach@144
   242
        } catch (ArrayIndexOutOfBoundsException e) {
jtulach@144
   243
            return (byte)100;
jtulach@144
   244
        }
jtulach@144
   245
    }
jtulach@144
   246
jtulach@144
   247
    static final String hexString="0123456789ABCDEF";
jtulach@144
   248
jtulach@144
   249
    public static char hexTable[]=hexString.toCharArray();
jtulach@144
   250
jtulach@144
   251
    static String toHex(long val, int width) {
jtulach@144
   252
        StringBuffer s = new StringBuffer();
jtulach@144
   253
        for (int i=width-1; i>=0; i--)
jtulach@144
   254
            s.append(hexTable[((int)(val>>(4*i)))&0xF]);
jtulach@144
   255
        return "0x"+s.toString();
jtulach@144
   256
    }
jtulach@144
   257
jtulach@144
   258
    static String toHex(long val) {
jtulach@144
   259
        int width;
jtulach@144
   260
        for (width=16; width>0; width--) {
jtulach@144
   261
            if ((val>>(width-1)*4)!=0) break;
jtulach@144
   262
        }
jtulach@144
   263
        return toHex(val, width);
jtulach@144
   264
    }
jtulach@144
   265
jtulach@144
   266
    static String toHex(int val) {
jtulach@144
   267
        int width;
jtulach@144
   268
        for (width=8; width>0; width--) {
jtulach@144
   269
            if ((val>>(width-1)*4)!=0) break;
jtulach@144
   270
        }
jtulach@144
   271
        return toHex(val, width);
jtulach@144
   272
    }
jtulach@144
   273
jtulach@144
   274
    public void error(String msg) {
jtulach@144
   275
        System.err.println("ERROR:" +msg);
jtulach@144
   276
    }
jtulach@144
   277
jtulach@144
   278
    /**
jtulach@144
   279
     * Returns the name of this class.
jtulach@144
   280
     */
jtulach@144
   281
    public String getClassName() {
jtulach@144
   282
        String res=null;
jtulach@144
   283
        if (this_class==0) {
jtulach@144
   284
            return res;
jtulach@144
   285
        }
jtulach@144
   286
        int tcpx;
jtulach@144
   287
        try {
jtulach@144
   288
            if (tags[this_class]!=CONSTANT_CLASS) {
jtulach@144
   289
                return res; //"<CP["+cpx+"] is not a Class> ";
jtulach@144
   290
            }
jtulach@144
   291
            tcpx=((CPX)cpool[this_class]).cpx;
jtulach@144
   292
        } catch (ArrayIndexOutOfBoundsException e) {
jtulach@144
   293
            return res; // "#"+cpx+"// invalid constant pool index";
jtulach@144
   294
        } catch (Throwable e) {
jtulach@144
   295
            return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
jtulach@144
   296
        }
jtulach@144
   297
jtulach@144
   298
        try {
jtulach@144
   299
            return (String)(cpool[tcpx]);
jtulach@144
   300
        } catch (ArrayIndexOutOfBoundsException e) {
jtulach@144
   301
            return  res; // "class #"+scpx+"// invalid constant pool index";
jtulach@144
   302
        } catch (ClassCastException e) {
jtulach@144
   303
            return  res; // "class #"+scpx+"// invalid constant pool reference";
jtulach@144
   304
        } catch (Throwable e) {
jtulach@144
   305
            return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
jtulach@144
   306
        }
jtulach@144
   307
jtulach@144
   308
    }
jtulach@144
   309
jtulach@144
   310
    /**
jtulach@144
   311
     * Returns the name of class at perticular index.
jtulach@144
   312
     */
jtulach@144
   313
    public String getClassName(int cpx) {
jtulach@144
   314
        String res="#"+cpx;
jtulach@144
   315
        if (cpx==0) {
jtulach@144
   316
            return res;
jtulach@144
   317
        }
jtulach@144
   318
        int scpx;
jtulach@144
   319
        try {
jtulach@144
   320
            if (tags[cpx]!=CONSTANT_CLASS) {
jtulach@144
   321
                return res; //"<CP["+cpx+"] is not a Class> ";
jtulach@144
   322
            }
jtulach@144
   323
            scpx=((CPX)cpool[cpx]).cpx;
jtulach@144
   324
        } catch (ArrayIndexOutOfBoundsException e) {
jtulach@144
   325
            return res; // "#"+cpx+"// invalid constant pool index";
jtulach@144
   326
        } catch (Throwable e) {
jtulach@144
   327
            return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
jtulach@144
   328
        }
jtulach@144
   329
        res="#"+scpx;
jtulach@144
   330
        try {
jtulach@144
   331
            return (String)(cpool[scpx]);
jtulach@144
   332
        } catch (ArrayIndexOutOfBoundsException e) {
jtulach@144
   333
            return  res; // "class #"+scpx+"// invalid constant pool index";
jtulach@144
   334
        } catch (ClassCastException e) {
jtulach@144
   335
            return  res; // "class #"+scpx+"// invalid constant pool reference";
jtulach@144
   336
        } catch (Throwable e) {
jtulach@144
   337
            return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
jtulach@144
   338
        }
jtulach@144
   339
    }
jtulach@144
   340
jtulach@144
   341
    /**
jtulach@144
   342
     * Returns true if it is a class
jtulach@144
   343
     */
jtulach@144
   344
    public boolean isClass() {
jtulach@144
   345
        if((access & ACC_INTERFACE) == 0) return true;
jtulach@144
   346
        return false;
jtulach@144
   347
    }
jtulach@144
   348
jtulach@144
   349
    /**
jtulach@144
   350
     * Returns true if it is a interface.
jtulach@144
   351
     */
jtulach@144
   352
    public boolean isInterface(){
jtulach@144
   353
        if((access & ACC_INTERFACE) != 0) return true;
jtulach@144
   354
        return false;
jtulach@144
   355
    }
jtulach@144
   356
jtulach@144
   357
    /**
jtulach@144
   358
     * Returns true if this member is public, false otherwise.
jtulach@144
   359
     */
jtulach@144
   360
    public boolean isPublic(){
jtulach@144
   361
        return (access & ACC_PUBLIC) != 0;
jtulach@144
   362
    }
jtulach@144
   363
jtulach@144
   364
    /**
jtulach@144
   365
     * Returns the access of this class or interface.
jtulach@144
   366
     */
jtulach@144
   367
    public String[] getAccess(){
jtulach@144
   368
        Vector v = new Vector();
jtulach@144
   369
        if ((access & ACC_PUBLIC)   !=0) v.addElement("public");
jtulach@144
   370
        if ((access & ACC_FINAL)    !=0) v.addElement("final");
jtulach@144
   371
        if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");
jtulach@144
   372
        String[] accflags = new String[v.size()];
jtulach@144
   373
        v.copyInto(accflags);
jtulach@144
   374
        return accflags;
jtulach@144
   375
    }
jtulach@144
   376
jtulach@144
   377
    /**
jtulach@144
   378
     * Returns list of innerclasses.
jtulach@144
   379
     */
jtulach@144
   380
    public InnerClassData[] getInnerClasses(){
jtulach@144
   381
        return innerClasses;
jtulach@144
   382
    }
jtulach@144
   383
jtulach@144
   384
    /**
jtulach@144
   385
     * Returns list of attributes.
jtulach@144
   386
     */
jtulach@144
   387
    public AttrData[] getAttributes(){
jtulach@144
   388
        return attrs;
jtulach@144
   389
    }
jtulach@144
   390
jtulach@144
   391
    /**
jtulach@144
   392
     * Returns true if superbit is set.
jtulach@144
   393
     */
jtulach@144
   394
    public boolean isSuperSet(){
jtulach@144
   395
        if ((access & ACC_SUPER)   !=0) return true;
jtulach@144
   396
        return false;
jtulach@144
   397
    }
jtulach@144
   398
jtulach@144
   399
    /**
jtulach@144
   400
     * Returns super class name.
jtulach@144
   401
     */
jtulach@144
   402
    public String getSuperClassName(){
jtulach@144
   403
        String res=null;
jtulach@144
   404
        if (super_class==0) {
jtulach@144
   405
            return res;
jtulach@144
   406
        }
jtulach@144
   407
        int scpx;
jtulach@144
   408
        try {
jtulach@144
   409
            if (tags[super_class]!=CONSTANT_CLASS) {
jtulach@144
   410
                return res; //"<CP["+cpx+"] is not a Class> ";
jtulach@144
   411
            }
jtulach@144
   412
            scpx=((CPX)cpool[super_class]).cpx;
jtulach@144
   413
        } catch (ArrayIndexOutOfBoundsException e) {
jtulach@144
   414
            return res; // "#"+cpx+"// invalid constant pool index";
jtulach@144
   415
        } catch (Throwable e) {
jtulach@144
   416
            return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
jtulach@144
   417
        }
jtulach@144
   418
jtulach@144
   419
        try {
jtulach@144
   420
            return (String)(cpool[scpx]);
jtulach@144
   421
        } catch (ArrayIndexOutOfBoundsException e) {
jtulach@144
   422
            return  res; // "class #"+scpx+"// invalid constant pool index";
jtulach@144
   423
        } catch (ClassCastException e) {
jtulach@144
   424
            return  res; // "class #"+scpx+"// invalid constant pool reference";
jtulach@144
   425
        } catch (Throwable e) {
jtulach@144
   426
            return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
jtulach@144
   427
        }
jtulach@144
   428
    }
jtulach@144
   429
jtulach@144
   430
    /**
jtulach@144
   431
     * Returns list of super interfaces.
jtulach@144
   432
     */
jtulach@144
   433
    public String[] getSuperInterfaces(){
jtulach@144
   434
        String interfacenames[] = new String[interfaces.length];
jtulach@144
   435
        int interfacecpx = -1;
jtulach@144
   436
        for(int i = 0; i < interfaces.length; i++){
jtulach@144
   437
            interfacecpx=((CPX)cpool[interfaces[i]]).cpx;
jtulach@144
   438
            interfacenames[i] = (String)(cpool[interfacecpx]);
jtulach@144
   439
        }
jtulach@144
   440
        return interfacenames;
jtulach@144
   441
    }
jtulach@144
   442
jtulach@144
   443
    /**
jtulach@144
   444
     * Returns string at prticular constant pool index.
jtulach@144
   445
     */
jtulach@144
   446
    public String getStringValue(int cpoolx) {
jtulach@144
   447
        try {
jtulach@144
   448
            return ((String)cpool[cpoolx]);
jtulach@144
   449
        } catch (ArrayIndexOutOfBoundsException e) {
jtulach@144
   450
            return "//invalid constant pool index:"+cpoolx;
jtulach@144
   451
        } catch (ClassCastException e) {
jtulach@144
   452
            return "//invalid constant pool ref:"+cpoolx;
jtulach@144
   453
        }
jtulach@144
   454
    }
jtulach@144
   455
jtulach@144
   456
    /**
jtulach@144
   457
     * Returns list of field info.
jtulach@144
   458
     */
jtulach@144
   459
    public  FieldData[] getFields(){
jtulach@144
   460
        return fields;
jtulach@144
   461
    }
jtulach@144
   462
jtulach@144
   463
    /**
jtulach@144
   464
     * Returns list of method info.
jtulach@144
   465
     */
jtulach@144
   466
    public  MethodData[] getMethods(){
jtulach@144
   467
        return methods;
jtulach@144
   468
    }
jtulach@144
   469
jtulach@144
   470
    /**
jtulach@144
   471
     * Returns constant pool entry at that index.
jtulach@144
   472
     */
jtulach@144
   473
    public CPX2 getCpoolEntry(int cpx){
jtulach@144
   474
        return ((CPX2)(cpool[cpx]));
jtulach@144
   475
    }
jtulach@144
   476
jtulach@144
   477
    public Object getCpoolEntryobj(int cpx){
jtulach@144
   478
        return (cpool[cpx]);
jtulach@144
   479
    }
jtulach@144
   480
jtulach@144
   481
    /**
jtulach@144
   482
     * Returns index of this class.
jtulach@144
   483
     */
jtulach@144
   484
    public int getthis_cpx(){
jtulach@144
   485
        return this_class;
jtulach@144
   486
    }
jtulach@144
   487
jtulach@144
   488
    public String TagString (int tag) {
jtulach@144
   489
        String res=Tables.tagName(tag);
jtulach@144
   490
        if (res==null)  return "BOGUS_TAG:"+tag;
jtulach@144
   491
        return res;
jtulach@144
   492
    }
jtulach@144
   493
jtulach@144
   494
    /**
jtulach@144
   495
     * Returns string at that index.
jtulach@144
   496
     */
jtulach@144
   497
    public String StringValue(int cpx) {
jtulach@144
   498
        if (cpx==0) return "#0";
jtulach@144
   499
        int tag;
jtulach@144
   500
        Object x;
jtulach@144
   501
        String suffix="";
jtulach@144
   502
        try {
jtulach@144
   503
            tag=tags[cpx];
jtulach@144
   504
            x=cpool[cpx];
jtulach@144
   505
        } catch (IndexOutOfBoundsException e) {
jtulach@144
   506
            return "<Incorrect CP index:"+cpx+">";
jtulach@144
   507
        }
jtulach@144
   508
jtulach@144
   509
        if (x==null) return "<NULL>";
jtulach@144
   510
        switch (tag) {
jtulach@144
   511
        case CONSTANT_UTF8: {
jtulach@144
   512
            StringBuffer sb=new StringBuffer();
jtulach@144
   513
            String s=(String)x;
jtulach@144
   514
            for (int k=0; k<s.length(); k++) {
jtulach@144
   515
                char c=s.charAt(k);
jtulach@144
   516
                switch (c) {
jtulach@144
   517
                case '\t': sb.append('\\').append('t'); break;
jtulach@144
   518
                case '\n': sb.append('\\').append('n'); break;
jtulach@144
   519
                case '\r': sb.append('\\').append('r'); break;
jtulach@144
   520
                case '\"': sb.append('\\').append('\"'); break;
jtulach@144
   521
                default: sb.append(c);
jtulach@144
   522
                }
jtulach@144
   523
            }
jtulach@144
   524
            return sb.toString();
jtulach@144
   525
        }
jtulach@144
   526
        case CONSTANT_DOUBLE: {
jtulach@144
   527
            Double d=(Double)x;
jtulach@144
   528
            String sd=d.toString();
jtulach@144
   529
            return sd+"d";
jtulach@144
   530
        }
jtulach@144
   531
        case CONSTANT_FLOAT: {
jtulach@144
   532
            Float f=(Float)x;
jtulach@144
   533
            String sf=(f).toString();
jtulach@144
   534
            return sf+"f";
jtulach@144
   535
        }
jtulach@144
   536
        case CONSTANT_LONG: {
jtulach@144
   537
            Long ln = (Long)x;
jtulach@144
   538
            return ln.toString()+'l';
jtulach@144
   539
        }
jtulach@144
   540
        case CONSTANT_INTEGER: {
jtulach@144
   541
            Integer in = (Integer)x;
jtulach@144
   542
            return in.toString();
jtulach@144
   543
        }
jtulach@144
   544
        case CONSTANT_CLASS:
jtulach@144
   545
            return javaName(getClassName(cpx));
jtulach@144
   546
        case CONSTANT_STRING:
jtulach@144
   547
            return StringValue(((CPX)x).cpx);
jtulach@144
   548
        case CONSTANT_FIELD:
jtulach@144
   549
        case CONSTANT_METHOD:
jtulach@144
   550
        case CONSTANT_INTERFACEMETHOD:
jtulach@144
   551
            //return getShortClassName(((CPX2)x).cpx1)+"."+StringValue(((CPX2)x).cpx2);
jtulach@144
   552
             return javaName(getClassName(((CPX2)x).cpx1))+"."+StringValue(((CPX2)x).cpx2);
jtulach@144
   553
jtulach@144
   554
        case CONSTANT_NAMEANDTYPE:
jtulach@144
   555
            return getName(((CPX2)x).cpx1)+":"+StringValue(((CPX2)x).cpx2);
jtulach@144
   556
        default:
jtulach@144
   557
            return "UnknownTag"; //TBD
jtulach@144
   558
        }
jtulach@144
   559
    }
jtulach@144
   560
jtulach@144
   561
    /**
jtulach@144
   562
     * Returns resolved java type name.
jtulach@144
   563
     */
jtulach@144
   564
    public String javaName(String name) {
jtulach@144
   565
        if( name==null) return "null";
jtulach@144
   566
        int len=name.length();
jtulach@144
   567
        if (len==0) return "\"\"";
jtulach@144
   568
        int cc='/';
jtulach@144
   569
    fullname: { // xxx/yyy/zzz
jtulach@144
   570
            int cp;
jtulach@144
   571
            for (int k=0; k<len; k += Character.charCount(cp)) {
jtulach@144
   572
                cp=name.codePointAt(k);
jtulach@144
   573
                if (cc=='/') {
jtulach@144
   574
                    if (!Character.isJavaIdentifierStart(cp)) break fullname;
jtulach@144
   575
                } else if (cp!='/') {
jtulach@144
   576
                    if (!Character.isJavaIdentifierPart(cp)) break fullname;
jtulach@144
   577
                }
jtulach@144
   578
                cc=cp;
jtulach@144
   579
            }
jtulach@144
   580
            return name;
jtulach@144
   581
        }
jtulach@144
   582
        return "\""+name+"\"";
jtulach@144
   583
    }
jtulach@144
   584
jtulach@144
   585
    public String getName(int cpx) {
jtulach@144
   586
        String res;
jtulach@144
   587
        try {
jtulach@144
   588
            return javaName((String)cpool[cpx]); //.replace('/','.');
jtulach@144
   589
        } catch (ArrayIndexOutOfBoundsException e) {
jtulach@144
   590
            return "<invalid constant pool index:"+cpx+">";
jtulach@144
   591
        } catch (ClassCastException e) {
jtulach@144
   592
            return "<invalid constant pool ref:"+cpx+">";
jtulach@144
   593
        }
jtulach@144
   594
    }
jtulach@144
   595
jtulach@144
   596
    /**
jtulach@144
   597
     * Returns unqualified class name.
jtulach@144
   598
     */
jtulach@144
   599
    public String getShortClassName(int cpx) {
jtulach@144
   600
        String classname=javaName(getClassName(cpx));
jtulach@144
   601
        pkgPrefixLen=classname.lastIndexOf("/")+1;
jtulach@144
   602
        if (pkgPrefixLen!=0) {
jtulach@144
   603
            pkgPrefix=classname.substring(0,pkgPrefixLen);
jtulach@144
   604
            if (classname.startsWith(pkgPrefix)) {
jtulach@144
   605
                return classname.substring(pkgPrefixLen);
jtulach@144
   606
            }
jtulach@144
   607
        }
jtulach@144
   608
        return classname;
jtulach@144
   609
    }
jtulach@144
   610
jtulach@144
   611
    /**
jtulach@144
   612
     * Returns source file name.
jtulach@144
   613
     */
jtulach@144
   614
    public String getSourceName(){
jtulach@144
   615
        return getName(source_cpx);
jtulach@144
   616
    }
jtulach@144
   617
jtulach@144
   618
    /**
jtulach@144
   619
     * Returns package name.
jtulach@144
   620
     */
jtulach@144
   621
    public String getPkgName(){
jtulach@144
   622
        String classname=getClassName(this_class);
jtulach@144
   623
        pkgPrefixLen=classname.lastIndexOf("/")+1;
jtulach@144
   624
        if (pkgPrefixLen!=0) {
jtulach@144
   625
            pkgPrefix=classname.substring(0,pkgPrefixLen);
jtulach@144
   626
            return("package  "+pkgPrefix.substring(0,pkgPrefixLen-1)+";\n");
jtulach@144
   627
        }else return null;
jtulach@144
   628
    }
jtulach@144
   629
jtulach@144
   630
    /**
jtulach@144
   631
     * Returns total constant pool entry count.
jtulach@144
   632
     */
jtulach@144
   633
    public int getCpoolCount(){
jtulach@144
   634
        return cpool_count;
jtulach@144
   635
    }
jtulach@144
   636
jtulach@144
   637
    public String StringTag(int cpx) {
jtulach@144
   638
        byte tag=0;
jtulach@144
   639
        String str=null;
jtulach@144
   640
        try {
jtulach@144
   641
            if (cpx==0) throw new IndexOutOfBoundsException();
jtulach@144
   642
            tag=tags[cpx];
jtulach@144
   643
            return      TagString(tag);
jtulach@144
   644
        } catch (IndexOutOfBoundsException e) {
jtulach@144
   645
            str="Incorrect CP index:"+cpx;
jtulach@144
   646
        }
jtulach@144
   647
        return str;
jtulach@144
   648
    }
jtulach@144
   649
jtulach@144
   650
    /**
jtulach@144
   651
     * Returns minor version of class file.
jtulach@144
   652
     */
jtulach@144
   653
    public int getMinor_version(){
jtulach@144
   654
        return minor_version;
jtulach@144
   655
    }
jtulach@144
   656
jtulach@144
   657
    /**
jtulach@144
   658
     * Returns major version of class file.
jtulach@144
   659
     */
jtulach@144
   660
    public int getMajor_version(){
jtulach@144
   661
        return major_version;
jtulach@144
   662
    }
jtulach@144
   663
}