diff options
Diffstat (limited to 'src/main/javassist/bytecode/InnerClassesAttribute.java')
-rw-r--r-- | src/main/javassist/bytecode/InnerClassesAttribute.java | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/src/main/javassist/bytecode/InnerClassesAttribute.java b/src/main/javassist/bytecode/InnerClassesAttribute.java new file mode 100644 index 0000000..df5645a --- /dev/null +++ b/src/main/javassist/bytecode/InnerClassesAttribute.java @@ -0,0 +1,241 @@ +/* + * Javassist, a Java-bytecode translator toolkit. + * Copyright (C) 1999-2007 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. + * + * 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. + */ + +package javassist.bytecode; + +import java.io.DataInputStream; +import java.util.Map; +import java.io.IOException; + +/** + * <code>InnerClasses_attribute</code>. + */ +public class InnerClassesAttribute extends AttributeInfo { + /** + * The name of this attribute <code>"InnerClasses"</code>. + */ + public static final String tag = "InnerClasses"; + + InnerClassesAttribute(ConstPool cp, int n, DataInputStream 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]); + ByteArray.write16bit(0, get(), 0); + } + + /** + * Returns <code>number_of_classes</code>. + */ + public int tableLength() { return ByteArray.readU16bit(get(), 0); } + + /** + * Returns <code>classes[nth].inner_class_info_index</code>. + */ + public int innerClassIndex(int nth) { + return ByteArray.readU16bit(get(), nth * 8 + 2); + } + + /** + * Returns the class name indicated + * by <code>classes[nth].inner_class_info_index</code>. + * + * @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 <code>classes[nth].inner_class_info_index</code> to + * the given index. + */ + public void setInnerClassIndex(int nth, int index) { + ByteArray.write16bit(index, get(), nth * 8 + 2); + } + + /** + * Returns <code>classes[nth].outer_class_info_index</code>. + */ + public int outerClassIndex(int nth) { + return ByteArray.readU16bit(get(), nth * 8 + 4); + } + + /** + * Returns the class name indicated + * by <code>classes[nth].outer_class_info_index</code>. + * + * @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 <code>classes[nth].outer_class_info_index</code> to + * the given index. + */ + public void setOuterClassIndex(int nth, int index) { + ByteArray.write16bit(index, get(), nth * 8 + 4); + } + + /** + * Returns <code>classes[nth].inner_name_index</code>. + */ + public int innerNameIndex(int nth) { + return ByteArray.readU16bit(get(), nth * 8 + 6); + } + + /** + * Returns the simple class name indicated + * by <code>classes[nth].inner_name_index</code>. + * + * @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 <code>classes[nth].inner_name_index</code> to + * the given index. + */ + public void setInnerNameIndex(int nth, int index) { + ByteArray.write16bit(index, get(), nth * 8 + 6); + } + + /** + * Returns <code>classes[nth].inner_class_access_flags</code>. + */ + public int accessFlags(int nth) { + return ByteArray.readU16bit(get(), nth * 8 + 8); + } + + /** + * Sets <code>classes[nth].inner_class_access_flags</code> to + * the given index. + */ + public void setAccessFlags(int nth, int flags) { + ByteArray.write16bit(flags, get(), nth * 8 + 8); + } + + /** + * Appends a new entry. + * + * @param inner <code>inner_class_info_index</code> + * @param outer <code>outer_class_info_index</code> + * @param name <code>inner_name_index</code> + * @param flags <code>inner_class_access_flags</code> + */ + 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 <code>inner_class_info_index</code> + * @param outer <code>outer_class_info_index</code> + * @param name <code>inner_name_index</code> + * @param flags <code>inner_class_access_flags</code> + */ + 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 = ByteArray.readU16bit(data, 0); + ByteArray.write16bit(n + 1, newData, 0); + + ByteArray.write16bit(inner, newData, len); + ByteArray.write16bit(outer, newData, len + 2); + ByteArray.write16bit(name, newData, len + 4); + ByteArray.write16bit(flags, newData, len + 6); + + set(newData); + } + + /** + * Makes a copy. Class names are replaced according to the + * given <code>Map</code> object. + * + * @param newCp the constant pool table used by the new copy. + * @param classnames pairs of replaced and substituted + * class names. + */ + 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 = ByteArray.readU16bit(src, 0); + ByteArray.write16bit(n, dest, 0); + int j = 2; + for (int i = 0; i < n; ++i) { + int innerClass = ByteArray.readU16bit(src, j); + int outerClass = ByteArray.readU16bit(src, j + 2); + int innerName = ByteArray.readU16bit(src, j + 4); + int innerAccess = ByteArray.readU16bit(src, j + 6); + + if (innerClass != 0) + innerClass = cp.copy(innerClass, newCp, classnames); + + ByteArray.write16bit(innerClass, dest, j); + + if (outerClass != 0) + outerClass = cp.copy(outerClass, newCp, classnames); + + ByteArray.write16bit(outerClass, dest, j + 2); + + if (innerName != 0) + innerName = cp.copy(innerName, newCp, classnames); + + ByteArray.write16bit(innerName, dest, j + 4); + ByteArray.write16bit(innerAccess, dest, j + 6); + j += 8; + } + + return attr; + } +} |