jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java
author chegar
Sun, 17 Aug 2014 15:51:56 +0100
changeset 25868 686eef1e7a79
parent 12457 jaxp/src/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java@c348e06f0e82
child 44797 8b3b3b911b8a
permissions -rw-r--r--
8054834: Modular Source Code Reviewed-by: alanb, chegar, ihse, mduigou Contributed-by: alan.bateman@oracle.com, alex.buckley@oracle.com, chris.hegarty@oracle.com, erik.joelsson@oracle.com, jonathan.gibbons@oracle.com, karen.kinnear@oracle.com, magnus.ihse.bursie@oracle.com, mandy.chung@oracle.com, mark.reinhold@oracle.com, paul.sandoz@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6
7f561c08de6b Initial load
duke
parents:
diff changeset
     1
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
     2
 * reserved comment block
7f561c08de6b Initial load
duke
parents:
diff changeset
     3
 * DO NOT REMOVE OR ALTER!
7f561c08de6b Initial load
duke
parents:
diff changeset
     4
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
     5
package com.sun.org.apache.bcel.internal.classfile;
7f561c08de6b Initial load
duke
parents:
diff changeset
     6
7f561c08de6b Initial load
duke
parents:
diff changeset
     7
/* ====================================================================
7f561c08de6b Initial load
duke
parents:
diff changeset
     8
 * The Apache Software License, Version 1.1
7f561c08de6b Initial load
duke
parents:
diff changeset
     9
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    10
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
7f561c08de6b Initial load
duke
parents:
diff changeset
    11
 * reserved.
7f561c08de6b Initial load
duke
parents:
diff changeset
    12
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    13
 * Redistribution and use in source and binary forms, with or without
7f561c08de6b Initial load
duke
parents:
diff changeset
    14
 * modification, are permitted provided that the following conditions
7f561c08de6b Initial load
duke
parents:
diff changeset
    15
 * are met:
7f561c08de6b Initial load
duke
parents:
diff changeset
    16
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    17
 * 1. Redistributions of source code must retain the above copyright
7f561c08de6b Initial load
duke
parents:
diff changeset
    18
 *    notice, this list of conditions and the following disclaimer.
7f561c08de6b Initial load
duke
parents:
diff changeset
    19
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    20
 * 2. Redistributions in binary form must reproduce the above copyright
7f561c08de6b Initial load
duke
parents:
diff changeset
    21
 *    notice, this list of conditions and the following disclaimer in
7f561c08de6b Initial load
duke
parents:
diff changeset
    22
 *    the documentation and/or other materials provided with the
7f561c08de6b Initial load
duke
parents:
diff changeset
    23
 *    distribution.
7f561c08de6b Initial load
duke
parents:
diff changeset
    24
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    25
 * 3. The end-user documentation included with the redistribution,
7f561c08de6b Initial load
duke
parents:
diff changeset
    26
 *    if any, must include the following acknowledgment:
7f561c08de6b Initial load
duke
parents:
diff changeset
    27
 *       "This product includes software developed by the
7f561c08de6b Initial load
duke
parents:
diff changeset
    28
 *        Apache Software Foundation (http://www.apache.org/)."
7f561c08de6b Initial load
duke
parents:
diff changeset
    29
 *    Alternately, this acknowledgment may appear in the software itself,
7f561c08de6b Initial load
duke
parents:
diff changeset
    30
 *    if and wherever such third-party acknowledgments normally appear.
7f561c08de6b Initial load
duke
parents:
diff changeset
    31
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    32
 * 4. The names "Apache" and "Apache Software Foundation" and
7f561c08de6b Initial load
duke
parents:
diff changeset
    33
 *    "Apache BCEL" must not be used to endorse or promote products
7f561c08de6b Initial load
duke
parents:
diff changeset
    34
 *    derived from this software without prior written permission. For
7f561c08de6b Initial load
duke
parents:
diff changeset
    35
 *    written permission, please contact apache@apache.org.
7f561c08de6b Initial load
duke
parents:
diff changeset
    36
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    37
 * 5. Products derived from this software may not be called "Apache",
7f561c08de6b Initial load
duke
parents:
diff changeset
    38
 *    "Apache BCEL", nor may "Apache" appear in their name, without
7f561c08de6b Initial load
duke
parents:
diff changeset
    39
 *    prior written permission of the Apache Software Foundation.
7f561c08de6b Initial load
duke
parents:
diff changeset
    40
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    41
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
7f561c08de6b Initial load
duke
parents:
diff changeset
    42
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
7f561c08de6b Initial load
duke
parents:
diff changeset
    43
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7f561c08de6b Initial load
duke
parents:
diff changeset
    44
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
7f561c08de6b Initial load
duke
parents:
diff changeset
    45
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
7f561c08de6b Initial load
duke
parents:
diff changeset
    46
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
7f561c08de6b Initial load
duke
parents:
diff changeset
    47
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
7f561c08de6b Initial load
duke
parents:
diff changeset
    48
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7f561c08de6b Initial load
duke
parents:
diff changeset
    49
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
7f561c08de6b Initial load
duke
parents:
diff changeset
    50
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
7f561c08de6b Initial load
duke
parents:
diff changeset
    51
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7f561c08de6b Initial load
duke
parents:
diff changeset
    52
 * SUCH DAMAGE.
7f561c08de6b Initial load
duke
parents:
diff changeset
    53
 * ====================================================================
7f561c08de6b Initial load
duke
parents:
diff changeset
    54
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    55
 * This software consists of voluntary contributions made by many
7f561c08de6b Initial load
duke
parents:
diff changeset
    56
 * individuals on behalf of the Apache Software Foundation.  For more
7f561c08de6b Initial load
duke
parents:
diff changeset
    57
 * information on the Apache Software Foundation, please see
7f561c08de6b Initial load
duke
parents:
diff changeset
    58
 * <http://www.apache.org/>.
7f561c08de6b Initial load
duke
parents:
diff changeset
    59
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    60
7f561c08de6b Initial load
duke
parents:
diff changeset
    61
import  com.sun.org.apache.bcel.internal.Constants;
7f561c08de6b Initial load
duke
parents:
diff changeset
    62
import  java.io.*;
7f561c08de6b Initial load
duke
parents:
diff changeset
    63
7f561c08de6b Initial load
duke
parents:
diff changeset
    64
/**
7f561c08de6b Initial load
duke
parents:
diff changeset
    65
 * This class represents the constant pool, i.e., a table of constants, of
7f561c08de6b Initial load
duke
parents:
diff changeset
    66
 * a parsed classfile. It may contain null references, due to the JVM
7f561c08de6b Initial load
duke
parents:
diff changeset
    67
 * specification that skips an entry after an 8-byte constant (double,
7f561c08de6b Initial load
duke
parents:
diff changeset
    68
 * long) entry.  Those interested in generating constant pools
7f561c08de6b Initial load
duke
parents:
diff changeset
    69
 * programatically should see <a href="../generic/ConstantPoolGen.html">
7f561c08de6b Initial load
duke
parents:
diff changeset
    70
 * ConstantPoolGen</a>.
7f561c08de6b Initial load
duke
parents:
diff changeset
    71
7f561c08de6b Initial load
duke
parents:
diff changeset
    72
 * @see     Constant
7f561c08de6b Initial load
duke
parents:
diff changeset
    73
 * @see     com.sun.org.apache.bcel.internal.generic.ConstantPoolGen
7f561c08de6b Initial load
duke
parents:
diff changeset
    74
 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
7f561c08de6b Initial load
duke
parents:
diff changeset
    75
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    76
public class ConstantPool implements Cloneable, Node, Serializable {
7f561c08de6b Initial load
duke
parents:
diff changeset
    77
  private int        constant_pool_count;
7f561c08de6b Initial load
duke
parents:
diff changeset
    78
  private Constant[] constant_pool;
7f561c08de6b Initial load
duke
parents:
diff changeset
    79
7f561c08de6b Initial load
duke
parents:
diff changeset
    80
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    81
   * @param constant_pool Array of constants
7f561c08de6b Initial load
duke
parents:
diff changeset
    82
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
    83
  public ConstantPool(Constant[] constant_pool)
7f561c08de6b Initial load
duke
parents:
diff changeset
    84
  {
7f561c08de6b Initial load
duke
parents:
diff changeset
    85
    setConstantPool(constant_pool);
7f561c08de6b Initial load
duke
parents:
diff changeset
    86
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
    87
7f561c08de6b Initial load
duke
parents:
diff changeset
    88
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    89
   * Read constants from given file stream.
7f561c08de6b Initial load
duke
parents:
diff changeset
    90
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
    91
   * @param file Input stream
7f561c08de6b Initial load
duke
parents:
diff changeset
    92
   * @throws IOException
7f561c08de6b Initial load
duke
parents:
diff changeset
    93
   * @throws ClassFormatException
7f561c08de6b Initial load
duke
parents:
diff changeset
    94
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
    95
  ConstantPool(DataInputStream file) throws IOException, ClassFormatException
7f561c08de6b Initial load
duke
parents:
diff changeset
    96
  {
7f561c08de6b Initial load
duke
parents:
diff changeset
    97
    byte tag;
7f561c08de6b Initial load
duke
parents:
diff changeset
    98
7f561c08de6b Initial load
duke
parents:
diff changeset
    99
    constant_pool_count = file.readUnsignedShort();
7f561c08de6b Initial load
duke
parents:
diff changeset
   100
    constant_pool       = new Constant[constant_pool_count];
7f561c08de6b Initial load
duke
parents:
diff changeset
   101
7f561c08de6b Initial load
duke
parents:
diff changeset
   102
    /* constant_pool[0] is unused by the compiler and may be used freely
7f561c08de6b Initial load
duke
parents:
diff changeset
   103
     * by the implementation.
7f561c08de6b Initial load
duke
parents:
diff changeset
   104
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   105
    for(int i=1; i < constant_pool_count; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   106
      constant_pool[i] = Constant.readConstant(file);
7f561c08de6b Initial load
duke
parents:
diff changeset
   107
7f561c08de6b Initial load
duke
parents:
diff changeset
   108
      /* Quote from the JVM specification:
7f561c08de6b Initial load
duke
parents:
diff changeset
   109
       * "All eight byte constants take up two spots in the constant pool.
7f561c08de6b Initial load
duke
parents:
diff changeset
   110
       * If this is the n'th byte in the constant pool, then the next item
7f561c08de6b Initial load
duke
parents:
diff changeset
   111
       * will be numbered n+2"
7f561c08de6b Initial load
duke
parents:
diff changeset
   112
       *
7f561c08de6b Initial load
duke
parents:
diff changeset
   113
       * Thus we have to increment the index counter.
7f561c08de6b Initial load
duke
parents:
diff changeset
   114
       */
