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/03/12 15:04:16 UTC

svn commit: r636332 - in /harmony/enhanced/classlib/trunk/modules/pack200/src: main/java/org/apache/harmony/pack200/ test/java/org/apache/harmony/pack200/tests/

Author: sjanuary
Date: Wed Mar 12 07:04:11 2008
New Revision: 636332

URL: http://svn.apache.org/viewvc?rev=636332&view=rev
Log:
Pack200 - Fix decoding bug, including fix for HARMONY-5589 ([classlib][pack200] AttributeLayout KS returning negative index)

Modified:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.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/ClassBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/RunCodec.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BHSDCodecTest.java

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java?rev=636332&r1=636331&r2=636332&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java Wed Mar 12 07:04:11 2008
@@ -56,6 +56,10 @@
 
     private long cardinality;
 
+    private long smallest;
+
+    private long largest;
+
 	/**
 	 * Constructs an unsigned, non-delta Codec with the given B and H values.
 	 *
@@ -123,6 +127,8 @@
         } else {
             cardinality = (long) ((long)(l * (1-Math.pow(h, b))/(1-h)) + Math.pow(h,b));
         }
+        smallest = calculateSmallest();
+        largest = calculateLargest();
 	}
 
 	/**
@@ -202,7 +208,7 @@
 	 * @return <code>true</code> if the encoding can encode this value
 	 */
 	public boolean encodes(long value) {
-		return (value >= smallest() && value <= largest());
+		return (value >= smallest && value <= largest);
 	}
 
     public byte[] encode(long value, long last) throws Pack200Exception {
@@ -270,10 +276,17 @@
 	 *
 	 * @return the largest value that this codec can represent.
 	 */
-	public long largest() {
+    public long largest() {
+        return largest;
+    }
+
+	private long calculateLargest() {
 		long result;
 		// TODO This can probably be optimized into a better mathematical statement
-		if (s == 0) {
+        if(d == 1) {
+            BHSDCodec bh0 = new BHSDCodec(b, h);
+            return bh0.largest();
+        } else if (s == 0) {
 			result = cardinality() - 1;
 		} else if (s == 1) {
 			result = cardinality() / 2 - 1;
@@ -285,18 +298,30 @@
 		return Math.min((s == 0 ? ((long) Integer.MAX_VALUE) << 1
 				: Integer.MAX_VALUE) - 1, result);
 	}
+
 	/**
 	 * Returns the smallest value that this codec can represent.
 	 *
 	 * @return the smallest value that this codec can represent.
 	 */
-	public long smallest() {
+    public long smallest() {
+        return smallest;
+    }
+
+	private long calculateSmallest() {
 		long result;
-		if (isSigned()) {
-			result = -cardinality() / (1 << s);
-		} else {
-			result = 0;
-		}
+         if (d == 1) {
+            BHSDCodec bh0 = new BHSDCodec(b, h);
+            return bh0.smallest();
+        } else if (isSigned()) {
+            result = -cardinality() / (1 << s);
+        } else {
+            if (cardinality > Integer.MAX_VALUE) {
+                result = Integer.MIN_VALUE;
+            } else {
+                result = 0;
+            }
+        }
 		return Math.max(Integer.MIN_VALUE, result);
 	}
 	/**

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=636332&r1=636331&r2=636332&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 Mar 12 07:04:11 2008
@@ -70,32 +70,6 @@
     public int[] decodeBandInt(String name, InputStream in,
             BHSDCodec codec, int count) throws IOException,
             Pack200Exception {
-        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) {
@@ -121,20 +95,44 @@
             // 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();
-                    }
+//        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();
+//                    }
+//                }
+//            }
+//        }
+        if(codecUsed instanceof BHSDCodec && ((BHSDCodec)codecUsed).isDelta()) {
+            BHSDCodec bhsd = (BHSDCodec)codecUsed;
+            long cardinality = bhsd.cardinality();
+            for (int i = 0; i < band.length; i++) {
+                while (band[i] > bhsd.largest()) {
+                    band[i] -= cardinality;
+                }
+                while (band[i] < bhsd.smallest()) {
+                    band[i] += cardinality;
                 }
             }
-        }
-        if(codecUsed instanceof BHSDCodec) {
-            long cardinality = ((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 < band.length; i++) {
-                while(band[i] > cardinality) {
-                    band[i] -= cardinality;
+                boolean favouredValue = Arrays.binarySearch(favoured,
+                        band[i]) > -1;
+                Codec theCodec = favouredValue ? popCodec
+                        .getFavouredCodec() : popCodec.getUnvafouredCodec();
+                if (theCodec instanceof BHSDCodec && ((BHSDCodec) theCodec).isDelta()) {
+                    BHSDCodec bhsd = (BHSDCodec)theCodec;
+                    long cardinality = bhsd.cardinality();
+                    while (band[i] > bhsd.largest()) {
+                        band[i] -= cardinality;
+                    }
+                    while (band[i] < bhsd.smallest()) {
+                        band[i] += cardinality;
+                    }
                 }
             }
         }
@@ -165,40 +163,12 @@
     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
-     *
-     * @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, 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, negativesAllowed);
+        int[] twoDResult = decodeBandInt(name, in, defaultCodec, totalCount);
         int index = 0;
         for (int i = 0; i < result.length; i++) {
             result[i] = new int[counts[i]];
@@ -235,6 +205,8 @@
         if (codec.getB() == 1 || count == 0) {
             return codec.decode(count, in);
         }
+        Codec codecUsed = codec;
+        long[] band;
         long[] getFirst = codec.decode(1, in);
         if (getFirst.length == 0) {
             return getFirst;
@@ -242,19 +214,53 @@
         long first = getFirst[0];
         if (codec.isSigned() && first >= -256 && first <= -1) {
             // Non-default codec should be used
-            Codec nonDefaultCodec = CodecEncoding.getCodec((int) (-1 - first),
+            codecUsed = CodecEncoding.getCodec((int) (-1 - first),
                     header.getBandHeadersInputStream(), codec);
-            return nonDefaultCodec.decode(count, in);
+            band = codecUsed.decode(count, in);
         } else if (!codec.isSigned() && first >= codec.getL()
                 && first <= codec.getL() + 255) {
             // Non-default codec should be used
-            Codec nonDefaultCodec = CodecEncoding.getCodec((int) first
+            codecUsed = CodecEncoding.getCodec((int) first
                     - codec.getL(), header.getBandHeadersInputStream(), codec);
-            return nonDefaultCodec.decode(count, in);
+            band = codecUsed.decode(count, in);
         } else {
             // First element should not be discarded
-            return codec.decode(count - 1, in, first);
+            band = codec.decode(count - 1, in, first);
         }
+
+        if(codecUsed instanceof BHSDCodec && ((BHSDCodec)codecUsed).isDelta()) {
+            BHSDCodec bhsd = (BHSDCodec)codecUsed;
+            long cardinality = bhsd.cardinality();
+            for (int i = 0; i < band.length; i++) {
+                while (band[i] > bhsd.largest()) {
+                    band[i] -= cardinality;
+                }
+                while (band[i] < bhsd.smallest()) {
+                    band[i] += cardinality;
+                }
+            }
+        } else if (codecUsed instanceof PopulationCodec) {
+            PopulationCodec popCodec = (PopulationCodec) codecUsed;
+            long[] favoured = (long[]) popCodec.getFavoured().clone();
+            Arrays.sort(favoured);
+            for (int i = 0; i < band.length; i++) {
+                boolean favouredValue = Arrays.binarySearch(favoured,
+                        band[i]) > -1;
+                Codec theCodec = favouredValue ? popCodec
+                        .getFavouredCodec() : popCodec.getUnvafouredCodec();
+                if (theCodec instanceof BHSDCodec && ((BHSDCodec) theCodec).isDelta()) {
+                    BHSDCodec bhsd = (BHSDCodec)theCodec;
+                    long cardinality = bhsd.cardinality();
+                    while (band[i] > bhsd.largest()) {
+                        band[i] -= cardinality;
+                    }
+                    while (band[i] < bhsd.smallest()) {
+                        band[i] += cardinality;
+                    }
+                }
+            }
+        }
+        return band;
     }
 
     public byte[] encodeBandLong(long[] data, BHSDCodec codec) throws IOException, Pack200Exception {
@@ -396,7 +402,7 @@
         }
         // TODO Merge the decode and parsing of a multiple structure into one
         String[] result1 = new String[sum];
-        int[] indices = decodeBandInt(name, in, codec, sum, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, sum);
         for (int i1 = 0; i1 < sum; i1++) {
             int index = indices[i1];
             if (index < 0 || index >= reference.length)
@@ -416,73 +422,6 @@
         return result;
     }
 
-    private int[] decodeBandInt(String name, InputStream in, BHSDCodec codec, int count, int maxValue) throws IOException, Pack200Exception {
-        int[] band;
-        Codec codecUsed = codec;
-        if (codec.getB() == 1 || count == 0) {
-            band = codec.decodeInts(count, in);
-        } else {
-            int[] getFirst = codec.decodeInts(1, in);
-            if (getFirst.length == 0) {
-                return new int[0];
-            }
-            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);
-            }
-        }
-
-
-        /*
-         * Note - this is not in the spec, but seems to be used as an
-         * optimization by the RI for bands where the minimum and maximum values
-         * are known (ie reference bands). It will not hurt any implementation
-         * that is following the spec because all the values decoded will be
-         * inside the range anyway.
-         */
-        if (codecUsed instanceof BHSDCodec) {
-            for (int i = 0; i < band.length; i++) {
-                while (band[i] < 0) {
-                    band[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 < 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 (band[i] < 0) {
-                            band[i] +=  ((BHSDCodec) theCodec).cardinality();
-                        }
-                        while (band[i] > maxValue) {
-                            band[i] -= ((BHSDCodec) theCodec).cardinality();
-                        }
-                    }
-                }
-            }
-        }
-        return band;
-    }
-
     /**
      * This is a local debugging message to aid the developer in writing this
      * class. It will be removed before going into production. If the property
@@ -498,7 +437,7 @@
 
     public CPInteger[] parseCPIntReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
         int[] reference = segment.getCpBands().getCpInt();
-        int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, count);
         CPInteger[] result = new CPInteger[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
@@ -512,7 +451,7 @@
 
     public CPDouble[] parseCPDoubleReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
         double[] reference = segment.getCpBands().getCpDouble();
-        int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, count);
         CPDouble[] result = new CPDouble[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
@@ -526,7 +465,7 @@
 
     public CPFloat[] parseCPFloatReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
         float[] reference = segment.getCpBands().getCpFloat();
-        int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, count);
         CPFloat[] result = new CPFloat[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
@@ -540,7 +479,7 @@
 
     public CPLong[] parseCPLongReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
         long[] reference = segment.getCpBands().getCpLong();
-        int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, count);
         CPLong[] result = new CPLong[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
@@ -554,7 +493,7 @@
 
     public CPUTF8[] parseCPUTF8References(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
         String[] reference = segment.getCpBands().getCpUTF8();
-        int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, count);
         CPUTF8[] result = new CPUTF8[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
@@ -576,7 +515,7 @@
             sum += counts[i];
         }
         CPUTF8[] result1 = new CPUTF8[sum];
-        int[] indices = decodeBandInt(name, in, codec, sum, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, sum);
         for (int i1 = 0; i1 < sum; i1++) {
             int index = indices[i1];
             if (index < 0 || index >= reference.length)
@@ -597,7 +536,7 @@
 
     public CPString[] parseCPStringReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
         String[] reference = segment.getCpBands().getCpString();
-        int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, count);
         CPString[] result = new CPString[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
@@ -613,7 +552,7 @@
         CpBands cpBands = segment.getCpBands();
         String[] reference = cpBands.getCpIMethodClass();
         String[] descriptors = cpBands.getCpIMethodDescriptor();
-        int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, count);
         CPInterfaceMethodRef[] result = new CPInterfaceMethodRef[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
@@ -632,7 +571,7 @@
         CpBands cpBands = segment.getCpBands();
         String[] reference = cpBands.getCpMethodClass();
         String[] descriptors = cpBands.getCpMethodDescriptor();
-        int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, count);
         CPMethodRef[] result = new CPMethodRef[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
@@ -650,7 +589,7 @@
         CpBands cpBands = segment.getCpBands();
         String[] reference = cpBands.getCpFieldClass();
         String[] descriptors = cpBands.getCpFieldDescriptor();
-        int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, count);
         CPFieldRef[] result = new CPFieldRef[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
@@ -667,7 +606,7 @@
     public CPNameAndType[] parseCPDescriptorReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
         CpBands cpBands = segment.getCpBands();
         String[] reference = cpBands.getCpDescriptor();
-        int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, count);
         CPNameAndType[] result = new CPNameAndType[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
@@ -681,7 +620,7 @@
 
     public CPUTF8[] parseCPSignatureReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
         String[] reference = segment.getCpBands().getCpSignature();
-        int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, count);
         CPUTF8[] result = new CPUTF8[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];
@@ -695,7 +634,7 @@
 
     public CPClass[] parseCPClassReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
         String[] reference = segment.getCpBands().getCpClass();
-        int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
+        int[] indices = decodeBandInt(name, in, codec, count);
         CPClass[] result = new CPClass[indices.length];
         for (int i1 = 0; i1 < count; i1++) {
             int index = indices[i1];

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java?rev=636332&r1=636331&r2=636332&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java Wed Mar 12 07:04:11 2008
@@ -24,12 +24,7 @@
 
 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;
@@ -806,7 +801,7 @@
                 localVariableTableN);
         int[][] localVariableTableSpanO = decodeBandInt(
                 "code_LocalVariableTable_span_O", in, Codec.BRANCH5,
-                localVariableTableN, false);
+                localVariableTableN);
         CPUTF8[][] localVariableTableNameRU = stringsToCPUTF8(parseReferences(
                 "code_LocalVariableTable_name_RU", in, Codec.UNSIGNED5,
                 localVariableTableN, cpBands.getCpUTF8()));

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/RunCodec.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/RunCodec.java?rev=636332&r1=636331&r2=636332&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/RunCodec.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/RunCodec.java Wed Mar 12 07:04:11 2008
@@ -18,6 +18,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Arrays;
 
 /**
  * A run codec is a grouping of two nested codecs; K values are decoded from
@@ -54,7 +55,54 @@
 			return this.last;
 		}
 	}
-	public String toString() {
+
+    public int[] decodeInts(int n, InputStream in) throws IOException, Pack200Exception {
+        int[] band = new int[n];
+        int[] aValues = aCodec.decodeInts(k, in);
+        normalise(aValues, aCodec);
+        int[] bValues = bCodec.decodeInts(n-k, in);
+        normalise(bValues, bCodec);
+        System.arraycopy(aValues, 0, band, 0, k);
+        System.arraycopy(bValues, 0, band, k, n-k);
+        return band;
+    }
+
+	private void normalise(int[] band, Codec codecUsed) {
+        if(codecUsed instanceof BHSDCodec && ((BHSDCodec)codecUsed).isDelta()) {
+            BHSDCodec bhsd = (BHSDCodec)codecUsed;
+            long cardinality = bhsd.cardinality();
+            for (int i = 0; i < band.length; i++) {
+                while (band[i] > bhsd.largest()) {
+                    band[i] -= cardinality;
+                }
+                while (band[i] < bhsd.smallest()) {
+                    band[i] += cardinality;
+                }
+            }
+        } else if (codecUsed instanceof PopulationCodec) {
+            PopulationCodec popCodec = (PopulationCodec) codecUsed;
+            long[] favoured = (long[]) popCodec.getFavoured().clone();
+            Arrays.sort(favoured);
+            for (int i = 0; i < band.length; i++) {
+                boolean favouredValue = Arrays.binarySearch(favoured,
+                        band[i]) > -1;
+                Codec theCodec = favouredValue ? popCodec
+                        .getFavouredCodec() : popCodec.getUnvafouredCodec();
+                if (theCodec instanceof BHSDCodec && ((BHSDCodec) theCodec).isDelta()) {
+                    BHSDCodec bhsd = (BHSDCodec)theCodec;
+                    long cardinality = bhsd.cardinality();
+                    while (band[i] > bhsd.largest()) {
+                        band[i] -= cardinality;
+                    }
+                    while (band[i] < bhsd.smallest()) {
+                        band[i] += cardinality;
+                    }
+                }
+            }
+        }
+    }
+
+    public String toString() {
 		return "RunCodec[k="+k+";aCodec="+aCodec+"bCodec="+bCodec+"]";
 	}
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java?rev=636332&r1=636331&r2=636332&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java Wed Mar 12 07:04:11 2008
@@ -224,7 +224,7 @@
      * only place one exists is in matchSpecificPoolEntryIndex().
      * To eliminate this dependency, we've implemented the
      * world's stupidest regexMatch. It knows about the two
-     * forms we care about: 
+     * forms we care about:
      *  .* (aka REGEX_MATCH_ALL)
      *  ^<init>.* (aka REGEX_MATCH_INIT)
      * and will answer correctly if those are passed as the

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BHSDCodecTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BHSDCodecTest.java?rev=636332&r1=636331&r2=636332&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BHSDCodecTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BHSDCodecTest.java Wed Mar 12 07:04:11 2008
@@ -17,6 +17,7 @@
 package org.apache.harmony.pack200.tests;
 
 import java.io.ByteArrayInputStream;
+import java.io.EOFException;
 import java.io.IOException;
 
 import junit.framework.TestCase;
@@ -36,15 +37,24 @@
 
             BHSDCodec codec = (BHSDCodec) CodecEncoding.getCodec(i, null, null);
 
-            // Test encode-decode with a selection of numbers within the range of the codec
-            long delta = (codec.largest() - codec.smallest()) / 4;
-            for (long j = codec.smallest(); j <= codec.largest() + 1; j += delta) {
-                byte[] encoded = codec.encode(j, 0);
-                long decoded = codec.decode(new ByteArrayInputStream(encoded),
-                        0);
-                if (j != decoded) {
-                    fail("Failed with codec: " + codec + " expected: " + j
-                            + ", got: " + decoded);
+            if(!codec.isDelta()) {
+                // Test encode-decode with a selection of numbers within the range of the codec
+                long largest = codec.largest();
+                long smallest = codec.isSigned() ? codec.smallest() : 0;
+                long difference = (largest - smallest) / 4;
+                for (long j = smallest; j <= largest; j += difference) {
+                    byte[] encoded = codec.encode(j, 0);
+                    long decoded = 0;
+                    try {
+                        decoded = codec.decode(new ByteArrayInputStream(encoded),
+                                0);
+                    } catch (EOFException e) {
+                        System.out.println(e);
+                    }
+                    if (j != decoded) {
+                        fail("Failed with codec: " + i + ", " + codec + " expected: " + j
+                                + ", got: " + decoded);
+                    }                   
                 }
             }