All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xapi.bytecode.attributes.InnerClassesAttribute Maven / Gradle / Ivy

Go to download

Everything needed to run a comprehensive dev environment. Just type X_ and pick a service from autocomplete; new dev modules will be added as they are built. The only dev service not included in the uber jar is xapi-dev-maven, as it includes all runtime dependencies of maven, adding ~4 seconds to build time, and 6 megabytes to the final output jar size (without xapi-dev-maven, it's ~1MB).

The newest version!
/*
 * Javassist, a Java-bytecode translator toolkit.
 * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License.  Alternatively, the contents of this file may be used under
 * the terms of the GNU Lesser General Public License Version 2.1 or later,
 * or the Apache License Version 2.0.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * MODIFIED BY James Nelson of We The Internet, 2013.
 * Repackaged to avoid conflicts with different versions of Javassist,
 * and modified Javassist APIs to make them more accessible to outside code.
 */
package xapi.bytecode.attributes;

import java.io.DataInput;
import java.io.IOException;
import java.util.Map;

import xapi.bytecode.ConstPool;
import xapi.util.X_Byte;

public class InnerClassesAttribute extends AttributeInfo {
    /**
     * The name of this attribute "InnerClasses".
     */
    public static final String tag = "InnerClasses";

    InnerClassesAttribute(ConstPool cp, int n, DataInput in)
        throws IOException
    {
        super(cp, n, in);
    }

    private InnerClassesAttribute(ConstPool cp, byte[] info) {
        super(cp, tag, info);
    }

    /**
     * Constructs an empty InnerClasses attribute.
     *
     * @see #append(String, String, String, int)
     */
    public InnerClassesAttribute(ConstPool cp) {
        super(cp, tag, new byte[2]);
        X_Byte.write16bit(0, get(), 0);
    }

    /**
     * Returns number_of_classes.
     */
    public int tableLength() { return X_Byte.readU16bit(get(), 0); }

    /**
     * Returns classes[nth].inner_class_info_index.
     */
    public int innerClassIndex(int nth) {
        return X_Byte.readU16bit(get(), nth * 8 + 2);
    }

    /**
     * Returns the class name indicated
     * by classes[nth].inner_class_info_index.
     *
     * @return null or the class name.
     */
    public String innerClass(int nth) {
        int i = innerClassIndex(nth);
        if (i == 0) {
          return null;
        } else {
          return constPool.getClassInfo(i);
        }
    }

    /**
     * Sets classes[nth].inner_class_info_index to
     * the given index.
     */
    public void setInnerClassIndex(int nth, int index) {
        X_Byte.write16bit(index, get(), nth * 8 + 2);
    }

    /**
     * Returns classes[nth].outer_class_info_index.
     */
    public int outerClassIndex(int nth) {
        return X_Byte.readU16bit(get(), nth * 8 + 4);
    }

    /**
     * Returns the class name indicated
     * by classes[nth].outer_class_info_index.
     *
     * @return null or the class name.
     */
    public String outerClass(int nth) {
        int i = outerClassIndex(nth);
        if (i == 0) {
          return null;
        } else {
          return constPool.getClassInfo(i);
        }
    }

    /**
     * Sets classes[nth].outer_class_info_index to
     * the given index.
     */
    public void setOuterClassIndex(int nth, int index) {
        X_Byte.write16bit(index, get(), nth * 8 + 4);
    }

    /**
     * Returns classes[nth].inner_name_index.
     */
    public int innerNameIndex(int nth) {
        return X_Byte.readU16bit(get(), nth * 8 + 6);
    }

    /**
     * Returns the simple class name indicated
     * by classes[nth].inner_name_index.
     *
     * @return null or the class name.
     */
    public String innerName(int nth) {
        int i = innerNameIndex(nth);
        if (i == 0) {
          return null;
        } else {
          return constPool.getUtf8Info(i);
        }
    }

    /**
     * Sets classes[nth].inner_name_index to
     * the given index.
     */
    public void setInnerNameIndex(int nth, int index) {
        X_Byte.write16bit(index, get(), nth * 8 + 6);
    }

    /**
     * Returns classes[nth].inner_class_access_flags.
     */
    public int accessFlags(int nth) {
        return X_Byte.readU16bit(get(), nth * 8 + 8);
    }

    /**
     * Sets classes[nth].inner_class_access_flags to
     * the given index.
     */
    public void setAccessFlags(int nth, int flags) {
        X_Byte.write16bit(flags, get(), nth * 8 + 8);
    }

    /**
     * Appends a new entry.
     *
     * @param inner     inner_class_info_index
     * @param outer     outer_class_info_index
     * @param name      inner_name_index
     * @param flags     inner_class_access_flags
     */
    public void append(String inner, String outer, String name, int flags) {
        int i = constPool.addClassInfo(inner);
        int o = constPool.addClassInfo(outer);
        int n = constPool.addUtf8Info(name);
        append(i, o, n, flags);
    }

    /**
     * Appends a new entry.
     *
     * @param inner     inner_class_info_index
     * @param outer     outer_class_info_index
     * @param name      inner_name_index
     * @param flags     inner_class_access_flags
     */
    public void append(int inner, int outer, int name, int flags) {
        byte[] data = get();
        int len = data.length;
        byte[] newData = new byte[len + 8];
        for (int i = 2; i < len; ++i) {
          newData[i] = data[i];
        }

        int n = X_Byte.readU16bit(data, 0);
        X_Byte.write16bit(n + 1, newData, 0);

        X_Byte.write16bit(inner, newData, len);
        X_Byte.write16bit(outer, newData, len + 2);
        X_Byte.write16bit(name, newData, len + 4);
        X_Byte.write16bit(flags, newData, len + 6);

        set(newData);
    }

    /**
     * Makes a copy.  Class names are replaced according to the
     * given Map object.
     *
     * @param newCp     the constant pool table used by the new copy.
     * @param classnames        pairs of replaced and substituted
     *                          class names.
     */
    @Override
    public AttributeInfo copy(ConstPool newCp, Map classnames) {
        byte[] src = get();
        byte[] dest = new byte[src.length];
        ConstPool cp = getConstPool();
        InnerClassesAttribute attr = new InnerClassesAttribute(newCp, dest);
        int n = X_Byte.readU16bit(src, 0);
        X_Byte.write16bit(n, dest, 0);
        int j = 2;
        for (int i = 0; i < n; ++i) {
            int innerClass = X_Byte.readU16bit(src, j);
            int outerClass = X_Byte.readU16bit(src, j + 2);
            int innerName = X_Byte.readU16bit(src, j + 4);
            int innerAccess = X_Byte.readU16bit(src, j + 6);

            if (innerClass != 0) {
              innerClass = cp.copy(innerClass, newCp, classnames);
            }

            X_Byte.write16bit(innerClass, dest, j);

            if (outerClass != 0) {
              outerClass = cp.copy(outerClass, newCp, classnames);
            }

            X_Byte.write16bit(outerClass, dest, j + 2);

            if (innerName != 0) {
              innerName = cp.copy(innerName, newCp, classnames);
            }

            X_Byte.write16bit(innerName, dest, j + 4);
            X_Byte.write16bit(innerAccess, dest, j + 6);
            j += 8;
        }

        return attr;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy