--- a/langtools/src/share/classes/com/sun/tools/classfile/AccessFlags.java Thu Jul 30 10:30:34 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/classfile/AccessFlags.java Thu Jul 30 07:48:24 2009 -0700
@@ -76,6 +76,10 @@
return (flags & mask) != 0;
}
+ public int byteLength() {
+ return 2;
+ }
+
private static final int[] classModifiers = {
ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT, ACC_MODULE
};
--- a/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java Thu Jul 30 10:30:34 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java Thu Jul 30 07:48:24 2009 -0700
@@ -166,6 +166,10 @@
public abstract <R,D> R accept(Attribute.Visitor<R,D> visitor, D data);
+ public int byteLength() {
+ return 6 + attribute_length;
+ }
+
public final int attribute_name_index;
public final int attribute_length;
--- a/langtools/src/share/classes/com/sun/tools/classfile/Attributes.java Thu Jul 30 10:30:34 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/classfile/Attributes.java Thu Jul 30 07:48:24 2009 -0700
@@ -95,6 +95,13 @@
return attrs.length;
}
+ public int byteLength() {
+ int length = 2;
+ for (Attribute a: attrs)
+ length += a.byteLength();
+ return length;
+ }
+
public final Attribute[] attrs;
public final Map<String, Attribute> map;
}
--- a/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java Thu Jul 30 10:30:34 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java Thu Jul 30 07:48:24 2009 -0700
@@ -139,6 +139,38 @@
return access_flags.is(ACC_INTERFACE);
}
+ public int byteLength() {
+ return 4 + // magic
+ 2 + // minor
+ 2 + // major
+ constant_pool.byteLength() +
+ 2 + // access flags
+ 2 + // this_class
+ 2 + // super_class
+ byteLength(interfaces) +
+ byteLength(fields) +
+ byteLength(methods) +
+ attributes.byteLength();
+ }
+
+ private int byteLength(int[] indices) {
+ return 2 + 2 * indices.length;
+ }
+
+ private int byteLength(Field[] fields) {
+ int length = 2;
+ for (Field f: fields)
+ length += f.byteLength();
+ return length;
+ }
+
+ private int byteLength(Method[] methods) {
+ int length = 2;
+ for (Method m: methods)
+ length += m.byteLength();
+ return length;
+ }
+
public final int magic;
public final int minor_version;
public final int major_version;
--- a/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java Thu Jul 30 10:30:34 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java Thu Jul 30 07:48:24 2009 -0700
@@ -25,7 +25,9 @@
package com.sun.tools.classfile;
+import java.io.DataOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.util.Iterator;
/**
@@ -179,6 +181,16 @@
return pool.length;
}
+ public int byteLength() {
+ int length = 2;
+ for (int i = 1; i < size(); ) {
+ CPInfo cpInfo = pool[i];
+ length += cpInfo.byteLength();
+ i += cpInfo.size();
+ }
+ return length;
+ }
+
public CPInfo get(int index) throws InvalidIndex {
if (index <= 0 || index >= pool.length)
throw new InvalidIndex(index);
@@ -291,6 +303,8 @@
return 1;
}
+ public abstract int byteLength();
+
public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
protected final ConstantPool cp;
@@ -315,6 +329,10 @@
return tag;
}
+ public int byteLength() {
+ return 5;
+ }
+
public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {
return cp.getClassInfo(class_index);
}
@@ -347,6 +365,10 @@
return CONSTANT_Class;
}
+ public int byteLength() {
+ return 3;
+ }
+
public String getName() throws ConstantPoolException {
return cp.getUTF8Value(name_index);
}
@@ -390,6 +412,10 @@
return CONSTANT_Double;
}
+ public int byteLength() {
+ return 9;
+ }
+
@Override
public int size() {
return 2;
@@ -439,6 +465,10 @@
return CONSTANT_Float;
}
+ public int byteLength() {
+ return 5;
+ }
+
@Override
public String toString() {
return "CONSTANT_Float_info[value: " + value + "]";
@@ -464,6 +494,10 @@
return CONSTANT_Integer;
}
+ public int byteLength() {
+ return 5;
+ }
+
@Override
public String toString() {
return "CONSTANT_Integer_info[value: " + value + "]";
@@ -513,6 +547,10 @@
return 2;
}
+ public int byteLength() {
+ return 9;
+ }
+
@Override
public String toString() {
return "CONSTANT_Long_info[value: " + value + "]";
@@ -561,6 +599,10 @@
return CONSTANT_NameAndType;
}
+ public int byteLength() {
+ return 5;
+ }
+
public String getName() throws ConstantPoolException {
return cp.getUTF8Value(name_index);
}
@@ -597,6 +639,10 @@
return CONSTANT_String;
}
+ public int byteLength() {
+ return 3;
+ }
+
public String getString() throws ConstantPoolException {
return cp.getUTF8Value(string_index);
}
@@ -626,6 +672,20 @@
return CONSTANT_Utf8;
}
+ public int byteLength() {
+ class SizeOutputStream extends OutputStream {
+ @Override
+ public void write(int b) throws IOException {
+ size++;
+ }
+ int size;
+ }
+ SizeOutputStream sizeOut = new SizeOutputStream();
+ DataOutputStream out = new DataOutputStream(sizeOut);
+ try { out.writeUTF(value); } catch (IOException ignore) { }
+ return 1 + sizeOut.size;
+ }
+
@Override
public String toString() {
if (value.length() < 32 && isPrintableAscii(value))
--- a/langtools/src/share/classes/com/sun/tools/classfile/Field.java Thu Jul 30 10:30:34 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/classfile/Field.java Thu Jul 30 07:48:24 2009 -0700
@@ -50,6 +50,10 @@
this.attributes = attributes;
}
+ public int byteLength() {
+ return 6 + attributes.byteLength();
+ }
+
public String getName(ConstantPool constant_pool) throws ConstantPoolException {
return constant_pool.getUTF8Value(name_index);
}
--- a/langtools/src/share/classes/com/sun/tools/classfile/Method.java Thu Jul 30 10:30:34 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/classfile/Method.java Thu Jul 30 07:48:24 2009 -0700
@@ -50,6 +50,10 @@
this.attributes = attributes;
}
+ public int byteLength() {
+ return 6 + attributes.byteLength();
+ }
+
public String getName(ConstantPool constant_pool) throws ConstantPoolException {
return constant_pool.getUTF8Value(name_index);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/T6866657.java Thu Jul 30 07:48:24 2009 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+
+/*
+ * @test
+ * @bug 6866657
+ * @summary add byteLength() method to primary classfile types
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.tools.*;
+import com.sun.tools.javap.*;
+
+public class T6866657
+{
+ public static void main(String... args) {
+ new T6866657().run();
+ }
+
+ void run() {
+ verify("java.lang.Object");
+ verify("java.lang.String");
+ verify("java.util.List");
+ verify("java.util.ArrayList");
+ if (errors > 0)
+ throw new Error(errors + " found.");
+ }
+
+ void verify(String className) {
+ try {
+ PrintWriter log = new PrintWriter(System.out);
+ JavaFileManager fileManager = JavapFileManager.create(null, log);
+ JavaFileObject fo = fileManager.getJavaFileForInput(StandardLocation.PLATFORM_CLASS_PATH, className, JavaFileObject.Kind.CLASS);
+ if (fo == null) {
+ error("Can't find " + className);
+ } else {
+ JavapTask t = new JavapTask(log, fileManager, null);
+ t.handleOptions(new String[] { "-sysinfo", className });
+ JavapTask.ClassFileInfo cfInfo = t.read(fo);
+ expectEqual(cfInfo.cf.byteLength(), cfInfo.size);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ error("Exception: " + e);
+ }
+ }
+
+ void expectEqual(int found, int expected) {
+ if (found != expected)
+ error("bad value found: " + found + " expected: " + expected);
+ }
+
+ void error(String msg) {
+ System.err.println(msg);
+ errors++;
+ }
+
+ int errors;
+}
+