You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ml...@apache.org on 2006/08/10 10:46:30 UTC

svn commit: r430314 - in /incubator/harmony/enhanced/classlib/trunk/modules/archive/src: main/java/org/apache/harmony/archive/internal/pack200/ test/java/org/apache/harmony/archive/tests/internal/pack200/ test/resources/org/apache/harmony/archive/tests...

Author: mloenko
Date: Thu Aug 10 01:46:28 2006
New Revision: 430314

URL: http://svn.apache.org/viewvc?rev=430314&view=rev
Log:
applied patch for HARMONY-1019
Adding RunCodec and segment encoding tests
(plus missing copyrights were added)

Added:
    incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/BHSDCodec.java
    incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/CodecEncoding.java
    incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/PopulationCodec.java
    incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/RunCodec.java
    incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/AllTests.java
    incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/CodecEncodingTest.java
    incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/PopulationCodecTest.java
    incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/resources/org/apache/harmony/archive/tests/internal/pack200/JustResources.pack   (with props)
Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Codec.java
    incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java
    incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/CodecTest.java
    incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/SegmentTest.java

Added: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/BHSDCodec.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/BHSDCodec.java?rev=430314&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/BHSDCodec.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/BHSDCodec.java Thu Aug 10 01:46:28 2006
@@ -0,0 +1,248 @@
+/*
+ *  Copyright 2006 The Apache Software Foundation or its licensors, 
+ *  as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * TODO Comment -- quite a lot can be nicked from Codec, since this was created
+ * from it
+ * 
+ * @author Alex Blewitt
+ * 
+ */
+public class BHSDCodec extends Codec {
+
+	/**
+	 * The maximum number of bytes in each coding word
+	 */
+	private int b;
+
+	/**
+	 * Whether delta encoding is used (0=false,1=true)
+	 */
+	private int d;
+
+	/**
+	 * The radix of the encoding
+	 */
+	private int h;
+
+	/**
+	 * The co-parameter of h; h-256
+	 */
+	private int l;
+
+	/**
+	 * Represents signed numbers or not (0=unsigned,1/2=signed)
+	 */
+	private int s;
+
+	/**
+	 * Constructs an unsigned, non-delta Codec with the given B and H values.
+	 * 
+	 * @param b
+	 *            the maximum number of bytes that a value can be encoded as
+	 *            [1..5]
+	 * @param h
+	 *            the radix of the encoding [1..256]
+	 */
+	public BHSDCodec(int b, int h) {
+		this(b, h, 0);
+	}
+
+	/**
+	 * Constructs a non-delta Codec with the given B, H and S values.
+	 * 
+	 * @param b
+	 *            the maximum number of bytes that a value can be encoded as
+	 *            [1..5]
+	 * @param h
+	 *            the radix of the encoding [1..256]
+	 * @param s
+	 *            whether the encoding represents signed numbers (s=0 is
+	 *            unsigned; s=1 is signed with 1s complement; s=2 is signed with ?)
+	 */
+	public BHSDCodec(int b, int h, int s) {
+		this(b, h, s, 0);
+	}
+
+	/**
+	 * Constructs a Codec with the given B, H, S and D values.
+	 * 
+	 * @param b
+	 *            the maximum number of bytes that a value can be encoded as
+	 *            [1..5]
+	 * @param h
+	 *            the radix of the encoding [1..256]
+	 * @param s
+	 *            whether the encoding represents signed numbers (s=0 is
+	 *            unsigned; s=1 is signed with 1s complement; s=2 is signed with ?)
+	 * @param d
+	 *            whether this is a delta encoding (d=0 is non-delta; d=1 is
+	 *            delta)
+	 */
+	public BHSDCodec(int b, int h, int s, int d) {
+		if (b < 1 || b > 5)
+			throw new IllegalArgumentException("1<=b<=5");
+		if (h < 1 || h > 256)
+			throw new IllegalArgumentException("1<=h<=256");
+		if (s < 0 || s > 2)
+			throw new IllegalArgumentException("0<=s<=2");
+		if (d < 0 || d > 1)
+			throw new IllegalArgumentException("0<=d<=1");
+		if (b == 1 && h != 256)
+			throw new IllegalArgumentException("b=1 -> h=256");
+		if (h == 256 && b == 5)
+			throw new IllegalArgumentException("h=256 -> b!=5");
+		this.b = b;
+		this.h = h;
+		this.s = s;
+		this.d = d;
+		this.l = 256 - h;
+	}
+
+	/**
+	 * Returns the cardinality of this codec; that is, the number of distinct
+	 * values that it can contain.
+	 * 
+	 * @return the cardinality of this codec
+	 */
+	public long cardinality() {
+		if (h > 1) {
+			return (long) (l * Math.pow(1 - h, b) / (1 - h) + Math.pow(h, b));
+		} else {
+			return (b * 255) + 1;
+		}
+	}
+
+	@Override
+	public long decode(InputStream in) throws IOException, Pack200Exception {
+		if (d != 0)
+			throw new Pack200Exception(
+					"Delta encoding used without passing in last value; this is a coding error");
+		return decode(in, 0);
+	}
+
+	@Override
+	public long decode(InputStream in, long last) throws IOException,
+			Pack200Exception {
+		int n = 0;
+		long z = 0;
+		long x;
+		do {
+			x = in.read();
+			if (x == -1)
+				throw new EOFException("End of stream reached whilst decoding");
+			z += x * Math.pow(h, n);
+		} while (++n < b && x >= l);
+		// This looks more complicated than it is
+		// When s=0, {1,2,3,4} is mapped to {1,2,3,4}
+		// When s=1, {1,2,3,4} is mapped to {-1,1,-2,2...}
+		// When s=2, {1,2,3,4} is mapped to {1,2,3,-1...}
+		if (s > 0) {
+			int u = ((1 << s) - 1);
+			if ((z & u) == u) {
+				z = z >>> s ^ -1L;
+			} else {
+				z = z - (z >>> s);
+			}
+		}
+		if (d == 1)
+			z += last;
+		return z;
+	}
+
+	/**
+	 * True if this encoding can code the given value
+	 * 
+	 * @param value
+	 *            the value to check
+	 * @return <code>true</code> if the encoding can encode this value
+	 */
+	public boolean encodes(long value) {
+		return (value >= smallest() && value <= largest());
+	}
+
+	/**
+	 * Returns the largest value that this codec can represent.
+	 * 
+	 * @eturn the largest value that this codec can represent.
+	 */
+	public long largest() {
+		long result;
+		if (d == 0) {
+			if (s == 0) {
+				result = cardinality() - 1;
+			} else if (s == 1) {
+				result = cardinality() / 2 - 1;
+			} else if (s == 2) {
+				result = (3L * cardinality()) / 4 - 1;
+			} else {
+				throw new Error("Unknown s value");
+			}
+		} else {
+			result = Long.MAX_VALUE;
+		}
+		return Math.min((s == 0 ? ((long) Integer.MAX_VALUE) << 1
+				: Integer.MAX_VALUE) - 1, result);
+	}
+
+	/**
+	 * Returns the smallest value that this codec can represent.
+	 * 
+	 * @eturn the smallest value that this codec can represent.
+	 */
+	public long smallest() {
+		long result;
+		if (d == 0) {
+			if (s == 0) {
+				result = 0;
+			} else {
+				result = -cardinality() / (1 << s);
+			}
+		} else {
+			result = Integer.MIN_VALUE;
+		}
+		return Math.max(Integer.MIN_VALUE, result);
+	}
+
+	/**
+	 * Returns the codec in the form (1,256) or (1,64,1,1). Note that trailing
+	 * zero fields are not shown.
+	 */
+	public String toString() {
+		StringBuffer buffer = new StringBuffer(11);
+		buffer.append('(');
+		buffer.append(b);
+		buffer.append(',');
+		buffer.append(h);
+		if (s != 0 || d != 0) {
+			buffer.append(",");
+			buffer.append(s);
+		}
+		if (d != 0) {
+			buffer.append(",");
+			buffer.append(d);
+		}
+		buffer.append(')');
+		return buffer.toString();
+	}
+
+}

