/** Return the index of a UTF entry or -1 if it doesn't exist. */
  int findUtf8(String value) {

    ConstantPoolEntry item = findMatchingEntry(value);
    if (item == null) return -1;

    return item.getIndex();
  }
 /**
  * Add an entry, but only if it doesn't exist.
  *
  * @return the constant pool index of the added or existing item.
  */
 private int addDirectEntry(ConstantPoolEntry item) {
   ConstantPoolEntry existingItem = findMatchingEntry(item);
   if (existingItem != null) {
     item = existingItem;
     // foundCount++;
   } else {
     addEntry(item.getKey(), item);
   }
   return item.getIndex();
 }
  protected void cptPut(ClassFormatOutput out) throws IOException {

    for (Enumeration e = cptEntries.elements(); e.hasMoreElements(); ) {
      ConstantPoolEntry item = (ConstantPoolEntry) e.nextElement();
      if (item == null) {
        continue;
      }

      item.put(out);
    }
  }
Exemple #4
0
  /**
   * Add an entry to the Constant Pool.
   *
   * @param cpe the new constant pool entry
   * @return the index of the new entry in the pool
   */
  public synchronized short addConstantPoolEntry(ConstantPoolEntry cpe) {

    ConstantPoolEntry old = (ConstantPoolEntry) constantHash.get(cpe);
    if (old != null) {
      return old.getConstantPoolIndex();
    }
    constantHash.put(cpe, cpe);

    constantPool.addElement(cpe);

    return (short) constantPool.size();
  }
  /** Add an index reference. */
  private int addIndexReference(int tag, int i1, int i2) {

    // search for the item using the pre-allocated object
    searchIndex.set(tag, i1, i2);

    ConstantPoolEntry item = findMatchingEntry(searchIndex);

    if (item == null) {
      item = new CONSTANT_Index_info(tag, i1, i2);
      addEntry(item.getKey(), item);
    }

    return item.getIndex();
  }
  private void doRenameString(int index, String newName) {
    ConstantPoolEntry cpe = getEntry(index);
    if (cpe.getTag() != VMDescriptor.CONSTANT_Utf8)
      throw new RuntimeException("unexpected type " + cpe);

    CONSTANT_Utf8_info newCpe = new CONSTANT_Utf8_info(newName);

    cptHashTable.remove(cpe.getKey());
    cptHashTable.put(newCpe.getKey(), newCpe);

    newCpe.index = index;

    cptEntries.set(index, newCpe);
  }
  /**
   * Generic add entry to constant pool. Includes the logic for an entry to occupy more than one
   * slot (e.g. long).
   *
   * @return The number of slots occupied by the entry. .
   */
  protected int addEntry(Object key, ConstantPoolEntry item) {

    item.setIndex(cptEntries.size());
    if (key != null) cptHashTable.put(key, item);
    cptEntries.addElement(item);

    cptEstimatedSize += item.classFileSize();

    if (item.doubleSlot()) {
      cptEntries.addElement(null);
      return 2;
    } else {
      return 1;
    }
  }
  public Enumeration getStrings() {
    HashSet strings = new HashSet(30, 0.8f);

    int size = cptEntries.size();
    for (int i = 1; i < size; i++) {
      ConstantPoolEntry cpe = getEntry(i);

      if ((cpe == null) || (cpe.getTag() != VMDescriptor.CONSTANT_String)) continue;

      CONSTANT_Index_info cii = (CONSTANT_Index_info) cpe;

      strings.add(nameIndexToString(cii.getI1()));
    }

    return java.util.Collections.enumeration(strings);
  }
  public void renameClassElements(Hashtable classNameMap, Hashtable memberNameMap) {

    // this & super class
    renameString(classNameMap, (CONSTANT_Index_info) getEntry(this_class));
    renameString(classNameMap, (CONSTANT_Index_info) getEntry(super_class));

    // implemented interfaces
    // handled by Class entries below

    // classes & Strings
    // descriptors
    int size = cptEntries.size();
    for (int i = 1; i < size; i++) {
      ConstantPoolEntry cpe = getEntry(i);

      if (cpe == null) continue;

      switch (cpe.getTag()) {
        case VMDescriptor.CONSTANT_String:
        case VMDescriptor.CONSTANT_Class:
          {
            CONSTANT_Index_info cii = (CONSTANT_Index_info) cpe;
            renameString(classNameMap, cii);
            break;
          }
        case VMDescriptor.CONSTANT_NameAndType:
          {
            CONSTANT_Index_info cii = (CONSTANT_Index_info) cpe;
            String newDescriptor = newDescriptor(classNameMap, nameIndexToString(cii.getI2()));
            if (newDescriptor != null) {
              doRenameString(cii.getI2(), newDescriptor);
            }
            break;
          }

        default:
          continue;
      }
    }

    // System.out.println("Starting Fields");

    // now the methods & fields, only descriptors at this time
    renameMembers(getFields(), classNameMap, memberNameMap);

    renameMembers(getMethods(), classNameMap, memberNameMap);
  }
  public static ClassInvestigator load(InputStream is) throws IOException {

    ClassInput classInput = new ClassInput(is);

    // Check the header
    int magic = classInput.getU4();
    int minor_version = classInput.getU2();
    int major_version = classInput.getU2();

    if (magic != VMDescriptor.JAVA_CLASS_FORMAT_MAGIC) throw new ClassFormatError();

    //	Read in the Constant Pool
    int constantPoolCount = classInput.getU2();

    ClassInvestigator ci = new ClassInvestigator(constantPoolCount);

    ci.minor_version = minor_version;
    ci.major_version = major_version;

    // Yes, index starts at 1, The '0'th constant pool entry
    // is reserved for the JVM and is not present in the class file.
    for (int i = 1; i < constantPoolCount; ) {
      ConstantPoolEntry item = ClassInvestigator.getConstant(classInput);
      i += ci.addEntry(item.getKey(), item);
    }

    // Read in access_flags and class indexes
    ci.access_flags = classInput.getU2();
    ci.this_class = classInput.getU2();
    ci.super_class = classInput.getU2();

    // interfaces is a simple int array
    int interfaceCount = classInput.getU2();
    if (interfaceCount != 0) {
      ci.interfaces = new int[interfaceCount];
      for (int i = 0; i < interfaceCount; i++) ci.interfaces[i] = classInput.getU2();
    }

    int fieldCount = classInput.getU2();
    if (fieldCount != 0) {
      ci.field_info = new MemberTable(fieldCount);
      for (int i = 0; i < fieldCount; i++) {
        ci.field_info.addEntry(readClassMember(ci, classInput));
      }
    }

    int methodCount = classInput.getU2();
    if (methodCount != 0) {
      ci.method_info = new MemberTable(methodCount);
      for (int i = 0; i < methodCount; i++) {
        ci.method_info.addEntry(readClassMember(ci, classInput));
      }
    }

    int attributeCount = classInput.getU2();
    if (attributeCount != 0) {
      ci.attribute_info = new Attributes(attributeCount);

      for (int i = 0; i < attributeCount; i++)
        ci.attribute_info.addEntry(new AttributeEntry(classInput));
    }
    return ci;
  }
 protected void resolve(ClassConstantPool pool) {
   super.resolve(pool);
   index = pool.indexOf(utf8);
 }