You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by sj...@apache.org on 2008/10/22 11:39:19 UTC

svn commit: r706922 - in /harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200: Archive.java BandSet.java CPSignature.java CpBands.java FileBands.java Segment.java

Author: sjanuary
Date: Wed Oct 22 02:39:19 2008
New Revision: 706922

URL: http://svn.apache.org/viewvc?rev=706922&view=rev
Log:
Pack200 progress, including gzip support and file bands implementation

Modified:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java?rev=706922&r1=706921&r2=706922&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java Wed Oct 22 02:39:19 2008
@@ -18,6 +18,7 @@
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -27,6 +28,8 @@
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+import java.util.zip.GZIPOutputStream;
 
 import org.objectweb.asm.ClassReader;
 
@@ -40,8 +43,11 @@
     private final OutputStream outputStream;
     private JarFile jarFile;
 
-    public Archive(JarInputStream inputStream, OutputStream outputStream) {
+    public Archive(JarInputStream inputStream, OutputStream outputStream, boolean gzip) throws IOException {
         this.inputStream = inputStream;
+        if(gzip) {
+            outputStream = new GZIPOutputStream(outputStream);
+        }
         this.outputStream = new BufferedOutputStream(outputStream);
     }
 
@@ -56,42 +62,71 @@
         List files = new ArrayList();
         List classNames = new ArrayList();
         List classModtimes = new ArrayList();
+        Manifest manifest = jarFile != null ? jarFile.getManifest() : inputStream.getManifest();
+        if(manifest!= null) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            manifest.write(baos);
+            files.add(new File("META-INF/MANIFEST.MF", baos.toByteArray(), 0));
+        }
         if(inputStream != null) {
             while(inputStream.available() > 0) {
                 JarEntry jarEntry = inputStream.getNextJarEntry();
                 if(jarEntry != null) {
-                    addJarEntry(jarEntry, new BufferedInputStream(inputStream), classes, classNames, classModtimes, files);
+                    addJarEntry(jarEntry, new BufferedInputStream(inputStream), classes, files);
                 }
             }
         } else {
             Enumeration jarEntries = jarFile.entries();
             while(jarEntries.hasMoreElements()) {
                 JarEntry jarEntry = (JarEntry) jarEntries.nextElement();
-                addJarEntry(jarEntry, new BufferedInputStream(jarFile.getInputStream(jarEntry)), classes, classNames, classModtimes, files);
+                addJarEntry(jarEntry, new BufferedInputStream(jarFile.getInputStream(jarEntry)), classes, files);
             }
         }
-        new Segment().pack(classes, classNames, classModtimes, files, outputStream);  // TODO: Multiple segments
+        new Segment().pack(classes, files, outputStream);  // TODO: Multiple segments
         outputStream.close();
     }
 
