You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ap...@apache.org on 2006/11/24 17:29:00 UTC
svn commit: r478907 [1/2] - in
/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200:
./ bytecode/
Author: apetrenko
Date: Fri Nov 24 08:28:57 2006
New Revision: 478907
URL: http://svn.apache.org/viewvc?view=rev&rev=478907
Log:
Patch for HARMONY-2246 "[classlib][pack200] Ongoing implementation"
Added:
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/Attribute.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPClass.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPConstant.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPConstantNumber.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPDouble.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPField.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPFieldRef.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPFloat.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPInteger.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPLong.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPMember.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPMethod.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPNameAndType.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPString.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPUTF8.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/ClassConstantPool.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/ClassFile.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/ClassFileEntry.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/ConstantPoolEntry.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/ConstantValueAttribute.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/ExceptionsAttribute.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/SourceFileAttribute.java
Removed:
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/ClassConstantPool.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/ClassFile.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/ClassFileEntry.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/ConstantPoolEntry.java
Modified:
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/AttributeLayout.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/AttributeLayoutMap.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Pack200PackerAdapter.java
harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java
Modified: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/AttributeLayout.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/AttributeLayout.java?view=diff&rev=478907&r1=478906&r2=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/AttributeLayout.java (original)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/AttributeLayout.java Fri Nov 24 08:28:57 2006
@@ -15,9 +15,11 @@
* limitations under the License.
*/
package org.apache.harmony.archive.internal.pack200;
-//NOTE: Do not use generics in this code; it needs to run on JVMs < 1.5
-//NOTE: Do not extract strings as messages; this code is still a work-in-progress
-//NOTE: Also, don't get rid of 'else' statements for the hell of it ...
+
+// NOTE: Do not use generics in this code; it needs to run on JVMs < 1.5
+// NOTE: Do not extract strings as messages; this code is still a
+// work-in-progress
+// NOTE: Also, don't get rid of 'else' statements for the hell of it ...
import org.apache.harmony.archive.internal.pack200.Segment.SegmentConstantPool;
public class AttributeLayout {
@@ -78,6 +80,40 @@
private long mask;
+ public static final String ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations";
+
+ public static final String ATTRIBUTE_CLASS_FILE_VERSION = "class-file version";
+
+ public static final String ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = "RuntimeInvisibleParameterAnnotations";
+
+ public static final String ATTRIBUTE_ANNOTATION_DEFAULT = "AnnotationDefault";
+
+ public static final String ATTRIBUTE_CODE = "Code";
+
+ public static final String ATTRIBUTE_SOURCE_FILE = "SourceFile";
+
+ public static final String ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable";
+
+ public static final String ATTRIBUTE_LOCAL_VARIABLE_TABLE = "LocalVariableTable";
+
+ public static final String ATTRIBUTE_LINE_NUMBER_TABLE = "LineNumberTable";
+
+ public static final String ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = "RuntimeVisibleParameterAnnotations";
+
+ public static final String ATTRIBUTE_INNER_CLASSES = "InnerClasses";
+
+ public static final String ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations";
+
+ public static final String ATTRIBUTE_DEPRECATED = "Deprecated";
+
+ public static final String ATTRIBUTE_CONSTANT_VALUE = "ConstantValue";
+
+ public static final String ATTRIBUTE_ENCLOSING_METHOD = "EnclosingMethod";
+
+ public static final String ATTRIBUTE_EXCEPTIONS = "Exceptions";
+
+ public static final String ATTRIBUTE_SIGNATURE = "Signature";
+
public static final int CONTEXT_CODE = 1 << 4;
public static final int CONTEXT_CLASS = 1 << 0;
@@ -112,16 +148,53 @@
}
}
+ public Object getValue(long value, String type, Segment segment)
+ throws Pack200Exception {
+ // TODO This really needs to be better tested, esp. the different types
+ // TODO This should have the ability to deal with RUN stuff too, and unions
+ if (layout.startsWith("KQ")) {
+ if (type.equals("Ljava/lang/String;")) {
+ Object value2 = getValue("KS", value, segment);
+ return value2;
+ } else {
+ return getValue("K" + type + layout.substring(2), value,
+ segment);
+ }
+ } else {
+ return getValue(layout, value, segment);
+ }
+ }
+
public Object getValue(long value, Segment segment) throws Pack200Exception {
+ return getValue(layout, value, segment);
+ }
+
+ private static Object getValue(String layout, long value, Segment segment)
+ throws Pack200Exception {
+ SegmentConstantPool pool = segment.getConstantPool();
if (layout.startsWith("R")) {
// references
if (layout.indexOf('N') != -1)
value--;
- SegmentConstantPool pool = segment.getConstantPool();
if (layout.startsWith("RU")) {
return pool.getValue(SegmentConstantPool.UTF_8, value);
} else if (layout.startsWith("RS")) {
return pool.getValue(SegmentConstantPool.SIGNATURE, value);
+ }
+ } else if (layout.startsWith("K")) {
+ char type = layout.charAt(1);
+ switch (type) {
+ case 'S': // String
+ return pool.getValue(SegmentConstantPool.CP_STRING, value);
+ case 'I': // Int (or byte or short)
+ case 'C': // Char
+ return pool.getValue(SegmentConstantPool.CP_INT, value);
+ case 'F': // Float
+ return pool.getValue(SegmentConstantPool.CP_FLOAT, value);
+ case 'J': // Long
+ return pool.getValue(SegmentConstantPool.CP_LONG,value);
+ case 'D': // Double
+ return pool.getValue(SegmentConstantPool.CP_DOUBLE,value);
}
}
throw new Pack200Exception("Unknown layout encoding: " + layout);
Modified: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/AttributeLayoutMap.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/AttributeLayoutMap.java?view=diff&rev=478907&r1=478906&r2=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/AttributeLayoutMap.java (original)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/AttributeLayoutMap.java Fri Nov 24 08:28:57 2006
@@ -27,61 +27,59 @@
* internationalised, and should not be translated.
*/
public class AttributeLayoutMap {
- // private static final String METADATA = "[NH[(1)]][RSHNH[RUH(1)]][TB(66,67,73,83,90)[KIH](68)[KDH](70)[KFH](74)[KJH](99)[RSH](101)[RSHRUH](115)[RUH](91)[NH[(0)]](64)[RSH[RUH(0)]]()[]]";
-
// create a whole bunch of AttributeLayouts here
private static AttributeLayout[] getDefaultAttributeLayouts()
throws Pack200Exception {
return new AttributeLayout[] {
- new AttributeLayout("LineNumberTable",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_LINE_NUMBER_TABLE,
AttributeLayout.CONTEXT_CODE, "NH[PHH]", 1),
- new AttributeLayout("LocalVariableTable",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TABLE,
AttributeLayout.CONTEXT_CODE, "NH[PHOHRUHRSHH]", 2),
- new AttributeLayout("LocalVariableTypeTable",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE,
AttributeLayout.CONTEXT_CODE, "NH[PHOHRUHRSHH]", 3),
- new AttributeLayout("SourceFile",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_SOURCE_FILE,
AttributeLayout.CONTEXT_CLASS, "RUNH", 17),
- new AttributeLayout("ConstantValue",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_CONSTANT_VALUE,
AttributeLayout.CONTEXT_FIELD, "KQH", 17),
- new AttributeLayout("Code", AttributeLayout.CONTEXT_METHOD,
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_CODE, AttributeLayout.CONTEXT_METHOD,
"*", 17),
- new AttributeLayout("EnclosingMethod",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_ENCLOSING_METHOD,
AttributeLayout.CONTEXT_CLASS, "RCHRDNH", 18),
- new AttributeLayout("Exceptions",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_EXCEPTIONS,
AttributeLayout.CONTEXT_METHOD, "NH[RCH]", 18),
- new AttributeLayout("Signature", AttributeLayout.CONTEXT_CLASS,
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE, AttributeLayout.CONTEXT_CLASS,
"RSH", 19),
- new AttributeLayout("Signature", AttributeLayout.CONTEXT_FIELD,
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE, AttributeLayout.CONTEXT_FIELD,
"RSH", 19),
- new AttributeLayout("Signature",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE,
AttributeLayout.CONTEXT_METHOD, "RSH", 19),
- new AttributeLayout("Deprecated",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_DEPRECATED,
AttributeLayout.CONTEXT_CLASS, "", 20),
- new AttributeLayout("Deprecated",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_DEPRECATED,
AttributeLayout.CONTEXT_FIELD, "", 20),
- new AttributeLayout("Deprecated",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_DEPRECATED,
AttributeLayout.CONTEXT_METHOD, "", 20),
- new AttributeLayout("RuntimeVisibleAnnotations",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
AttributeLayout.CONTEXT_CLASS, "*", 21),
- new AttributeLayout("RuntimeVisibleAnnotations",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
AttributeLayout.CONTEXT_FIELD, "*", 21),
- new AttributeLayout("RuntimeVisibleAnnotations",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
AttributeLayout.CONTEXT_METHOD, "*", 21),
- new AttributeLayout("RuntimeInvisibleAnnotations",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS,
AttributeLayout.CONTEXT_CLASS, "*", 22),
- new AttributeLayout("RuntimeInvisibleAnnotations",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS,
AttributeLayout.CONTEXT_FIELD, "*", 22),
- new AttributeLayout("RuntimeInvisibleAnnotations",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS,
AttributeLayout.CONTEXT_METHOD, "*", 22),
- new AttributeLayout("InnerClasses",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_INNER_CLASSES,
AttributeLayout.CONTEXT_CLASS, "*", 23),
- new AttributeLayout("RuntimeVisibleParameterAnnotations",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS,
AttributeLayout.CONTEXT_METHOD, "*", 23),
- new AttributeLayout("class-file version",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_CLASS_FILE_VERSION,
AttributeLayout.CONTEXT_CLASS, "*", 24),
- new AttributeLayout("RuntimeInvisibleParameterAnnotations",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS,
AttributeLayout.CONTEXT_METHOD, "*", 24),
- new AttributeLayout("AnnotationDefault",
+ new AttributeLayout(AttributeLayout.ATTRIBUTE_ANNOTATION_DEFAULT,
AttributeLayout.CONTEXT_METHOD, "*", 25) };
}
Modified: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Pack200PackerAdapter.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Pack200PackerAdapter.java?view=diff&rev=478907&r1=478906&r2=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Pack200PackerAdapter.java (original)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Pack200PackerAdapter.java Fri Nov 24 08:28:57 2006
@@ -18,10 +18,8 @@
//NOTE: Do not use generics in this code; it needs to run on JVMs < 1.5
//NOTE: Do not extract strings as messages; this code is still a work-in-progress
//NOTE: Also, don't get rid of 'else' statements for the hell of it ...
-import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.SortedMap;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.Pack200.Packer;
Modified: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java?view=diff&rev=478907&r1=478906&r2=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java (original)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java Fri Nov 24 08:28:57 2006
@@ -15,20 +15,32 @@
* limitations under the License.
*/
package org.apache.harmony.archive.internal.pack200;
-//NOTE: Do not use generics in this code; it needs to run on JVMs < 1.5
-//NOTE: Do not extract strings as messages; this code is still a work-in-progress
-//NOTE: Also, don't get rid of 'else' statements for the hell of it ...
+
+// NOTE: Do not use generics in this code; it needs to run on JVMs < 1.5
+// NOTE: Do not extract strings as messages; this code is still a
+// work-in-progress
+// NOTE: Also, don't get rid of 'else' statements for the hell of it ...
import java.io.ByteArrayInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.zip.GZIPInputStream;
-import org.apache.harmony.archive.internal.pack200.ClassFileEntry.SourceFile;
+import org.apache.harmony.archive.internal.pack200.bytecode.Attribute;
+import org.apache.harmony.archive.internal.pack200.bytecode.CPClass;
+import org.apache.harmony.archive.internal.pack200.bytecode.CPField;
+import org.apache.harmony.archive.internal.pack200.bytecode.CPMethod;
+import org.apache.harmony.archive.internal.pack200.bytecode.ClassConstantPool;
+import org.apache.harmony.archive.internal.pack200.bytecode.ClassFile;
+import org.apache.harmony.archive.internal.pack200.bytecode.ClassFileEntry;
+import org.apache.harmony.archive.internal.pack200.bytecode.ConstantValueAttribute;
+import org.apache.harmony.archive.internal.pack200.bytecode.ExceptionsAttribute;
+import org.apache.harmony.archive.internal.pack200.bytecode.SourceFileAttribute;
/**
* A Pack200 archive consists of one (or more) segments. Each segment is
@@ -65,23 +77,46 @@
public class SegmentConstantPool {
public static final int ALL = 0;
+ public static final int CP_DOUBLE = 7;
+
+ // define in archive order
+
+ public static final int CP_FLOAT = 4; // TODO Check this
+
+ public static final int CP_INT = 3;
+
+ public static final int CP_LONG = 6;
+
+ public static final int CP_STRING = 5;
+
public static final int SIGNATURE = 2; // TODO and more to come --
- // define in archive order
public static final int UTF_8 = 1;
public Object getValue(int cp, long value) throws Pack200Exception {
- int index = (int)value;
- if (index == -1)
+ int index = (int) value;
+ if (index == -1) {
return null;
- if (index < 0)
+ } else if (index < 0) {
throw new Pack200Exception("Cannot have a negative range");
- if (cp == UTF_8)
+ } else if (cp == UTF_8) {
return cpUTF8[index];
- if (cp == SIGNATURE)
+ } else if (cp == CP_STRING) {
+ return cpString[index];
+ } else if (cp == SIGNATURE) {
return cpSignature[index];
- // etc
- throw new Error("Get value incomplete");
+ } else if (cp == CP_INT) {
+ return new Integer(cpInt[index]);
+ } else if (cp == CP_FLOAT) {
+ return new Float(cpFloat[index]);
+ } else if (cp == CP_DOUBLE) {
+ return new Double(cpDouble[index]);
+ } else if (cp == CP_LONG) {
+ return new Long(cpLong[index]);
+ } else {
+ // etc
+ throw new Error("Get value incomplete");
+ }
}
}
@@ -144,6 +179,10 @@
}
}
+ private int archiveMajor;
+
+ private int archiveMinor;
+
private long archiveModtime;
private long archiveSize;
@@ -238,6 +277,8 @@
private int fieldAttrCount;
+ private ArrayList[][] fieldAttributes;
+
private String[][] fieldDescr;
private long[][] fieldFlags;
@@ -262,15 +303,15 @@
private int innerClassCount;
- private int archiveMajor;
-
private int methodAttrCount;
+ private ArrayList[][] methodAttributes;
+
private String[][] methodDescr;
- private long[][] methodFlags;
+ private ExceptionsAttribute[][] methodExceptions;
- private int archiveMinor;
+ private long[][] methodFlags;
private int numberOfFiles;
@@ -280,6 +321,68 @@
private int segmentsRemaining;
+ private ClassFile buildClassFile(int classNum) {
+ ClassFile classFile = new ClassFile();
+ classFile.major = defaultClassMajorVersion; // TODO If
+ // classVersionMajor[] use
+ // that instead
+ classFile.minor = defaultClassMinorVersion; // TODO if
+ // classVersionMinor[] use
+ // that instead
+ // build constant pool
+ ClassConstantPool cp = classFile.pool;
+ String fullName = classThis[classNum];
+ // SourceFile attribute
+ int i = fullName.lastIndexOf("/") + 1; // if lastIndexOf==-1, then
+ // -1+1=0, so str.substring(0)
+ // == str
+ String fileName = fullName.substring(i) + ".java";
+ classFile.attributes = new Attribute[] { (Attribute) cp
+ .add(new SourceFileAttribute(fileName)) };
+ // this/superclass
+ ClassFileEntry cfThis = cp.add(new CPClass(fullName));
+ ClassFileEntry cfSuper = cp.add(new CPClass(classSuper[classNum]));
+ // add interfaces
+ ClassFileEntry cfInterfaces[] = new ClassFileEntry[classInterfaces[classNum].length];
+ for (i = 0; i < cfInterfaces.length; i++) {
+ cfInterfaces[i] = cp.add(new CPClass(classInterfaces[classNum][i]));
+ }
+ // add fields
+ ClassFileEntry cfFields[] = new ClassFileEntry[classFieldCount[classNum]];
+ // fieldDescr and fieldFlags used to create this
+ for (i = 0; i < cfFields.length; i++) {
+ cfFields[i] = cp.add(new CPField(fieldDescr[classNum][i],
+ fieldFlags[classNum][i], fieldAttributes[classNum][i]));
+ }
+ // add methods
+ ClassFileEntry cfMethods[] = new ClassFileEntry[classMethodCount[classNum]];
+ // fieldDescr and fieldFlags used to create this
+ for (i = 0; i < cfMethods.length; i++) {
+ cfMethods[i] = cp.add(new CPMethod(methodDescr[classNum][i],
+ methodFlags[classNum][i], methodAttributes[classNum][i]));
+ }
+ // sort CP according to cp_All
+ cp.resolve();
+ // print out entries
+ debug("Constant pool looks like:");
+ for (i = 1; i <= cp.size(); i++) {
+ debug(String.valueOf(i) + ":" + String.valueOf(cp.get(i)));
+ }
+ // NOTE the indexOf is only valid after the cp.resolve()
+ // build up remainder of file
+ classFile.accessFlags = (int) classFlags[classNum];
+ classFile.thisClass = cp.indexOf(cfThis);
+ classFile.superClass = cp.indexOf(cfSuper);
+ // TODO placate format of file for writing purposes
+ classFile.interfaces = new int[cfInterfaces.length];
+ for (i = 0; i < cfInterfaces.length; i++) {
+ classFile.interfaces[i] = cp.indexOf(cfInterfaces[i]);
+ }
+ classFile.fields = cfFields;
+ classFile.methods = cfMethods;
+ return classFile;
+ }
+
/**
* This is a local debugging message to aid the developer in writing this
* class. It will be removed before going into production. If the property
@@ -462,89 +565,6 @@
public int getNumberOfFiles() {
return numberOfFiles;
}
- /**
- * Writes the segment to an output stream. The output stream should be pre-buffered for
- * efficiency. Also takes the same input stream for reading, since the file bits may
- * not be loaded and thus just copied from one stream to another.
- * Doesn't close the output stream when finished, in case there are more entries (e.g.
- * further segments) to be written.
- * @param out the JarOutputStream to write data to
- * @param in the same InputStream that was used to parse the segment
- * @throws IOException if an error occurs whilst reading or writing to the streams
- * @throws Pack200Exception if an error occurs whilst unpacking data
- */
- public void writeJar(JarOutputStream out, InputStream in ) throws IOException, Pack200Exception {
- processFileBits(in);
- DataOutputStream dos = new DataOutputStream(out);
- // out.setLevel(JarEntry.DEFLATED)
- // now write the files out
- int classNum = 0;
- for(int i=0;i<numberOfFiles;i++) {
- String name = fileName[i];
- long modtime = archiveModtime + fileModtime[i];
- boolean deflate = (fileOptions[i] & 1) == 1 || options.shouldDeflate();
- boolean isClass = (fileOptions[i] & 2) == 2 || name == null || name.equals("");
- if (isClass) {
- // pull from headers
- if (name == null || name.equals(""))
- name = cpClass[classNum] + ".class";
- };
- JarEntry entry = new JarEntry(name);
- if (deflate)
- entry.setMethod(JarEntry.DEFLATED);
- entry.setTime(modtime);
- out.putNextEntry(entry);
-
- if(isClass){
- // write to dos
- ClassFile classFile = buildClassFile(classNum);
- classFile.write(dos);
- dos.flush();
- classNum++;
- } else {
- long size = fileSize[i];
- entry.setSize(size);
- // TODO pull from in
- byte[] data = fileBits[i];
- out.write(data);
- }
- }
- dos.flush();
- out.finish();
- out.flush();
- }
-
- private ClassFile buildClassFile(int classNum) {
- ClassFile classFile = new ClassFile();
- classFile.major = defaultClassMajorVersion; // TODO If classVersionMajor[] use that instead
- classFile.minor = defaultClassMinorVersion; // TODO if classVersionMinor[] use that instead
- // build constant pool
- ClassFileEntry cfThis = new ConstantPoolEntry.Class(classThis[classNum]);
- ClassFileEntry cfSuper = new ConstantPoolEntry.Class(classSuper[classNum]);
- ClassFileEntry cfInterfaces[] = new ClassFileEntry[classInterfaces[classNum].length];
- for(int i=0;i<cfInterfaces.length;i++) {
- cfInterfaces[i] = new ConstantPoolEntry.Class(classInterfaces[classNum][i]);
- }
- ClassConstantPool cp = classFile.pool;
- cp.add(cfThis);
- cp.add(cfSuper);
- // build up remainder of file
- classFile.accessFlags = (int) classFlags[classNum];
- classFile.thisClass = cp.indexOf(cfThis);
- classFile.superClass = cp.indexOf(cfSuper);
- // TODO placate format of file for writing purposes
- classFile.interfaces = new int[0];
- classFile.fields = new int[0];
- classFile.methods = new int[0];
- SourceFile sf;
- classFile.attributes = new ClassFileEntry.Attribute[] { sf = new ClassFileEntry.SourceFile(classThis[classNum] + ".java") };
- cp.add(sf);
-
- // sort CP according to cp_All
- cp.resolve();
-
- return classFile;
- }
private SegmentOptions getOptions() {
return options;
@@ -605,6 +625,75 @@
attributeDefinitionMap = new AttributeLayoutMap();
}
+ /**
+ * @param in
+ * @throws Pack200Exception
+ * @throws IOException
+ */
+ private void parseAttributeMethodExceptions(InputStream in)
+ throws Pack200Exception, IOException {
+ // TODO Should refactor this stuff into the layout somehow
+ AttributeLayout layout = attributeDefinitionMap.getAttributeLayout(
+ "Exceptions", AttributeLayout.CONTEXT_METHOD);
+ Codec codec = layout.getCodec();
+ methodExceptions = new ExceptionsAttribute[classCount][];
+ int[][] numExceptions = new int[classCount][];
+ for (int i = 0; i < classCount; i++) {
+ numExceptions[i] = new int[methodFlags[i].length];
+ for (int j = 0; j < methodFlags[i].length; j++) {
+ long flag = methodFlags[i][j];
+ if (layout.matches(flag)) {
+ numExceptions[i][j] = (int) codec.decode(in);
+ }
+ }
+ }
+ for (int i = 0; i < classCount; i++) {
+ methodExceptions[i] = new ExceptionsAttribute[methodFlags[i].length];
+ for (int j = 0; j < methodFlags[i].length; j++) {
+ long flag = methodFlags[i][j];
+ int n = numExceptions[i][j];
+ CPClass[] exceptions = new CPClass[n];
+ if (layout.matches(flag)) {
+ for (int k = 0; k < n; k++) {
+ long result = codec.decode(in);
+ exceptions[k] = new CPClass(cpClass[(int) result]);
+ }
+ }
+ methodExceptions[i][j] = new ExceptionsAttribute(exceptions);
+ methodAttributes[i][j].add(methodExceptions[i][j]);
+ }
+ }
+ }
+
+ /**
+ * @param in
+ *
+ */
+ private void parseAttributeMethodSignature(InputStream in)
+ throws Pack200Exception, IOException {
+ parseAttributeUnknown(AttributeLayout.ATTRIBUTE_SIGNATURE,
+ AttributeLayout.CONTEXT_METHOD, methodFlags);
+ }
+
+ /**
+ * @param name
+ * @param flags
+ * @throws Pack200Exception
+ */
+ private void parseAttributeUnknown(String name, int context, long[][] flags)
+ throws Pack200Exception {
+ debug("Parsing unknown attributes for " + name);
+ AttributeLayout layout = attributeDefinitionMap.getAttributeLayout(
+ name, context);
+ for (int i = 0; i < flags.length; i++) {
+ for (int j = 0; j < flags[i].length; j++) {
+ if (layout.matches(flags[i][j]))
+ throw new Error("We've got data for " + name
+ + " and we don't know what to do with it (yet)");
+ }
+ }
+ }
+
private void parseBcBands(InputStream in) {
debug("Unimplemented bc_bands");
}
@@ -625,17 +714,19 @@
debug("unimplemented class_attr_indexes");
debug("unimplemented class_attr_calls");
AttributeLayout layout = attributeDefinitionMap.getAttributeLayout(
- "SourceFile", AttributeLayout.CONTEXT_CLASS);
+ AttributeLayout.ATTRIBUTE_SOURCE_FILE,
+ AttributeLayout.CONTEXT_CLASS);
for (int i = 0; i < classCount; i++) {
long flag = classFlags[i];
if (layout.matches(flag)) {
// we've got a value to read
+ // TODO File this as a sourcefile attribute and don't generate
+ // everything below
long result = layout.getCodec().decode(in);
Object value = layout.getValue(result, this);
- debug("Processed value " + value + " for SourceFile");
+ debug("Processed value " + value + " for SourceFile");
}
}
- debug("unimplemented class_SourceFile_RUN");
debug("unimplemented class_EnclosingMethod_RC");
debug("unimplemented class_EnclosingMethod_RDN");
debug("unimplemented class_Signature_RS");
@@ -658,10 +749,10 @@
classInterfaces = new String[classCount][];
int[] classInterfaceLengths = decodeBandInt("class_interface_count",
in, Codec.DELTA5, classCount);
- for (int i = 0; i < classCount; i++) {
- classInterfaces[i] = parseReferences("class_interface", in,
- Codec.DELTA5, classInterfaceLengths[i], cpClass);
- }
+ // for (int i = 0; i < classCount; i++) {
+ classInterfaces = parseReferences("class_interface", in, Codec.DELTA5,
+ classCount, classInterfaceLengths, cpClass);
+ // }
classFieldCount = decodeBandInt("class_field_count", in, Codec.DELTA5,
classCount);
classMethodCount = decodeBandInt("class_method_count", in,
@@ -702,7 +793,22 @@
}
}
- private void parseCodeBands(InputStream in) {
+ private void parseCodeBands(InputStream in) throws Pack200Exception {
+ // look through each method
+ int codeBands = 0;
+ AttributeLayout layout = attributeDefinitionMap.getAttributeLayout(
+ AttributeLayout.ATTRIBUTE_CODE,
+ AttributeLayout.CONTEXT_METHOD);
+
+ for (int i = 0; i < classCount; i++) {
+ for (int j = 0; j < methodFlags[i].length; j++) {
+ long flag = methodFlags[i][j];
+ if (layout.matches(flag))
+ codeBands++;
+ }
+ }
+ if (codeBands > 0)
+ throw new Error("Can't handle non-abstract, non-native methods/initialisers at the moment (found " + codeBands + " code bands)");
debug("unimplemented code_headers");
debug("unimplemented code_max_stack");
debug("unimplemented code_max_na_locals");
@@ -855,8 +961,8 @@
private void parseCpLong(InputStream in) throws IOException,
Pack200Exception {
- cpLong = parseFlags("cp_Long", in, cpLongCount, Codec.UDELTA5,
- Codec.DELTA5);
+ cpLong = parseFlags("cp_Long", in, cpLongCount, new int[] { 1 },
+ Codec.UDELTA5, Codec.DELTA5)[0];
}
/**
@@ -1015,16 +1121,10 @@
private void parseFieldBands(InputStream in) throws IOException,
Pack200Exception {
- fieldDescr = new String[classCount][];
- for (int i = 0; i < classCount; i++) {
- fieldDescr[i] = parseReferences("field_descr", in, Codec.DELTA5,
- classFieldCount[i], cpDescriptor);
- }
- fieldFlags = new long[classCount][];
- for (int i = 0; i < classCount; i++) {
- fieldFlags[i] = parseFlags("field_flags", in, classFieldCount[i],
- Codec.UNSIGNED5, options.hasFieldFlagsHi());
- }
+ fieldDescr = parseReferences("field_descr", in, Codec.DELTA5,
+ classCount, classFieldCount, cpDescriptor);
+ fieldFlags = parseFlags("field_flags", in, classCount, classFieldCount,
+ Codec.UNSIGNED5, options.hasFieldFlagsHi());
for (int i = 0; i < classCount; i++) {
for (int j = 0; j < fieldFlags[i].length; j++) {
long flag = fieldFlags[i][j];
@@ -1037,7 +1137,33 @@
"There are attribute flags, and I don't know what to do with them");
debug("unimplemented field_attr_indexes");
debug("unimplemented field_attr_calls");
- debug("unimplemented field_ConstantValueKQ");
+ AttributeLayout layout = attributeDefinitionMap.getAttributeLayout(
+ "ConstantValue", AttributeLayout.CONTEXT_FIELD);
+ Codec codec = layout.getCodec();
+ fieldAttributes = new ArrayList[classCount][];
+ for (int i = 0; i < classCount; i++) {
+ fieldAttributes[i] = new ArrayList[fieldFlags[i].length];
+ for (int j = 0; j < fieldFlags[i].length; j++) {
+ fieldAttributes[i][j] = new ArrayList();
+ long flag = fieldFlags[i][j];
+ if (layout.matches(flag)) {
+ // we've got a value to read
+ long result = codec.decode(in);
+ String desc = fieldDescr[i][j];
+ int colon = desc.indexOf(':');
+ // String name = desc.substring(0, colon);
+ String type = desc.substring(colon + 1);
+ // TODO Got to get better at this ... in any case, it should
+ // be e.g. KIB or KIH
+ if (type.equals("B") || type.equals("H"))
+ type = "I";
+ Object value = layout.getValue(result, type, this);
+ fieldAttributes[i][j]
+ .add(new ConstantValueAttribute(value));
+ debug("Processed value " + value + " for ConstantValue");
+ }
+ }
+ }
debug("unimplemented field_Signature_RS");
parseMetadataBands("field");
}
@@ -1060,6 +1186,15 @@
*/
private void parseFileBands(InputStream in) throws IOException,
Pack200Exception {
+ if (false && System.getProperty("debug.pack200") != null) {
+ // TODO HACK
+ fileSize = new long[numberOfFiles];
+ fileModtime = new long[numberOfFiles];
+ fileOptions = new long[numberOfFiles];
+ fileName = new String[numberOfFiles];
+ Arrays.fill(fileName, "");
+ return;
+ }
long last;
fileName = parseReferences("file_name", in, Codec.UNSIGNED5,
numberOfFiles, cpUTF8);
@@ -1091,28 +1226,43 @@
}
private long[] parseFlags(String name, InputStream in, int count,
- Codec codec) throws IOException, Pack200Exception {
- return parseFlags(name, in, count, codec, true);
+ Codec codec, boolean hasHi) throws IOException, Pack200Exception {
+ return parseFlags(name, in, 1, new int[] { count }, (hasHi ? codec
+ : null), codec)[0];
}
- private long[] parseFlags(String name, InputStream in, int count,
- Codec codec, boolean hasHi) throws IOException, Pack200Exception {
- return parseFlags(name, in, count, (hasHi ? codec : null), codec);
+ private long[][] parseFlags(String name, InputStream in, int count,
+ int counts[], Codec codec, boolean hasHi) throws IOException,
+ Pack200Exception {
+ return parseFlags(name, in, count, counts, (hasHi ? codec : null),
+ codec);
}
- private long[] parseFlags(String name, InputStream in, int count,
- Codec hiCodec, Codec loCodec) throws IOException, Pack200Exception {
- long[] result = new long[count];
- // TODO Refactor into band parsing
- long last = 0;
- for (int i = 0; i < count && hiCodec != null; i++) {
- last = hiCodec.decode(in, last);
- result[i] = last << 32;
+ private long[][] parseFlags(String name, InputStream in, int count,
+ int counts[], Codec hiCodec, Codec loCodec) throws IOException,
+ Pack200Exception {
+ // TODO Move away from decoding into a parseBand type structure
+ if (count == 0) {
+ return new long[][] { {} };
}
- for (int i = 0; i < count; i++) {
- last = loCodec.decode(in, last);
- result[i] = result[i] | last;
+ long[][] result = new long[count][];
+ // TODO What happens when the decode here indicates a different
+ // encoding?
+ // TODO Move this to a decodeBandInt
+ long last = 0;
+ for (int j = 0; j < count; j++) {
+ result[j] = new long[counts[j]];
+ for (int i = 0; i < counts[j] && hiCodec != null; i++) {
+ last = hiCodec.decode(in, last);
+ result[j][i] = last << 32;
+ }
}
+ last = 0;
+ for (int j = 0; j < count; j++)
+ for (int i = 0; i < counts[j]; i++) {
+ last = loCodec.decode(in, last);
+ result[j][i] = result[j][i] | last;
+ }
// TODO Remove debugging code
debug("Parsed *" + name + " (" + result.length + ")");
return result;
@@ -1175,17 +1325,10 @@
private void parseMethodBands(InputStream in) throws IOException,
Pack200Exception {
- methodDescr = new String[classCount][];
- for (int i = 0; i < classCount; i++) {
- methodDescr[i] = parseReferences("method_descr", in, Codec.MDELTA5,
- classMethodCount[i], cpDescriptor);
- }
- methodFlags = new long[classCount][];
- for (int i = 0; i < classCount; i++) {
- methodFlags[i] = parseFlags("method_flags", in,
- classMethodCount[i], Codec.UNSIGNED5, options
- .hasMethodFlagsHi());
- }
+ methodDescr = parseReferences("method_descr", in, Codec.MDELTA5,
+ classCount, classMethodCount, cpDescriptor);
+ methodFlags = parseFlags("method_flags", in, classCount,
+ classMethodCount, Codec.UNSIGNED5, options.hasMethodFlagsHi());
for (int i = 0; i < classCount; i++) {
for (int j = 0; j < methodFlags[i].length; j++) {
long flag = methodFlags[i][j];
@@ -1199,9 +1342,16 @@
debug("unimplemented method_attr_count");
debug("unimplemented method_attr_indexes");
debug("unimplemented method_attr_calls");
- debug("unimplemented method_Exceptions_N");
- debug("unimplemented method_Exceptions_RC");
- debug("unimplemented method_Signature_RS");
+ // assign empty method attributes
+ methodAttributes = new ArrayList[classCount][];
+ for (int i = 0; i < classCount; i++) {
+ methodAttributes[i] = new ArrayList[methodFlags[i].length];
+ for (int j = 0; j < methodFlags[i].length; j++) {
+ methodAttributes[i][j] = new ArrayList();
+ }
+ }
+ parseAttributeMethodExceptions(in);
+ parseAttributeMethodSignature(in);
parseMetadataBands("method");
}
@@ -1210,7 +1360,8 @@
* using <code>codec</code> to decode the values as indexes into
* <code>reference</code> (which is populated prior to this call). An
* exception is thrown if a decoded index falls outside the range
- * [0..reference.length-1].
+ * [0..reference.length-1]. Unlike the other parseReferences, this
+ * post-processes the result into an array of results.
*
* @param name
* TODO
@@ -1230,22 +1381,73 @@
* if a problem occurs with an unexpected value or unsupported
* codec
*/
- private String[] parseReferences(String name, InputStream in,
- BHSDCodec codec, int count, String[] reference) throws IOException,
- Pack200Exception {
- String[] result = new String[count];
- int[] decode = decodeBandInt(name, in, codec, count);
+ private String[][] parseReferences(String name, InputStream in,
+ BHSDCodec codec, int count, int counts[], String[] reference)
+ throws IOException, Pack200Exception {
+ if (count == 0) {
+ return new String[][] { {} };
+ }
+ String[][] result = new String[count][];
+ int sum = 0;
for (int i = 0; i < count; i++) {
- int index = decode[i];
+ result[i] = new String[counts[i]];
+ sum += counts[i];
+ }
+ // TODO Merge the decode and parsing of a multiple structure into one
+ String[] result1 = new String[sum];
+ int[] decode = decodeBandInt(name, in, codec, sum);
+ for (int i1 = 0; i1 < sum; i1++) {
+ int index = decode[i1];
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
"Something has gone wrong during parsing references");
- result[i] = reference[index];
+ result1[i1] = reference[index];
+ }
+ String[] refs = result1;
+ // TODO Merge the decode and parsing of a multiple structure into one
+ int pos = 0;
+ for (int i = 0; i < count; i++) {
+ int num = counts[i];
+ result[i] = new String[num];
+ System.arraycopy(refs, pos, result[i], 0, num);
+ pos += num;
}
return result;
}
/**
+ * Helper method to parse <i>count</i> references from <code>in</code>,
+ * using <code>codec</code> to decode the values as indexes into
+ * <code>reference</code> (which is populated prior to this call). An
+ * exception is thrown if a decoded index falls outside the range
+ * [0..reference.length-1].
+ *
+ * @param name
+ * TODO
+ * @param in
+ * the input stream to read from
+ * @param codec
+ * the codec to use for decoding
+ * @param count
+ * the number of references to decode
+ * @param reference
+ * the array of values to use for the indexes; often
+ * {@link #cpUTF8}
+ *
+ * @throws IOException
+ * if a problem occurs during reading from the underlying stream
+ * @throws Pack200Exception
+ * if a problem occurs with an unexpected value or unsupported
+ * codec
+ */
+ private String[] parseReferences(String name, InputStream in,
+ BHSDCodec codec, int count, String[] reference) throws IOException,
+ Pack200Exception {
+ return parseReferences(name, in, codec, 1, new int[] { count },
+ reference)[0];
+ }
+
+ /**
* This performs the actual work of parsing against a non-static instance of
* Segment.
*
@@ -1282,7 +1484,6 @@
parseIcBands(in);
parseClassBands(in);
parseBcBands(in);
- // TODO Re-enable these after completing class/bytecode bands
parseFileBands(in);
}
@@ -1321,6 +1522,34 @@
}
}
+ /**
+ * Sets the major version of this archive.
+ *
+ * @param version
+ * the minor version of the archive
+ * @throws Pack200Exception
+ * if the major version is not 150
+ */
+ private void setArchiveMajorVersion(int version) throws Pack200Exception {
+ if (version != 150)
+ throw new Pack200Exception("Invalid segment major version");
+ archiveMajor = version;
+ }
+
+ /**
+ * Sets the minor version of this archive
+ *
+ * @param version
+ * the minor version of the archive
+ * @throws Pack200Exception
+ * if the minor version is not 7
+ */
+ private void setArchiveMinorVersion(int version) throws Pack200Exception {
+ if (version != 7)
+ throw new Pack200Exception("Invalid segment minor version");
+ archiveMinor = version;
+ }
+
public void setArchiveModtime(long archiveModtime) {
this.archiveModtime = archiveModtime;
}
@@ -1405,34 +1634,6 @@
innerClassCount = (int) value;
}
- /**
- * Sets the major version of this archive.
- *
- * @param version
- * the minor version of the archive
- * @throws Pack200Exception
- * if the major version is not 150
- */
- private void setArchiveMajorVersion(int version) throws Pack200Exception {
- if (version != 150)
- throw new Pack200Exception("Invalid segment major version");
- archiveMajor = version;
- }
-
- /**
- * Sets the minor version of this archive
- *
- * @param version
- * the minor version of the archive
- * @throws Pack200Exception
- * if the minor version is not 7
- */
- private void setArchiveMinorVersion(int version) throws Pack200Exception {
- if (version != 7)
- throw new Pack200Exception("Invalid segment minor version");
- archiveMinor = version;
- }
-
public void setNumberOfFiles(long value) {
numberOfFiles = (int) value;
}
@@ -1443,5 +1644,79 @@
public void setSegmentsRemaining(long value) {
segmentsRemaining = (int) value;
+ }
+
+ /**
+ * This is only here to provide a mechanism to turn off the warnings (and to
+ * prevent anyone from accidentally removing them from the file)
+ *
+ * @deprecated this will be deleted in the future, once I've started to use
+ * them
+ *
+ */
+ int shutUpAboutTheStupidNotReadVariablesYetIHaventImplementedIt() {
+ return archiveMajor + archiveMinor + cpLong.hashCode()
+ + icName.hashCode() + icOuterClass.hashCode()
+ + icThisClass.hashCode();
+ }
+
+ /**
+ * Writes the segment to an output stream. The output stream should be
+ * pre-buffered for efficiency. Also takes the same input stream for
+ * reading, since the file bits may not be loaded and thus just copied from
+ * one stream to another. Doesn't close the output stream when finished, in
+ * case there are more entries (e.g. further segments) to be written.
+ *
+ * @param out
+ * the JarOutputStream to write data to
+ * @param in
+ * the same InputStream that was used to parse the segment
+ * @throws IOException
+ * if an error occurs whilst reading or writing to the streams
+ * @throws Pack200Exception
+ * if an error occurs whilst unpacking data
+ */
+ public void writeJar(JarOutputStream out, InputStream in)
+ throws IOException, Pack200Exception {
+ processFileBits(in);
+ DataOutputStream dos = new DataOutputStream(out);
+ // out.setLevel(JarEntry.DEFLATED)
+ // now write the files out
+ int classNum = 0;
+ for (int i = 0; i < numberOfFiles; i++) {
+ String name = fileName[i];
+ long modtime = archiveModtime + fileModtime[i];
+ boolean deflate = (fileOptions[i] & 1) == 1
+ || options.shouldDeflate();
+ boolean isClass = (fileOptions[i] & 2) == 2 || name == null
+ || name.equals("");
+ if (isClass) {
+ // pull from headers
+ if (name == null || name.equals(""))
+ name = classThis[classNum] + ".class";
+ }
+ JarEntry entry = new JarEntry(name);
+ if (deflate)
+ entry.setMethod(JarEntry.DEFLATED);
+ entry.setTime(modtime);
+ out.putNextEntry(entry);
+
+ if (isClass) {
+ // write to dos
+ ClassFile classFile = buildClassFile(classNum);
+ classFile.write(dos);
+ dos.flush();
+ classNum++;
+ } else {
+ long size = fileSize[i];
+ entry.setSize(size);
+ // TODO pull from in
+ byte[] data = fileBits[i];
+ out.write(data);
+ }
+ }
+ dos.flush();
+ out.finish();
+ out.flush();
}
}
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/Attribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/Attribute.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/Attribute.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/Attribute.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+
+public abstract class Attribute extends ClassFileEntry {
+ private CPUTF8 attributeName;
+
+ private int attributeNameIndex;
+
+ public Attribute(String attributeName) {
+ this.attributeName = new CPUTF8(attributeName);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (this.getClass() != obj.getClass())
+ return false;
+ final Attribute other = (Attribute) obj;
+ if (attributeName == null) {
+ if (other.attributeName != null)
+ return false;
+ } else if (!attributeName.equals(other.attributeName))
+ return false;
+ return true;
+ }
+
+ protected CPUTF8 getAttributeName() {
+ return attributeName;
+ }
+
+ protected abstract int getLength();
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result
+ + ((attributeName == null) ? 0 : attributeName.hashCode());
+ return result;
+ }
+
+ protected void resolve(ClassConstantPool pool) {
+ super.resolve(pool);
+ attributeNameIndex = pool.indexOf(attributeName);
+ }
+
+ protected void doWrite(DataOutputStream dos) throws IOException {
+ dos.writeShort(attributeNameIndex);
+ dos.writeInt(getLength());
+ writeBody(dos);
+ }
+
+ protected abstract void writeBody(DataOutputStream dos)
+ throws IOException;
+
+}
\ No newline at end of file
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPClass.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPClass.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPClass.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPClass.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+
+public class CPClass extends ConstantPoolEntry {
+ private int index;
+
+ public String name;
+
+ private CPUTF8 utf8;
+
+ public CPClass(String name) {
+ super(ConstantPoolEntry.CP_Class);
+ this.name = name;
+ this.utf8 = new CPUTF8(name);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (this.getClass() != obj.getClass())
+ return false;
+ final CPClass other = (CPClass) obj;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (utf8 == null) {
+ if (other.utf8 != null)
+ return false;
+ } else if (!utf8.equals(other.utf8))
+ return false;
+ return true;
+ }
+
+ protected ClassFileEntry[] getNestedClassFileEntries() {
+ return new ClassFileEntry[] { utf8, };
+ }
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((name == null) ? 0 : name.hashCode());
+ result = PRIME * result + ((utf8 == null) ? 0 : utf8.hashCode());
+ return result;
+ }
+
+ protected void resolve(ClassConstantPool pool) {
+ super.resolve(pool);
+ index = pool.indexOf(utf8);
+ }
+
+ public String toString() {
+ return "Class: " + name;
+ }
+
+ protected void writeBody(DataOutputStream dos) throws IOException {
+ dos.writeShort(index);
+ }
+}
\ No newline at end of file
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPConstant.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPConstant.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPConstant.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPConstant.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,43 @@
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+
+public abstract class CPConstant extends ConstantPoolEntry {
+
+ private Object value;
+
+ public CPConstant(byte tag, Object value) {
+ super(tag);
+ this.value = value;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (this.getClass() != obj.getClass())
+ return false;
+ final CPConstant other = (CPConstant) obj;
+ if (value == null) {
+ if (other.value != null)
+ return false;
+ } else if (!value.equals(other.value))
+ return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+ protected Object getValue() {
+ return value;
+ }
+
+
+
+}
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPConstantNumber.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPConstantNumber.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPConstantNumber.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPConstantNumber.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,15 @@
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+
+public abstract class CPConstantNumber extends CPConstant {
+
+ public CPConstantNumber(byte tag, Object value) {
+ super(tag, value);
+ }
+
+ protected Number getNumber() {
+ return (Number)getValue();
+ }
+
+
+}
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPDouble.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPDouble.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPDouble.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPDouble.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class CPDouble extends CPConstantNumber {
+ public CPDouble(java.lang.Double value) {
+ super(ConstantPoolEntry.CP_Double,value);
+ }
+
+ @Override
+ protected void writeBody(DataOutputStream dos) throws IOException {
+ dos.writeDouble(getNumber().doubleValue());
+ }
+
+ @Override
+ public String toString() {
+ return "Double: " + getValue();
+ }
+
+}
\ No newline at end of file
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPField.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPField.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPField.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPField.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,11 @@
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+import java.util.List;
+
+public class CPField extends CPMember {
+
+ public CPField(String descriptor, long flags, List attributes) {
+ super(descriptor, flags, attributes);
+ }
+
+}
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPFieldRef.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPFieldRef.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPFieldRef.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPFieldRef.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+
+public class CPFieldRef extends ConstantPoolEntry {
+
+ CPClass className;
+ transient int classNameIndex;
+
+
+ private CPNameAndType nameAndType;
+ transient int nameAndTypeIndex;
+ public CPFieldRef(String className, String descriptor) {
+ super(ConstantPoolEntry.CP_Fieldref);
+ this.className = new CPClass(className);
+ this.nameAndType = new CPNameAndType(descriptor);
+ }
+
+
+ @Override
+ protected ClassFileEntry[] getNestedClassFileEntries() {
+ ClassFileEntry[] entries = new ClassFileEntry[2];
+ entries[0] = className;
+ entries[1] = nameAndType;
+ return entries;
+ }
+
+
+ @Override
+ protected void resolve(ClassConstantPool pool) {
+ super.resolve(pool);
+ nameAndTypeIndex = pool.indexOf(nameAndType);
+ classNameIndex = pool.indexOf(className);
+ }
+
+ protected void writeBody(DataOutputStream dos) throws IOException {
+ dos.writeShort(classNameIndex);
+ dos.writeShort(nameAndTypeIndex);
+ }
+
+ @Override
+ public String toString() {
+ return "FieldRef: " + className + "#" + nameAndType;
+ }
+
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((className == null) ? 0 : className.hashCode());
+ result = PRIME * result + ((nameAndType == null) ? 0 : nameAndType.hashCode());
+ return result;
+ }
+
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final CPFieldRef other = (CPFieldRef) obj;
+ if (className == null) {
+ if (other.className != null)
+ return false;
+ } else if (!className.equals(other.className))
+ return false;
+ if (nameAndType == null) {
+ if (other.nameAndType != null)
+ return false;
+ } else if (!nameAndType.equals(other.nameAndType))
+ return false;
+ return true;
+ }
+
+}
\ No newline at end of file
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPFloat.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPFloat.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPFloat.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPFloat.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class CPFloat extends CPConstantNumber {
+ public CPFloat(java.lang.Float value) {
+ super(ConstantPoolEntry.CP_Float,value);
+ }
+
+ @Override
+ protected void writeBody(DataOutputStream dos) throws IOException {
+ dos.writeFloat(getNumber().floatValue());
+ }
+
+ @Override
+ public String toString() {
+ return "Float: " + getValue();
+ }
+
+}
\ No newline at end of file
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPInteger.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPInteger.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPInteger.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPInteger.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class CPInteger extends CPConstantNumber {
+
+ public CPInteger(java.lang.Integer value) {
+ super(ConstantPoolEntry.CP_Integer,value);
+ }
+
+ @Override
+ protected void writeBody(DataOutputStream dos) throws IOException {
+ dos.writeInt(getNumber().intValue());
+ }
+
+ @Override
+ public String toString() {
+ return "Integer: " + getValue();
+ }
+
+}
\ No newline at end of file
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPLong.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPLong.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPLong.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPLong.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class CPLong extends CPConstantNumber {
+
+ public CPLong(java.lang.Long value) {
+ super(ConstantPoolEntry.CP_Long,value);
+ }
+
+ @Override
+ protected void writeBody(DataOutputStream dos) throws IOException {
+ dos.writeLong(getNumber().longValue());
+ }
+
+ @Override
+ public String toString() {
+ return "Long: " + getValue();
+ }
+
+}
\ No newline at end of file
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPMember.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPMember.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPMember.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPMember.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class CPMember extends ClassFileEntry {
+
+ List attributes;
+
+
+ short flags;
+
+ CPUTF8 name;
+ transient int nameIndex;
+
+
+ private CPUTF8 descriptor;
+ transient int descriptorIndex;
+ public CPMember(String descriptor, long flags, List attributes) {
+ int colon = descriptor.indexOf(':');
+ this.name = new CPUTF8(descriptor.substring(0,colon));
+ this.descriptor = new CPUTF8(descriptor.substring(colon+1));
+ this.flags = (short) flags;
+ this.attributes = (attributes == null ? new ArrayList() : attributes);
+ }
+
+
+ @Override
+ protected ClassFileEntry[] getNestedClassFileEntries() {
+ int attributeCount = attributes.size();
+ ClassFileEntry[] entries = new ClassFileEntry[attributeCount+2];
+ entries[0] = name;
+ entries[1] = descriptor;
+ for (int i = 0; i < attributeCount; i++) {
+ entries[i+2] = (Attribute) attributes.get(i);
+ }
+ return entries;
+ }
+
+
+ @Override
+ protected void resolve(ClassConstantPool pool) {
+ super.resolve(pool);
+ nameIndex = pool.indexOf(name);
+ descriptorIndex = pool.indexOf(descriptor);
+ for (Iterator it = attributes.iterator(); it.hasNext();) {
+ Attribute attribute = (Attribute) it.next();
+ attribute.resolve(pool);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Field: " + name + "(" + descriptor + ")";
+ }
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((attributes == null) ? 0 : attributes.hashCode());
+ result = PRIME * result + ((descriptor == null) ? 0 : descriptor.hashCode());
+ result = PRIME * result + flags;
+ result = PRIME * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final CPMember other = (CPMember) obj;
+ if (attributes == null) {
+ if (other.attributes != null)
+ return false;
+ } else if (!attributes.equals(other.attributes))
+ return false;
+ if (descriptor == null) {
+ if (other.descriptor != null)
+ return false;
+ } else if (!descriptor.equals(other.descriptor))
+ return false;
+ if (flags != other.flags)
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+
+
+ @Override
+ protected void doWrite(DataOutputStream dos) throws IOException {
+ dos.writeShort(flags);
+ dos.writeShort(nameIndex);
+ dos.writeShort(descriptorIndex);
+ int attributeCount = attributes.size();
+ dos.writeShort(attributeCount);
+ for (int i = 0; i < attributeCount; i++) {
+ Attribute attribute = (Attribute) attributes.get(i);
+ attribute.doWrite(dos);
+ }
+
+ }
+
+}
\ No newline at end of file
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPMethod.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPMethod.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPMethod.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPMethod.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,11 @@
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+import java.util.List;
+
+public class CPMethod extends CPMember {
+
+ public CPMethod(String descriptor, long flags, List attributes) {
+ super(descriptor, flags, attributes);
+ }
+
+}
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPNameAndType.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPNameAndType.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPNameAndType.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPNameAndType.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+
+public class CPNameAndType extends ConstantPoolEntry {
+
+ CPUTF8 descriptor;
+
+ transient int descriptorIndex;
+
+ CPUTF8 name;
+
+ transient int nameIndex;
+
+ public CPNameAndType(String descriptor) {
+ super(ConstantPoolEntry.CP_NameAndType);
+ int colon = descriptor.indexOf(':');
+ this.name = new CPUTF8(descriptor.substring(0,colon));
+ this.descriptor = new CPUTF8(descriptor.substring(colon+1));
+ }
+
+ @Override
+ protected void resolve(ClassConstantPool pool) {
+ super.resolve(pool);
+ descriptorIndex = pool.indexOf(descriptor);
+ nameIndex = pool.indexOf(name);
+ }
+
+ /*
+ * field_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2
+ * attributes_count; attribute_info attributes[attributes_count]; }
+ */
+ @Override
+ protected void writeBody(DataOutputStream dos) throws IOException {
+ dos.writeShort(nameIndex);
+ dos.writeShort(descriptorIndex);
+ }
+
+ @Override
+ public String toString() {
+ return "NameAndType: " + name + "(" + descriptor + ")";
+ }
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((descriptor == null) ? 0 : descriptor.hashCode());
+ result = PRIME * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final CPNameAndType other = (CPNameAndType) obj;
+ if (descriptor == null) {
+ if (other.descriptor != null)
+ return false;
+ } else if (!descriptor.equals(other.descriptor))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+
+}
\ No newline at end of file
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPString.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPString.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPString.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPString.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class CPString extends CPConstant {
+ private transient int nameIndex;
+ private CPUTF8 name;
+
+ public CPString(java.lang.String value) {
+ super(ConstantPoolEntry.CP_String,value);
+ this.name = new CPUTF8((String) getValue());
+
+ }
+
+ @Override
+ protected void writeBody(DataOutputStream dos) throws IOException {
+ dos.writeShort(nameIndex);
+ }
+
+ @Override
+ public String toString() {
+ return "String: " + getValue();
+ }
+
+ /**
+ * Allows the constant pool entries to resolve their nested entries
+ *
+ * @param pool
+ */
+ protected void resolve(ClassConstantPool pool) {
+ super.resolve(pool);
+ nameIndex = pool.indexOf(name);
+ }
+
+ protected ClassFileEntry[] getNestedClassFileEntries() {
+ return new ClassFileEntry[] { name };
+ }
+
+}
\ No newline at end of file
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPUTF8.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPUTF8.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPUTF8.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/CPUTF8.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+public class CPUTF8 extends ConstantPoolEntry {
+ private String utf8;
+
+ public CPUTF8(String utf8) {
+ super(ConstantPoolEntry.CP_UTF8);
+ this.utf8 = utf8;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (this.getClass() != obj.getClass())
+ return false;
+ final CPUTF8 other = (CPUTF8) obj;
+ if (utf8 == null) {
+ if (other.utf8 != null)
+ return false;
+ } else if (!utf8.equals(other.utf8))
+ return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((utf8 == null) ? 0 : utf8.hashCode());
+ return result;
+ }
+
+ public String toString() {
+ return "UTF8: " + utf8;
+ }
+
+ protected void writeBody(DataOutputStream dos) throws IOException {
+ byte[] bytes;
+ try {
+ // TODO Check that this is the right UTF-8 for bytes
+ if (utf8 == null) {
+ bytes = new byte[0];
+ } else {
+ bytes = utf8.getBytes("UTF-8");
+ }
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Couldn't convert string " + utf8
+ + " to UTF-8");
+ }
+ dos.writeShort(bytes.length);
+ dos.write(bytes);
+ }
+
+}
\ No newline at end of file
Added: harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/ClassConstantPool.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/ClassConstantPool.java?view=auto&rev=478907
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/ClassConstantPool.java (added)
+++ harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/bytecode/ClassConstantPool.java Fri Nov 24 08:28:57 2006
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200.bytecode;
+
+// NOTE: Do not use generics in this code; it needs to run on JVMs < 1.5
+// NOTE: Do not extract strings as messages; this code is still a
+// work-in-progress
+// NOTE: Also, don't get rid of 'else' statements for the hell of it ...
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class ClassConstantPool {
+ public String toString() {
+ return entries.toString();
+ }
+ private List others = new ArrayList();
+
+ private List entries = new ArrayList();
+
+ private boolean resolved;
+
+ public ClassFileEntry add(ClassFileEntry entry) {
+ // TODO this should be a set - we don't want duplicates
+ // Only add in constant pools, but resolve all types since they may
+ // introduce new constant pool entries
+ if (entry instanceof ConstantPoolEntry) {
+ if (!entries.contains(entry)) {
+ entries.add(entry);
+ // TODO This will be a bugger when they're sorted.
+ if (entry instanceof CPLong ||entry instanceof CPDouble)
+ entries.add(entry); //these get 2 slots because of their size
+ }
+ } else {
+ if (!others.contains(entry))
+ others.add(entry);
+ }
+ ClassFileEntry[] nestedEntries = entry.getNestedClassFileEntries();
+ for (int i = 0; i < nestedEntries.length; i++) {
+ add(nestedEntries[i]);
+ }
+ return entry;
+ }
+
+ public int indexOf(ClassFileEntry entry) {
+ if (!resolved)
+ throw new IllegalStateException("Constant pool is not yet resolved; this does not make any sense");
+ return entries.indexOf(entry) + 1;
+ }
+
+ public int size() {
+ return entries.size();
+ }
+
+ public ClassFileEntry get(int i) {
+ if (!resolved)
+ throw new IllegalStateException("Constant pool is not yet resolved; this does not make any sense");
+ return (ClassFileEntry) entries.get(--i);
+ }
+
+ public void resolve() {
+ resolved= true;
+ Iterator it = entries.iterator();
+ while (it.hasNext()) {
+ ClassFileEntry entry = (ClassFileEntry) it.next();
+ entry.resolve(this);
+ }
+ it = others.iterator();
+ while (it.hasNext()) {
+ ClassFileEntry entry = (ClassFileEntry) it.next();
+ entry.resolve(this);
+ }
+ }
+
+}