⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 constantpoolgen.java

📁 Java Bytecode Editor 是一个 JAVA 的字节码反汇编和修改器。它可以很方便的修改已经编译成 Class 文件的 JAVA 文件。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package org.apache.bcel.generic;

/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *    "Apache BCEL" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache BCEL", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import org.apache.bcel.Constants;
import org.apache.bcel.classfile.*;
import java.util.HashMap;

/** 
 * This class is used to build up a constant pool. The user adds
 * constants via `addXXX' methods, `addString', `addClass',
 * etc.. These methods return an index into the constant
 * pool. Finally, `getFinalConstantPool()' returns the constant pool
 * built up. Intermediate versions of the constant pool can be
 * obtained with `getConstantPool()'. A constant pool has capacity for
 * Constants.MAX_SHORT entries. Note that the first (0) is used by the
 * JVM and that Double and Long constants need two slots.
 *
 * @version $Id: ConstantPoolGen.java,v 1.2 2006/08/22 15:33:21 andos Exp $
 * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
 * @see Constant
 */
public class ConstantPoolGen implements java.io.Serializable {
  /**
	 * 
	 */
	private static final long serialVersionUID = 8551552812169741014L;
protected int        size      = 1024; // Inital size, sufficient in most cases
  protected Constant[] constants = new Constant[size];
  protected int        index     = 1; // First entry (0) used by JVM

  private static final String METHODREF_DELIM  = ":";
  private static final String IMETHODREF_DELIM = "#";
  private static final String FIELDREF_DELIM   = "&";
  private static final String NAT_DELIM        = "%";

  private static class Index implements java.io.Serializable {
    /**
	 * 
	 */
	private static final long serialVersionUID = -9187078620578535161L;
	int index;
    Index(int i) { index = i; }
  }