-    private void addJarEntry(JarEntry jarEntry, InputStream stream, List javaClasses, List classNames, List classModtimes, List files) throws IOException, Pack200Exception {
+    private void addJarEntry(JarEntry jarEntry, InputStream stream, List javaClasses, List files) throws IOException, Pack200Exception {
         String name = jarEntry.getName();
+        long size = jarEntry.getSize();
+        if (size > Integer.MAX_VALUE) {
+            throw new RuntimeException("Large Class!");
+        }
+        byte[] bytes = new byte[(int)size];
+        int read = stream.read(bytes);
+        if(read != size) {
+            throw new RuntimeException("Error reading from stream");
+        }
         if(name.endsWith(".class")) {
-            long size = jarEntry.getSize();
-            if (size > Integer.MAX_VALUE) {
-                throw new RuntimeException("Large Class!");
-            }
-            byte[] bytes = new byte[(int)size];
-            int read = stream.read(bytes);
-            if(read != size) {
-                throw new RuntimeException("Error reading from stream");
-            }
             ClassReader classParser = new Pack200ClassReader(bytes);
             javaClasses.add(classParser);
-            classNames.add(name);
-            classModtimes.add(new Long(jarEntry.getTime()));
-        } else {
-            // TODO: it's a file...
+            bytes = new byte[0];
+        }
+        files.add(new File(name, bytes, jarEntry.getTime()));
+    }
+
+    static class File {
+
+        private final String name;
+        private final byte[] contents;
+        private final long modtime;
+
+        public File(String name, byte[] contents, long modtime) {
+            this.name = name;
+            this.contents = contents;
+            this.modtime = modtime;
+        }
+
+        public byte[] getContents() {
+            return contents;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public long getModtime() {
+            return modtime;
         }
     }
 

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java?rev=706922&r1=706921&r2=706922&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java Wed Oct 22 02:39:19 2008
@@ -36,7 +36,7 @@
     public byte[] encodeBandInt(String name, int[] ints, BHSDCodec defaultCodec) throws Pack200Exception {
         // TODO non-default codecs
         if(ints.length > 0) {
-            System.out.println("encoding " + name + ", size = " + ints.length);
+//            System.out.println("encoding " + name + ", size = " + ints.length);
             int first = ints[0];
             if(defaultCodec.getB() != 1) {
                 if (defaultCodec.isSigned() && first >= -256 && first <= -1) {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java?rev=706922&r1=706921&r2=706922&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java Wed Oct 22 02:39:19 2008
@@ -33,6 +33,9 @@
     }
 
     public int compareTo(Object arg0) {
+        if(signature.equals(((CPSignature) arg0).signature)) {
+            return 0;
+        }
         if (formStartsWithBracket
                 && !((CPSignature) arg0).formStartsWithBracket) {
             return 1;
@@ -45,12 +48,16 @@
             return classes.size() - ((CPSignature) arg0).classes.size();
         }
         if (classes.size() > 0) {
-            CPClass myFirstClass = (CPClass) classes.get(0);
-            CPClass compareClass = (CPClass) ((CPSignature) arg0).classes
-                    .get(0);
-            return myFirstClass.toString().compareTo(compareClass.toString())
-                    * 1000
-                    + signature.compareTo(((CPSignature) arg0).signature);
+            int classComp = 0;
+            for (int i = classes.size() - 1; i >=0; i--) {
+                CPClass cpClass = (CPClass) classes.get(i);
+                CPClass compareClass = (CPClass) ((CPSignature) arg0).classes
+                        .get(i);
+                classComp = classComp * 10 + cpClass.compareTo(compareClass);
+            }
+            if(classComp != 0) {
+                return classComp;
+            }
         }
         return signature.compareTo(((CPSignature) arg0).signature);
     }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java?rev=706922&r1=706921&r2=706922&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java Wed Oct 22 02:39:19 2008
@@ -414,7 +414,7 @@
                         for (int j = i + 1; j < chars.length; j++) {
                             char c = chars[j];
                             if (Character.isLetter(c) || Character.isDigit(c)
-                                    || c == '/') {
+                                    || c == '/' || c == '$' || c == '_') {
                                 className.append(c);
                             } else {
                                 classes.add(className.toString());

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java?rev=706922&r1=706921&r2=706922&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java Wed Oct 22 02:39:19 2008
@@ -20,39 +20,45 @@
 import java.io.OutputStream;
 import java.util.List;
 
+import org.apache.harmony.pack200.Archive.File;
+
 public class FileBands extends BandSet {
 
-    private final List files;
     private final SegmentHeader segmentHeader;
     private final CPUTF8[] fileName;
     private int[] file_name;
     private final long[] file_modtime;
     private final long[] file_size;
     private final int[] file_options;
-    private final int[] file_bits;
+    private final byte[][] file_bits;
 
     public FileBands(CpBands cpBands, SegmentHeader segmentHeader,
-            List classNames, List classModTimes, List files) {
+            List files) {
         this.segmentHeader = segmentHeader;
-        this.files = files;
-        int numClasses = classNames.size();
-        int size = /* files.size() + */numClasses;
+        int size =  files.size();
         fileName = new CPUTF8[size];
         file_modtime = new long[size];
         file_size = new long[size];
         file_options = new int[size];
         CPUTF8 emptyString = cpBands.getCPUtf8("");
-        for (int i = 0; i < numClasses; i++) {
-            fileName[i] = emptyString;
-            file_options[i] |= (1 << 1);
-        }
-        file_bits = new int[0];
-        // for (int i = 0; i < files.size(); i++) {
-        // fileNames[i + numClasses] = ?
-        // }
-        // for (int i = 0; i < array.length; i++) {
-        //
-        // }
+        int totalSize = 0;
+        file_bits = new byte[files.size()][];
+         for (int i = 0; i < files.size(); i++) {
+             File file = (File)files.get(i);
+             String name = file.getName();
+             fileName[i] = cpBands.getCPUtf8(name); // TODO: sometimes this can be the empty string
+             if(name.endsWith(".class")) {
+//                 fileName[i] = emptyString;
+                 file_options[i] |= (1 << 1);
+//             } else {
+//                 fileName[i] = cpBands.getCPUtf8(name);
+             }
+             byte[] bytes = file.getContents();
+             file_size[i] = bytes.length;
+             totalSize += file_size[i];
+             file_modtime[i] = file.getModtime();
+             file_bits[i] = file.getContents();
+         }
     }
 
     public void finaliseBands() {
@@ -73,8 +79,22 @@
             out.write(encodeBandInt("file_options", file_options,
                     Codec.UNSIGNED5));
         }
-        out.write(encodeBandInt("file_bits", file_bits, Codec.BYTE1));
+        out.write(encodeBandInt("file_bits", flatten(file_bits), Codec.BYTE1));
+    }
 
+    private int[] flatten(byte[][] bytes) {
+        int total = 0;
+        for (int i = 0; i < bytes.length; i++) {
+            total += bytes[i].length;
+        }
+        int[] band = new int[total];
+        int index = 0;
+        for (int i = 0; i < bytes.length; i++) {
+            for (int j = 0; j < bytes[i].length; j++) {
+                band[index++] = bytes[i][j];
+            }
+        }
+        return band;
     }
 
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java?rev=706922&r1=706921&r2=706922&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java Wed Oct 22 02:39:19 2008
@@ -47,11 +47,10 @@
     private final SegmentAnnotationVisitor annotationVisitor = new SegmentAnnotationVisitor();
     private Pack200ClassReader currentClassReader;
 
-    public void pack(List classes, List classNames, List classModTimes,
-            List files, OutputStream out) throws IOException, Pack200Exception {
+    public void pack(List classes, List files, OutputStream out)
+            throws IOException, Pack200Exception {
         segmentHeader = new SegmentHeader();
-        segmentHeader.setFile_count(classes.size() + files.size()); // TODO:
-                                                                    // files
+        segmentHeader.setFile_count(files.size());
         cpBands = new CpBands(segmentHeader);
         attributeDefinitionBands = new AttributeDefinitionBands(segmentHeader,
                 cpBands);
@@ -59,8 +58,7 @@
         classBands = new ClassBands(segmentHeader, cpBands,
                 attributeDefinitionBands, classes.size());
         bcBands = new BcBands(cpBands, this);
-        fileBands = new FileBands(cpBands, segmentHeader, classNames,
-                classModTimes, files);
+        fileBands = new FileBands(cpBands, segmentHeader, files);
 
         processClasses(classes);