7f561c08de6b Initial load
duke
parents:
diff changeset
   115
      tag = constant_pool[i].getTag();
7f561c08de6b Initial load
duke
parents:
diff changeset
   116
      if((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long))
7f561c08de6b Initial load
duke
parents:
diff changeset
   117
        i++;
7f561c08de6b Initial load
duke
parents:
diff changeset
   118
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   119
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   120
7f561c08de6b Initial load
duke
parents:
diff changeset
   121
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   122
   * Called by objects that are traversing the nodes of the tree implicitely
7f561c08de6b Initial load
duke
parents:
diff changeset
   123
   * defined by the contents of a Java class. I.e., the hierarchy of methods,
7f561c08de6b Initial load
duke
parents:
diff changeset
   124
   * fields, attributes, etc. spawns a tree of objects.
7f561c08de6b Initial load
duke
parents:
diff changeset
   125
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   126
   * @param v Visitor object
7f561c08de6b Initial load
duke
parents:
diff changeset
   127
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   128
  public void accept(Visitor v) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   129
    v.visitConstantPool(this);
7f561c08de6b Initial load
duke
parents:
diff changeset
   130
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   131
7f561c08de6b Initial load
duke
parents:
diff changeset
   132
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   133
   * Resolve constant to a string representation.
7f561c08de6b Initial load
duke
parents:
diff changeset
   134
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   135
   * @param  constant Constant to be printed
