aboutsummaryrefslogtreecommitdiff
path: root/src/main/javassist/bytecode/InnerClassesAttribute.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/javassist/bytecode/InnerClassesAttribute.java')
-rw-r--r--src/main/javassist/bytecode/InnerClassesAttribute.java241
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;
+ }
+}