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);
+ }
}
}