Index: src/main/java/org/apache/harmony/pack200/BandSet.java =================================================================== --- src/main/java/org/apache/harmony/pack200/BandSet.java (revision 608803) +++ src/main/java/org/apache/harmony/pack200/BandSet.java (working copy) @@ -19,6 +19,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; import org.apache.harmony.pack200.bytecode.CPClass; import org.apache.harmony.pack200.bytecode.CPDouble; @@ -359,9 +360,9 @@ /* * 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 encoding that is - * following the spec because all the values decoded will be inside the - * range anyway. + * 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 < returnBand.length; i++) { @@ -372,6 +373,24 @@ returnBand[i] -= ((BHSDCodec) codecUsed).cardinality(); } } + } else if (codecUsed instanceof PopulationCodec) { + PopulationCodec popCodec = (PopulationCodec)codecUsed; + long[] favoured = 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; + Codec theCodec = favouredValue ? popCodec.getFavouredCodec(): popCodec.getUnvafouredCodec(); + if(theCodec instanceof BHSDCodec) { + while (returnBand[i] < 0) { + returnBand[i] += ((BHSDCodec) theCodec).cardinality(); + } + while (returnBand[i] > maxValue) { + returnBand[i] -= ((BHSDCodec) theCodec).cardinality(); + } + } + } + } } return returnBand; Index: src/main/java/org/apache/harmony/pack200/CodecEncoding.java =================================================================== --- src/main/java/org/apache/harmony/pack200/CodecEncoding.java (revision 588229) +++ src/main/java/org/apache/harmony/pack200/CodecEncoding.java (working copy) @@ -123,7 +123,7 @@ int h = code + 1; // This handles the special cases for invalid combinations of data. return new BHSDCodec(b,h,s,d); - } else if (value >= 117 && value <= 140) { + } else if (value >= 117 && value <= 140) { // Run codec int offset = value - 117; int kx = offset & 3; boolean kbflag = (offset >> 2 & 1) == 1; @@ -146,7 +146,7 @@ bCodec = getCodec(in.read(),in,defaultCodec); } return new RunCodec(k,aCodec,bCodec); - } else if (value >= 141 && value <= 188) { + } else if (value >= 141 && value <= 188) { // Population Codec int offset = value - 141; boolean fdef = (offset & 1) == 1; boolean udef = (offset >> 1 & 1) == 1; @@ -166,9 +166,9 @@ return new PopulationCodec(fCodec,l,uCodec); } else { Codec fCodec = (fdef ? defaultCodec : getCodec(in.read(),in,defaultCodec) ); + Codec tCodec = getCodec(in.read(),in,defaultCodec); Codec uCodec = (udef ? defaultCodec : getCodec(in.read(),in,defaultCodec) ); - Codec tCodec = getCodec(in.read(),in,defaultCodec); - return new PopulationCodec(fCodec,uCodec,tCodec); + return new PopulationCodec(fCodec,tCodec,uCodec); } } else { throw new Pack200Exception("Invalid codec encoding byte (" + value + ") found" ); Index: src/main/java/org/apache/harmony/pack200/PopulationCodec.java =================================================================== --- src/main/java/org/apache/harmony/pack200/PopulationCodec.java (revision 591346) +++ src/main/java/org/apache/harmony/pack200/PopulationCodec.java (working copy) @@ -24,6 +24,7 @@ private Codec tokenCodec; private Codec unvafouredCodec; private int l; + private long[] favoured; public PopulationCodec(Codec favouredCodec, Codec tableCodec, Codec unvafouredCodec) { this.favouredCodec = favouredCodec; @@ -52,7 +53,7 @@ public long[] decode(int n, InputStream in) throws IOException, Pack200Exception { - long favoured[] = new long[n]; // there must be <= n values, but probably a lot less + 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; @@ -71,7 +72,7 @@ // 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) { @@ -102,4 +103,16 @@ } return result; } + + public long[] getFavoured() { + return favoured; + } + + public Codec getFavouredCodec() { + return favouredCodec; + } + + public Codec getUnvafouredCodec() { + return unvafouredCodec; + } }