harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ton...@apache.org
Subject svn commit: r633384 [13/15] - in /harmony/enhanced/classlib/branches/java6: depends/build/platform/ depends/files/ depends/files/bcprov/ doc/ doc/classlib/ make/ make/linux.ia64/ make/linux.ppc32/ make/linux.ppc64/ make/linux.x86.libstdc++6/ make/linux...
Date Tue, 04 Mar 2008 08:02:45 GMT
Modified: harmony/enhanced/classlib/branches/java6/modules/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java Tue Mar  4 00:02:13 2008
@@ -65,7 +65,7 @@
  * The two errors can be handled in three ways, the default one is to report the
  * error to the invoker by a {@link CoderResult CoderResult} instance, and the
  * alternatives are to ignore it or to replace the erroneous input with the
- * replacement string. The replacement string is "\uFFFD" by default and can be
+ * replacement string. The replacement string is "\uFFFD" by default and can be
  * changed by invoking {@link #replaceWith(String) replaceWith} method. The
  * invoker of this decoder can choose one way by specifying a
  * {@link CodingErrorAction CodingErrorAction} instance for each error type via
@@ -138,7 +138,7 @@
      * Construct a new <code>CharsetDecoder</code> using given
      * <code>Charset</code>, average number and maximum number of characters
      * created by this decoder for one input byte, and the default replacement
-     * string "\uFFFD".
+     * string "&#92;uFFFD".
      * 
      * @param charset
      *            this decoder's <code>Charset</code>, which create this

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java Tue Mar  4 00:02:13 2008
@@ -17,12 +17,15 @@
 package org.apache.harmony.pack200;
 
 import java.io.BufferedInputStream;
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
 import java.util.jar.JarOutputStream;
 import java.util.zip.GZIPInputStream;
 
@@ -54,18 +57,41 @@
 
     private boolean deflateHint;
 
+    private String inputFileName;
+
+    /**
+     * Creates an Archive with the given input and output file names.
+     * @param inputFile
+     * @param outputFile
+     * @throws FileNotFoundException if the input file does not exist
+     * @throws IOException
+     */
     public Archive(String inputFile, String outputFile)
             throws FileNotFoundException, IOException {
+        this.inputFileName = inputFile;
         inputStream = new FileInputStream(inputFile);
         outputStream = new JarOutputStream(new FileOutputStream(outputFile));
     }
 
+    /**
+     * Creates an Archive with streams for the input and output files.
+     * Note: If you use this method then calling {@link #setRemovePackFile(boolean)}
+     * will have no effect.
+     * @param inputStream
+     * @param outputStream
+     * @throws IOException
+     */
     public Archive(InputStream inputStream, JarOutputStream outputStream)
-            throws FileNotFoundException, IOException {
+            throws IOException {
         this.inputStream = inputStream;
         this.outputStream = outputStream;
     }
 
+    /**
+     * Unpacks the Archive from the input file to the output file
+     * @throws Pack200Exception
+     * @throws IOException
+     */
     public void unpack() throws Pack200Exception, IOException {
         outputStream.setComment("PACK200");
         try {
@@ -83,25 +109,33 @@
                 inputStream.reset();
             }
             inputStream.mark(4);
-            int[] jarMagic = { 0xCA, 0xFE, 0xBA, 0xBE }; // Magic word for a Jar file
-            byte word[] = new byte[4];
-            inputStream.read(word);
-            boolean compressedWithE0 = true;
-            for (int m = 0; m < jarMagic.length; m++) {
-                if (word[m] != jarMagic[m]) {
-                    compressedWithE0 = false;
+            int[] magic = { 0xCA, 0xFE, 0xD0, 0x0D }; // Magic word for pack200
+            int word[] = new int[4];
+            for (int i = 0; i < word.length; i++) {
+                word[i] = inputStream.read();
+            }
+            boolean compressedWithE0 = false;
+            for (int m = 0; m < magic.length; m++) {
+                if (word[m] != magic[m]) {
+                    compressedWithE0 = true;
                 }
             }
             inputStream.reset();
             if(compressedWithE0) { // The original Jar was not packed, so just copy it across
-                byte[] bytes = new byte[16384];
-                int bytesRead = 0;
-                while(bytesRead != -1) {
-                    bytesRead = inputStream.read(bytes);                    
-                    outputStream.write(bytes, 0, bytesRead);
+                JarInputStream jarInputStream = new JarInputStream(inputStream);
+                JarEntry jarEntry;
+                while((jarEntry = jarInputStream.getNextJarEntry()) != null) {
+                    outputStream.putNextEntry(jarEntry);
+                    byte[] bytes = new byte[16384];
+                    int bytesRead = jarInputStream.read(bytes);
+                    while(bytesRead != -1) {
+                        outputStream.write(bytes, 0, bytesRead);
+                        bytesRead = jarInputStream.read(bytes);
+                    }
+                    outputStream.closeEntry();
                 }
             } else {
-                while (inputStream.available() > 0) {
+                while (available(inputStream)) {
                     Segment segment = new Segment();
                     segment.setLogLevel(logLevel);
                     segment.setLogStream(logFile != null ? (OutputStream) logFile
@@ -110,20 +144,36 @@
                         segment.overrideDeflateHint(deflateHint);
                     }
                     segment.unpack(inputStream, outputStream);
+                    outputStream.flush();
                 }
             }
-        } catch (IOException e) {
+        } finally {
             try {
                 inputStream.close();
-            } finally {
+            } catch (Exception e2) {}
+            try {
                 outputStream.close();
-            }
+            } catch (Exception e2) {}
         }
         if (removePackFile) {
-
+            File file = new File(inputFileName);
+            file.delete();
         }
     }
 
+    private boolean available(InputStream inputStream) throws IOException {
+        inputStream.mark(1);
+        int check = inputStream.read();
+        inputStream.reset();
+        return check != -1;
+    }
+
+    /**
+     * If removePackFile is set to true, the input file is deleted after
+     * unpacking
+     *
+     * @param removePackFile
+     */
     public void setRemovePackFile(boolean removePackFile) {
         this.removePackFile = removePackFile;
     }
@@ -142,7 +192,6 @@
         } else if (logLevel == LOG_LEVEL_QUIET) {
             logLevel = LOG_LEVEL_QUIET;
         }
-        ;
     }
 
     public void setLogFile(String logFileName) throws FileNotFoundException {

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java Tue Mar  4 00:02:13 2008
@@ -68,17 +68,99 @@
      *             invalid
      */
     public int[] decodeBandInt(String name, InputStream in,
-            BHSDCodec defaultCodec, int count) throws IOException,
+            BHSDCodec codec, int count) throws IOException,
             Pack200Exception {
-        // TODO Might be able to improve this directly.
-        int[] result = new int[count];
-        long[] longResult = decodeBandLong(name, in, defaultCodec, count);
-        for (int i = 0; i < count; i++) {
-            result[i] = (int) longResult[i];
+        return decodeBandInt(name, in, codec, count, true);
+    }
+
+    /**
+     * Decode a band and return an array of <code>int</code> values
+     *
+     * @param name
+     *            the name of the band (primarily for logging/debugging
+     *            purposes)
+     * @param in
+     *            the InputStream to decode from
+     * @param defaultCodec
+     *            the default codec for this band
+     * @param count
+     *            the number of elements to read
+     * @return an array of decoded <code>int</code> values
+     * @throws IOException
+     *             if there is a problem reading from the underlying input
+     *             stream
+     * @throws Pack200Exception
+     *             if there is a problem decoding the value or that the value is
+     *             invalid
+     */
+    public int[] decodeBandInt(String name, InputStream in,
+            BHSDCodec codec, int count, boolean negativesAllowed) throws IOException,
+            Pack200Exception {
+        int[] band;
+        Codec codecUsed = codec;
+        if (codec.getB() == 1 || count == 0) {
+            return codec.decodeInts(count, in);
         }
-        return result;
+        int[] getFirst = codec.decodeInts(1, in);
+        if (getFirst.length == 0) {
+            return getFirst;
+        }
+        int first = getFirst[0];
+        if (codec.isSigned() && first >= -256 && first <= -1) {
+            // Non-default codec should be used
+            codecUsed = CodecEncoding.getCodec((-1 - first),
+                    header.getBandHeadersInputStream(), codec);
+            band = codecUsed.decodeInts(count, in);
+        } else if (!codec.isSigned() && first >= codec.getL()
+                && first <= codec.getL() + 255) {
+            // Non-default codec should be used
+            codecUsed = CodecEncoding.getCodec(first
+                    - codec.getL(), header.getBandHeadersInputStream(), codec);
+            band = codecUsed.decodeInts(count, in);
+        } else {
+            // First element should not be discarded
+            band = codec.decodeInts(count - 1, in, first);
+        }
+        if(!negativesAllowed && codec != codecUsed) {
+            if(codecUsed instanceof BHSDCodec && ((BHSDCodec)codecUsed).isSigned()) {
+                for (int i = 0; i < band.length; i++) {
+                    while(band[i] < 0) {
+                        band[i] += ((BHSDCodec)codecUsed).cardinality();
+                    }
+                }
+            }
+        }
+        return band;
+    }
+
+    /**
+     * Decode a band and return an array of <code>int[]</code> values
+     *
+     * @param name
+     *            the name of the band (primarily for logging/debugging
+     *            purposes)
+     * @param in
+     *            the InputStream to decode from
+     * @param defaultCodec
+     *            the default codec for this band
+     * @param counts
+     *            the numbers of elements to read for each int array within the
+     *            array to be returned
+     * @return an array of decoded <code>int[]</code> values
+     * @throws IOException
+     *             if there is a problem reading from the underlying input
+     *             stream
+     * @throws Pack200Exception
+     *             if there is a problem decoding the value or that the value is
+     *             invalid
+     */
+    public int[][] decodeBandInt(String name, InputStream in,
+            BHSDCodec defaultCodec, int[] counts)
+            throws IOException, Pack200Exception {
+        return decodeBandInt(name, in, defaultCodec, counts, true);
     }
 
+    // TODO: Use this version for all bands that shouldn't have negatives.
     /**
      * Decode a band and return an array of <code>int[]</code> values
      *
@@ -100,13 +182,15 @@
      *             if there is a problem decoding the value or that the value is
      *             invalid
      */
-    public int[][] decodeBandInt(String name, InputStream in, BHSDCodec defaultCodec, int[] counts) throws IOException, Pack200Exception {
+    public int[][] decodeBandInt(String name, InputStream in,
+            BHSDCodec defaultCodec, int[] counts, boolean negativesAllowed)
+            throws IOException, Pack200Exception {
         int[][] result = new int[counts.length][];
         int totalCount = 0;
         for (int i = 0; i < counts.length; i++) {
             totalCount += counts[i];
         }
-        int[] twoDResult = decodeBandInt(name, in, defaultCodec, totalCount);
+        int[] twoDResult = decodeBandInt(name, in, defaultCodec, totalCount, negativesAllowed);
         int index = 0;
         for (int i = 0; i < result.length; i++) {
             result[i] = new int[counts[i]];
@@ -325,37 +409,33 @@
     }
 
     private int[] decodeBandInt(String name, InputStream in, BHSDCodec codec, int count, int maxValue) throws IOException, Pack200Exception {
-        long[] band;
+        int[] band;
         Codec codecUsed = codec;
         if (codec.getB() == 1 || count == 0) {
-            band = codec.decode(count, in);
+            band = codec.decodeInts(count, in);
         } else {
-            long[] getFirst = codec.decode(1, in);
+            int[] getFirst = codec.decodeInts(1, in);
             if (getFirst.length == 0) {
                 return new int[0];
             }
-            long first = getFirst[0];
+            int first = getFirst[0];
             if (codec.isSigned() && first >= -256 && first <= -1) {
                 // Non-default codec should be used
-                codecUsed = CodecEncoding.getCodec((int) (-1 - first),
+                codecUsed = CodecEncoding.getCodec((-1 - first),
                         header.getBandHeadersInputStream(), codec);
-                band = codecUsed.decode(count, in);
+                band = codecUsed.decodeInts(count, in);
             } else if (!codec.isSigned() && first >= codec.getL()
                     && first <= codec.getL() + 255) {
                 // Non-default codec should be used
-                codecUsed = CodecEncoding.getCodec((int) first
+                codecUsed = CodecEncoding.getCodec(first
                         - codec.getL(), header.getBandHeadersInputStream(), codec);
-                band = codecUsed.decode(count, in);
+                band = codecUsed.decodeInts(count, in);
             } else {
                 // First element should not be discarded
-                band = codec.decode(count - 1, in, first);
+                band = codec.decodeInts(count - 1, in, first);
             }
         }
 
-        int[] returnBand = new int[band.length];
-        for (int i = 0; i < returnBand.length; i++) {
-            returnBand[i] = (int)band[i];
-        }
 
         /*
          * Note - this is not in the spec, but seems to be used as an
@@ -365,35 +445,34 @@
          * inside the range anyway.
          */
         if (codecUsed instanceof BHSDCodec) {
-            for (int i = 0; i < returnBand.length; i++) {
-                while (returnBand[i] < 0) {
-                    returnBand[i] += ((BHSDCodec) codecUsed).cardinality();
+            for (int i = 0; i < band.length; i++) {
+                while (band[i] < 0) {
+                    band[i] += ((BHSDCodec) codecUsed).cardinality();
                 }
-                while (returnBand[i] > maxValue) {
-                    returnBand[i] -= ((BHSDCodec) codecUsed).cardinality();
+                while (band[i] > maxValue) {
+                    band[i] -= ((BHSDCodec) codecUsed).cardinality();
                 }
             }
         } else if (codecUsed instanceof PopulationCodec) {
             PopulationCodec popCodec = (PopulationCodec)codecUsed;
             long[] favoured = (long[]) popCodec.getFavoured().clone();
             Arrays.sort(favoured);
-            for (int i = 0; i < returnBand.length; i++) {
-                if(returnBand[i] < 0 || returnBand[i] > maxValue) {
-                    boolean favouredValue = Arrays.binarySearch(favoured, returnBand[i]) > -1;
+            for (int i = 0; i < band.length; i++) {
+                if(band[i] < 0 || band[i] > maxValue) {
+                    boolean favouredValue = Arrays.binarySearch(favoured, band[i]) > -1;
                     Codec theCodec = favouredValue ? popCodec.getFavouredCodec(): popCodec.getUnvafouredCodec();
                     if(theCodec instanceof BHSDCodec) {
-                        while (returnBand[i] < 0) {
-                            returnBand[i] +=  ((BHSDCodec) theCodec).cardinality();
+                        while (band[i] < 0) {
+                            band[i] +=  ((BHSDCodec) theCodec).cardinality();
                         }
-                        while (returnBand[i] > maxValue) {
-                            returnBand[i] -= ((BHSDCodec) theCodec).cardinality();
+                        while (band[i] > maxValue) {
+                            band[i] -= ((BHSDCodec) theCodec).cardinality();
                         }
                     }
                 }
             }
         }
-
-        return returnBand;
+        return band;
     }
 
     /**
@@ -418,7 +497,7 @@
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
                         "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result[i1] = new CPInteger(new Integer(reference[index]));
+            result[i1] = segment.getCpBands().cpIntegerValue(new Integer(reference[index]));
         }
         return result;
     }
@@ -432,7 +511,7 @@
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
                         "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result[i1] = new CPDouble(new Double(reference[index]));
+            result[i1] = segment.getCpBands().cpDoubleValue(new Double(reference[index]));
         }
         return result;
     }
@@ -446,7 +525,7 @@
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
                         "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result[i1] = new CPFloat(new Float(reference[index]));
+            result[i1] = segment.getCpBands().cpFloatValue(new Float(reference[index]));
         }
         return result;
     }
@@ -460,7 +539,7 @@
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
                         "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result[i1] = new CPLong(new Long(reference[index]));
+            result[i1] = segment.getCpBands().cpLongValue(new Long(reference[index]));
         }
         return result;
     }
@@ -474,7 +553,7 @@
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
                         "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result[i1] = new CPUTF8(reference[index], ClassConstantPool.DOMAIN_UNDEFINED);
+            result[i1] = segment.getCpBands().cpUTF8Value(reference[index], ClassConstantPool.DOMAIN_NORMALASCIIZ);
         }
         return result;
     }
@@ -495,7 +574,7 @@
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
                         "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result1[i1] = new CPUTF8(reference[index], ClassConstantPool.DOMAIN_UNDEFINED);
+            result1[i1] = segment.getCpBands().cpUTF8Value(reference[index], ClassConstantPool.DOMAIN_NORMALASCIIZ);
         }
         CPUTF8[] refs = result1;
         int pos = 0;
@@ -517,58 +596,69 @@
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
                         "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result[i1] = new CPString(reference[index]);
+            result[i1] = segment.getCpBands().cpStringValue(reference[index]);
         }
         return result;
     }
 
     public CPInterfaceMethodRef[] parseCPInterfaceMethodRefReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
-        String[] reference = segment.getCpBands().getCpIMethodClass();
-        String[] descriptors = segment.getCpBands().getCpIMethodDescriptor();
+        CpBands cpBands = segment.getCpBands();
+        String[] reference = cpBands.getCpIMethodClass();
+        String[] descriptors = cpBands.getCpIMethodDescriptor();
         int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
         CPInterfaceMethodRef[] result = new CPInterfaceMethodRef[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
-                        "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result[i1] = new CPInterfaceMethodRef(reference[index], descriptors[index]);
+                        "Something has gone wrong during parsing references, index = "
+                                + index + ", array size = " + reference.length);
+            result[i1] = new CPInterfaceMethodRef(cpBands
+                    .cpClassValue(reference[index]), cpBands
+                    .cpNameAndTypeValue(descriptors[index]));
         }
         return result;
     }
 
     public CPMethodRef[] parseCPMethodRefReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
-        String[] reference = segment.getCpBands().getCpMethodClass();
-        String[] descriptors = segment.getCpBands().getCpMethodDescriptor();
+        CpBands cpBands = segment.getCpBands();
+        String[] reference = cpBands.getCpMethodClass();
+        String[] descriptors = cpBands.getCpMethodDescriptor();
         int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
         CPMethodRef[] result = new CPMethodRef[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
-                        "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result[i1] = new CPMethodRef(reference[index], descriptors[index]);
+                        "Something has gone wrong during parsing references, index = "
+                                + index + ", array size = " + reference.length);
+            result[i1] = new CPMethodRef(cpBands.cpClassValue(reference[index]),
+                    cpBands.cpNameAndTypeValue(descriptors[index]));
         }
         return result;
     }
 
     public CPFieldRef[] parseCPFieldRefReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
-        String[] reference = segment.getCpBands().getCpFieldClass();
-        String[] descriptors = segment.getCpBands().getCpFieldDescriptor();
+        CpBands cpBands = segment.getCpBands();
+        String[] reference = cpBands.getCpFieldClass();
+        String[] descriptors = cpBands.getCpFieldDescriptor();
         int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
         CPFieldRef[] result = new CPFieldRef[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
-                        "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result[i1] = new CPFieldRef(reference[index], descriptors[index]);
+                        "Something has gone wrong during parsing references, index = "
+                                + index + ", array size = " + reference.length);
+            result[i1] = new CPFieldRef(cpBands.cpClassValue(reference[index]),
+                    cpBands.cpNameAndTypeValue(descriptors[index]));
         }
         return result;
     }
 
     public CPNameAndType[] parseCPDescriptorReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
-        String[] reference = segment.getCpBands().getCpDescriptor();
+        CpBands cpBands = segment.getCpBands();
+        String[] reference = cpBands.getCpDescriptor();
         int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
         CPNameAndType[] result = new CPNameAndType[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
@@ -576,7 +666,7 @@
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
                         "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result[i1] = new CPNameAndType(reference[index]);
+            result[i1] = cpBands.cpNameAndTypeValue(reference[index]);
         }
         return result;
     }
@@ -590,7 +680,7 @@
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
                         "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result[i1] = new CPUTF8(reference[index], ClassConstantPool.DOMAIN_UNDEFINED);
+            result[i1] = segment.getCpBands().cpUTF8Value(reference[index], ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
         }
         return result;
     }
@@ -604,7 +694,7 @@
             if (index < 0 || index >= reference.length)
                 throw new Pack200Exception(
                         "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
-            result[i1] = new CPClass(reference[index]);
+            result[i1] = segment.getCpBands().cpClassValue(reference[index]);
         }
         return result;
     }

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java Tue Mar  4 00:02:13 2008
@@ -141,14 +141,6 @@
                    }
                    for (int i = 0; i < methodByteCodePacked[c][m].length; i++) {
                        int codePacked = 0xff & methodByteCodePacked[c][m][i];
-                       // TODO a lot of this needs to be encapsulated in the
-                       // place that
-                       // calculates what the arguments are, since (a) it will
-                       // need
-                       // to know where to get them, and (b) what to do with
-                       // them
-                       // once they've been gotten. But that's for another
-                       // time.
                        switch (codePacked) {
                        case 16: // bipush
                        case 188: // newarray
@@ -263,12 +255,12 @@
                             int nextInstruction = 0xff & methodByteCodePacked[c][m][i+1];
                             wideByteCodes.add(new Integer(nextInstruction));
                             if (nextInstruction == 132) { // iinc
-                                bcLocalCount += 2;
+                                bcLocalCount ++;
                                 bcShortCount++;
                             } else if (endsWithLoad(nextInstruction)
                                     || endsWithStore(nextInstruction)
                                     || nextInstruction == 169) {
-                                bcLocalCount += 2;
+                                bcLocalCount ++;
                             } else {
                                 debug("Found unhandled " + ByteCode.getByteCode(nextInstruction));
                             }
@@ -394,7 +386,7 @@
                     if(handlerCount != null) {
                         for (int j = 0; j < handlerCount[i]; j++) {
                             String handlerClass = handlerClassTypes[i][j];
-                            CPClass cpHandlerClass = new CPClass(handlerClass);
+                            CPClass cpHandlerClass = segment.getCpBands().cpClassValue(handlerClass);
                             ExceptionTableEntry entry = new ExceptionTableEntry(
                                     handlerStartPCs[i][j], handlerEndPCs[i][j],
                                     handlerCatchPCs[i][j], cpHandlerClass);
@@ -406,7 +398,6 @@
                             operandManager, exceptionTable);
                     methodAttributes[c][m].add(codeAttr);
                     codeAttr.renumber(codeAttr.byteCodeOffsets);
-                    // Should I add all the attributes in here?
                  ArrayList currentAttributes = (ArrayList)orderedCodeAttributes.get(i);
                  for(int index=0;index < currentAttributes.size(); index++) {
                      Attribute currentAttribute = (Attribute)currentAttributes.get(index);

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java Tue Mar  4 00:02:13 2008
@@ -24,9 +24,15 @@
 
 import org.apache.harmony.pack200.bytecode.Attribute;
 import org.apache.harmony.pack200.bytecode.CPClass;
+import org.apache.harmony.pack200.bytecode.CPDouble;
+import org.apache.harmony.pack200.bytecode.CPFloat;
+import org.apache.harmony.pack200.bytecode.CPInteger;
+import org.apache.harmony.pack200.bytecode.CPLong;
 import org.apache.harmony.pack200.bytecode.CPNameAndType;
+import org.apache.harmony.pack200.bytecode.CPString;
 import org.apache.harmony.pack200.bytecode.CPUTF8;
 import org.apache.harmony.pack200.bytecode.ClassConstantPool;
+import org.apache.harmony.pack200.bytecode.ClassFileEntry;
 import org.apache.harmony.pack200.bytecode.ConstantValueAttribute;
 import org.apache.harmony.pack200.bytecode.EnclosingMethodAttribute;
 import org.apache.harmony.pack200.bytecode.ExceptionsAttribute;
@@ -228,8 +234,8 @@
                         type = "I";
                     Object value = constantValueLayout.getValue(result, type,
                             cpBands.getConstantPool());
-                    fieldAttributes[i][j]
-                            .add(new ConstantValueAttribute(value));
+                    fieldAttributes[i][j].add(new ConstantValueAttribute(
+                            getClassFileEntry(value)));
                     constantValueIndex++;
                 }
                 if (signatureLayout.matches(flag)) {
@@ -238,7 +244,7 @@
                     String desc = fieldDescr[i][j];
                     int colon = desc.indexOf(':');
                     String type = desc.substring(colon + 1);
-                    CPUTF8 value = new CPUTF8((String) signatureLayout.getValue(result, type,
+                    CPUTF8 value = cpBands.cpUTF8Value((String) signatureLayout.getValue(result, type,
                             cpBands.getConstantPool()), ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
                     fieldAttributes[i][j]
                             .add(new SignatureAttribute(value));
@@ -256,6 +262,24 @@
         }
     }
 
+    private ClassFileEntry getClassFileEntry(Object value) {
+        ClassFileEntry entry = null;
+        if (value instanceof ClassFileEntry) {
+            entry = (ClassFileEntry)value;
+        } else if (value instanceof java.lang.Integer) {
+            entry = cpBands.cpIntegerValue((Integer) value);
+        } else if (value instanceof java.lang.Long) {
+            entry = cpBands.cpLongValue((Long) value);
+        } else if (value instanceof java.lang.Float) {
+            entry = cpBands.cpFloatValue((Float) value);
+        } else if (value instanceof java.lang.Double) {
+            entry = cpBands.cpDoubleValue((Double) value);
+        } else if (value instanceof java.lang.String) {
+            entry = cpBands.cpStringValue((String) value);
+        }
+        return entry;
+    }
+
     private void parseMethodBands(InputStream in) throws IOException,
             Pack200Exception {
         methodDescr = parseReferences("method_descr", in, Codec.MDELTA5,
@@ -344,7 +368,7 @@
                     String[] exceptions = methodExceptionsRS[methodExceptionsIndex];
                     CPClass[] exceptionClasses = new CPClass[n];
                     for (int k = 0; k < n; k++) {
-                        exceptionClasses[k] = new CPClass(exceptions[k]);
+                        exceptionClasses[k] = cpBands.cpClassValue(exceptions[k]);
                     }
                     methodAttributes[i][j].add(new ExceptionsAttribute(
                             exceptionClasses));
@@ -362,8 +386,8 @@
                         type = "I";
                     Object value = methodSignatureLayout.getValue(result, type, cpBands
                             .getConstantPool());
-                    methodAttributes[i][j]
-                            .add(new ConstantValueAttribute(value));
+                    methodAttributes[i][j].add(new ConstantValueAttribute(
+                            getClassFileEntry(value)));
                     methodSignatureIndex++;
                 }
                 // Non-predefined attributes
@@ -561,12 +585,12 @@
                     // Add .java to the end
                     value = className + ".java";
                 }
-                classAttributes[i].add(new SourceFileAttribute(value));
+                classAttributes[i].add(new SourceFileAttribute(cpBands.cpUTF8Value(value, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ)));
                 sourceFileIndex++;
             }
             if (enclosingMethodLayout.matches(flag)) {
-                CPClass theClass = new CPClass(enclosingMethodRC[enclosingMethodIndex]);
-                CPNameAndType theMethod = new CPNameAndType(enclosingMethodRDN[enclosingMethodIndex]);
+                CPClass theClass = cpBands.cpClassValue(enclosingMethodRC[enclosingMethodIndex]);
+                CPNameAndType theMethod = cpBands.cpNameAndTypeValue(enclosingMethodRDN[enclosingMethodIndex]);
                 classAttributes[i].add(new EnclosingMethodAttribute(theClass, theMethod));
                 enclosingMethodIndex++;
             }
@@ -574,7 +598,8 @@
                 long result = classSignature[signatureIndex];
                 Object value = signatureLayout.getValue(result, cpBands
                         .getConstantPool());
-                classAttributes[i].add(new ConstantValueAttribute(value));
+                classAttributes[i].add(new ConstantValueAttribute(
+                        getClassFileEntry(value)));
                 signatureIndex++;
             }
             if (innerClassLayout.matches(flag)) {
@@ -760,7 +785,7 @@
                 localVariableTableN);
         int[][] localVariableTableSpanO = decodeBandInt(
                 "code_LocalVariableTable_span_O", in, Codec.BRANCH5,
-                localVariableTableN);
+                localVariableTableN, false);
         CPUTF8[][] localVariableTableNameRU = stringsToCPUTF8(parseReferences(
                 "code_LocalVariableTable_name_RU", in, Codec.UNSIGNED5,
                 localVariableTableN, cpBands.getCpUTF8()));
@@ -887,7 +912,7 @@
         for (int i = 0; i < strings.length; i++) {
             cpUTF8s[i] = new CPUTF8[strings[i].length];
             for (int j = 0; j < strings[i].length; j++) {
-                cpUTF8s[i][j] = new CPUTF8(strings[i][j], ClassConstantPool.DOMAIN_NORMALASCIIZ);
+                cpUTF8s[i][j] = cpBands.cpUTF8Value(strings[i][j], ClassConstantPool.DOMAIN_NORMALASCIIZ);
             }
         }
         return cpUTF8s;
@@ -898,7 +923,7 @@
     private CPUTF8[] stringsToCPUTF8(String[] strings) {
         CPUTF8[] cpUTF8s = new CPUTF8[strings.length];
         for (int i = 0; i < strings.length; i++) {
-            cpUTF8s[i] = new CPUTF8(strings[i], ClassConstantPool.DOMAIN_UNDEFINED);
+            cpUTF8s[i] = cpBands.cpUTF8Value(strings[i], ClassConstantPool.DOMAIN_NORMALASCIIZ);
         }
         return cpUTF8s;
     }
@@ -950,7 +975,7 @@
             int[] backwardsCallCounts, String contextName) throws IOException, Pack200Exception {
         MetadataBandGroup[] mbg = new MetadataBandGroup[RxA.length];
         for (int i = 0; i < RxA.length; i++) {
-            mbg[i] = new MetadataBandGroup(RxA[i]);
+            mbg[i] = new MetadataBandGroup(RxA[i], cpBands);
             String rxa = RxA[i];
             if (rxa.indexOf("P") >= 0) {
                 mbg[i].param_NB = decodeBandInt(contextName + "_" + rxa

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java Tue Mar  4 00:02:13 2008
@@ -94,133 +94,162 @@
  * canonical number. {@link CodecEncoding#canonicalCodec})
  */
 public abstract class Codec {
-	/**
-	 * BCI5 = (5,4): Used for storing branching information in bytecode.
-	 */
-	public static final BHSDCodec BCI5 = new BHSDCodec(5, 4);
-
-	/**
-	 * BRANCH5 = (5,4,2): Used for storing branching information in bytecode.
-	 */
-	public static final BHSDCodec BRANCH5 = new BHSDCodec(5, 4, 2);
-
-	/**
-	 * BYTE1 = (1,256): Used for storing plain bytes.
-	 */
-	public static final BHSDCodec BYTE1 = new BHSDCodec(1, 256);
-
-	/**
-	 * CHAR3 = (3,128): Used for storing text (UTF-8) strings. NB This isn't
-	 * quite the same as UTF-8, but has similar properties; ASCII characters
-	 * &lt; 127 are stored in a single byte.
-	 */
-	public static final BHSDCodec CHAR3 = new BHSDCodec(3, 128);
-
-	/**
-	 * DELTA5 = (5,64,1,1): Used for the majority of numerical codings where
-	 * there is a correlated sequence of signed values.
-	 */
-	public static final BHSDCodec DELTA5 = new BHSDCodec(5, 64, 1, 1);
-
-	/**
-	 * MDELTA5 = (5,64,2,1): Used for the majority of numerical codings where
-	 * there is a correlated sequence of signed values, but where most of them
-	 * are expected to be non-negative.
-	 */
-	public static final BHSDCodec MDELTA5 = new BHSDCodec(5, 64, 2, 1);
-
-	/**
-	 * SIGNED5 = (5,64,1): Used for small signed values.
-	 */
-	public static final BHSDCodec SIGNED5 = new BHSDCodec(5, 64, 1);
-
-	/**
-	 * UDELTA5 = (5,64,0,1): Used for the majority of numerical codings where
-	 * there is a correlated sequence of unsigned values.
-	 */
-	public static final BHSDCodec UDELTA5 = new BHSDCodec(5, 64, 0, 1);
-
-	/**
-	 * UNSIGNED5 = (5,64): Used for small unsigned values.
-	 */
-	public static final BHSDCodec UNSIGNED5 = new BHSDCodec(5, 64);
-
-	/**
-	 * Decode a sequence of bytes from the given input stream, returning the
-	 * value as a long. Note that this method can only be applied for non-delta
-	 * encodings.
-	 *
-	 * @param in
-	 *            the input stream to read from
-	 * @return the value as a long
-	 * @throws IOException
-	 *             if there is a problem reading from the underlying input
-	 *             stream
-	 * @throws Pack200Exception
-	 *             if the encoding is a delta encoding
-	 */
-	public abstract long decode(InputStream in) throws IOException,
-			Pack200Exception;
-
-	/**
-	 * Decode a sequence of bytes from the given input stream, returning the
-	 * value as a long. If this encoding is a delta encoding (d=1) then the
-	 * previous value must be passed in as a parameter. If it is a non-delta
-	 * encoding, then it does not matter what value is passed in, so it makes
-	 * sense for the value to be passed in by default using code similar to:
-	 *
-	 * <pre>
-	 * long last = 0;
-	 * while (condition) {
-	 * 	last = codec.decode(in, last);
-	 * 	// do something with last
-	 * }
-	 * </pre>
-	 *
-	 * @param in
-	 *            the input stream to read from
-	 * @param last
-	 *            the previous value read, which must be supplied if the codec
-	 *            is a delta encoding
-	 * @return the value as a long
-	 * @throws IOException
-	 *             if there is a problem reading from the underlying input
-	 *             stream
-	 * @throws Pack200Exception
-	 *             if there is a problem decoding the value or that the value is
-	 *             invalid
-	 */
-	public abstract long decode(InputStream in, long last) throws IOException,
-			Pack200Exception;
-
-	/**
-	 * Decodes a sequence of <code>n</code> values from <code>in</code>.
-	 * This should probably be used in most cases, since some codecs
-	 * (such as @{link PopCodec}) only work when the number of values
-	 * to be read is known.
-	 *
-	 * @param n
-	 *            the number of values to decode
-	 * @param in
-	 *            the input stream to read from
-	 * @return an array of <code>long</code> values corresponding to values
-	 *         decoded
-	 * @throws IOException
-	 *             if there is a problem reading from the underlying input
-	 *             stream
-	 * @throws Pack200Exception
-	 *             if there is a problem decoding the value or that the value is
-	 *             invalid
-	 */
-	public long[] decode(int n, InputStream in) throws IOException,
-			Pack200Exception {
-		long result[] = new long[n];
-		long last = 0;
-		for(int i=0;i<n;i++) {
-			result[i] = last = decode(in,last);
-		}
-		return result;
-	}
+    /**
+     * BCI5 = (5,4): Used for storing branching information in bytecode.
+     */
+    public static final BHSDCodec BCI5 = new BHSDCodec(5, 4);
+
+    /**
+     * BRANCH5 = (5,4,2): Used for storing branching information in bytecode.
+     */
+    public static final BHSDCodec BRANCH5 = new BHSDCodec(5, 4, 2);
+
+    /**
+     * BYTE1 = (1,256): Used for storing plain bytes.
+     */
+    public static final BHSDCodec BYTE1 = new BHSDCodec(1, 256);
+
+    /**
+     * CHAR3 = (3,128): Used for storing text (UTF-8) strings. NB This isn't
+     * quite the same as UTF-8, but has similar properties; ASCII characters
+     * &lt; 127 are stored in a single byte.
+     */
+    public static final BHSDCodec CHAR3 = new BHSDCodec(3, 128);
+
+    /**
+     * DELTA5 = (5,64,1,1): Used for the majority of numerical codings where
+     * there is a correlated sequence of signed values.
+     */
+    public static final BHSDCodec DELTA5 = new BHSDCodec(5, 64, 1, 1);
+
+    /**
+     * MDELTA5 = (5,64,2,1): Used for the majority of numerical codings where
+     * there is a correlated sequence of signed values, but where most of them
+     * are expected to be non-negative.
+     */
+    public static final BHSDCodec MDELTA5 = new BHSDCodec(5, 64, 2, 1);
+
+    /**
+     * SIGNED5 = (5,64,1): Used for small signed values.
+     */
+    public static final BHSDCodec SIGNED5 = new BHSDCodec(5, 64, 1);
+
+    /**
+     * UDELTA5 = (5,64,0,1): Used for the majority of numerical codings where
+     * there is a correlated sequence of unsigned values.
+     */
+    public static final BHSDCodec UDELTA5 = new BHSDCodec(5, 64, 0, 1);
+
+    /**
+     * UNSIGNED5 = (5,64): Used for small unsigned values.
+     */
+    public static final BHSDCodec UNSIGNED5 = new BHSDCodec(5, 64);
+
+    /**
+     * Decode a sequence of bytes from the given input stream, returning the
+     * value as a long. Note that this method can only be applied for non-delta
+     * encodings.
+     *
+     * @param in
+     *            the input stream to read from
+     * @return the value as a long
+     * @throws IOException
+     *             if there is a problem reading from the underlying input
+     *             stream
+     * @throws Pack200Exception
+     *             if the encoding is a delta encoding
+     */
+    public abstract long decode(InputStream in) throws IOException,
+            Pack200Exception;
+
+    /**
+     * Decode a sequence of bytes from the given input stream, returning the
+     * value as a long. If this encoding is a delta encoding (d=1) then the
+     * previous value must be passed in as a parameter. If it is a non-delta
+     * encoding, then it does not matter what value is passed in, so it makes
+     * sense for the value to be passed in by default using code similar to:
+     *
+     * <pre>
+     * long last = 0;
+     * while (condition) {
+     *  last = codec.decode(in, last);
+     *  // do something with last
+     * }
+     * </pre>
+     *
+     * @param in
+     *            the input stream to read from
+     * @param last
+     *            the previous value read, which must be supplied if the codec
+     *            is a delta encoding
+     * @return the value as a long
+     * @throws IOException
+     *             if there is a problem reading from the underlying input
+     *             stream
+     * @throws Pack200Exception
+     *             if there is a problem decoding the value or that the value is
+     *             invalid
+     */
+    public abstract long decode(InputStream in, long last) throws IOException,
+            Pack200Exception;
+
+    /**
+     * Decodes a sequence of <code>n</code> values from <code>in</code>.
+     * This should probably be used in most cases, since some codecs
+     * (such as @{link PopCodec}) only work when the number of values
+     * to be read is known.
+     *
+     * @param n
+     *            the number of values to decode
+     * @param in
+     *            the input stream to read from
+     * @return an array of <code>long</code> values corresponding to values
+     *         decoded
+     * @throws IOException
+     *             if there is a problem reading from the underlying input
+     *             stream
+     * @throws Pack200Exception
+     *             if there is a problem decoding the value or that the value is
+     *             invalid
+     */
+    public long[] decode(int n, InputStream in) throws IOException,
+            Pack200Exception {
+        long result[] = new long[n];
+        long last = 0;
+        for(int i=0;i<n;i++) {
+            result[i] = last = decode(in,last);
+        }
+        return result;
+    }
+
+    /**
+     * Decodes a sequence of <code>n</code> values from <code>in</code>.
+     * This should probably be used in most cases, since some codecs
+     * (such as @{link PopCodec}) only work when the number of values
+     * to be read is known.
+     *
+     * @param n
+     *            the number of values to decode
+     * @param in
+     *            the input stream to read from
+     * @return an array of <code>int</code> values corresponding to values
+     *         decoded
+     * @throws IOException
+     *             if there is a problem reading from the underlying input
+     *             stream
+     * @throws Pack200Exception
+     *             if there is a problem decoding the value or that the value is
+     *             invalid
+     */
+    public int[] decodeInts(int n, InputStream in) throws IOException,
+            Pack200Exception {
+        int result[] = new int[n];
+        int last = 0;
+        for(int i=0;i<n;i++) {
+            result[i] = last = (int) decode(in,last);
+        }
+        return result;
+    }
 
     /**
      * Decodes a sequence of <code>n</code> values from <code>in</code>.
@@ -247,6 +276,35 @@
         long last = firstValue;
         for(int i=1;i<n+1;i++) {
             result[i] = last = decode(in,last);
+        }
+        return result;
+    }
+
+    /**
+     * Decodes a sequence of <code>n</code> values from <code>in</code>.
+     *
+     * @param n
+     *            the number of values to decode
+     * @param in
+     *            the input stream to read from
+     * @param firstValue
+     *            the first value in the band if it has already been read
+     * @return an array of <code>int</code> values corresponding to values
+     *         decoded, with firstValue as the first value in the array.
+     * @throws IOException
+     *             if there is a problem reading from the underlying input
+     *             stream
+     * @throws Pack200Exception
+     *             if there is a problem decoding the value or that the value is
+     *             invalid
+     */
+    public int[] decodeInts(int n, InputStream in, int firstValue) throws IOException,
+            Pack200Exception {
+        int result[] = new int[n + 1];
+        result[0] = firstValue;
+        int last = firstValue;
+        for(int i=1;i<n+1;i++) {
+            result[i] = last = (int) decode(in,last);
         }
         return result;
     }

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java Tue Mar  4 00:02:13 2008
@@ -19,6 +19,17 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.apache.harmony.pack200.bytecode.CPClass;
+import org.apache.harmony.pack200.bytecode.CPDouble;
+import org.apache.harmony.pack200.bytecode.CPFloat;
+import org.apache.harmony.pack200.bytecode.CPInteger;
+import org.apache.harmony.pack200.bytecode.CPLong;
+import org.apache.harmony.pack200.bytecode.CPNameAndType;
+import org.apache.harmony.pack200.bytecode.CPString;
+import org.apache.harmony.pack200.bytecode.CPUTF8;
+import org.apache.harmony.pack200.bytecode.ClassConstantPool;
 
 public class CpBands extends BandSet {
 
@@ -26,39 +37,33 @@
         return pool;
     }
 
-
     private final SegmentConstantPool pool = new SegmentConstantPool(this);
 
     private String[] cpClass;
-
     private String[] cpDescriptor;
-
     private double[] cpDouble;
-
     private String[] cpFieldClass;
-
     private String[] cpFieldDescriptor;
-
     private float[] cpFloat;
-
     private String[] cpIMethodClass;
-
     private String[] cpIMethodDescriptor;
-
     private int[] cpInt;
-
     private long[] cpLong;
-
     private String[] cpMethodClass;
-
     private String[] cpMethodDescriptor;
-
     private String[] cpSignature;
-
     private String[] cpString;
-
     private String[] cpUTF8;
 
+    private HashMap[] stringsToCPUTF8 = new HashMap[ClassConstantPool.NUM_DOMAINS];
+    private HashMap stringsToCPStrings = new HashMap();
+    private HashMap longsToCPLongs = new HashMap();
+    private HashMap integersToCPIntegers = new HashMap();
+    private HashMap floatsToCPFloats = new HashMap();
+    private HashMap stringsToCPClass = new HashMap();
+    private HashMap doublesToCPDoubles = new HashMap();
+    private HashMap descriptorsToCPNameAndTypes = new HashMap();
+
 
     public CpBands(Segment segment) {
         super(segment);
@@ -419,4 +424,107 @@
         return cpUTF8;
     }
 
-}
+    public CPUTF8 cpUTF8Value(String string, int domain) {
+        if(stringsToCPUTF8[domain] == null) {
+            stringsToCPUTF8[domain] = new HashMap();
+        }
+        CPUTF8 cputf8 = (CPUTF8) stringsToCPUTF8[domain].get(string);
+        if(cputf8 == null) {
+            cputf8 = new CPUTF8(string, domain);
+            stringsToCPUTF8[domain].put(string, cputf8);
+        }
+        return cputf8;
+    }
+
+    public CPString cpStringValue(String string) {
+        CPString cpString = (CPString) stringsToCPStrings.get(string);
+        if(cpString == null) {
+            cpString = new CPString(cpUTF8Value(string, ClassConstantPool.DOMAIN_NORMALASCIIZ));
+            stringsToCPStrings.put(string, cpString);
+        }
+        return cpString;
+    }
+
+    public CPLong cpLongValue(Long l) {
+        CPLong cpLong = (CPLong) longsToCPLongs.get(l);
+        if(cpLong == null) {
+            cpLong = new CPLong(l);
+            longsToCPLongs.put(l, cpLong);
+        }
+        return cpLong;
+    }
+
+    public CPInteger cpIntegerValue(Integer i) {
+        CPInteger cpInteger = (CPInteger) integersToCPIntegers.get(i);
+        if(cpInteger == null) {
+            cpInteger = new CPInteger(i);
+            integersToCPIntegers.put(i, cpInteger);
+        }
+        return cpInteger;
+    }
+
+    public CPFloat cpFloatValue(Float f) {
+        CPFloat cpFloat = (CPFloat) floatsToCPFloats.get(f);
+        if(cpFloat == null) {
+            cpFloat = new CPFloat(f);
+            floatsToCPFloats.put(f, cpFloat);
+        }
+        return cpFloat;
+    }
+
+    public CPClass cpClassValue(String string) {
+        CPClass cpString = (CPClass) stringsToCPClass.get(string);
+        if(cpString == null) {
+            cpString = new CPClass(cpUTF8Value(string, ClassConstantPool.DOMAIN_NORMALASCIIZ));
+            stringsToCPClass.put(string, cpString);
+        }
+        return cpString;
+    }
+
+    public CPDouble cpDoubleValue(Double dbl) {
+        CPDouble cpDouble = (CPDouble) doublesToCPDoubles.get(dbl);
+        if(cpDouble == null) {
+            cpDouble = new CPDouble(dbl);
+            doublesToCPDoubles.put(dbl, cpDouble);
+        }
+        return cpDouble;
+    }
+
+    public CPNameAndType cpNameAndTypeValue(String descriptor) {
+        CPNameAndType cpNameAndType = (CPNameAndType) descriptorsToCPNameAndTypes.get(descriptor);
+        if(cpNameAndType == null) {
+            int descriptorDomain = ClassConstantPool.DOMAIN_UNDEFINED;
+            int colon = descriptor.indexOf(':');
+            String nameString = descriptor.substring(0,colon);
+            String descriptorString = descriptor.substring(colon+1);
+            // For some reason, descriptors which have just plain
+            // native types are stored in DOMAIN_NORMALASCIIZ rather
+            // than in DOMAIN_SIGNATUREASCIIZ. This might indicate
+            // that DOMAIN_SIGNATUREASCIIZ is poorly named.
+            boolean nativeDescriptor = true;
+            for(int index=0; index < descriptorString.length(); index++) {
+                char currentChar = descriptorString.charAt(index);
+                if(Character.isLetter(currentChar)) {
+                    if(currentChar == 'L') {
+                        nativeDescriptor = false;
+                    }
+                    break;
+                }
+            }
+            int domain = ClassConstantPool.DOMAIN_NAMEANDTYPE;
+            CPUTF8 name = cpUTF8Value(nameString, ClassConstantPool.DOMAIN_NORMALASCIIZ);
+            if( nativeDescriptor ) {
+                // Native signatures are stored in DOMAIN_NORMALASCIIZ, not
+                // DOMAIN_SIGNATUREASCIIZ for some reason.
+                descriptorDomain = ClassConstantPool.DOMAIN_NORMALASCIIZ;
+            } else {
+                descriptorDomain = ClassConstantPool.DOMAIN_SIGNATUREASCIIZ;
+            }
+            CPUTF8 descriptorU = cpUTF8Value(descriptorString, descriptorDomain);
+            cpNameAndType = new CPNameAndType(name, descriptorU, domain);
+            descriptorsToCPNameAndTypes.put(descriptor, cpNameAndType);
+        }
+        return cpNameAndType;
+    }
+
+}
\ No newline at end of file

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java Tue Mar  4 00:02:13 2008
@@ -29,8 +29,6 @@
  * Pack200 Inner Class Bands
  */
 public class IcBands extends BandSet {
-
-
     private IcTuple[] icAll;
 
     private String[] cpUTF8;
@@ -92,14 +90,12 @@
         List relevantTuples = new ArrayList();
         IcTuple[] allTuples = getIcTuples();
         int allTuplesSize = allTuples.length;
-        SegmentUtils.debug("-------\nRelevant() " + className);
         for(int index=0; index < allTuplesSize; index++) {
             if(allTuples[index].outerClassString().equals(className)) {
                 relevantTuples.add(allTuples[index]);
             }
         }
 
-        SegmentUtils.debug("self halt");
         List classPoolClasses = cp.allClasses();
         boolean changed = true;
         // For every class in both ic_this_class and cp,
@@ -109,26 +105,12 @@
             changed = false;
             for(int allTupleIndex=0; allTupleIndex < allTuplesSize; allTupleIndex++) {
                 Iterator it = classPoolClasses.iterator();
-                SegmentUtils.debug("\n\n----\nLooking through class pool for: " + allTuples[allTupleIndex].thisClassString());
                 while(it.hasNext()) {
                     CPClass classInPool = (CPClass)it.next();
                     String poolClassName = classInPool.name;
-                    SegmentUtils.debug("    " + poolClassName);
                     if(poolClassName.equals(allTuples[allTupleIndex].thisClassString())) {
                         // If the tuple isn't already in there, then add it
-                        SegmentUtils.debug("     -> match");
                         if(relevantTuples.indexOf(allTuples[allTupleIndex]) == -1) {
-                            SegmentUtils.debug("        -> added");
-                            relevantTuples.add(allTuples[allTupleIndex]);
-                            changed = true;
-                        }
-                    }
-                    // TODO: is this right?
-                    if(poolClassName.equals(allTuples[allTupleIndex].outerClassString())) {
-                        // If the tuple isn't already in there, then add it
-                        SegmentUtils.debug("     -> omatch");
-                        if(relevantTuples.indexOf(allTuples[allTupleIndex]) == -1) {
-                            SegmentUtils.debug("        -> oadded");
                             relevantTuples.add(allTuples[allTupleIndex]);
                             changed = true;
                         }
@@ -137,12 +119,21 @@
             }
         }
 
-        IcTuple[] result = new IcTuple[relevantTuples.size()];
-        for(int index=0; index < result.length; index++) {
-            result[index] = (IcTuple)relevantTuples.get(index);
-            SegmentUtils.debug("Returning relevantTuple: " + result[index].thisClassString());
+        // Now order the result as a subsequence of ic_all
+        IcTuple[] orderedRelevantTuples = new IcTuple[relevantTuples.size()];
+        int orderedRelevantIndex = 0;
+        for(int index=0; index < allTuplesSize; index++) {
+            if(relevantTuples.contains(allTuples[index])) {
+                orderedRelevantTuples[orderedRelevantIndex] = allTuples[index];
+                orderedRelevantIndex++;
+            }
+        }
+        if(orderedRelevantIndex != orderedRelevantTuples.length) {
+            // This should never happen. If it does, we have a
+            // logic error in the ordering code.
+            throw new Error("Missing a tuple when ordering them");
         }
-        return result;
+        return orderedRelevantTuples;
     }
 
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcTuple.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcTuple.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcTuple.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcTuple.java Tue Mar  4 00:02:13 2008
@@ -102,7 +102,8 @@
         if(predicted()) {
             return C;
         } else {
-            // TODO: this may not be right.
+            // TODO: this may not be right. What if I 
+            // get a class like Foo#Bar$Baz$Bug?
             return C2 + "$" + N;
         }
     }
@@ -146,26 +147,15 @@
                 member = false;
             }
             if(index + 1 != lastPosition) {
+                // TODO: might need more logic to handle
+                // classes with separators of non-$ characters
+                // (ie Foo#Bar)
                 cachedOuterClassString += '$';
             }
         }
-        // Now special-case: if the last part of the outer
-        // class name is all digits, then the cachedOuterClassString
-        // is null (an anonymous outer class). If the cachedInnerClassString
-        // is all digits, then the cachedInnerClassString is null (an
-        // anonymous inner class).
-        // TODO: Don't know about this - we might need to
-        // do this later on (after we've determined what's
-        // anonymous and what isn't) so we point to the right
-        // class file entries.
-//        if(isAllDigits(nameComponents[lastPosition - 1])) {
-//            cachedOuterClassString = null;
-//            anonymous = false;
-//        }
         if(isAllDigits(cachedSimpleClassName)) {
             anonymous = true;
             member = false;
-//            cachedSimpleClassName = C;
         }
     }
 

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java Tue Mar  4 00:02:13 2008
@@ -29,6 +29,7 @@
 import org.apache.harmony.pack200.bytecode.CPLong;
 import org.apache.harmony.pack200.bytecode.CPNameAndType;
 import org.apache.harmony.pack200.bytecode.CPUTF8;
+import org.apache.harmony.pack200.bytecode.ClassConstantPool;
 import org.apache.harmony.pack200.bytecode.RuntimeVisibleorInvisibleAnnotationsAttribute;
 import org.apache.harmony.pack200.bytecode.RuntimeVisibleorInvisibleParameterAnnotationsAttribute;
 import org.apache.harmony.pack200.bytecode.AnnotationsAttribute.Annotation;
@@ -41,9 +42,11 @@
 public class MetadataBandGroup {
 
     private String type;
+    private CpBands cpBands;
 
-    public MetadataBandGroup(String type) {
+    public MetadataBandGroup(String type, CpBands cpBands) {
         this.type = type;
+        this.cpBands = cpBands;
     }
 
     private List attributes;
@@ -148,9 +151,10 @@
             annotations[i] = getAnnotation(types[i], pairCounts[i], namesIterator);
         }
         return new RuntimeVisibleorInvisibleAnnotationsAttribute(type
-                .equals("RVA") ? "RuntimeVisibleAnnotations"
-                : "RuntimeInvisibleAnnotations",
-                annotations);
+                .equals("RVA") ? cpBands.cpUTF8Value("RuntimeVisibleAnnotations",
+                ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ) : cpBands.cpUTF8Value(
+                "RuntimeInvisibleAnnotations",
+                ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ), annotations);
     }
 
     private Attribute getParameterAttribute(int numParameters, Iterator namesIterator ) {
@@ -165,8 +169,11 @@
             parameter_annotations[i] = new ParameterAnnotation(annotations);
         }
         return new RuntimeVisibleorInvisibleParameterAnnotationsAttribute(type
-                .equals("RVA") ? "RuntimeVisibleParameterAnnotations"
-                : "RuntimeInvisibleParameterAnnotations",
+                .equals("RVA") ? cpBands.cpUTF8Value(
+                "RuntimeVisibleParameterAnnotations",
+                ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ) : cpBands.cpUTF8Value(
+                "RuntimeInvisibleParameterAnnotations",
+                ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ),
                 parameter_annotations);
     }
 
@@ -201,7 +208,7 @@
             case 'e':
                 // TODO: check this - it may not work if the first string already has a colon in it
                 String enumString = caseet_Iterator.next() + ":" + caseec_Iterator.next();
-                return new CPNameAndType(enumString);
+                return cpBands.cpNameAndTypeValue(enumString);
             case 's':
                 return cases_Iterator.next();
             case '[':

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/NewAttributeBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/NewAttributeBands.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/NewAttributeBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/NewAttributeBands.java Tue Mar  4 00:02:13 2008
@@ -35,6 +35,7 @@
 import org.apache.harmony.pack200.bytecode.CPNameAndType;
 import org.apache.harmony.pack200.bytecode.CPString;
 import org.apache.harmony.pack200.bytecode.CPUTF8;
+import org.apache.harmony.pack200.bytecode.ClassConstantPool;
 import org.apache.harmony.pack200.bytecode.NewAttribute;
 
 /**
@@ -102,7 +103,9 @@
      * @return
      */
     private Attribute getOneAttribute(int index, List elements) {
-        NewAttribute attribute = new NewAttribute(attributeLayout.getName());
+        NewAttribute attribute = new NewAttribute(segment.getCpBands()
+                .cpUTF8Value(attributeLayout.getName(),
+                        ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ));
         for (Iterator iter = elements.iterator(); iter.hasNext();) {
             AttributeLayoutElement element = (AttributeLayoutElement) iter.next();
             element.addToAttribute(index, attribute);

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java Tue Mar  4 00:02:13 2008
@@ -20,77 +20,77 @@
 import java.io.InputStream;
 
 public class PopulationCodec extends Codec {
-	private Codec favouredCodec;
-	private Codec tokenCodec;
-	private Codec unvafouredCodec;
-	private int l;
+    private final Codec favouredCodec;
+    private Codec tokenCodec;
+    private final Codec unvafouredCodec;
+    private int l;
     private long[] favoured;
 
-	public PopulationCodec(Codec favouredCodec, Codec tableCodec, Codec unvafouredCodec) {
-		this.favouredCodec = favouredCodec;
-		this.tokenCodec = tableCodec;
-		this.unvafouredCodec = unvafouredCodec;
-	}
-
-	public PopulationCodec(Codec favouredCodec, int l, Codec unvafouredCodec) {
-		if (l >= 256 || l <=0)
-			throw new IllegalArgumentException("L must be between 1..255");
-		this.favouredCodec = favouredCodec;
-		this.l = l;
-		this.unvafouredCodec = unvafouredCodec;
-	}
-
-
-	public long decode(InputStream in) throws IOException, Pack200Exception {
-		throw new Pack200Exception("Population encoding does not work unless the number of elements are known");
-	}
-
-
-	public long decode(InputStream in, long last) throws IOException,
-			Pack200Exception {
-		throw new Pack200Exception("Population encoding does not work unless the number of elements are known");
-	}
-
-
-	public long[] decode(int n, InputStream in) throws IOException, Pack200Exception {
-		favoured = new long[n]; // there must be <= n  values, but probably a lot less
-		long result[];
-		// read table of favorites first
-		long smallest = Long.MAX_VALUE;
-		long last = 0;
-		long value = 0; // TODO Are these sensible starting points?
-		int k = -1;
-		while( true ) {
-			last = value;
-			value = favouredCodec.decode(in,last);
-			if ( value == smallest || value == last)
-				break;
-			favoured[++k] = value;
-			if (Math.abs(smallest) > Math.abs(value)) {
-				smallest = value;
-			} else if (Math.abs(smallest) == Math.abs(value) ) {
-				// ensure that -X and +X -> +X
-				smallest = Math.abs(smallest);
-			}
-		}
-		// if tokenCodec needs to be derived from the T, L and K values
-		if (tokenCodec == null) {
-			if (k < 256) {
-				tokenCodec = Codec.BYTE1;
-			} else {
-				// if k >= 256, b >= 2
-				int b = 1;
-				while(++b < 5 && tokenCodec == null) {
-					BHSDCodec codec = new BHSDCodec(b,256-l,0);
-					if (codec.encodes(k))
-						tokenCodec = codec;
-				}
-				if (tokenCodec == null)
-					throw new Pack200Exception("Cannot calculate token codec from " + k + " and " + l);
-			}
-		}
-		// read favorites
-		result = tokenCodec.decode(n, in);
+    public PopulationCodec(Codec favouredCodec, Codec tableCodec, Codec unvafouredCodec) {
+        this.favouredCodec = favouredCodec;
+        this.tokenCodec = tableCodec;
+        this.unvafouredCodec = unvafouredCodec;
+    }
+
+    public PopulationCodec(Codec favouredCodec, int l, Codec unvafouredCodec) {
+        if (l >= 256 || l <=0)
+            throw new IllegalArgumentException("L must be between 1..255");
+        this.favouredCodec = favouredCodec;
+        this.l = l;
+        this.unvafouredCodec = unvafouredCodec;
+    }
+
+
+    public long decode(InputStream in) throws IOException, Pack200Exception {
+        throw new Pack200Exception("Population encoding does not work unless the number of elements are known");
+    }
+
+
+    public long decode(InputStream in, long last) throws IOException,
+            Pack200Exception {
+        throw new Pack200Exception("Population encoding does not work unless the number of elements are known");
+    }
+
+
+    public long[] decode(int n, InputStream in) throws IOException, Pack200Exception {
+        favoured = new long[n]; // there must be <= n  values, but probably a lot less
+        long result[];
+        // read table of favorites first
+        long smallest = Long.MAX_VALUE;
+        long last = 0;
+        long value = 0; // TODO Are these sensible starting points?
+        int k = -1;
+        while( true ) {
+            last = value;
+            value = favouredCodec.decode(in,last);
+            if ( value == smallest || value == last)
+                break;
+            favoured[++k] = value;
+            if (Math.abs(smallest) > Math.abs(value)) {
+                smallest = value;
+            } else if (Math.abs(smallest) == Math.abs(value) ) {
+                // ensure that -X and +X -> +X
+                smallest = Math.abs(smallest);
+            }
+        }
+        // if tokenCodec needs to be derived from the T, L and K values
+        if (tokenCodec == null) {
+            if (k < 256) {
+                tokenCodec = Codec.BYTE1;
+            } else {
+                // if k >= 256, b >= 2
+                int b = 1;
+                while(++b < 5 && tokenCodec == null) {
+                    BHSDCodec codec = new BHSDCodec(b,256-l,0);
+                    if (codec.encodes(k))
+                        tokenCodec = codec;
+                }
+                if (tokenCodec == null)
+                    throw new Pack200Exception("Cannot calculate token codec from " + k + " and " + l);
+            }
+        }
+        // read favorites
+        result = tokenCodec.decode(n, in);
         // read unfavorites
         last = 0;
         for(int i = 0; i < n; i++) {
@@ -101,7 +101,17 @@
                 result[i] = favoured[index-1];
             }
         }
-		return result;
+        return result;
+    }
+
+
+    public int[] decodeInts(int n, InputStream in) throws IOException, Pack200Exception {
+        long[] result = decode(n, in);
+        int[] intRes = new int[result.length];
+        for (int i = 0; i < intRes.length; i++) {
+            intRes[i] = (int)result[i];
+        }
+        return intRes;
     }
 
     public long[] getFavoured() {

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java Tue Mar  4 00:02:13 2008
@@ -21,6 +21,9 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
 import java.util.jar.JarEntry;
 import java.util.jar.JarOutputStream;
 import java.util.zip.GZIPInputStream;
@@ -128,68 +131,98 @@
 				.getAttributeLayout(AttributeLayout.ATTRIBUTE_SOURCE_FILE,
 						AttributeLayout.CONTEXT_CLASS);
 		if (SOURCE_FILE.matches(classBands.getClassFlags()[classNum])) {
-			String fileName = fullName.substring(i) + ".java";
+		    int firstDollar = SegmentUtils.indexOfFirstDollar(fullName);
+		    String fileName = null;
+
+		    if(firstDollar > -1 && (i <= firstDollar)) {
+		        fileName = fullName.substring(i, firstDollar) + ".java";
+		    } else {
+		        fileName = fullName.substring(i) + ".java";
+		    }
 			classFile.attributes = new Attribute[] { (Attribute) cp
-					.add(new SourceFileAttribute(fileName)) };
+					.add(new SourceFileAttribute(cpBands.cpUTF8Value(fileName, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ))) };
 		} else {
 			classFile.attributes = new Attribute[] {};
 		}
 		// this/superclass
-		ClassFileEntry cfThis = cp.add(new CPClass(fullName));
-		ClassFileEntry cfSuper = cp.add(new CPClass(classBands.getClassSuper()[classNum]));
+		ClassFileEntry cfThis = cp.add(cpBands.cpClassValue(fullName));
+		ClassFileEntry cfSuper = cp.add(cpBands.cpClassValue(classBands.getClassSuper()[classNum]));
 		// add interfaces
 		ClassFileEntry cfInterfaces[] = new ClassFileEntry[classBands.getClassInterfaces()[classNum].length];
 		for (i = 0; i < cfInterfaces.length; i++) {
-			cfInterfaces[i] = cp.add(new CPClass(classBands.getClassInterfaces()[classNum][i]));
+			cfInterfaces[i] = cp.add(cpBands.cpClassValue(classBands.getClassInterfaces()[classNum][i]));
 		}
 		// add fields
 		ClassFileEntry cfFields[] = new ClassFileEntry[classBands.getClassFieldCount()[classNum]];
 		// fieldDescr and fieldFlags used to create this
 		for (i = 0; i < cfFields.length; i++) {
-			cfFields[i] = cp.add(new CPField(classBands.getFieldDescr()[classNum][i],
+            String descriptorStr = classBands.getFieldDescr()[classNum][i];
+            int colon = descriptorStr.indexOf(':');
+            CPUTF8 name = cpBands.cpUTF8Value(descriptorStr.substring(0,colon), ClassConstantPool.DOMAIN_NORMALASCIIZ);
+            CPUTF8 descriptor = cpBands.cpUTF8Value(descriptorStr.substring(colon+1), ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
+            cfFields[i] = cp.add(new CPField(name, descriptor,
                     classBands.getFieldFlags()[classNum][i], classBands.getFieldAttributes()[classNum][i]));
 		}
 		// add methods
 		ClassFileEntry cfMethods[] = new ClassFileEntry[classBands.getClassMethodCount()[classNum]];
 		// fieldDescr and fieldFlags used to create this
 		for (i = 0; i < cfMethods.length; i++) {
-			cfMethods[i] = cp.add(new CPMethod(classBands.getMethodDescr()[classNum][i],
-                    classBands.getMethodFlags()[classNum][i], classBands.getMethodAttributes()[classNum][i]));
+            String descriptorStr = classBands.getMethodDescr()[classNum][i];
+            int colon = descriptorStr.indexOf(':');
+            CPUTF8 name = cpBands.cpUTF8Value(descriptorStr.substring(0,colon), ClassConstantPool.DOMAIN_NORMALASCIIZ);
+            CPUTF8 descriptor = cpBands.cpUTF8Value(descriptorStr.substring(colon+1), ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
+			cfMethods[i] = cp.add(new CPMethod(name, descriptor, classBands
+                    .getMethodFlags()[classNum][i], classBands
+                    .getMethodAttributes()[classNum][i]));
+		}
+
+		// add inner class attribute (if required)
+		boolean addInnerClassesAttr = false;
+		IcTuple[] ic_local = getClassBands().getIcLocal()[classNum];
+		boolean ic_local_sent = false;
+		if(ic_local != null) {
+		    ic_local_sent = true;
 		}
-		// TODO: maybe this is a better place to add ic_relevant?
-		// This seems like the right thing to do.
-		boolean addedClasses = false;
 		InnerClassesAttribute innerClassesAttribute = new InnerClassesAttribute("InnerClasses");
 		IcTuple[] ic_relevant = getIcBands().getRelevantIcTuples(fullName, cp);
-
-		for(int index = 0; index < ic_relevant.length; index++) {
-		    String innerClassString = ic_relevant[index].thisClassString();
-		    String outerClassString = ic_relevant[index].outerClassString();
-		    String simpleClassName = ic_relevant[index].simpleClassName();
+		IcTuple[] ic_stored = computeIcStored(ic_local, ic_relevant);
+		for(int index = 0; index < ic_stored.length; index++) {
+		    String innerClassString = ic_stored[index].thisClassString();
+		    String outerClassString = ic_stored[index].outerClassString();
+		    String simpleClassName = ic_stored[index].simpleClassName();
 
 		    CPClass innerClass = null;
 		    CPUTF8 innerName = null;
 		    CPClass outerClass = null;
 
-		    if(ic_relevant[index].isAnonymous()) {
-		        innerClass = new CPClass(innerClassString);
+		    if(ic_stored[index].isAnonymous()) {
+		        innerClass = cpBands.cpClassValue(innerClassString);
 		    } else {
-	            innerClass = new CPClass(innerClassString);
-	            innerName = new CPUTF8(simpleClassName, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ);
+	            innerClass = cpBands.cpClassValue(innerClassString);
+	            innerName = cpBands.cpUTF8Value(simpleClassName, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ);
 		    }
 
-		    // TODO: I think we need to worry about if the
-		    // OUTER class is a member or not - not the
-		    // ic_relevant itself.
-//		    if(ic_relevant[index].isMember()) {
-		        outerClass = new CPClass(outerClassString);
-//		    }
+		    if(ic_stored[index].isMember()) {
+		        outerClass = cpBands.cpClassValue(outerClassString);
+		    }
 
-	        int flags = ic_relevant[index].F;
+	        int flags = ic_stored[index].F;
 	        innerClassesAttribute.addInnerClassesEntry(innerClass, outerClass, innerName, flags);
-	        addedClasses = true;
+	        addInnerClassesAttr = true;
+		}
+		// If ic_local is sent and it's empty, don't add
+		// the inner classes attribute.
+		if(ic_local_sent && (ic_local.length == 0)) {
+		    addInnerClassesAttr = false;
 		}
-		if(addedClasses) {
+
+		// If ic_local is not sent and ic_relevant is empty,
+		// don't add the inner class attribute.
+		if(!ic_local_sent && (ic_relevant.length == 0)) {
+		    addInnerClassesAttr = false;
+		}
+
+		if(addInnerClassesAttr) {
 		    // Need to add the InnerClasses attribute to the
 		    // existing classFile attributes.
 		    Attribute[] originalAttrs = classFile.attributes;
@@ -225,6 +258,54 @@
 
 
 	/**
+	 * Given an ic_local and an ic_relevant, use them to
+	 * calculate what should be added as ic_stored.
+	 * @param ic_local IcTuple[] array of local transmitted tuples
+	 * @param ic_relevant IcTuple[] array of relevant tuples
+	 * @return IcTuple[] array of tuples to be stored. If ic_local
+	 *     is null or empty, the values returned may not be correct.
+	 *     The caller will have to determine if this is the case.
+	 */
+	private IcTuple[] computeIcStored(IcTuple[] ic_local, IcTuple[] ic_relevant) {
+	    List result = new ArrayList();
+	    List resultCopy = new ArrayList();
+	    List localList = new ArrayList();
+	    List relevantList = new ArrayList();
+	    if(ic_local != null) {
+	        // If ic_local is null, this code doesn't get
+	        // executed - which means the list ends up being
+	        // ic_relevant.
+	        for(int index=0; index < ic_local.length; index++) {
+	            result.add(ic_local[index]);
+	            resultCopy.add(ic_local[index]);
+	            localList.add(ic_local[index]);
+	        }
+	    }
+	    for(int index=0; index < ic_relevant.length; index++) {
+	        result.add(ic_relevant[index]);
+	        resultCopy.add(ic_relevant[index]);
+	        relevantList.add(ic_relevant[index]);
+	    }
+
+	    // Since we're removing while iterating, iterate over
+	    // a copy.
+	    Iterator it = resultCopy.iterator();
+
+	    while(it.hasNext()) {
+	        IcTuple tuple = (IcTuple)it.next();
+	        if(localList.contains(tuple) && relevantList.contains(tuple)) {
+	            while(result.remove(tuple)) {};
+	        }
+	    }
+	    IcTuple[] resultArray = new IcTuple[result.size()];
+	    for(int index=0; index < resultArray.length; index++) {
+	        resultArray[index] = (IcTuple)result.get(index);
+	    }
+	    return resultArray;
+    }
+
+
+    /**
 	 * This performs the actual work of parsing against a non-static instance of
 	 * Segment.
 	 *
@@ -267,7 +348,7 @@
     public void unpack(InputStream in, JarOutputStream out) throws IOException,
             Pack200Exception {
         if (!in.markSupported())
-            in = new BufferedInputStream(in);        
+            in = new BufferedInputStream(in);
         parseSegment(in);
         writeJar(out);
     }
@@ -357,7 +438,6 @@
 			}
 		}
 		dos.flush();
-		out.finish();
 		out.flush();
 	}
 



Mime
View raw message