  /**
   * Initialize with given array of constants.
   *
   * @param c array of given constants, new ones will be appended
   */
  public ConstantPoolGen(Constant[] cs) {
    if(cs.length > size) {
      size      = cs.length;
      constants = new Constant[size];
    }

    System.arraycopy(cs, 0, constants, 0, cs.length);

    if(cs.length > 0)
      index = cs.length;

    for(int i=1; i < index; i++) {
      Constant c = constants[i];

      if(c instanceof ConstantString) {
	ConstantString s  = (ConstantString)c;
	ConstantUtf8   u8 = (ConstantUtf8)constants[s.getStringIndex()];

	string_table.put(u8.getBytes(), new Index(i));
      } else if(c instanceof ConstantClass) {
	ConstantClass s  = (ConstantClass)c;
	ConstantUtf8  u8 = (ConstantUtf8)constants[s.getNameIndex()];

	class_table.put(u8.getBytes(), new Index(i));
      } else if(c instanceof ConstantNameAndType) {
	ConstantNameAndType n    = (ConstantNameAndType)c;
	ConstantUtf8        u8   = (ConstantUtf8)constants[n.getNameIndex()];
	ConstantUtf8        u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()];

	n_a_t_table.put(u8.getBytes() + NAT_DELIM + u8_2.getBytes(), new Index(i));
       } else if(c instanceof ConstantUtf8) {
         ConstantUtf8 u = (ConstantUtf8)c;
         
         utf8_table.put(u.getBytes(), new Index(i));
      } else if(c instanceof ConstantCP) {
	ConstantCP          m     = (ConstantCP)c;
	ConstantClass       clazz = (ConstantClass)constants[m.getClassIndex()];
	ConstantNameAndType n     = (ConstantNameAndType)constants[m.getNameAndTypeIndex()];
	
        ConstantUtf8 u8         = (ConstantUtf8)constants[clazz.getNameIndex()];
        String       class_name = u8.getBytes().replace('/', '.');

	u8 = (ConstantUtf8)constants[n.getNameIndex()];
	String method_name = u8.getBytes();

	u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
	String signature = u8.getBytes();

	String delim = METHODREF_DELIM;

	if(c instanceof ConstantInterfaceMethodref)
	  delim = IMETHODREF_DELIM;
	else if(c instanceof ConstantFieldref)
	  delim = FIELDREF_DELIM;

	cp_table.put(class_name + delim + method_name + delim + signature, new Index(i));
      }
    }
  }

  /**
   * Initialize with given constant pool.
   */
  public ConstantPoolGen(ConstantPool cp) {
    this(cp.getConstantPool());
  }

  /**
   * Create empty constant pool.
   */
  public ConstantPoolGen() {}

  /** Resize internal array of constants.
   */
  protected void adjustSize() {
    if(index + 3 >= size) {
      Constant[] cs = constants;

      size      *= 2;
      constants  = new Constant[size];
      System.arraycopy(cs, 0, constants, 0, index);
    }
  }

  private HashMap<String, Index> string_table = new HashMap<String, Index>();

  /** 
   * Look for ConstantString in ConstantPool containing String `str'.
   *
   * @param str String to search for
   * @return index on success, -1 otherwise
   */
  public int lookupString(String str) {
    Index index = (Index)string_table.get(str);
    return (index != null)? index.index : -1;
  }
  
  /**
   * Add a new String constant to the ConstantPool, if it is not already in there.
   *
   * @param str String to add
   * @return index of entry
   */
  public int addString(String str) {
    int ret;
    
    if((ret = lookupString(str)) != -1)
      return ret; // Already in CP

    int utf8 = addUtf8(str);

    adjustSize();

    ConstantString s  = new ConstantString(utf8);
       
    ret = index;
    constants[index++] = s;

    string_table.put(str, new Index(ret));

    return ret;
  }

  private HashMap<String, Index> class_table = new HashMap<String, Index>();

  /**
   * Look for ConstantClass in ConstantPool named `str'.
   *
   * @param str String to search for
   * @return index on success, -1 otherwise
   */
  public int lookupClass(String str) {
    Index index = (Index)class_table.get(str.replace('.', '/'));
    return (index != null)? index.index : -1;
  }

  private int addClass_(String clazz) {
    int    ret;

    if((ret = lookupClass(clazz)) != -1)
      return ret; // Already in CP

    adjustSize();

    ConstantClass c = new ConstantClass(addUtf8(clazz));

    ret = index;
    constants[index++] = c;

    class_table.put(clazz, new Index(ret));

    return ret;
  }

  /**
   * Add a new Class reference to the ConstantPool, if it is not already in there.
   *
   * @param str Class to add
   * @return index of entry
   */
  public int addClass(String str) {
    return addClass_(str.replace('.', '/'));
  }

  /**
   * Add a new Class reference to the ConstantPool for a given type.
   *
   * @param str Class to add
   * @return index of entry
   */
  public int addClass(ObjectType type) {
    return addClass(type.getClassName());
  }

  /**
   * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY
   * instruction, e.g. to the ConstantPool.
   *
   * @param type type of array class
   * @return index of entry
   */
  public int addArrayClass(ArrayType type) {
    return addClass_(type.getSignature());
  }

  /** 
   * Look for ConstantInteger in ConstantPool.
   *
   * @param n integer number to look for
   * @return index on success, -1 otherwise
   */
  public int lookupInteger(int n) {
    for(int i=1; i < index; i++) {
      if(constants[i] instanceof ConstantInteger) {
	ConstantInteger c = (ConstantInteger)constants[i];

	if(c.getBytes() == n)
	  return i;
      }
    }

    return -1;
  }

  /**
   * Add a new Integer constant to the ConstantPool, if it is not already in there.
   *
   * @param n integer number to add
   * @return index of entry
   */
  public int addInteger(int n) {
    int  ret;

    if((ret = lookupInteger(n)) != -1)
      return ret; // Already in CP

    adjustSize();

    ret = index;
    constants[index++] = new ConstantInteger(n);

    return ret;
  }

  /** 
   * Look for ConstantFloat in ConstantPool.
   *
   * @param n Float number to look for
   * @return index on success, -1 otherwise
   */
  public int lookupFloat(float n) {
    int bits = Float.floatToIntBits(n);

    for(int i=1; i < index; i++) {
      if(constants[i] instanceof ConstantFloat) {
	ConstantFloat c = (ConstantFloat)constants[i];

	if(Float.floatToIntBits(c.getBytes()) == bits)
	  return i;
      }
    }

    return -1;
  }

  /**
   * Add a new Float constant to the ConstantPool, if it is not already in there.
   *
   * @param n Float number to add
   * @return index of entry
   */
  public int addFloat(float n) {
    int  ret;

    if((ret = lookupFloat(n)) != -1)
      return ret; // Already in CP

    adjustSize();

    ret = index;
    constants[index++] = new ConstantFloat(n);

    return ret;
  }

  private HashMap<String, Index> utf8_table = new HashMap<String, Index>();

  /** 
   * Look for ConstantUtf8 in ConstantPool.
   *
   * @param n Utf8 string to look for
   * @return index on success, -1 otherwise
   */
  public int lookupUtf8(String n) {
    Index index = (Index)utf8_table.get(n);

    return (index != null)? index.index : -1;
  }

  /**
   * Add a new Utf8 constant to the ConstantPool, if it is not already in there.
   *
   * @param n Utf8 string to add
   * @return index of entry
   */
  public int addUtf8(String n) {
    int  ret;

    if((ret = lookupUtf8(n)) != -1)
      return ret; // Already in CP

    adjustSize();

    ret = index;
    constants[index++] = new ConstantUtf8(n);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -