Index: /Users/alex/Documents/Harmony/Workspace/Pack200/src/main/java/org/apache/harmony/archive/internal/pack200/AttributeLayout.java =================================================================== --- /Users/alex/Documents/Harmony/Workspace/Pack200/src/main/java/org/apache/harmony/archive/internal/pack200/AttributeLayout.java (revision 467508) +++ /Users/alex/Documents/Harmony/Workspace/Pack200/src/main/java/org/apache/harmony/archive/internal/pack200/AttributeLayout.java (working copy) @@ -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 { @@ -112,17 +114,41 @@ } } + public Object getValue(long value, String type, Segment segment) + throws Pack200Exception { + if (layout.startsWith("KQ")) { + 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 'B': + case 'S': + case 'C': + case 'Z': + case 'I': + return pool.getValue(SegmentConstantPool.CP_INT,value); + } } throw new Pack200Exception("Unknown layout encoding: " + layout); } Index: /Users/alex/Documents/Harmony/Workspace/Pack200/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java =================================================================== --- /Users/alex/Documents/Harmony/Workspace/Pack200/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java (revision 467508) +++ /Users/alex/Documents/Harmony/Workspace/Pack200/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java (working copy) @@ -15,20 +15,31 @@ * 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.Iterator; 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.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.CPField; +import org.apache.harmony.archive.internal.pack200.bytecode.SourceFileAttribute; /** * A Pack200 archive consists of one (or more) segments. Each segment is @@ -66,22 +77,29 @@ public static final int ALL = 0; public static final int SIGNATURE = 2; // TODO and more to come -- - // define in archive order + // define in archive order + public static final int UTF_8 = 1; + public static final int CP_INT = 3; + 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 == SIGNATURE) { return cpSignature[index]; - // etc - throw new Error("Get value incomplete"); + } else if (cp == CP_INT) { + return new Integer(cpInt[index]); + } else { + // etc + throw new Error("Get value incomplete"); + } } } @@ -280,6 +298,8 @@ private int segmentsRemaining; + private ArrayList[][] fieldAttributes; + /** * 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,40 +482,49 @@ 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 + * 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 { + 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