Modified: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Codec.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Codec.java?rev=430314&r1=430313&r2=430314&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Codec.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Codec.java Thu Aug 10 01:46:28 2006
@@ -16,7 +16,6 @@
  */
 package org.apache.harmony.archive.internal.pack200;
 
-import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
 
@@ -98,146 +97,57 @@
  * @author Alex Blewitt
  * @version $Revision: $
  */
-public class Codec {
+public abstract class Codec {
 	/**
 	 * BCI5 = (5,4): Used for storing branching information in bytecode.
 	 */
-	public static Codec BCI5 = new Codec(5, 4);
+	public static Codec BCI5 = new BHSDCodec(5, 4);
 
 	/**
 	 * BRANCH5 = (5,4,2): Used for storing branching information in bytecode.
 	 */
-	public static final Codec BRANCH5 = new Codec(5, 4, 2);
+	public static final Codec BRANCH5 = new BHSDCodec(5, 4, 2);
 
 	/**
 	 * BYTE1 = (1,256): Used for storing plain bytes.
 	 */
-	public static final Codec BYTE1 = new Codec(1, 256);
+	public static final Codec 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 Codec CHAR3 = new Codec(3, 128);
+	public static final Codec 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 Codec DELTA5 = new Codec(5, 64, 1, 1);
+	public static final Codec DELTA5 = new BHSDCodec(5, 64, 1, 1);
 
 	/**
 	 * DELTA5 = (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 Codec MDELTA5 = new Codec(5, 64, 2, 1);
+	public static final Codec MDELTA5 = new BHSDCodec(5, 64, 2, 1);
 
 	/**
 	 * SIGNED5 = (5,64,1): Used for small signed values.
 	 */
-	public static final Codec SIGNED5 = new Codec(5, 64, 1);
+	public static final Codec 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 Codec UDELTA5 = new Codec(5, 64, 0, 1);
+	public static final Codec UDELTA5 = new BHSDCodec(5, 64, 0, 1);
 
 	/**
 	 * USIGNED5 = (5,64): Used for small unsigned values.
 	 */
-	public static final Codec UNSIGNED5 = new Codec(5, 64);
-
-	/**
-	 * The maximum number of bytes in each coding word
-	 */
-	private int b;
-
-	/**
-	 * Whether delta encoding is used (0=false,1=true)
-	 */
-	private int d;
-
-	/**
-	 * The radix of the encoding
-	 */
-	private int h;
-
-	/**
-	 * The co-parameter of h; h-256
-	 */
-	private int l;
-
-	/**
-	 * Represents signed numbers or not (0=unsigned,1/2=signed)
-	 */
-	private int s;
-
-	/**
-	 * Constructs an unsigned, non-delta Codec with the given B and H values.
-	 * 
-	 * @param b
-	 *            the maximum number of bytes that a value can be encoded as
-	 *            [1..5]
-	 * @param h
-	 *            the radix of the encoding [1..256]
-	 */
-	public Codec(int b, int h) {
-		this(b, h, 0);
-	}
-
-	/**
-	 * Constructs a non-delta Codec with the given B, H and S values.
-	 * 
-	 * @param b
-	 *            the maximum number of bytes that a value can be encoded as
-	 *            [1..5]
-	 * @param h
-	 *            the radix of the encoding [1..256]
-	 * @param s
-	 *            whether the encoding represents signed numbers (s=0 is
-	 *            unsigned; s=1 is signed with 1s complement; s=2 is signed with ?)
-	 */
-	public Codec(int b, int h, int s) {
-		this(b, h, s, 0);
-	}
-
-	/**
-	 * Constructs a Codec with the given B, H, S and D values.
-	 * 
-	 * @param b
-	 *            the maximum number of bytes that a value can be encoded as
-	 *            [1..5]
-	 * @param h
-	 *            the radix of the encoding [1..256]
-	 * @param s
-	 *            whether the encoding represents signed numbers (s=0 is
-	 *            unsigned; s=1 is signed with 1s complement; s=2 is signed with ?)
-	 * @param d
-	 *            whether this is a delta encoding (d=0 is non-delta; d=1 is
-	 *            delta)
-	 */
-	public Codec(int b, int h, int s, int d) {
-		if (b < 1 || b > 5)
-			throw new IllegalArgumentException("1<=b<=5");
-		if (h < 1 || h > 256)
-			throw new IllegalArgumentException("1<=h<=256");
-		if (s < 0 || s > 2)
-			throw new IllegalArgumentException("0<=s<=2");
-		if (d < 0 || d > 1)
-			throw new IllegalArgumentException("0<=d<=1");
-		if (b == 1 && h != 256)
-			throw new IllegalArgumentException("b=1 -> h=256");
-		if (h == 256 && b == 5)
-			throw new IllegalArgumentException("h=256 -> b!=5");
-		this.b = b;
-		this.h = h;
-		this.s = s;
-		this.d = d;
-		this.l = 256 - h;
-	}
+	public static final Codec UNSIGNED5 = new BHSDCodec(5, 64);
 
 	/**
 	 * Decode a sequence of bytes from the given input stream, returning the
@@ -253,12 +163,8 @@
 	 * @throws Pack200Exception
 	 *             if the encoding is a delta encoding
 	 */
-	public long decode(InputStream in) throws IOException, Pack200Exception {
-		if (d != 0)
-			throw new Pack200Exception(
-					"Delta encoding used without passing in last value; this is a coding error");
-		return decode(in, 0);
-	}
+	public abstract long decode(InputStream in) throws IOException,
+			Pack200Exception;
 
 	/**
 	 * Decode a sequence of bytes from the given input stream, returning the
@@ -275,9 +181,6 @@
 	 * }
 	 * </pre>
 	 * 
-	 * TODO Note that s=2 encodings are not yet supported, and will result in an
-	 * Error
-	 * 
 	 * @param in
 	 *            the input stream to read from
 	 * @param long
@@ -291,52 +194,35 @@
 	 *             if there is a problem decoding the value or that the value is
 	 *             invalid
 	 */
-	public long decode(InputStream in, long last) throws IOException,
-			Pack200Exception {
-		int n = 0;
-		long z = 0;
-		long x;
-		do {
-			x = in.read();
-			if (x == -1)
-				throw new EOFException("End of stream reached whilst decoding");
-			z += x * Math.pow(h, n);
-		} while (++n < b && x >= l);
-		// process sign bit -- one's complement?
-		if (s == 1) {
-			if ((z & 1) == 1) {
-				z = z >>> 1 ^ -1L;
-			} else {
-				z >>>= 1;
-			}
-		} else if (s == 2) { // two's complement?
-			throw new Error("s==2 not yet implemented");
-		}
-		if (d == 1)
-			z += last;
-		return z;
-	}
+	public abstract long decode(InputStream in, long last) throws IOException,
+			Pack200Exception;
 
 	/**
-	 * Returns the codec in the form (1,256) or (1,64,1,1). Note that trailing
-	 * zero fields are not shown.
+	 * 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 String toString() {
-		StringBuffer buffer = new StringBuffer(11);
-		buffer.append('(');
-		buffer.append(b);
-		buffer.append(',');
-		buffer.append(h);
-		if (s != 0 || d != 0) {
-			buffer.append(",");
-			buffer.append(s);
-		}
-		if (d != 0) {
-			buffer.append(",");
-			buffer.append(d);
+	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);
 		}
-		buffer.append(')');
-		return buffer.toString();
+		return result;
 	}
-
 }

Added: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/CodecEncoding.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/CodecEncoding.java?rev=430314&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/CodecEncoding.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/CodecEncoding.java Thu Aug 10 01:46:28 2006
@@ -0,0 +1,176 @@
+/*
+ *  Copyright 2006 The Apache Software Foundation or its licensors, 
+ *  as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class CodecEncoding {
+	/**
+	 * The canonical encodings are defined to allow a single byte to represent
+	 * one of the standard encodings. The following values are defined in the
+	 * Pack200 specification, and this array cannot be changed.
+	 */
+	private static Codec[] canonicalCodec = { null, new BHSDCodec(1, 256),
+			new BHSDCodec(1, 256, 1), new BHSDCodec(1, 256, 0, 1),
+			new BHSDCodec(1, 256, 1, 1), new BHSDCodec(2, 256),
+			new BHSDCodec(2, 256, 1), new BHSDCodec(2, 256, 0, 1),
+			new BHSDCodec(2, 256, 1, 1), new BHSDCodec(3, 256),
+			new BHSDCodec(3, 256, 1), new BHSDCodec(3, 256, 0, 1),
+			new BHSDCodec(3, 256, 1, 1), new BHSDCodec(4, 256),
+			new BHSDCodec(4, 256, 1), new BHSDCodec(4, 256, 0, 1),
+			new BHSDCodec(4, 256, 1, 1), new BHSDCodec(5, 4), new BHSDCodec(5, 4, 1),
+			new BHSDCodec(5, 4, 2), new BHSDCodec(5, 16), new BHSDCodec(5, 16, 1),
+			new BHSDCodec(5, 16, 2), new BHSDCodec(5, 32), new BHSDCodec(5, 32, 1),
+			new BHSDCodec(5, 32, 2), new BHSDCodec(5, 64), new BHSDCodec(5, 64, 1),
+			new BHSDCodec(5, 64, 2), new BHSDCodec(5, 128), new BHSDCodec(5, 128, 1),
+			new BHSDCodec(5, 128, 2), new BHSDCodec(5, 4, 0, 1), 
+			new BHSDCodec(5, 4, 1, 1), new BHSDCodec(5, 4, 2, 1),
+			new BHSDCodec(5, 16, 0, 1), new BHSDCodec(5, 16, 1, 1),
+			new BHSDCodec(5, 16, 2, 1), new BHSDCodec(5, 32, 0, 1),
+			new BHSDCodec(5, 32, 1, 1), new BHSDCodec(5, 32, 2, 1),
+			new BHSDCodec(5, 64, 0, 1), new BHSDCodec(5, 64, 1, 1),new BHSDCodec(5, 64, 2, 1),
+			new BHSDCodec(5, 128, 0, 1), new BHSDCodec(5, 128, 1, 1),
+			new BHSDCodec(5, 128, 2, 1), new BHSDCodec(2, 192),
+			new BHSDCodec(2, 224), new BHSDCodec(2, 240), new BHSDCodec(2, 248),
+			new BHSDCodec(2, 252), new BHSDCodec(2, 8, 0, 1), new BHSDCodec(2, 8, 1, 1),
+			new BHSDCodec(2, 16, 0, 1), new BHSDCodec(2, 16, 1, 1),
+			new BHSDCodec(2, 32, 0, 1), new BHSDCodec(2, 32, 1, 1),
+			new BHSDCodec(2, 64, 0, 1), new BHSDCodec(2, 64, 1, 1),
+			new BHSDCodec(2, 128, 0, 1), new BHSDCodec(2, 128, 1, 1),
+			new BHSDCodec(2, 192, 0, 1), new BHSDCodec(2, 192, 1, 1),
+			new BHSDCodec(2, 224, 0, 1), new BHSDCodec(2, 224, 1, 1),
+			new BHSDCodec(2, 240, 0, 1), new BHSDCodec(2, 240, 1, 1),
+			new BHSDCodec(2, 248, 0, 1), new BHSDCodec(2, 248, 1, 1),
+			new BHSDCodec(3, 192), new BHSDCodec(3, 224), new BHSDCodec(3, 240),
+			new BHSDCodec(3, 248), new BHSDCodec(3, 252), new BHSDCodec(3, 8, 0, 1),
+			new BHSDCodec(3, 8, 1, 1), new BHSDCodec(3, 16, 0, 1),
+			new BHSDCodec(3, 16, 1, 1), new BHSDCodec(3, 32, 0, 1),
+			new BHSDCodec(3, 32, 1, 1), new BHSDCodec(3, 64, 0, 1),
+			new BHSDCodec(3, 64, 1, 1), new BHSDCodec(3, 128, 0, 1),
+			new BHSDCodec(3, 128, 1, 1), new BHSDCodec(3, 192, 0, 1),
+			new BHSDCodec(3, 192, 1, 1), new BHSDCodec(3, 224, 0, 1),
+			new BHSDCodec(3, 224, 1, 1), new BHSDCodec(3, 240, 0, 1),
+			new BHSDCodec(3, 240, 1, 1), new BHSDCodec(3, 248, 0, 1),
+			new BHSDCodec(3, 248, 1, 1), new BHSDCodec(4, 192),
+			new BHSDCodec(4, 224), new BHSDCodec(4, 240), new BHSDCodec(4, 248),
+			new BHSDCodec(4, 252), new BHSDCodec(4, 8, 0, 1), new BHSDCodec(4, 8, 1, 1),
+			new BHSDCodec(4, 16, 0, 1), new BHSDCodec(4, 16, 1, 1),
+			new BHSDCodec(4, 32, 0, 1), new BHSDCodec(4, 32, 1, 1),
+			new BHSDCodec(4, 64, 0, 1), new BHSDCodec(4, 64, 1, 1),
+			new BHSDCodec(4, 128, 0, 1), new BHSDCodec(4, 128, 1, 1),
+			new BHSDCodec(4, 192, 0, 1), new BHSDCodec(4, 192, 1, 1),
+			new BHSDCodec(4, 224, 0, 1), new BHSDCodec(4, 224, 1, 1),
+			new BHSDCodec(4, 240, 0, 1), new BHSDCodec(4, 240, 1, 1),
+			new BHSDCodec(4, 248, 0, 1), new BHSDCodec(4, 248, 1, 1) };
+
+	/** 
+	 * Returns the codec specified by the given value byte and optional byte header.
+	 * If the value is >=116, then bytes may be consumed from the secondary input
+	 * stream, which is taken to be the contents of the band_headers byte array.
+	 * Since the values from this are consumed and not repeated, the input stream
+	 * should be reused for subsequent encodings. This does not therefore close
+	 * the input stream.
+	 * @param value the canonical encoding value
+	 * @param in the input stream to read additional byte headers from
+	 * @param defaultCodec TODO
+	 * @return the corresponding codec, or <code>null</code> if the default should be used
+	 * @throws IOException 
+	 * @throws IOException if there is a problem reading from the input stream (which
+	 * in reality, is never, since the band_headers are likely stored in a byte array
+	 * and accessed via a ByteArrayInputStream. However, an EOFException could occur
+	 * if things go titsup.com.
+	 * @throws Pack200Exception 
+	 */
+	public static Codec getCodec(int value, InputStream in, Codec defaultCodec) throws IOException, Pack200Exception {
+		// Sanity check to make sure that no-one's been buggering with
+		// the canonical codecs, which would really cause havoc
+		if (canonicalCodec.length != 116) 
+			throw new Error("Canonical encodings have been incorrectly modified");
+		if (value < 0) {
+			throw new IllegalArgumentException(
+					"Encoding cannot be less than zero");
+		} else if (value == 0) {
+			return defaultCodec;
+		} else if (value <= 115) {
+			return canonicalCodec[value];
+		} else if (value == 116) {
+			int code = in.read();
+			if (code == -1)
+				throw new EOFException("End of buffer read whilst trying to decode codec");
+			int d = (code & 0x01);
+			int s = (code >> 1 & 0x03);
+			int b = (code >> 3 & 0x07) + 1; // this might result in an invalid number, but it's checked in the Codec constructor
+			code = in.read();
+			if (code == -1)
+				throw new EOFException("End of buffer read whilst trying to decode codec");
+			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) {
+			int offset = value - 117;
+			int kx = offset & 3;
+			boolean kbflag = (offset >> 2 & 1) == 1;
+			boolean adef = (offset >> 3 & 1) == 1;
+			boolean bdef = (offset >> 4 & 1) == 1;
+			// If both A and B use the default encoding, what's the point of having a run of default values followed by default values
+			if (adef && bdef)
+				throw new Pack200Exception("ADef and BDef should never both be true");
+			int kb = (kbflag ? in.read() : 3);
+			int k = (kb+1) * (int)Math.pow(16, kx);
+			Codec aCodec, bCodec;
+			if (adef) {
+				aCodec = defaultCodec;
+			} else {
+				aCodec = getCodec(in.read(),in,defaultCodec); 
+			}
+			if (bdef) {
+				bCodec = defaultCodec;
+			} else {
+				bCodec = getCodec(in.read(),in,defaultCodec); 
+			}
+			return new RunCodec(k,aCodec,bCodec);
+		} else if (value >= 141 && value <= 188) {
+			int offset = value - 141;
+			boolean fdef = (offset & 1) == 1; 
+			boolean udef = (offset >> 1 & 1) == 1;
+			int tdefl = offset >> 2;
+			boolean tdef = tdefl == 0;
+			// From section 6.7.3 of spec
+			final int[] tdefToL= {0,4,8,16,32,64,128,192,224,240,248,252 };
+			int l = tdefToL[tdefl];
+			// NOTE: Do not re-factor this to bring out uCodec; the order in which
+			// they are read from the stream is important
+			if (tdef) {
+				Codec fCodec = (fdef ? defaultCodec : getCodec(in.read(),in,defaultCodec) );
+				Codec uCodec = (udef ? defaultCodec : getCodec(in.read(),in,defaultCodec) );
+				// Unfortunately, if tdef, then tCodec depends both on l and also on k, the
+				// number of items read from the fCodec. So we don't know in advance what
+				// the codec will be.
+				return new PopulationCodec(fCodec,l,uCodec);
+			} else {
+				Codec fCodec = (fdef ? defaultCodec : 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);
+			}
+		} else {
+			throw new Pack200Exception("Invalid codec encoding byte (" + value + ") found" );
+		}
+	}
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/PopulationCodec.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/PopulationCodec.java?rev=430314&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/PopulationCodec.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/PopulationCodec.java Thu Aug 10 01:46:28 2006
@@ -0,0 +1,107 @@
+/*
+ *  Copyright 2006 The Apache Software Foundation or its licensors, 
+ *  as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.harmony.archive.internal.pack200;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+public class PopulationCodec extends Codec {
+	private Codec favouredCodec;
+	private Codec tokenCodec;
+	private Codec unvafouredCodec;
+	private int l;
+	
+	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;
+	}
+
+	@Override
+	public long decode(InputStream in) throws IOException, Pack200Exception {
+		throw new Pack200Exception("Population encoding does not work unless the number of elements are known");
+	}
+
+	@Override
+	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");
+	}
+
+	@Override
+	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
+		long result[];
+		// read table of favourites 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 favourites
+		result = tokenCodec.decode(n, in);
+		// read unfavourites
+		last = 0;
+		for(int i=0;i<n;i++) {
+			int index = (int) result[i];
+			if (index == 0) {
+				result[i] = unvafouredCodec.decode(in, last);
+			} else {
+				result[i] = favoured[index-1];
+			}
+		}
+		return result;
+	}	
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/RunCodec.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/RunCodec.java?rev=430314&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/RunCodec.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/RunCodec.java Thu Aug 10 01:46:28 2006
@@ -0,0 +1,63 @@
+/*
+ *  Copyright 2006 The Apache Software Foundation or its licensors, 
+ *  as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.harmony.archive.internal.pack200;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A run codec is a grouping of two nested codecs; K values are decoded from
+ * the first codec, and the remaining codes are decoded from the remaining
+ * codec. Note that since this codec maintains state, the instances are
+ * not reusable.
+ *
+ * @author Alex Blewitt
+ * @version $Revision: $
+ */
+public class RunCodec extends Codec {
+	private int k;
+	private Codec aCodec;
+	private Codec bCodec;
+	private long last;
+
+	public RunCodec(int k, Codec aCodec, Codec bCodec) throws Pack200Exception {
+		if (k <= 0)
+			throw new Pack200Exception("Cannot have a RunCodec for a negative number of numbers");
+		if (aCodec == null || bCodec == null)
+			throw new Pack200Exception("Must supply both codecs for a RunCodec");
+		this.k = k;
+		this.aCodec = aCodec;
+		this.bCodec = bCodec;
+	}
+	public long decode(InputStream in) throws IOException, Pack200Exception {
+		return decode(in,this.last);
+	}
+
+	public long decode(InputStream in, long last) throws IOException, Pack200Exception {
+		if(--k>=0) {
+			long value = aCodec.decode(in,last);
+			this.last = (k == 0 ? 0 : value);
+			return value;
+		} else {
+			this.last = bCodec.decode(in,last);
+			return this.last;			
+		}
+	}
+	public String toString() {
+		return "RunCodec[k="+k+";aCodec="+aCodec+"bCodec="+bCodec+"]";
+	}
+}

Modified: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java?rev=430314&r1=430313&r2=430314&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java Thu Aug 10 01:46:28 2006
@@ -211,6 +211,30 @@
 
 	private int segmentsRemaining;
 
+	private String[] icThisClass;
+
+	private int[] icFlags;
+
+	private String[] icOuterClass;
+
+	private Object icName;
+
+	private String[] classThis;
+
+	private String[] classSuper;
+
+	private String[][] classInterfaces;
+
+	private int[] classFieldCount;
+
+	private int[] classMethodCount;
+
+	private String[][] fieldDescr;
+
+	private long[][] fieldFlags;
+
+	private int fieldAttrCount;
+
 	public long getArchiveModtime() {
 		return archiveModtime;
 	}
@@ -283,8 +307,76 @@
 		System.err.println("Not yet implemented");
 	}
 
-	private void parseClassBands(InputStream in) {
-		System.err.println("Not yet implemented");
+	private void parseClassBands(InputStream in) throws IOException,
+			Pack200Exception {
+		classThis = parseReferences(in, Codec.DELTA5, classCount, cpClass);
+		classSuper = parseReferences(in, Codec.DELTA5, classCount, cpClass);
+		classInterfaces = new String[classCount][];
+		int[] classInterfaceLengths = new int[classCount];
+		long last = 0;
+		for (int i = 0; i < classCount; i++) {
+			classInterfaceLengths[i] = (int) (last = Codec.DELTA5.decode(in,
+					last));
+		}
+		for (int i = 0; i < classCount; i++) {
+			classInterfaces[i] = parseReferences(in, Codec.DELTA5,
+					classInterfaceLengths[i], cpClass);
+		}
+		classFieldCount = new int[classCount];
+		last = 0;
+		for (int i = 0; i < classCount; i++) {
+			classFieldCount[i] = (int) (last = Codec.DELTA5.decode(in, last));
+		}
+		classMethodCount = new int[classCount];
+		last = 0;
+		for (int i = 0; i < classCount; i++) {
+			classMethodCount[i] = (int) (last = Codec.DELTA5.decode(in, last));
+		}
+		parseFieldBands(in);
+		parseMethodBands(in);
+		parseClassAttrBands(in);
+		parseCodeBands(in);
+	}
+
+	private void parseCodeBands(InputStream in) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	private void parseClassAttrBands(InputStream in) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	private void parseMethodBands(InputStream in) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	private void parseFieldBands(InputStream in) throws IOException,
+			Pack200Exception {
+		long last;
+		fieldDescr = new String[classCount][];
+		last = 0;
+		for (int i = 0; i < classCount; i++) {
+			fieldDescr[i] = parseReferences(in, Codec.DELTA5,
+					classFieldCount[i], cpClass);
+		}
+		fieldFlags = new long[classCount][];
+		for (int i = 0; i < classCount; i++) {
+			fieldFlags[i] = parseFlags(in, classFieldCount[i], Codec.UNSIGNED5,
+					options.hasFieldFlagsHi());
+		}
+		for (int i = 0; i < classCount; i++) {
+			for (int j = 0; i < fieldFlags[i].length; j++) {
+				long flag = fieldFlags[i][j];
+				if ((flag & (1 << 16)) != 0)
+					fieldAttrCount++;
+			}
+		}
+		if (fieldAttrCount > 0)
+			throw new Error("There are attribute flags, and I don't know what to do with them");
+		// TODO if we have fieldAttrcount then we ought to do other parsing
 	}
 
 	private void parseClassCounts(InputStream in) throws IOException,
@@ -436,16 +528,32 @@
 
 	private void parseCpLong(InputStream in) throws IOException,
 			Pack200Exception {
-		cpLong = new long[cpLongCount];
+		cpLong = parseFlags(in, cpLongCount, Codec.UDELTA5, Codec.DELTA5);
+	}
+
+	private long[] parseFlags(InputStream in, int count, Codec codec,
+			boolean hasHi) throws IOException, Pack200Exception {
+		return parseFlags(in, count, (hasHi ? codec : null), codec);
+	}
+
+	private long[] parseFlags(InputStream in, int count, Codec codec)
+			throws IOException, Pack200Exception {
+		return parseFlags(in, count, codec, true);
+	}
+
+	private long[] parseFlags(InputStream in, int count, Codec hiCodec,
+			Codec loCodec) throws IOException, Pack200Exception {
+		long[] result = new long[count];
 		long last = 0;
-		for (int i = 0; i < cpLongCount; i++) {
-			last = Codec.UDELTA5.decode(in, last);
-			cpLong[i] = last << 32;
+		for (int i = 0; i < count && hiCodec != null; i++) {
+			last = hiCodec.decode(in, last);
+			result[i] = last << 32;
 		}
-		for (int i = 0; i < cpLongCount; i++) {
-			last = Codec.DELTA5.decode(in, last);
-			cpLong[i] = cpLong[i] | last;
+		for (int i = 0; i < count; i++) {
+			last = loCodec.decode(in, last);
+			result[i] = result[i] | last;
 		}
+		return result;
 	}
 
 	/**
@@ -648,8 +756,20 @@
 		}
 	}
 
-	private void parseIcBands(InputStream in) {
-		System.err.println("Not yet implemented");
+	private void parseIcBands(InputStream in) throws IOException,
+			Pack200Exception {
+		icThisClass = parseReferences(in, Codec.UDELTA5, innerClassCount,
+				cpClass);
+		icFlags = new int[innerClassCount];
+		long last = 0;
+		int outerClasses = 0;
+		for (int i = 0; i < innerClassCount; i++) {
+			icFlags[i] = (int) (last = Codec.UNSIGNED5.decode(in, last));
+			if ((icFlags[i] & 1 << 16) != 0)
+				outerClasses++;
+		}
+		icOuterClass = parseReferences(in, Codec.DELTA5, outerClasses, cpClass);
+		icName = parseReferences(in, Codec.DELTA5, outerClasses, cpUTF8);
 	}
 
 	/**
@@ -721,12 +841,13 @@
 		parseCpMethod(in);
 		parseCpIMethod(in);
 		parseAttributeDefinition(in);
-		parseIcBands(in); // Not yet implemented
+		parseIcBands(in);
 		parseClassBands(in); // Not yet implemented
 		parseBcBands(in); // Not yet implemented
-		parseFileBands(in);
-		processFileBits(in); // this just caches them in file_bits; it should
-								// probably start writing here?
+		// TODO Re-enable these after completing class/bytecode bands
+		// parseFileBands(in);
+		// processFileBits(in); // this just caches them in file_bits; it should
+		// probably start writing here?
 	}
 
 	private void parseSegmentHeader(InputStream in) throws IOException,

Added: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/AllTests.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/AllTests.java?rev=430314&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/AllTests.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/AllTests.java Thu Aug 10 01:46:28 2006
@@ -0,0 +1,42 @@
+/* Copyright 2004 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.archive.tests.internal.pack200;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite for org.apache.harmony.archive.internal.pack200 package.
+ */
+public class AllTests {
+
+	public static void main(String[] args) {
+		junit.textui.TestRunner.run(suite());
+	}
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(
+                "Suite org.apache.harmony.archive.tests.internal.pack200");
+		// $JUnit-BEGIN$
+		suite.addTestSuite(CodecEncodingTest.class);
+		suite.addTestSuite(CodecTest.class);
+		suite.addTestSuite(PopulationCodecTest.class);
+		suite.addTestSuite(SegmentOptionsTest.class);
+		suite.addTestSuite(SegmentTest.class);
+		// $JUnit-END$
+		return suite;
+	}
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/CodecEncodingTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/CodecEncodingTest.java?rev=430314&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/CodecEncodingTest.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/CodecEncodingTest.java Thu Aug 10 01:46:28 2006
@@ -0,0 +1,165 @@
+/*
+ *  Copyright 2006 The Apache Software Foundation or its licensors, 
+ *  as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.harmony.archive.tests.internal.pack200;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.archive.internal.pack200.BHSDCodec;
+import org.apache.harmony.archive.internal.pack200.Codec;
+import org.apache.harmony.archive.internal.pack200.CodecEncoding;
+import org.apache.harmony.archive.internal.pack200.Pack200Exception;
+
+/**
+ * @author Alex Blewitt
+ * @version $Revision: $
+ */
+public class CodecEncodingTest extends TestCase {
+	public void testCanonicalEncodings() throws IOException, Pack200Exception { 
+		Codec defaultCodec = new BHSDCodec(2,16,0,0);
+		assertEquals(defaultCodec,CodecEncoding.getCodec(0,null, defaultCodec));
+		Map map = new HashMap();
+		// These are the canonical encodings specified by the Pack200 spec
+		map.put(new Integer(1), "(1,256)");
+		map.put(new Integer(2), "(1,256,1)");
+		map.put(new Integer(3), "(1,256,0,1)");
+		map.put(new Integer(4), "(1,256,1,1)");
+		map.put(new Integer(5), "(2,256)");
+		map.put(new Integer(6), "(2,256,1)");
+		map.put(new Integer(7), "(2,256,0,1)");
+		map.put(new Integer(8), "(2,256,1,1)");
+		map.put(new Integer(9), "(3,256)");
+		map.put(new Integer(10), "(3,256,1)");
+		map.put(new Integer(11), "(3,256,0,1)");
+		map.put(new Integer(12), "(3,256,1,1)");
+		map.put(new Integer(13), "(4,256)");
+		map.put(new Integer(14), "(4,256,1)");
+		map.put(new Integer(15), "(4,256,0,1)");
+		map.put(new Integer(16), "(4,256,1,1)");
+		map.put(new Integer(17), "(5,4)");
+		map.put(new Integer(18), "(5,4,1)");
+		map.put(new Integer(19), "(5,4,2)");
+		map.put(new Integer(20), "(5,16)");
+		map.put(new Integer(21), "(5,16,1)");
+		map.put(new Integer(22), "(5,16,2)");
+		map.put(new Integer(23), "(5,32)");
+		map.put(new Integer(24), "(5,32,1)");
+		map.put(new Integer(25), "(5,32,2)");
+		map.put(new Integer(26), "(5,64)");
+		map.put(new Integer(27), "(5,64,1)");
+		map.put(new Integer(28), "(5,64,2)");
+		map.put(new Integer(29), "(5,128)");
+		map.put(new Integer(30), "(5,128,1)");
+		map.put(new Integer(31), "(5,128,2)");
+		map.put(new Integer(32), "(5,4,0,1)");
+		map.put(new Integer(33), "(5,4,1,1)");
+		map.put(new Integer(34), "(5,4,2,1)");
+		map.put(new Integer(35), "(5,16,0,1)");
+		map.put(new Integer(36), "(5,16,1,1)");
+		map.put(new Integer(37), "(5,16,2,1)");
+		map.put(new Integer(38), "(5,32,0,1)");
+		map.put(new Integer(39), "(5,32,1,1)");
+		map.put(new Integer(40), "(5,32,2,1)");
+		map.put(new Integer(41), "(5,64,0,1)");
+		map.put(new Integer(42), "(5,64,1,1)");
+		map.put(new Integer(43), "(5,64,2,1)");
+		map.put(new Integer(44), "(5,128,0,1)");
+		map.put(new Integer(45), "(5,128,1,1)");
+		map.put(new Integer(46), "(5,128,2,1)");
+		map.put(new Integer(47), "(2,192)");
+		map.put(new Integer(48), "(2,224)");
+		map.put(new Integer(49), "(2,240)");
+		map.put(new Integer(50), "(2,248)");
+		map.put(new Integer(51), "(2,252)");
+		map.put(new Integer(52), "(2,8,0,1)");
+		map.put(new Integer(53), "(2,8,1,1)");
+		map.put(new Integer(54), "(2,16,0,1)");
+		map.put(new Integer(55), "(2,16,1,1)");
+		map.put(new Integer(56), "(2,32,0,1)");
+		map.put(new Integer(57), "(2,32,1,1)");
+		map.put(new Integer(58), "(2,64,0,1)");
+		map.put(new Integer(59), "(2,64,1,1)");
+		map.put(new Integer(60), "(2,128,0,1)");
+		map.put(new Integer(61), "(2,128,1,1)");
+		map.put(new Integer(62), "(2,192,0,1)");
+		map.put(new Integer(63), "(2,192,1,1)");
+		map.put(new Integer(64), "(2,224,0,1)");
+		map.put(new Integer(65), "(2,224,1,1)");
+		map.put(new Integer(66), "(2,240,0,1)");
+		map.put(new Integer(67), "(2,240,1,1)");
+		map.put(new Integer(68), "(2,248,0,1)");
+		map.put(new Integer(69), "(2,248,1,1)");
+		map.put(new Integer(70), "(3,192)");
+		map.put(new Integer(71), "(3,224)");
+		map.put(new Integer(72), "(3,240)");
+		map.put(new Integer(73), "(3,248)");
+		map.put(new Integer(74), "(3,252)");
+		map.put(new Integer(75), "(3,8,0,1)");
+		map.put(new Integer(76), "(3,8,1,1)");
+		map.put(new Integer(77), "(3,16,0,1)");
+		map.put(new Integer(78), "(3,16,1,1)");
+		map.put(new Integer(79), "(3,32,0,1)");
+		map.put(new Integer(80), "(3,32,1,1)");
+		map.put(new Integer(81), "(3,64,0,1)");
+		map.put(new Integer(82), "(3,64,1,1)");
+		map.put(new Integer(83), "(3,128,0,1)");
+		map.put(new Integer(84), "(3,128,1,1)");
+		map.put(new Integer(85), "(3,192,0,1)");
+		map.put(new Integer(86), "(3,192,1,1)");
+		map.put(new Integer(87), "(3,224,0,1)");
+		map.put(new Integer(88), "(3,224,1,1)");
+		map.put(new Integer(89), "(3,240,0,1)");
+		map.put(new Integer(90), "(3,240,1,1)");
+		map.put(new Integer(91), "(3,248,0,1)");
+		map.put(new Integer(92), "(3,248,1,1)");
+		map.put(new Integer(93), "(4,192)");
+		map.put(new Integer(94), "(4,224)");
+		map.put(new Integer(95), "(4,240)");
+		map.put(new Integer(96), "(4,248)");
+		map.put(new Integer(97), "(4,252)");
+		map.put(new Integer(98), "(4,8,0,1)");
+		map.put(new Integer(99), "(4,8,1,1)");
+		map.put(new Integer(100), "(4,16,0,1)");
+		map.put(new Integer(101), "(4,16,1,1)");
+		map.put(new Integer(102), "(4,32,0,1)");
+		map.put(new Integer(103), "(4,32,1,1)");
+		map.put(new Integer(104), "(4,64,0,1)");
+		map.put(new Integer(105), "(4,64,1,1)");
+		map.put(new Integer(106), "(4,128,0,1)");
+		map.put(new Integer(107), "(4,128,1,1)");
+		map.put(new Integer(108), "(4,192,0,1)");
+		map.put(new Integer(109), "(4,192,1,1)");
+		map.put(new Integer(110), "(4,224,0,1)");
+		map.put(new Integer(111), "(4,224,1,1)");
+		map.put(new Integer(112), "(4,240,0,1)");
+		map.put(new Integer(113), "(4,240,1,1)");
+		map.put(new Integer(114), "(4,248,0,1)");
+		map.put(new Integer(115), "(4,248,1,1)");
+		for(int i=1;i<=115;i++) {
+			assertEquals(map.get(new Integer(i)),CodecEncoding.getCodec(i,null, null).toString());
+		}
+	}
+	public void testArbitraryCodec() throws IOException, Pack200Exception {
+		assertEquals("(1,256)",CodecEncoding.getCodec(116,new ByteArrayInputStream(new byte[] { 0x00, (byte)0xFF}), null).toString());
+		assertEquals("(5,128,2,1)",CodecEncoding.getCodec(116,new ByteArrayInputStream(new byte[] { 0x25, (byte)0x7F}), null).toString());
+		assertEquals("(2,128,1,1)",CodecEncoding.getCodec(116,new ByteArrayInputStream(new byte[] { 0x0B, (byte)0x7F}), null).toString());
+	}
+}

Modified: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/CodecTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/CodecTest.java?rev=430314&r1=430313&r2=430314&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/CodecTest.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/CodecTest.java Thu Aug 10 01:46:28 2006
@@ -22,8 +22,10 @@
 
 import junit.framework.TestCase;
 
+import org.apache.harmony.archive.internal.pack200.BHSDCodec;
 import org.apache.harmony.archive.internal.pack200.Codec;
 import org.apache.harmony.archive.internal.pack200.Pack200Exception;
+import org.apache.harmony.archive.internal.pack200.RunCodec;
 
 
 /**
@@ -35,7 +37,7 @@
 	public void testInvalidCodings() {
 		for (int i = 0; i < 256; i++) {
 			try {
-				new Codec(1, i);
+				new BHSDCodec(1, i);
 				fail("b=1 -> h=256");
 			} catch (IllegalArgumentException e) {
 				assertTrue(true);
@@ -43,7 +45,7 @@
 		}
 		for (int i = 1; i <= 5; i++) {
 			try {
-				new Codec(i, 256);
+				new BHSDCodec(i, 256);
 				if (i == 5)
 					fail("h=256 -> b!=5");
 			} catch (IllegalArgumentException e) {
@@ -75,14 +77,13 @@
 	}
 
 	public void testByte1Delta() throws Exception {
-		Codec BYTE1D = new Codec(1, 256, 0, 1);
+		Codec BYTE1D = new BHSDCodec(1, 256, 0, 1);
 		long last = 0;
 		for (int i = 1; i < 255; i++)
 			last = decode(BYTE1D, new byte[] { (byte) 1 }, i, last);
 	}
-
 	public void testByte1DeltaException() throws Exception {
-		Codec BYTE1D = new Codec(1, 256, 0, 1);
+		Codec BYTE1D = new BHSDCodec(1, 256, 0, 1);
 		try {
 			BYTE1D.decode(new ByteArrayInputStream(new byte[] { (byte) 1 }));
 			fail("Decoding with a delta stream and not passing a last value should throw exception");
@@ -90,7 +91,92 @@
 			assertTrue(true);
 		}
 	}
+	public void testByte1Signed() throws Exception {
+		Codec BYTE1S2 = new BHSDCodec(1,256,2);
+		decode(BYTE1S2,new byte[] { 0 }, 0, 0);
+		decode(BYTE1S2,new byte[] { 1 }, 1, 0);
+		decode(BYTE1S2,new byte[] { 2 }, 2, 0);
+		decode(BYTE1S2,new byte[] { 3 }, -1, 0);
+		decode(BYTE1S2,new byte[] { 4 }, 3, 0);
+		decode(BYTE1S2,new byte[] { 5 }, 4, 0);
+		decode(BYTE1S2,new byte[] { 6 }, 5, 0);
+		decode(BYTE1S2,new byte[] { 7 }, -2, 0);
+		decode(BYTE1S2,new byte[] { 8 }, 6, 0);
+		decode(BYTE1S2,new byte[] { 9 }, 7, 0);
+		decode(BYTE1S2,new byte[] { 10 }, 8, 0);
+		decode(BYTE1S2,new byte[] { 11 }, -3, 0);
+	}
+	public void testCardinality() throws Exception {
+		BHSDCodec byte1 = (BHSDCodec) Codec.BYTE1;
+		assertEquals(256,byte1.cardinality());
+		assertEquals(0,byte1.smallest());
+		assertEquals(255,byte1.largest());
+		assertFalse(byte1.encodes(-257));
+		assertFalse(byte1.encodes(-256));
+		assertFalse(byte1.encodes(-255));
+		assertFalse(byte1.encodes(-129));
+		assertFalse(byte1.encodes(-128));
+		assertFalse(byte1.encodes(-127));
+		assertFalse(byte1.encodes(-1));
+		assertTrue(byte1.encodes(0));
+		assertTrue(byte1.encodes(1));
+		assertTrue(byte1.encodes(255));
+		assertFalse(byte1.encodes(256));
+		BHSDCodec byte1s = new BHSDCodec(1,256,1);
+		assertEquals(256,byte1s.cardinality());
+		assertEquals(-128,byte1s.smallest());
+		assertEquals(127,byte1s.largest());
+		assertFalse(byte1s.encodes(-257));
+		assertFalse(byte1s.encodes(-256));
+		assertFalse(byte1s.encodes(-255));
+		assertFalse(byte1s.encodes(-129));
+		assertTrue(byte1s.encodes(-128));
+		assertTrue(byte1s.encodes(-127));
+		assertTrue(byte1s.encodes(-1));
+		assertTrue(byte1s.encodes(0));
+		assertTrue(byte1s.encodes(1));
+		assertTrue(byte1s.encodes(127));
+		assertFalse(byte1s.encodes(128));
+		assertFalse(byte1s.encodes(129));
+		assertFalse(byte1s.encodes(255));
+		assertFalse(byte1s.encodes(256));
+		BHSDCodec byte2s = new BHSDCodec(1,256,2);
+		assertEquals(256,byte2s.cardinality());
+		assertEquals(-64,byte2s.smallest());
+		assertEquals(191,byte2s.largest());
+		assertFalse(byte2s.encodes(-257));
+		assertFalse(byte2s.encodes(-256));
+		assertFalse(byte2s.encodes(-255));
+		assertFalse(byte2s.encodes(-129));
+		assertFalse(byte2s.encodes(-128));
+		assertFalse(byte2s.encodes(-127));
+		assertFalse(byte2s.encodes(-65));
+		assertTrue(byte2s.encodes(-64));
+		assertTrue(byte2s.encodes(-64));
+		assertTrue(byte2s.encodes(-1));
+		assertTrue(byte2s.encodes(0));
+		assertTrue(byte2s.encodes(1));
+		assertTrue(byte2s.encodes(127));
+		assertTrue(byte2s.encodes(128));
+		assertTrue(byte2s.encodes(191));
+		assertFalse(byte2s.encodes(192));
+		assertFalse(byte2s.encodes(256));		
+	}
 
+	public void testRunCodec() throws Exception {
+		RunCodec runCodec = new RunCodec(1,Codec.UNSIGNED5,Codec.BYTE1);
+		ByteArrayInputStream bais = new ByteArrayInputStream(new byte[]{ (byte) 192,0,(byte) 192,0});
+		assertEquals(192,runCodec.decode(bais));
+		assertEquals(192,runCodec.decode(bais));
+		assertEquals(0,runCodec.decode(bais));
+		assertEquals(0,bais.available());
+		runCodec = new RunCodec(1,Codec.BYTE1,Codec.UNSIGNED5);
+		bais = new ByteArrayInputStream(new byte[]{ (byte) 192,0,(byte) 192,0});
+		assertEquals(192,runCodec.decode(bais));
+		assertEquals(0,runCodec.decode(bais));
+		assertEquals(192,runCodec.decode(bais));
+		assertEquals(0,bais.available());
+	}
 	public void testUnsigned5() throws Exception {
 		decode(Codec.UNSIGNED5, new byte[] { 1 }, 1, 0);
 		decode(Codec.UNSIGNED5, new byte[] { (byte) 191 }, 191, 0);

Added: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/PopulationCodecTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/PopulationCodecTest.java?rev=430314&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/PopulationCodecTest.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/PopulationCodecTest.java Thu Aug 10 01:46:28 2006
@@ -0,0 +1,57 @@
+/*
+ *  Copyright 2006 The Apache Software Foundation or its licensors, 
+ *  as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.harmony.archive.tests.internal.pack200;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.archive.internal.pack200.BHSDCodec;
+import org.apache.harmony.archive.internal.pack200.Codec;
+import org.apache.harmony.archive.internal.pack200.Pack200Exception;
+import org.apache.harmony.archive.internal.pack200.PopulationCodec;
+
+public class PopulationCodecTest extends TestCase {
+	public void testPopulationCodec() throws IOException, Pack200Exception {
+		checkDecode(new byte[] { 4,5,6,4,2,1,3,0,7 }, new long[]{ 5,4,6,7 }, Codec.BYTE1);
+		// Codec.SIGNED5 can be trivial for small n, because the encoding is 2n if even, 2n-1 if odd
+		// Therefore they're left here to explain what the values are :-)
+		checkDecode(new byte[] { 4*2,4*2-1,6*2,4*2,2*2,1*2,3*2,0,7*2 }, new long[]{ -4,4,6,7 }, Codec.SIGNED5);
+		checkDecode(new byte[] { 4*2-1,4*2,6*2,4*2,2*2,1*2,3*2,0,7*2 }, new long[]{ 4,-4,6,7 }, Codec.SIGNED5);
+		checkDecode(new byte[] { 1,1,1 }, new long[]{ 1 }, Codec.BYTE1);
+		checkDecode(new byte[] { 2,2,1 }, new long[]{ 2 }, Codec.BYTE1);
+		checkDecode(new byte[] { 1,1,2 }, new long[]{ -1 }, Codec.SIGNED5);
+		checkDecode(new byte[] { 2,2,0,1,3 }, new long[]{ 3,2 }, Codec.BYTE1);
+		checkDecode(new byte[] { 1,2,3,4,4,2,3,4,0,1 }, new long[]{ 2,3,4,1 }, Codec.BYTE1);
+		checkDecode(new byte[] { 3,2,1,4,4,2,3,4,0,1 }, new long[]{ 2,1,4,1 }, Codec.BYTE1);
+		checkDecode(new byte[] { 3,2,1,4,1,2,3,4,0,1 }, new long[]{ 2,1,4,1 }, Codec.BYTE1);
+	}
+
+	private void checkDecode(byte[] data, long[] expectedResult, Codec codec) throws IOException, Pack200Exception {
+		InputStream in = new ByteArrayInputStream(data );
+		
+		long[] result = new PopulationCodec(codec,codec,codec).decode(expectedResult.length,in);
+		assertEquals(expectedResult.length,result.length);
+		for(int i=0;i<expectedResult.length;i++) {
+			assertEquals(expectedResult[i],result[i]);
+		}
+		assertEquals(0,in.available());
+	}
+
+}

Modified: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/SegmentTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/SegmentTest.java?rev=430314&r1=430313&r2=430314&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/SegmentTest.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/java/org/apache/harmony/archive/tests/internal/pack200/SegmentTest.java Thu Aug 10 01:46:28 2006
@@ -33,5 +33,13 @@
 		assertNotNull(Segment.parse(Segment.class
 				.getResourceAsStream("/org/apache/harmony/archive/tests/internal/pack200/HelloWorld.pack")));
 	}
+	/**
+	 * @param args
+	 * @throws Exception
+	 */
+	public void testJustResources() throws Exception {
+		assertNotNull(Segment.parse(Segment.class
+				.getResourceAsStream("/org/apache/harmony/archive/tests/internal/pack200/JustResources.pack")));
+	}
 
 }

Added: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/resources/org/apache/harmony/archive/tests/internal/pack200/JustResources.pack
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/resources/org/apache/harmony/archive/tests/internal/pack200/JustResources.pack?rev=430314&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/resources/org/apache/harmony/archive/tests/internal/pack200/JustResources.pack
------------------------------------------------------------------------------
    svn:executable = *

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/test/resources/org/apache/harmony/archive/tests/internal/pack200/JustResources.pack
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream