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
* < 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