7f561c08de6b Initial load
duke
parents:
diff changeset
   136
   * @return String representation
7f561c08de6b Initial load
duke
parents:
diff changeset
   137
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   138
  public String constantToString(Constant c)
7f561c08de6b Initial load
duke
parents:
diff changeset
   139
       throws ClassFormatException
7f561c08de6b Initial load
duke
parents:
diff changeset
   140
  {
7f561c08de6b Initial load
duke
parents:
diff changeset
   141
    String   str;
7f561c08de6b Initial load
duke
parents:
diff changeset
   142
    int      i;
7f561c08de6b Initial load
duke
parents:
diff changeset
   143
    byte     tag = c.getTag();
7f561c08de6b Initial load
duke
parents:
diff changeset
   144
7f561c08de6b Initial load
duke
parents:
diff changeset
   145
    switch(tag) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   146
    case Constants.CONSTANT_Class:
7f561c08de6b Initial load
duke
parents:
diff changeset
   147
      i   = ((ConstantClass)c).getNameIndex();
7f561c08de6b Initial load
duke
parents:
diff changeset
   148
      c   = getConstant(i, Constants.CONSTANT_Utf8);
7f561c08de6b Initial load
duke
parents:
diff changeset
   149
      str = Utility.compactClassName(((ConstantUtf8)c).getBytes(), false);
7f561c08de6b Initial load
duke
parents:
diff changeset
   150
      break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   151
7f561c08de6b Initial load
duke
parents:
diff changeset
   152
    case Constants.CONSTANT_String:
7f561c08de6b Initial load
duke
parents:
diff changeset
   153
      i   = ((ConstantString)c).getStringIndex();
7f561c08de6b Initial load
duke
parents:
diff changeset
   154
      c   = getConstant(i, Constants.CONSTANT_Utf8);
7f561c08de6b Initial load
duke
parents:
diff changeset
   155
      str = "\"" + escape(((ConstantUtf8)c).getBytes()) + "\"";
7f561c08de6b Initial load
duke
parents:
diff changeset
   156
      break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   157
7f561c08de6b Initial load
duke
parents:
diff changeset
   158
    case Constants.CONSTANT_Utf8:    str = ((ConstantUtf8)c).getBytes();         break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   159
    case Constants.CONSTANT_Double:  str = "" + ((ConstantDouble)c).getBytes();  break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   160
    case Constants.CONSTANT_Float:   str = "" + ((ConstantFloat)c).getBytes();   break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   161
    case Constants.CONSTANT_Long:    str = "" + ((ConstantLong)c).getBytes();    break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   162
    case Constants.CONSTANT_Integer: str = "" + ((ConstantInteger)c).getBytes(); break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   163
7f561c08de6b Initial load
duke
parents:
diff changeset
   164
    case Constants.CONSTANT_NameAndType:
7f561c08de6b Initial load
duke
parents:
diff changeset
   165
      str = (constantToString(((ConstantNameAndType)c).getNameIndex(),
7f561c08de6b Initial load
duke
parents:
diff changeset
   166
                              Constants.CONSTANT_Utf8) + " " +
7f561c08de6b Initial load
duke
parents:
diff changeset
   167
             constantToString(((ConstantNameAndType)c).getSignatureIndex(),
7f561c08de6b Initial load
duke
parents:
diff changeset
   168
                              Constants.CONSTANT_Utf8));
7f561c08de6b Initial load
duke
parents:
diff changeset
   169
      break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   170
7f561c08de6b Initial load
duke
parents:
diff changeset
   171
    case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref:
7f561c08de6b Initial load
duke
parents:
diff changeset
   172
    case Constants.CONSTANT_Fieldref:
7f561c08de6b Initial load
duke
parents:
diff changeset
   173
      str = (constantToString(((ConstantCP)c).getClassIndex(),
7f561c08de6b Initial load
duke
parents:
diff changeset
   174
                              Constants.CONSTANT_Class) + "." +
7f561c08de6b Initial load
duke
parents:
diff changeset
   175
             constantToString(((ConstantCP)c).getNameAndTypeIndex(),
7f561c08de6b Initial load
duke
parents:
diff changeset
   176
                              Constants.CONSTANT_NameAndType));
7f561c08de6b Initial load
duke
parents:
diff changeset
   177
      break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   178
7f561c08de6b Initial load
duke
parents:
diff changeset
   179
    default: // Never reached
7f561c08de6b Initial load
duke
parents:
diff changeset
   180
      throw new RuntimeException("Unknown constant type " + tag);
7f561c08de6b Initial load
duke
parents:
diff changeset
   181
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   182
7f561c08de6b Initial load
duke
parents:
diff changeset
   183
    return str;
7f561c08de6b Initial load
duke
parents:
diff changeset
   184
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   185
7f561c08de6b Initial load
duke
parents:
diff changeset
   186
  private static final String escape(String str) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   187
    int          len = str.length();
7f561c08de6b Initial load
duke
parents:
diff changeset
   188
    StringBuffer buf = new StringBuffer(len + 5);
7f561c08de6b Initial load
duke
parents:
diff changeset
   189
    char[]       ch  = str.toCharArray();
7f561c08de6b Initial load
duke
parents:
diff changeset
   190
7f561c08de6b Initial load
duke
parents:
diff changeset
   191
    for(int i=0; i < len; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   192
      switch(ch[i]) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   193
      case '\n' : buf.append("\\n"); break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   194
      case '\r' : buf.append("\\r"); break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   195
      case '\t' : buf.append("\\t"); break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   196
      case '\b' : buf.append("\\b"); break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   197
      case '"'  : buf.append("\\\""); break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   198
      default: buf.append(ch[i]);
7f561c08de6b Initial load
duke
parents:
diff changeset
   199
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   200
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   201
7f561c08de6b Initial load
duke
parents:
diff changeset
   202
    return buf.toString();
7f561c08de6b Initial load
duke
parents:
diff changeset
   203
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   204
7f561c08de6b Initial load
duke
parents:
diff changeset
   205
7f561c08de6b Initial load
duke
parents:
diff changeset
   206
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   207
   * Retrieve constant at `index' from constant pool and resolve it to
7f561c08de6b Initial load
duke
parents:
diff changeset
   208
   * a string representation.
7f561c08de6b Initial load
duke
parents:
diff changeset
   209
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   210
   * @param  index of constant in constant pool
7f561c08de6b Initial load
duke
parents:
diff changeset
   211
   * @param  tag expected type
7f561c08de6b Initial load
duke
parents:
diff changeset
   212
   * @return String representation
7f561c08de6b Initial load
duke
parents:
diff changeset
   213
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   214
  public String constantToString(int index, byte tag)
7f561c08de6b Initial load
duke
parents:
diff changeset
   215
       throws ClassFormatException
7f561c08de6b Initial load
duke
parents:
diff changeset
   216
  {
7f561c08de6b Initial load
duke
parents:
diff changeset
   217
    Constant c = getConstant(index, tag);
7f561c08de6b Initial load
duke
parents:
diff changeset
   218
    return constantToString(c);
7f561c08de6b Initial load
duke
parents:
diff changeset
   219
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   220
7f561c08de6b Initial load
duke
parents:
diff changeset
   221
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   222
   * Dump constant pool to file stream in binary format.
7f561c08de6b Initial load
duke
parents:
diff changeset
   223
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   224
   * @param file Output file stream
7f561c08de6b Initial load
duke
parents:
diff changeset
   225
   * @throws IOException
7f561c08de6b Initial load
duke
parents:
diff changeset
   226
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   227
  public void dump(DataOutputStream file) throws IOException
7f561c08de6b Initial load
duke
parents:
diff changeset
   228
  {
7f561c08de6b Initial load
duke
parents:
diff changeset
   229
    file.writeShort(constant_pool_count);
7f561c08de6b Initial load
duke
parents:
diff changeset
   230
7f561c08de6b Initial load
duke
parents:
diff changeset
   231
    for(int i=1; i < constant_pool_count; i++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   232
      if(constant_pool[i] != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   233
        constant_pool[i].dump(file);
7f561c08de6b Initial load
duke
parents:
diff changeset
   234
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   235
7f561c08de6b Initial load
duke
parents:
diff changeset
   236
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   237
   * Get constant from constant pool.
7f561c08de6b Initial load
duke
parents:
diff changeset
   238
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   239
   * @param  index Index in constant pool
7f561c08de6b Initial load
duke
parents:
diff changeset
   240
   * @return Constant value
7f561c08de6b Initial load
duke
parents:
diff changeset
   241
   * @see    Constant
7f561c08de6b Initial load
duke
parents:
diff changeset
   242
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   243
  public Constant getConstant(int index) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   244
    if (index >= constant_pool.length || index < 0)
7f561c08de6b Initial load
duke
parents:
diff changeset
   245
      throw new ClassFormatException("Invalid constant pool reference: " +
7f561c08de6b Initial load
duke
parents:
diff changeset
   246
                                 index + ". Constant pool size is: " +
7f561c08de6b Initial load
duke
parents:
diff changeset
   247
                                 constant_pool.length);
7f561c08de6b Initial load
duke
parents:
diff changeset
   248
    return constant_pool[index];
7f561c08de6b Initial load
duke
parents:
diff changeset
   249
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   250
7f561c08de6b Initial load
duke
parents:
diff changeset
   251
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   252
   * Get constant from constant pool and check whether it has the
7f561c08de6b Initial load
duke
parents:
diff changeset
   253
   * expected type.
7f561c08de6b Initial load
duke
parents:
diff changeset
   254
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   255
   * @param  index Index in constant pool
7f561c08de6b Initial load
duke
parents:
diff changeset
   256
   * @param  tag Tag of expected constant, i.e., its type
7f561c08de6b Initial load
duke
parents:
diff changeset
   257
   * @return Constant value
7f561c08de6b Initial load
duke
parents:
diff changeset
   258
   * @see    Constant
7f561c08de6b Initial load
duke
parents:
diff changeset
   259
   * @throws  ClassFormatException
7f561c08de6b Initial load
duke
parents:
diff changeset
   260
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   261
  public Constant getConstant(int index, byte tag)
7f561c08de6b Initial load
duke
parents:
diff changeset
   262
       throws ClassFormatException
7f561c08de6b Initial load
duke
parents:
diff changeset
   263
  {
7f561c08de6b Initial load
duke
parents:
diff changeset
   264
    Constant c;
7f561c08de6b Initial load
duke
parents:
diff changeset
   265
7f561c08de6b Initial load
duke
parents:
diff changeset
   266
    c = getConstant(index);
7f561c08de6b Initial load
duke
parents:
diff changeset
   267
7f561c08de6b Initial load
duke
parents:
diff changeset
   268
    if(c == null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   269
      throw new ClassFormatException("Constant pool at index " + index + " is null.");
7f561c08de6b Initial load
duke
parents:
diff changeset
   270
7f561c08de6b Initial load
duke
parents:
diff changeset
   271
    if(c.getTag() == tag)
7f561c08de6b Initial load
duke
parents:
diff changeset
   272
      return c;
7f561c08de6b Initial load
duke
parents:
diff changeset
   273
    else
7f561c08de6b Initial load
duke
parents:
diff changeset
   274
      throw new ClassFormatException("Expected class `" + Constants.CONSTANT_NAMES[tag] +
7f561c08de6b Initial load
duke
parents:
diff changeset
   275
                                 "' at index " + index + " and got " + c);
7f561c08de6b Initial load
duke
parents:
diff changeset
   276
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   277
7f561c08de6b Initial load
duke
parents:
diff changeset
   278
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   279
   * @return Array of constants.
7f561c08de6b Initial load
duke
parents:
diff changeset
   280
   * @see    Constant
7f561c08de6b Initial load
duke
parents:
diff changeset
   281
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   282
  public Constant[] getConstantPool() { return constant_pool;  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   283
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   284
   * Get string from constant pool and bypass the indirection of
7f561c08de6b Initial load
duke
parents:
diff changeset
   285
   * `ConstantClass' and `ConstantString' objects. I.e. these classes have
7f561c08de6b Initial load
duke
parents:
diff changeset
   286
   * an index field that points to another entry of the constant pool of
7f561c08de6b Initial load
duke
parents:
diff changeset
   287
   * type `ConstantUtf8' which contains the real data.
7f561c08de6b Initial load
duke
parents:
diff changeset
   288
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
   289
   * @param  index Index in constant pool
7f561c08de6b Initial load
duke
parents:
diff changeset
   290
   * @param  tag Tag of expected constant, either ConstantClass or ConstantString
7f561c08de6b Initial load
duke
parents:
diff changeset
   291
   * @return Contents of string reference
7f561c08de6b Initial load
duke
parents:
diff changeset
   292
   * @see    ConstantClass
7f561c08de6b Initial load
duke
parents:
diff changeset
   293
   * @see    ConstantString
7f561c08de6b Initial load
duke
parents:
diff changeset
   294
   * @throws  ClassFormatException
7f561c08de6b Initial load
duke
parents:
diff changeset
   295
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   296
  public String getConstantString(int index, byte tag)
7f561c08de6b Initial load
duke
parents:
diff changeset
   297
       throws ClassFormatException
7f561c08de6b Initial load
duke
parents:
diff changeset
   298
  {
7f561c08de6b Initial load
duke
parents:
diff changeset
   299
    Constant c;
7f561c08de6b Initial load
duke
parents:
diff changeset
   300
    int    i;
7f561c08de6b Initial load
duke
parents:
diff changeset
   301
7f561c08de6b Initial load
duke
parents:
diff changeset
   302
    c = getConstant(index, tag);
7f561c08de6b Initial load
duke
parents:
diff changeset
   303
7f561c08de6b Initial load
duke
parents:
diff changeset
   304
    /* This switch() is not that elegant, since the two classes have the
7f561c08de6b Initial load
duke
parents:
diff changeset
   305
     * same contents, they just differ in the name of the index
7f561c08de6b Initial load
duke
parents:
diff changeset
   306
     * field variable.
7f561c08de6b Initial load
duke
parents:
diff changeset
   307
     * But we want to stick to the JVM naming conventions closely though
7f561c08de6b Initial load
duke
parents:
diff changeset
   308
     * we could have solved these more elegantly by using the same
7f561c08de6b Initial load
duke
parents:
diff changeset
   309
     * variable name or by subclassing.
7f561c08de6b Initial load
duke
parents:
diff changeset
   310
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   311
    switch(tag) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   312
    case Constants.CONSTANT_Class:  i = ((ConstantClass)c).getNameIndex();    break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   313
    case Constants.CONSTANT_String: i = ((ConstantString)c).getStringIndex(); break;
7f561c08de6b Initial load
duke
parents:
diff changeset
   314
    default:
7f561c08de6b Initial load
duke
parents:
diff changeset
   315
      throw new RuntimeException("getConstantString called with illegal tag " + tag);
7f561c08de6b Initial load
duke
parents:
diff changeset
   316
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   317
7f561c08de6b Initial load
duke
parents:
diff changeset
   318
    // Finally get the string from the constant pool
7f561c08de6b Initial load
duke
parents:
diff changeset
   319
    c = getConstant(i, Constants.CONSTANT_Utf8);
7f561c08de6b Initial load
duke
parents:
diff changeset
   320
    return ((ConstantUtf8)c).getBytes();
7f561c08de6b Initial load
duke
parents:
diff changeset
   321
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   322
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   323
   * @return Length of constant pool.
7f561c08de6b Initial load
duke
parents:
diff changeset
   324
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   325
  public int getLength()
7f561c08de6b Initial load
duke
parents:
diff changeset
   326
  {
7f561c08de6b Initial load
duke
parents:
diff changeset
   327
    return constant_pool_count;
7f561c08de6b Initial load
duke
parents:
diff changeset
   328
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   329
7f561c08de6b Initial load
duke
parents:
diff changeset
   330
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   331
   * @param constant Constant to set
7f561c08de6b Initial load
duke
parents:
diff changeset
   332
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   333
  public void setConstant(int index, Constant constant) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   334
    constant_pool[index] = constant;
7f561c08de6b Initial load
duke
parents:
diff changeset
   335
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   336
7f561c08de6b Initial load
duke
parents:
diff changeset
   337
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   338
   * @param constant_pool
7f561c08de6b Initial load
duke
parents:
diff changeset
   339
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   340
  public void setConstantPool(Constant[] constant_pool) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   341
    this.constant_pool = constant_pool;
7f561c08de6b Initial load
duke
parents:
diff changeset
   342
    constant_pool_count = (constant_pool == null)? 0 : constant_pool.length;
7f561c08de6b Initial load
duke
parents:
diff changeset
   343
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   344
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   345
   * @return String representation.
7f561c08de6b Initial load
duke
parents:
diff changeset
   346
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   347
  public String toString() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   348
    StringBuffer buf = new StringBuffer();
7f561c08de6b Initial load
duke
parents:
diff changeset
   349
7f561c08de6b Initial load
duke
parents:
diff changeset
   350
    for(int i=1; i < constant_pool_count; i++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   351
      buf.append(i + ")" + constant_pool[i] + "\n");
7f561c08de6b Initial load
duke
parents:
diff changeset
   352
7f561c08de6b Initial load
duke
parents:
diff changeset
   353
    return buf.toString();
7f561c08de6b Initial load
duke
parents:
diff changeset
   354
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   355
7f561c08de6b Initial load
duke
parents:
diff changeset
   356
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   357
   * @return deep copy of this constant pool
7f561c08de6b Initial load
duke
parents:
diff changeset
   358
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   359
  public ConstantPool copy() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   360
    ConstantPool c = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   361
7f561c08de6b Initial load
duke
parents:
diff changeset
   362
    try {
7f561c08de6b Initial load
duke
parents:
diff changeset
   363
      c = (ConstantPool)clone();
7f561c08de6b Initial load
duke
parents:
diff changeset
   364
    } catch(CloneNotSupportedException e) {}
7f561c08de6b Initial load
duke
parents:
diff changeset
   365
7f561c08de6b Initial load
duke
parents:
diff changeset
   366
    c.constant_pool = new Constant[constant_pool_count];
7f561c08de6b Initial load
duke
parents:
diff changeset
   367
7f561c08de6b Initial load
duke
parents:
diff changeset
   368
    for(int i=1; i < constant_pool_count; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   369
      if(constant_pool[i] != null)
7f561c08de6b Initial load
duke
parents:
diff changeset
   370
        c.constant_pool[i] = constant_pool[i].copy();
7f561c08de6b Initial load
duke
parents:
diff changeset
   371
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   372
7f561c08de6b Initial load
duke
parents:
diff changeset
   373
    return c;
7f561c08de6b Initial load
duke
parents:
diff changeset
   374
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   375
}