harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ton...@apache.org
Subject svn commit: r646264 [7/13] - in /harmony/enhanced/classlib/branches/java6: depends/build/ depends/build/platform/ depends/files/ modules/accessibility/ modules/annotation/ modules/applet/ modules/archive/ modules/archive/src/main/java/java/util/jar/ mo...
Date Wed, 09 Apr 2008 11:02:07 GMT
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java Wed Apr  9 04:01:14 2008
@@ -24,16 +24,12 @@
 
 import org.apache.harmony.pack200.bytecode.Attribute;
 import org.apache.harmony.pack200.bytecode.CPClass;
-import org.apache.harmony.pack200.bytecode.CPDouble;
-import org.apache.harmony.pack200.bytecode.CPFloat;
-import org.apache.harmony.pack200.bytecode.CPInteger;
-import org.apache.harmony.pack200.bytecode.CPLong;
 import org.apache.harmony.pack200.bytecode.CPNameAndType;
-import org.apache.harmony.pack200.bytecode.CPString;
 import org.apache.harmony.pack200.bytecode.CPUTF8;
 import org.apache.harmony.pack200.bytecode.ClassConstantPool;
 import org.apache.harmony.pack200.bytecode.ClassFileEntry;
 import org.apache.harmony.pack200.bytecode.ConstantValueAttribute;
+import org.apache.harmony.pack200.bytecode.DeprecatedAttribute;
 import org.apache.harmony.pack200.bytecode.EnclosingMethodAttribute;
 import org.apache.harmony.pack200.bytecode.ExceptionsAttribute;
 import org.apache.harmony.pack200.bytecode.LineNumberTableAttribute;
@@ -43,7 +39,7 @@
 import org.apache.harmony.pack200.bytecode.SourceFileAttribute;
 
 /**
- * Pack200 Class Bands
+ * Class Bands
  */
 public class ClassBands extends BandSet {
 
@@ -51,6 +47,8 @@
 
     private long[] classFlags;
 
+    private long[] classAccessFlags; // Access flags for writing to the class file
+
     private String[][] classInterfaces;
 
     private int[] classMethodCount;
@@ -81,19 +79,23 @@
 
     private long[][] fieldFlags;
 
+    private long[][] fieldAccessFlags;
+
     private ArrayList[][] methodAttributes;
 
     private String[][] methodDescr;
 
     private long[][] methodFlags;
 
-    private AttributeLayoutMap attrMap;
+    private long[][] methodAccessFlags;
+
+    private final AttributeLayoutMap attrMap;
 
-    private CpBands cpBands;
+    private final CpBands cpBands;
 
-    private SegmentOptions options;
+    private final SegmentOptions options;
 
-    private int classCount;
+    private final int classCount;
 
     private int[] methodAttrCalls;
 
@@ -220,9 +222,16 @@
             }
         }
 
+        AttributeLayout deprecatedLayout = attrMap.getAttributeLayout(
+                AttributeLayout.ATTRIBUTE_DEPRECATED,
+                AttributeLayout.CONTEXT_FIELD);
+
         for (int i = 0; i < classCount; i++) {
             for (int j = 0; j < fieldFlags[i].length; j++) {
                 long flag = fieldFlags[i][j];
+                if(deprecatedLayout.matches(flag)) {
+                    fieldAttributes[i][j].add(new DeprecatedAttribute());
+                }
                 if (constantValueLayout.matches(flag)) {
                     // we've got a value to read
                     long result = field_constantValue_KQ[constantValueIndex];
@@ -357,12 +366,19 @@
             }
         }
 
+        AttributeLayout deprecatedLayout = attrMap.getAttributeLayout(
+                AttributeLayout.ATTRIBUTE_DEPRECATED,
+                AttributeLayout.CONTEXT_METHOD);
+
         // Add attributes to the attribute arrays
         int methodExceptionsIndex = 0;
         int methodSignatureIndex = 0;
         for (int i = 0; i < methodAttributes.length; i++) {
             for (int j = 0; j < methodAttributes[i].length; j++) {
                 long flag = methodFlags[i][j];
+                if(deprecatedLayout.matches(flag)) {
+                    methodAttributes[i][j].add(new DeprecatedAttribute());
+                }
                 if (methodExceptionsLayout.matches(flag)) {
                     int n = numExceptions[methodExceptionsIndex];
                     String[] exceptions = methodExceptionsRS[methodExceptionsIndex];
@@ -451,6 +467,10 @@
         int[] classAttrCalls = decodeBandInt("class_attr_calls", in,
                 Codec.UNSIGNED5, callCount);
 
+        AttributeLayout deprecatedLayout = attrMap.getAttributeLayout(
+                AttributeLayout.ATTRIBUTE_DEPRECATED,
+                AttributeLayout.CONTEXT_CLASS);
+
         AttributeLayout sourceFileLayout = attrMap.getAttributeLayout(
                 AttributeLayout.ATTRIBUTE_SOURCE_FILE,
                 AttributeLayout.CONTEXT_CLASS);
@@ -558,7 +578,9 @@
         icLocal = new IcTuple[classCount][];
         for (int i = 0; i < classCount; i++) {
             long flag = classFlags[i];
-
+            if(deprecatedLayout.matches(classFlags[i])) {
+                classAttributes[i].add(new DeprecatedAttribute());
+            }
             if (sourceFileLayout.matches(flag)) {
                 long result = classSourceFile[sourceFileIndex];
                 String value = (String) sourceFileLayout.getValue(result,
@@ -607,25 +629,31 @@
                 // decided at the end when creating class constant pools
                 icLocal[i] = new IcTuple[classInnerClassesN[innerClassIndex]];
                 for (int j = 0; j < icLocal[i].length; j++) {
-                    IcTuple icTuple = new IcTuple();
-                    icTuple.C = cpClass[classInnerClassesRC[innerClassIndex][j]];
-                    icTuple.F = classInnerClassesF[innerClassIndex][j];
-                    if (icTuple.F != 0) {
-                        icTuple.C2 = cpClass[classInnerClassesOuterRCN[innerClassC2NIndex]];
-                        icTuple.N = cpUTF8[classInnerClassesNameRUN[innerClassC2NIndex]];
+                    String icTupleC = null;
+                    int icTupleF = -1;
+                    String icTupleC2 = null;
+                    String icTupleN = null;
+
+                    icTupleC = cpClass[classInnerClassesRC[innerClassIndex][j]];
+                    icTupleF = classInnerClassesF[innerClassIndex][j];
+                    if (icTupleF != 0) {
+                        icTupleC2 = cpClass[classInnerClassesOuterRCN[innerClassC2NIndex]];
+                        icTupleN = cpUTF8[classInnerClassesNameRUN[innerClassC2NIndex]];
                         innerClassC2NIndex++;
                     } else {
                         // Get from icBands
                         IcBands icBands = segment.getIcBands();
                         IcTuple[] icAll = icBands.getIcTuples();
                         for (int k = 0; k < icAll.length; k++) {
-                            if (icAll[k].C.equals(icTuple.C)) {
-                                icTuple.C2 = icAll[k].C2;
-                                icTuple.N = icAll[k].N;
+                            if (icAll[k].getC().equals(icTupleC)) {
+                                icTupleC2 = icAll[k].getC2();
+                                icTupleN = icAll[k].getN();
                                 break;
                             }
                         }
                     }
+
+                    IcTuple icTuple = new IcTuple(icTupleC, icTupleF, icTupleC2, icTupleN);
                     icLocal[i][j] = icTuple;
                 }
                 innerClassIndex++;
@@ -785,7 +813,7 @@
                 localVariableTableN);
         int[][] localVariableTableSpanO = decodeBandInt(
                 "code_LocalVariableTable_span_O", in, Codec.BRANCH5,
-                localVariableTableN, false);
+                localVariableTableN);
         CPUTF8[][] localVariableTableNameRU = stringsToCPUTF8(parseReferences(
                 "code_LocalVariableTable_name_RU", in, Codec.UNSIGNED5,
                 localVariableTableN, cpBands.getCpUTF8()));
@@ -1173,14 +1201,35 @@
         return numBackwardsCalls;
     }
 
+    public ArrayList[] getClassAttributes() {
+        return classAttributes;
+    }
+
     public int[] getClassFieldCount() {
         return classFieldCount;
     }
 
-    public long[] getClassFlags() {
+    public long[] getRawClassFlags() {
         return classFlags;
     }
 
+    public long[] getClassFlags() throws Pack200Exception {
+    	if(classAccessFlags == null) {
+    		long mask = 0x7FFF;
+    		for (int i = 0; i < 16; i++) {
+				AttributeLayout layout = attrMap.getAttributeLayout(i, AttributeLayout.CONTEXT_CLASS);
+				if(layout != null && !layout.isDefaultLayout()) {
+					mask &= ~(1 << i);
+				}
+			}
+    		classAccessFlags = new long[classFlags.length];
+    		for (int i = 0; i < classFlags.length; i++) {
+    				classAccessFlags[i] = classFlags[i] & mask;
+    		}
+    	}
+        return classAccessFlags;
+    }
+
     public String[][] getClassInterfaces() {
         return classInterfaces;
     }
@@ -1213,8 +1262,24 @@
         return fieldDescr;
     }
 
-    public long[][] getFieldFlags() {
-        return fieldFlags;
+    public long[][] getFieldFlags() throws Pack200Exception {
+    	if(fieldAccessFlags == null) {
+    		long mask = 0x7FFF;
+    		for (int i = 0; i < 16; i++) {
+				AttributeLayout layout = attrMap.getAttributeLayout(i, AttributeLayout.CONTEXT_FIELD);
+				if(layout != null && !layout.isDefaultLayout()) {
+					mask &= ~(1 << i);
+				}
+			}
+    		fieldAccessFlags = new long[fieldFlags.length][];
+    		for (int i = 0; i < fieldFlags.length; i++) {
+    			fieldAccessFlags[i] = new long[fieldFlags[i].length];
+				for (int j = 0; j < fieldFlags[i].length; j++) {
+					fieldAccessFlags[i][j] = fieldFlags[i][j] & mask;
+				}
+    		}
+    	}
+        return fieldAccessFlags;
     }
 
     /**
@@ -1246,8 +1311,24 @@
         return methodDescr;
     }
 
-    public long[][] getMethodFlags() {
-        return methodFlags;
+    public long[][] getMethodFlags() throws Pack200Exception {
+    	if(methodAccessFlags == null) {
+    		long mask = 0x7FFF;
+    		for (int i = 0; i < 16; i++) {
+				AttributeLayout layout = attrMap.getAttributeLayout(i, AttributeLayout.CONTEXT_METHOD);
+				if(layout != null && !layout.isDefaultLayout()) {
+					mask &= ~(1 << i);
+				}
+			}
+    		methodAccessFlags = new long[methodFlags.length][];
+    		for (int i = 0; i < methodFlags.length; i++) {
+    			methodAccessFlags[i] = new long[methodFlags[i].length];
+				for (int j = 0; j < methodFlags[i].length; j++) {
+					methodAccessFlags[i][j] = methodFlags[i][j] & mask;
+				}
+    		}
+    	}
+        return methodAccessFlags;
     }
 
     /**

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java Wed Apr  9 04:01:14 2008
@@ -20,78 +20,16 @@
 import java.io.InputStream;
 
 /**
- * A codec allows a sequence of bytes to be decoded into integer values (or vice
- * versa). It uses a variable-length encoding and a modified sign representation
- * such that small numbers are represented as a single byte, whilst larger
- * numbers take more bytes to encode. The number may be signed or unsigned; if
- * it is unsigned, it can be weighted towards positive numbers or equally
- * distributed using a one's complement. The codec also supports delta coding,
- * where a sequence of numbers is represented as a series of first-order
- * differences. So a delta encoding of the integers [1..10] would be represented
- * as a sequence of 10x1s. This allows the absolute value of a coded integer to
- * fall outside of the 'small number' range, whilst still being encoded as a
- * single byte.
+ * A Codec allows a sequence of bytes to be decoded into integer values (or vice
+ * versa).
  *
- * A codec is configured with four parameters:
- * <dl>
- * <dt>B</dt>
- * <dd>The maximum number of bytes that each value is encoded as. B must be a
- * value between [1..5]. For a pass-through coding (where each byte is encoded
- * as itself, aka {@link #BYTE1}, B is 1 (each byte takes a maximum of 1 byte).</dd>
- * <dt>H</dt>
- * <dd>The radix of the integer. Values are defined as a sequence of values,
- * where value <code>n</code> is multiplied by <code>H^<sup>n</sup></code>.
- * So the number 1234 may be represented as the sequence 4 3 2 1 with a radix
- * (H) of 10. Note that other permutations are also possible; 43 2 1 will also
- * encode 1234. The co-parameter L is defined as 256-H. This is important
- * because only the last value in a sequence may be &lt; L; all prior values
- * must be &gt; L.</dd>
- * <dt>S</dt>
- * <dd>Whether the codec represents signed values (or not). This may have 3
- * values; 0 (unsigned), 1 (signed, ones complement) or 2 (signed, but not sure
- * what the difference is) TODO Update documentation when I know what the
- * difference is</dd>
- * <dt>D</dt>
- * <dd>Whether the codec represents a delta encoding. This may be 0 (no delta)
- * or 1 (delta encoding). A delta encoding of 1 indicates that values are
- * cumulative; a sequence of <code>1 1 1 1 1</code> will represent the
- * sequence <code>1 2 3 4 5</code>. For this reason, the codec supports two
- * variants of decode; one {@link #decode(InputStream, long) with} and one
- * {@link #decode(InputStream) without} a <code>last</code> parameter. If the
- * codec is a non-delta encoding, then the value is ignored if passed. If the
- * codec is a delta encoding, it is a run-time error to call the value without
- * the extra parameter, and the previous value should be returned. (It was
- * designed this way to support multi-threaded access without requiring a new
- * instance of the Codec to be cloned for each use.)
- * <dt>
- * </dl>
- *
- * Codecs are notated as (B,H,S,D) and either D or S,D may be omitted if zero.
- * Thus {@link #BYTE1} is denoted (1,256,0,0) or (1,256). The
- * {@link #toString()} method prints out the condensed form of the encoding.
- * Often, the last character in the name ({@link #BYTE1}, {@link #UNSIGNED5})
- * gives a clue as to the B value. Those that start with U ({@link #UDELTA5},
- * {@link #UNSIGNED5}) are unsigned; otherwise, in most cases, they are signed.
- * The presence of the word Delta ({@link #DELTA5}, {@link #UDELTA5})
- * indicates a delta encoding is used.
- *
- * This codec is really quite cool for storing compressed information, and could
- * be used entirely separately from the Pack200 implementation for efficient
- * transfer of integer data if required.
- *
- * Note that all information is byte-oriented; for decoding float/double
- * information, the bit values are converted (not cast) into a long type. Note
- * that long values are used throughout even though most may be cast to ints;
- * this is primarily to avoid having to worry about signed values, even if it
- * would be more efficient to do so.
- *
- * There are a number of standard codecs ({@link #UDELTA5}, {@link #UNSIGNED5},
+ * There are a number of standard Codecs ({@link #UDELTA5}, {@link #UNSIGNED5},
  * {@link #BYTE1}, {@link #CHAR3}) that are used in the implementation of many
  * bands; but there are a variety of other ones, and indeed the specification
  * assumes that other combinations of values can result in more specific and
  * efficient formats. There are also a sequence of canonical encodings defined
- * by the Pack200 specification, which allow a codec to be referred to by
- * canonical number. {@link CodecEncoding#canonicalCodec})
+ * by the Pack200 specification, which allow a Codec to be referred to by
+ * canonical number. {@link CodecEncoding#getCodec(int, InputStream, Codec)})
  */
 public abstract class Codec {
     /**

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java Wed Apr  9 04:01:14 2008
@@ -20,6 +20,9 @@
 import java.io.IOException;
 import java.io.InputStream;
 
+/**
+ * CodecEncoding is used to get the right Codec for a given meta-encoding
+ */
 public class CodecEncoding {
 
 	/**
@@ -87,11 +90,12 @@
 	 * 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

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java Wed Apr  9 04:01:14 2008
@@ -31,6 +31,9 @@
 import org.apache.harmony.pack200.bytecode.CPUTF8;
 import org.apache.harmony.pack200.bytecode.ClassConstantPool;
 
+/**
+ * Constant Pool bands
+ */
 public class CpBands extends BandSet {
 
     public SegmentConstantPool getConstantPool() {
@@ -55,14 +58,14 @@
     private String[] cpString;
     private String[] cpUTF8;
 
-    private HashMap[] stringsToCPUTF8 = new HashMap[ClassConstantPool.NUM_DOMAINS];
-    private HashMap stringsToCPStrings = new HashMap();
-    private HashMap longsToCPLongs = new HashMap();
-    private HashMap integersToCPIntegers = new HashMap();
-    private HashMap floatsToCPFloats = new HashMap();
-    private HashMap stringsToCPClass = new HashMap();
-    private HashMap doublesToCPDoubles = new HashMap();
-    private HashMap descriptorsToCPNameAndTypes = new HashMap();
+    private final HashMap[] stringsToCPUTF8 = new HashMap[ClassConstantPool.NUM_DOMAINS];
+    private final HashMap stringsToCPStrings = new HashMap();
+    private final HashMap longsToCPLongs = new HashMap();
+    private final HashMap integersToCPIntegers = new HashMap();
+    private final HashMap floatsToCPFloats = new HashMap();
+    private final HashMap stringsToCPClass = new HashMap();
+    private final HashMap doublesToCPDoubles = new HashMap();
+    private final HashMap descriptorsToCPNameAndTypes = new HashMap();
 
 
     public CpBands(Segment segment) {
@@ -136,14 +139,12 @@
     private void parseCpDouble(InputStream in) throws IOException,
             Pack200Exception {
         int cpDoubleCount = header.getCpDoubleCount();
-        cpDouble = new double[cpDoubleCount];
-        long[] hiBits = decodeBandLong("cp_Double_hi", in, Codec.UDELTA5,
-                cpDoubleCount);
-        long[] loBits = decodeBandLong("cp_Double_lo", in, Codec.DELTA5,
-                cpDoubleCount);
-        for (int i = 0; i < cpDoubleCount; i++) {
-            cpDouble[i] = Double.longBitsToDouble(hiBits[i] << 32 | loBits[i]);
-        }
+        long[] band = parseFlags("cp_Double", in, cpDoubleCount,
+                Codec.UDELTA5, Codec.DELTA5);
+        cpDouble = new double[band.length];
+        for (int i = 0; i < band.length; i++) {
+			cpDouble[i] = Double.longBitsToDouble(band[i]);
+		}
     }
 
     /**
@@ -336,7 +337,10 @@
 
         // Read in the big suffix data
         int[] bigSuffixCounts = decodeBandInt("cp_Utf8_big_suffix", in, Codec.DELTA5, bigSuffixCount);
-        int[][] bigSuffixDataBand = decodeBandInt("cp_Utf8_big_chars", in, Codec.DELTA5, bigSuffixCounts);
+        int[][] bigSuffixDataBand = new int[bigSuffixCount][];
+        for (int i = 0; i < bigSuffixDataBand.length; i++) {
+			bigSuffixDataBand[i] = decodeBandInt("cp_Utf8_big_chars " + i, in, Codec.DELTA5, bigSuffixCounts[i]);
+		}
 
         // Convert big suffix data to characters
         char bigSuffixData[][] = new char[bigSuffixCount][];

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java Wed Apr  9 04:01:14 2008
@@ -39,12 +39,12 @@
 
     private long[] fileSize;
 
-    private String[] cpUTF8;
+    private final String[] cpUTF8;
 
     private InputStream in;
 
     /**
-     * @param header
+     * @param segment
      */
     public FileBands(Segment segment) {
         super(segment);

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IMatcher.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IMatcher.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IMatcher.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IMatcher.java Wed Apr  9 04:01:14 2008
@@ -16,6 +16,9 @@
  */
 package org.apache.harmony.pack200;
 
+/**
+ * Interface for a class that can perform matching on flag values.
+ */
 public interface IMatcher {
 
 	public abstract boolean matches(long value);

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java Wed Apr  9 04:01:14 2008
@@ -26,17 +26,18 @@
 import org.apache.harmony.pack200.bytecode.ClassConstantPool;
 
 /**
- * Pack200 Inner Class Bands
+ * Inner Class Bands
  */
 public class IcBands extends BandSet {
+
     private IcTuple[] icAll;
 
-    private String[] cpUTF8;
+    private final String[] cpUTF8;
 
-    private String[] cpClass;
+    private final String[] cpClass;
 
     /**
-     * @param header
+     * @param segment
      */
     public IcBands(Segment segment) {
         super(segment);
@@ -55,23 +56,43 @@
                 innerClassCount, cpClass);
         int[] icFlags = decodeBandInt("ic_flags", in, Codec.UNSIGNED5, innerClassCount);
         int outerClasses = SegmentUtils.countBit16(icFlags);
-        String[] icOuterClass = parseReferences("ic_outer_class", in, Codec.DELTA5,
-                outerClasses, cpClass);
-        String[] icName = parseReferences("ic_name", in, Codec.DELTA5, outerClasses,
-                cpUTF8);
+        int[] icOuterClassInts = decodeBandInt("ic_outer_class", in, Codec.DELTA5,
+                outerClasses);
+        String[] icOuterClass = new String[outerClasses];
+        for (int i = 0; i < icOuterClass.length; i++) {
+        	if(icOuterClassInts[i] == 0) {
+        		icOuterClass[i] = null;
+        	} else {
+        		icOuterClass[i] = cpClass[icOuterClassInts[i] - 1];
+        	}
+		}
+        int[] icNameInts = decodeBandInt("ic_name", in, Codec.DELTA5, outerClasses);
+        String[] icName = new String[outerClasses];
+        for (int i = 0; i < icName.length; i++) {
+        	if(icNameInts[i] == 0) {
+        		icName[i] = null;
+        	} else {
+        		icName[i] = cpUTF8[icNameInts[i] - 1];
+        	}
+		}
 
         // Construct IC tuples
         icAll = new IcTuple[icThisClass.length];
         int index = 0;
         for (int i = 0; i < icThisClass.length; i++) {
-            icAll[i] = new IcTuple();
-            icAll[i].C = icThisClass[i];
-            icAll[i].F = icFlags[i];
+            String icTupleC = null;
+            int icTupleF = -1;
+            String icTupleC2 = null;
+            String icTupleN = null;
+
+            icTupleC = icThisClass[i];
+            icTupleF = icFlags[i];
             if((icFlags[i] & 1<<16) != 0) {
-                icAll[i].C2 = icOuterClass[index];
-                icAll[i].N = icName[index];
+                icTupleC2 = icOuterClass[index];
+                icTupleN = icName[index];
                 index++;
             }
+            icAll[i] = new IcTuple(icTupleC, icTupleF, icTupleC2, icTupleN);
         }
     }
 
@@ -91,16 +112,17 @@
         IcTuple[] allTuples = getIcTuples();
         int allTuplesSize = allTuples.length;
         for(int index=0; index < allTuplesSize; index++) {
-            if(allTuples[index].outerClassString().equals(className)) {
+            if(allTuples[index].shouldAddToRelevantForClassName(className)  ) {
                 relevantTuples.add(allTuples[index]);
             }
         }
 
         List classPoolClasses = cp.allClasses();
         boolean changed = true;
-        // For every class in both ic_this_class and cp,
+        // For every class constant in both ic_this_class and cp,
         // add it to ic_relevant. Repeat until no more
         // changes to ic_relevant.
+
         while(changed) {
             changed = false;
             for(int allTupleIndex=0; allTupleIndex < allTuplesSize; allTupleIndex++) {
@@ -118,6 +140,39 @@
                 }
             }
         }
+
+        // Not part of spec: fix up by adding to relevantTuples the parents
+        // of inner classes which are themselves inner classes.
+        // i.e., I think that if Foo$Bar$Baz gets added, Foo$Bar needs to be added
+        // as well.
+
+        boolean changedFixup = true;
+        ArrayList tuplesToAdd = new ArrayList();
+        while(changedFixup) {
+            changedFixup = false;
+            for(int index=0; index < relevantTuples.size(); index++) {
+                IcTuple aRelevantTuple = (IcTuple)relevantTuples.get(index);
+                for(int allTupleIndex = 0; allTupleIndex < allTuplesSize; allTupleIndex++) {
+                    if(aRelevantTuple.outerClassString().equals(allTuples[allTupleIndex].thisClassString())) {
+                        if(!aRelevantTuple.outerIsAnonymous()) {
+                            tuplesToAdd.add(allTuples[allTupleIndex]);
+                        }
+                    }
+                }
+            }
+            if(tuplesToAdd.size() > 0) {
+                Iterator it = tuplesToAdd.iterator();
+                while(it.hasNext()) {
+                    IcTuple tuple = (IcTuple)it.next();
+                    if(!relevantTuples.contains(tuple)) {
+                        changedFixup = true;
+                        relevantTuples.add(tuple);
+                    }
+                }
+                tuplesToAdd = new ArrayList();
+            }
+        }
+        // End not part of the spec. Ugh.
 
         // Now order the result as a subsequence of ic_all
         IcTuple[] orderedRelevantTuples = new IcTuple[relevantTuples.size()];

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcTuple.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcTuple.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcTuple.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcTuple.java Wed Apr  9 04:01:14 2008
@@ -18,14 +18,42 @@
 
 import java.util.ArrayList;
 
+/**
+ * An IcTuple is the set of information that describes an inner class.
+ *
+ * C is the fully qualified class name<br>
+ * F is the flags<br>
+ * C2 is the outer class name, or null if it can be inferred from C<br>
+ * N is the inner class name, or null if it can be inferred from C<br>
+ */
 public class IcTuple {
 
-    public static int NESTED_CLASS_FLAG = 0x00010000;
-    public String C; // this class
-    public int F; // flags
-    public String C2; // outer class
-    public String N; // name
+    public IcTuple(String C, int F, String C2, String N) {
+        this.C = C;
+        this.F = F;
+        this.C2 = C2;
+        this.N = N;
+        if(null == N) {
+            predictSimple = true;
+        }
+        if(null == C2) {
+            predictOuter = true;
+        }
+        initializeClassStrings();
+    }
 
+    public IcTuple(String C, int F) {
+        this(C, F, null, null);
+    }
+
+    public static final int NESTED_CLASS_FLAG = 0x00010000;
+    protected String C; // this class
+    protected int F; // flags
+    protected String C2; // outer class
+    protected String N; // name
+
+    private boolean predictSimple = false;
+    private boolean predictOuter = false;
     private String cachedOuterClassString = null;
     private String cachedSimpleClassName = null;
     private boolean initialized = false;
@@ -36,16 +64,13 @@
      * Answer true if the receiver is predicted;
      * answer false if the receiver is specified
      * explicitly in the outer and name fields.
-     * @return
      */
     public boolean predicted() {
-        return ((F & NESTED_CLASS_FLAG) == 0);
+        return predictOuter || predictSimple;
     }
 
     /**
      * Break the receiver into components at $ boundaries.
-     *
-     * @return
      */
     public String[] innerBreakAtDollar(String className) {
         ArrayList resultList = new ArrayList();
@@ -76,9 +101,6 @@
      * @return String name of outer class
      */
     public String outerClassString() {
-        if(!initialized) {
-            initializeClassStrings();
-        }
         return cachedOuterClassString;
     }
 
@@ -87,9 +109,6 @@
      * @return String name of inner class
      */
     public String simpleClassName() {
-        if(!initialized) {
-            initializeClassStrings();
-        }
         return cachedSimpleClassName;
     }
 
@@ -102,45 +121,84 @@
         if(predicted()) {
             return C;
         } else {
-            // TODO: this may not be right. What if I 
+            // TODO: this may not be right. What if I
             // get a class like Foo#Bar$Baz$Bug?
             return C2 + "$" + N;
         }
     }
 
     public boolean isMember() {
-        initializeClassStrings();
         return member;
     }
 
     public boolean isAnonymous() {
-        initializeClassStrings();
         return anonymous;
     }
 
+    public boolean outerIsAnonymous() {
+        String [] result = innerBreakAtDollar(cachedOuterClassString);
+        if(result.length == 0) {
+            throw new Error("Should have an outer before checking if it's anonymous");
+        }
+
+        for(int index=0; index < result.length; index++) {
+            if(isAllDigits(result[index])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean shouldAddToRelevantForClassName(String className) {
+        // If the outerClassString of the tuple doesn't match the
+        // class name of the class we're looking through, don't
+        // consider it relevant.
+        if(!outerClassString().equals(className)) {
+            return false;
+        }
+        // If it's not anon and the outer is not anon, it's relevant
+        if(!isAnonymous() && !outerIsAnonymous()) {
+            return true;
+        }
+
+        // Otherwise it's not relevant.
+        return false;
+    }
+
     private void initializeClassStrings() {
         if(initialized) {
             return;
         }
         initialized = true;
-        if(!predicted()) {
-            cachedOuterClassString = C2;
+
+        if(!predictSimple) {
             cachedSimpleClassName = N;
-            return;
+        }
+        if(!predictOuter) {
+            cachedOuterClassString = C2;
         }
         // Class names must be calculated from
         // this class name.
         String nameComponents[] = innerBreakAtDollar(C);
         if(nameComponents.length == 0) {
-            throw new Error("Unable to predict outer class name: " + C);
+            // Unable to predict outer class
+            // throw new Error("Unable to predict outer class name: " + C);
         }
         if(nameComponents.length == 1) {
-            throw new Error("Unable to predict inner class name: " + C);
+            // Unable to predict simple class name
+            // throw new Error("Unable to predict inner class name: " + C);
+        }
+        if(nameComponents.length < 2) {
+            // If we get here, we hope cachedSimpleClassName
+            // and cachedOuterClassString were caught by the
+            // predictSimple / predictOuter code above.
+            return;
         }
+
         // If we get to this point, nameComponents.length must be >=2
         int lastPosition = nameComponents.length - 1;
         cachedSimpleClassName = nameComponents[lastPosition];
-        cachedOuterClassString = new String();
+        cachedOuterClassString = "";
         for(int index=0; index < lastPosition; index++) {
             cachedOuterClassString += nameComponents[index];
             if(isAllDigits(nameComponents[index])) {
@@ -153,9 +211,21 @@
                 cachedOuterClassString += '$';
             }
         }
+        // TODO: these two blocks are the same as blocks
+        // above. Can we eliminate some by reworking the logic?
+        if(!predictSimple) {
+            cachedSimpleClassName = N;
+        }
+        if(!predictOuter) {
+            cachedOuterClassString = C2;
+        }
         if(isAllDigits(cachedSimpleClassName)) {
             anonymous = true;
             member = false;
+            if((F & 65536) == 65536) {
+                // Predicted class - marking as member
+                member = true;
+            }
         }
     }
 
@@ -181,5 +251,60 @@
         result.append(outerClassString());
         result.append(')');
         return result.toString();
+    }
+
+    public boolean nullSafeEquals(String stringOne, String stringTwo) {
+        if(null==stringOne) {
+            return null==stringTwo;
+        }
+        return stringOne.equals(stringTwo);
+    }
+
+    public boolean equals(Object object) {
+        if(object.getClass() != this.getClass()) {
+            return false;
+        }
+        IcTuple compareTuple = (IcTuple)object;
+
+        if(!nullSafeEquals(this.C, compareTuple.C)) {
+            return false;
+        }
+
+        if(!nullSafeEquals(this.C2, compareTuple.C2)) {
+            return false;
+        }
+
+        if(!nullSafeEquals(this.N, compareTuple.N)) {
+            return false;
+        }
+        return true;
+    }
+
+    public int hashCode() {
+        return 17 + C.hashCode() + C2.hashCode() + N.hashCode();
+    }
+
+    public String getC() {
+        return C;
+    }
+
+    public int getF() {
+        return F;
+    }
+
+    public String getC2() {
+        return C2;
+    }
+
+    public String getN() {
+        return N;
+    }
+
+    public String realOuterClassString() {
+        int firstDollarPosition = cachedOuterClassString.indexOf('$');
+        if(firstDollarPosition <= 0) {
+            return cachedOuterClassString;
+        }
+        return cachedOuterClassString.substring(0, firstDollarPosition);
     }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java Wed Apr  9 04:01:14 2008
@@ -27,7 +27,6 @@
 import org.apache.harmony.pack200.bytecode.CPFloat;
 import org.apache.harmony.pack200.bytecode.CPInteger;
 import org.apache.harmony.pack200.bytecode.CPLong;
-import org.apache.harmony.pack200.bytecode.CPNameAndType;
 import org.apache.harmony.pack200.bytecode.CPUTF8;
 import org.apache.harmony.pack200.bytecode.ClassConstantPool;
 import org.apache.harmony.pack200.bytecode.RuntimeVisibleorInvisibleAnnotationsAttribute;
@@ -37,12 +36,12 @@
 import org.apache.harmony.pack200.bytecode.RuntimeVisibleorInvisibleParameterAnnotationsAttribute.ParameterAnnotation;
 
 /**
- * Group of metadata bands, e.g. class_RVA_bands, method_AD_bands etc
+ * A group of metadata bands, such as class_RVA_bands, method_AD_bands etc.
  */
 public class MetadataBandGroup {
 
-    private String type;
-    private CpBands cpBands;
+    private final String type;
+    private final CpBands cpBands;
 
     public MetadataBandGroup(String type, CpBands cpBands) {
         this.type = type;

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/NewAttributeBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/NewAttributeBands.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/NewAttributeBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/NewAttributeBands.java Wed Apr  9 04:01:14 2008
@@ -43,9 +43,7 @@
  */
 public class NewAttributeBands extends BandSet {
 
-    private AttributeLayout attributeLayout;
-
-    private List attributes;
+    private final AttributeLayout attributeLayout;
 
     private int backwardsCallCount;
 
@@ -68,15 +66,6 @@
     }
 
     /**
-     * Returns the list of attributes read in by this band set.  This method
-     * should only be called after unpack() or it will return null.
-     * @return List of Attributes
-     */
-    public List getAttributes() {
-        return attributes;
-    }
-
-    /**
      * Parse the bands relating to this AttributeLayout and return the correct
      * class file attributes as a List of {@link Attribute}
      * @throws Pack200Exception
@@ -115,7 +104,6 @@
 
     /**
      * Tokenise the layout into AttributeElements
-     * @return a List of AttributeElements
      * @throws IOException
      */
     private void parseLayout() throws IOException {
@@ -364,7 +352,7 @@
 
     private class Integral extends LayoutElement {
 
-        private String tag;
+        private final String tag;
         private long[] band;
 
         public Integral(String tag) {
@@ -428,9 +416,9 @@
      */
     private class Replication extends LayoutElement {
 
-        private Integral countElement;
+        private final Integral countElement;
 
-        private List layoutElements = new ArrayList();
+        private final List layoutElements = new ArrayList();
 
         public Replication(String tag, String contents) throws IOException {
             this.countElement = new Integral(tag);
@@ -479,9 +467,9 @@
      */
     private class Union extends LayoutElement {
 
-        private Integral unionTag;
-        private List unionCases;
-        private List defaultCaseBody;
+        private final Integral unionTag;
+        private final List unionCases;
+        private final List defaultCaseBody;
         private int[] caseCounts;
         private int defaultCount;
 
@@ -572,7 +560,7 @@
 
     private class Call extends LayoutElement {
 
-        private int callableIndex;
+        private final int callableIndex;
         private Callable callable;
 
         public Call(int callableIndex) {
@@ -608,11 +596,11 @@
      */
     private class Reference extends LayoutElement {
 
-        private String tag;
+        private final String tag;
 
         private Object band;
 
-        private int length;
+        private final int length;
 
         public Reference(String tag) {
             this.tag = tag;
@@ -677,9 +665,9 @@
 
     }
 
-    private class Callable implements AttributeLayoutElement {
+    private static class Callable implements AttributeLayoutElement {
 
-        private List body;
+        private final List body;
 
         private boolean isBackwardsCallable;
 
@@ -748,7 +736,7 @@
 
         private List body;
 
-        private List tags;
+        private final List tags;
 
         public UnionCase(List tags) {
             this.tags = tags;
@@ -809,9 +797,8 @@
     }
 
     /**
-     * Returns the codec that should be used for the given layout element
+     * Returns the {@link BHSDCodec} that should be used for the given layout element
      * @param layoutElement
-     * @return
      */
     public BHSDCodec getCodec(String layoutElement) {
         if (layoutElement.indexOf("O") >= 0) { //$NON-NLS-1$
@@ -875,7 +862,10 @@
         }
         stream.reset();
         char[] digits = new char[length];
-        stream.read(digits);
+        int read = stream.read(digits);
+        if (read != digits.length) {
+        	throw new IOException("Error reading from the input stream");
+        }
         return Integer.parseInt((negative ? "-" : "") + new String(digits));
     }
 

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Pack200Exception.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Pack200Exception.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Pack200Exception.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Pack200Exception.java Wed Apr  9 04:01:14 2008
@@ -39,7 +39,7 @@
 	 * @param message
 	 *            the text message to display
 	 * @param cause
-	 *            the throwable that caused this problem
+	 *            the {@link Throwable} that caused this problem
 	 */
 	public Pack200Exception(String message, Throwable cause) {
 		super(message, cause);
@@ -49,7 +49,7 @@
 	 * Create a new Pack200 exception with the given message and cause
 	 *
 	 * @param cause
-	 *            the throwable that caused this problem
+	 *            the {@link Throwable} that caused this problem
 	 */
 	public Pack200Exception(Throwable cause) {
 		super(cause);

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java Wed Apr  9 04:01:14 2008
@@ -19,7 +19,14 @@
 import java.io.IOException;
 import java.io.InputStream;
 
+/**
+ * A PopulationCodec is a Codec that is well suited to encoding data that shows
+ * statistical or repetetive patterns, containign for example a few numbers
+ * which are repeated a lot throughout the set, but not necessarily
+ * sequentially.
+ */
 public class PopulationCodec extends Codec {
+
     private final Codec favouredCodec;
     private Codec tokenCodec;
     private final Codec unvafouredCodec;
@@ -58,12 +65,11 @@
         // read table of favorites first
         long smallest = Long.MAX_VALUE;
         long last = 0;
-        long value = 0; // TODO Are these sensible starting points?
+        long value = 0;
         int k = -1;
         while( true ) {
-            last = value;
             value = favouredCodec.decode(in,last);
-            if ( value == smallest || value == last)
+            if (k > -1 && (value == smallest || value == last))
                 break;
             favoured[++k] = value;
             if (Math.abs(smallest) > Math.abs(value)) {
@@ -72,6 +78,7 @@
                 // ensure that -X and +X -> +X
                 smallest = Math.abs(smallest);
             }
+            last = value;
         }
         // if tokenCodec needs to be derived from the T, L and K values
         if (tokenCodec == null) {

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

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java Wed Apr  9 04:01:14 2008
@@ -21,6 +21,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -40,18 +41,13 @@
 import org.apache.harmony.pack200.bytecode.SourceFileAttribute;
 
 /**
- * A Pack200 archive consists of one (or more) segments. Each segment is
- * standalone, in the sense that every segment has the magic number header;
+ * A Pack200 archive consists of one or more segments. Each segment is
+ * stand-alone, in the sense that every segment has the magic number header;
  * thus, every segment is also a valid archive. However, it is possible to
  * combine (non-GZipped) archives into a single large archive by concatenation
  * alone. Thus all the hard work in unpacking an archive falls to understanding
  * a segment.
  *
- * This class implements the Pack200 specification by an entry point ({@link #parse(InputStream)})
- * which in turn delegates to a variety of other parse methods. Each parse
- * method corresponds (roughly) to the name of the bands in the Pack200
- * specification.
- *
  * The first component of a segment is the header; this contains (amongst other
  * things) the expected counts of constant pool entries, which in turn defines
  * how many values need to be read from the stream. Because values are variable
@@ -69,30 +65,11 @@
  */
 public class Segment {
 
+    public static final int LOG_LEVEL_VERBOSE = 2;
 
-	/**
-     * TODO: Do we need this method now we have Archive as the main entry point?
-     *
-	 * Decode a segment from the given input stream. This does not attempt to
-	 * re-assemble or export any class files, but it contains enough information
-	 * to be able to re-assemble class files by external callers.
-	 *
-	 * @param in
-	 *            the input stream to read from
-	 * @return a segment parsed from the input stream
-	 * @throws IOException
-	 *             if a problem occurs during reading from the underlying stream
-	 * @throws Pack200Exception
-	 *             if a problem occurs with an unexpected value or unsupported
-	 *             codec
-	 */
-	public static Segment parse(InputStream in) throws IOException,
-			Pack200Exception {
-		Segment segment = new Segment();
-        segment.parseSegment(in);
-		return segment;
-	}
+    public static final int LOG_LEVEL_STANDARD = 1;
 
+    public static final int LOG_LEVEL_QUIET = 0;
 
     private SegmentHeader header;
 
@@ -112,6 +89,10 @@
 
     private boolean deflateHint;
 
+	private int logLevel;
+
+	private PrintWriter logStream;
+
 	private ClassFile buildClassFile(int classNum) throws Pack200Exception {
 		ClassFile classFile = new ClassFile();
 		classFile.major = header.getDefaultClassMajorVersion(); // TODO If
@@ -127,23 +108,60 @@
 		int i = fullName.lastIndexOf("/") + 1; // if lastIndexOf==-1, then
 		// -1+1=0, so str.substring(0)
 		// == str
-		AttributeLayout SOURCE_FILE = attrDefinitionBands.getAttributeDefinitionMap()
-				.getAttributeLayout(AttributeLayout.ATTRIBUTE_SOURCE_FILE,
-						AttributeLayout.CONTEXT_CLASS);
-		if (SOURCE_FILE.matches(classBands.getClassFlags()[classNum])) {
-		    int firstDollar = SegmentUtils.indexOfFirstDollar(fullName);
-		    String fileName = null;
 
-		    if(firstDollar > -1 && (i <= firstDollar)) {
-		        fileName = fullName.substring(i, firstDollar) + ".java";
-		    } else {
-		        fileName = fullName.substring(i) + ".java";
-		    }
-			classFile.attributes = new Attribute[] { (Attribute) cp
-					.add(new SourceFileAttribute(cpBands.cpUTF8Value(fileName, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ))) };
-		} else {
-			classFile.attributes = new Attribute[] {};
-		}
+		// Get the source file attribute
+        ArrayList classAttributes = classBands.getClassAttributes()[classNum];
+        SourceFileAttribute sourceFileAttribute = null;
+        for(int index=0; index < classAttributes.size(); index++) {
+            if(((Attribute)classAttributes.get(index)).isSourceFileAttribute()) {
+                sourceFileAttribute = ((SourceFileAttribute)classAttributes.get(index));
+            }
+        }
+
+        if(sourceFileAttribute == null) {
+            // If we don't have a source file attribute yet, we need
+            // to infer it from the class.
+            AttributeLayout SOURCE_FILE = attrDefinitionBands.getAttributeDefinitionMap()
+    				.getAttributeLayout(AttributeLayout.ATTRIBUTE_SOURCE_FILE,
+    						AttributeLayout.CONTEXT_CLASS);
+    		if (SOURCE_FILE.matches(classBands.getRawClassFlags()[classNum])) {
+    		    int firstDollar = SegmentUtils.indexOfFirstDollar(fullName);
+    		    String fileName = null;
+
+    		    if(firstDollar > -1 && (i <= firstDollar)) {
+    		        fileName = fullName.substring(i, firstDollar) + ".java";
+    		    } else {
+    		        fileName = fullName.substring(i) + ".java";
+    		    }
+    		    sourceFileAttribute = new SourceFileAttribute(cpBands.cpUTF8Value(fileName, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ));
+    			classFile.attributes = new Attribute[] { (Attribute) cp
+    					.add(sourceFileAttribute) };
+    		} else {
+                classFile.attributes = new Attribute[] {};
+            }
+        } else {
+            classFile.attributes = new Attribute[] { (Attribute) cp.add(sourceFileAttribute)};
+        }
+
+		// If we see any class attributes, add them to the class's attributes that will
+		// be written out. Keep SourceFileAttributes out since we just
+		// did them above.
+	    ArrayList classAttributesWithoutSourceFileAttribute = new ArrayList();
+	    for(int index=0; index < classAttributes.size(); index++) {
+	        Attribute attrib = (Attribute)classAttributes.get(index);
+	        if(!attrib.isSourceFileAttribute()) {
+	            classAttributesWithoutSourceFileAttribute.add(attrib);
+	        }
+	    }
+        Attribute[] originalAttributes = classFile.attributes;
+        classFile.attributes = new Attribute[originalAttributes.length + classAttributesWithoutSourceFileAttribute.size()];
+        System.arraycopy(originalAttributes, 0, classFile.attributes, 0, originalAttributes.length);
+	    for(int index=0; index < classAttributesWithoutSourceFileAttribute.size(); index++) {
+	        Attribute attrib = ((Attribute)classAttributesWithoutSourceFileAttribute.get(index));
+	        cp.add(attrib);
+	        classFile.attributes[originalAttributes.length + index] = attrib;
+	    }
+
 		// this/superclass
 		ClassFileEntry cfThis = cp.add(cpBands.cpClassValue(fullName));
 		ClassFileEntry cfSuper = cp.add(cpBands.cpClassValue(classBands.getClassSuper()[classNum]));
@@ -165,20 +183,20 @@
 		}
 		// add methods
 		ClassFileEntry cfMethods[] = new ClassFileEntry[classBands.getClassMethodCount()[classNum]];
-		// fieldDescr and fieldFlags used to create this
+		// methodDescr and methodFlags used to create this
 		for (i = 0; i < cfMethods.length; i++) {
             String descriptorStr = classBands.getMethodDescr()[classNum][i];
             int colon = descriptorStr.indexOf(':');
             CPUTF8 name = cpBands.cpUTF8Value(descriptorStr.substring(0,colon), ClassConstantPool.DOMAIN_NORMALASCIIZ);
             CPUTF8 descriptor = cpBands.cpUTF8Value(descriptorStr.substring(colon+1), ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
-			cfMethods[i] = cp.add(new CPMethod(name, descriptor, classBands
+            cfMethods[i] = cp.add(new CPMethod(name, descriptor, classBands
                     .getMethodFlags()[classNum][i], classBands
                     .getMethodAttributes()[classNum][i]));
 		}
 
 		// add inner class attribute (if required)
 		boolean addInnerClassesAttr = false;
-		IcTuple[] ic_local = getClassBands().getIcLocal()[classNum];
+        IcTuple[] ic_local = getClassBands().getIcLocal()[classNum];
 		boolean ic_local_sent = false;
 		if(ic_local != null) {
 		    ic_local_sent = true;
@@ -236,11 +254,6 @@
 		}
 		// sort CP according to cp_All
 		cp.resolve(this);
-		// print out entries
-		debug("Constant pool looks like:");
-		for (i = 1; i <= cp.size(); i++) {
-			debug(String.valueOf(i) + ":" + String.valueOf(cp.get(i)));
-		}
 		// NOTE the indexOf is only valid after the cp.resolve()
 		// build up remainder of file
 		classFile.accessFlags = (int) classBands.getClassFlags()[classNum];
@@ -319,8 +332,8 @@
 	 */
 	private void parseSegment(InputStream in) throws IOException,
 			Pack200Exception {
-		debug("-------");
-        header = new SegmentHeader();
+		log(LOG_LEVEL_VERBOSE, "-------");
+        header = new SegmentHeader(this);
         header.unpack(in);
         cpBands = new CpBands(this);
         cpBands.unpack(in);
@@ -353,23 +366,6 @@
         writeJar(out);
     }
 
-    /**
-     * This is a local debugging message to aid the developer in writing this
-     * class. It will be removed before going into production. If the property
-     * 'debug.pack200' is set, this will generate messages to stderr; otherwise,
-     * it will be silent.
-     *
-     * @param message
-     * @deprecated this should be removed from production code
-     */
-    protected void debug(String message) {
-        if (System.getProperty("debug.pack200") != null) {
-            System.err.println(message);
-        }
-    }
-
-
-
 	/**
 	 * Writes the segment to an output stream. The output stream should be
 	 * pre-buffered for efficiency. Also takes the same input stream for
@@ -379,12 +375,10 @@
 	 *
 	 * @param out
 	 *            the JarOutputStream to write data to
-	 * @param in
-	 *            the same InputStream that was used to parse the segment
 	 * @throws IOException
-	 *             if an error occurs whilst reading or writing to the streams
+	 *             if an error occurs while reading or writing to the streams
 	 * @throws Pack200Exception
-	 *             if an error occurs whilst unpacking data
+	 *             if an error occurs while processing data
 	 */
 	public void writeJar(JarOutputStream out)
 			throws IOException, Pack200Exception {
@@ -480,15 +474,17 @@
 
 
     public void setLogLevel(int logLevel) {
-
+    	this.logLevel = logLevel;
     }
 
-    public void setLogStream(OutputStream stream) {
-
+    public void setLogStream(OutputStream logStream) {
+    	this.logStream = new PrintWriter(logStream);
     }
 
     public void log(int logLevel, String message) {
-
+    	if (this.logLevel >= logLevel) {
+    		logStream.println(message);
+    	}
     }
 
     /**

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentConstantPool.java Wed Apr  9 04:01:14 2008
@@ -16,19 +16,19 @@
  */
 package org.apache.harmony.pack200;
 
-import java.util.ArrayList;
-
 import org.apache.harmony.pack200.bytecode.CPFieldRef;
 import org.apache.harmony.pack200.bytecode.CPInterfaceMethodRef;
 import org.apache.harmony.pack200.bytecode.CPMethodRef;
 import org.apache.harmony.pack200.bytecode.ClassConstantPool;
 import org.apache.harmony.pack200.bytecode.ConstantPoolEntry;
 
+/**
+ * SegmentConstantPool manages the constant pool used for re-creating class
+ * files.
+ */
 public class SegmentConstantPool {
-    /**
-     *
-     */
-    private CpBands bands;
+
+    private final CpBands bands;
 
     /**
      * @param bands
@@ -53,7 +53,10 @@
     public static final int CP_METHOD = 11;
     public static final int CP_IMETHOD = 12;
 
-    // TODO: All CP***??
+    protected static final String REGEX_MATCH_ALL = ".*";
+    protected static final String INITSTRING = "<init>";
+    protected static final String REGEX_MATCH_INIT = "^" + INITSTRING + ".*";
+
     public Object getValue(int cp, long value) throws Pack200Exception {
         int index = (int) value;
         if (index == -1) {
@@ -79,8 +82,7 @@
         } else if (cp == CP_DESCR) {
             return bands.getCpDescriptor()[index];
         } else {
-            // etc
-            throw new Error("Get value incomplete");
+            throw new Error("Tried to get a value I don't know about: " + cp);
         }
     }
 
@@ -144,7 +146,7 @@
      */
     public ConstantPoolEntry getInitMethodPoolEntry(int cp, long value, String desiredClassName) throws Pack200Exception {
     	int realIndex = -1;
-    	String desiredRegex = "^<init>.*";
+    	String desiredRegex = REGEX_MATCH_INIT;
     	if (cp == CP_METHOD) {
     		realIndex = matchSpecificPoolEntryIndex(bands.getCpMethodClass(), bands.getCpMethodDescriptor(), desiredClassName, desiredRegex, (int)value);
     	} else {
@@ -182,7 +184,7 @@
      * @return int index into nameArray, or -1 if not found.
      */
     protected int matchSpecificPoolEntryIndex(String[] nameArray, String compareString, int desiredIndex) {
-    	return matchSpecificPoolEntryIndex(nameArray, nameArray, compareString, ".*", desiredIndex);
+    	return matchSpecificPoolEntryIndex(nameArray, nameArray, compareString, REGEX_MATCH_ALL, desiredIndex);
     }
 
     /**
@@ -205,7 +207,7 @@
     	int instanceCount = -1;
     	for(int index=0; index < primaryArray.length; index++) {
     		if((primaryArray[index].equals(primaryCompareString)) &&
-    				secondaryArray[index].matches(secondaryCompareRegex)) {
+    				regexMatches(secondaryCompareRegex, secondaryArray[index]) ) {
     			instanceCount++;
     			if(instanceCount == desiredIndex) {
     				return index;
@@ -217,6 +219,33 @@
     	return -1;
     }
 
+    /**
+     * We don't want a dependency on regex in Pack200. The
+     * only place one exists is in matchSpecificPoolEntryIndex().
+     * To eliminate this dependency, we've implemented the
+     * world's stupidest regexMatch. It knows about the two
+     * forms we care about:
+     *  .* (aka REGEX_MATCH_ALL)
+     *  ^<init>.* (aka REGEX_MATCH_INIT)
+     * and will answer correctly if those are passed as the
+     * regexString.
+     * @param regexString String against which the compareString will be matched
+     * @param compareString String to match against the regexString
+     * @return boolean true if the compareString matches the regexString;
+     *  otherwise false.
+     */
+    protected static boolean regexMatches(String regexString, String compareString) {
+        if(REGEX_MATCH_ALL.equals(regexString)) {
+            return true;
+        }
+        if(REGEX_MATCH_INIT.equals(regexString)) {
+            if(compareString.length() < (INITSTRING.length())) {
+                return false;
+            }
+            return(INITSTRING.equals(compareString.substring(0, INITSTRING.length())));
+        }
+        throw new Error("regex trying to match a pattern I don't know: " + regexString);
+    }
 
     public ConstantPoolEntry getConstantPoolEntry(int cp, long value) throws Pack200Exception {
         int index = (int) value;
@@ -261,46 +290,4 @@
             throw new Error("Get value incomplete");
         }
     }
-
-    public ConstantPoolEntry[] getCpAll() throws Pack200Exception {
-        	ArrayList cpAll = new ArrayList();
-        	// TODO: this is 1.5-specific. Try to get rid
-        	// of it.
-        	for(int index=0; index < bands.getCpUTF8().length; index++) {
-        		cpAll.add(getConstantPoolEntry(UTF_8, index));
-        	}
-        	for(int index=0; index < bands.getCpInt().length; index++) {
-        		cpAll.add(getConstantPoolEntry(CP_INT, index));
-        	}
-        	for(int index=0; index < bands.getCpFloat().length; index++) {
-        		cpAll.add(getConstantPoolEntry(CP_FLOAT, index));
-        	}
-        	for(int index=0; index < bands.getCpLong().length; index++) {
-        		cpAll.add(getConstantPoolEntry(CP_LONG, index));
-        	}
-        	for(int index=0; index < bands.getCpDouble().length; index++) {
-        		cpAll.add(getConstantPoolEntry(CP_DOUBLE, index));
-        	}
-        	for(int index=0; index < bands.getCpString().length; index++) {
-        		cpAll.add(getConstantPoolEntry(CP_STRING, index));
-        	}
-        	for(int index=0; index < bands.getCpClass().length; index++) {
-        		cpAll.add(getConstantPoolEntry(CP_CLASS, index));
-        	}
-        	for(int index=0; index < bands.getCpFieldClass().length; index++) {
-        		cpAll.add(getConstantPoolEntry(CP_FIELD, index));
-        	}
-        	for(int index=0; index < bands.getCpMethodClass().length; index++) {
-        		cpAll.add(getConstantPoolEntry(CP_METHOD, index));
-        	}
-        	for(int index=0; index < bands.getCpIMethodClass().length; index++) {
-        		cpAll.add(getConstantPoolEntry(CP_IMETHOD, index));
-        	}
-
-        	ConstantPoolEntry[] result = new ConstantPoolEntry[cpAll.size()];
-        	cpAll.toArray(result);
-        	return result;
-        }
-
-
-    }
+}
\ No newline at end of file

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentHeader.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentHeader.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentHeader.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentHeader.java Wed Apr  9 04:01:14 2008
@@ -21,6 +21,9 @@
 import java.io.IOException;
 import java.io.InputStream;
 
+/**
+ * SegmentHeader is the header band of a {@link Segment}
+ */
 public class SegmentHeader {
 
     private int archiveMajor;
@@ -75,6 +78,8 @@
 
     private SegmentOptions options;
 
+	private final Segment segment;
+
 
     /**
      * The magic header for a Pack200 Segment is 0xCAFED00D. I wonder where they
@@ -82,6 +87,10 @@
      */
     private static final int[] magic = { 0xCA, 0xFE, 0xD0, 0x0D };
 
+    public SegmentHeader(Segment segment) {
+		this.segment = segment;
+	}
+
     public void unpack(InputStream in) throws IOException,
             Pack200Exception, Error, Pack200Exception {
         long word[] = decodeScalar("archive_magic_word", in, Codec.BYTE1,
@@ -328,8 +337,7 @@
      */
     private long[] decodeScalar(String name, InputStream in, BHSDCodec codec,
             int n) throws IOException, Pack200Exception {
-        // TODO Remove debugging code
-        debug("Parsed #" + name + " (" + n + ")");
+        segment.log(Segment.LOG_LEVEL_VERBOSE, "Parsed #" + name + " (" + n + ")");
         return codec.decode(n, in);
     }
 
@@ -355,7 +363,7 @@
     private long decodeScalar(String name, InputStream in, BHSDCodec codec)
             throws IOException, Pack200Exception {
         long ret =  codec.decode(in);
-        debug("Parsed #" + name + " as " + ret);
+        segment.log(Segment.LOG_LEVEL_VERBOSE, "Parsed #" + name + " as " + ret);
         return ret;
     }
 
@@ -394,7 +402,7 @@
      *             if a problem occurs with an unexpected value or unsupported
      *             codec
      */
-    private static void readFully(InputStream in, byte[] data)
+    private void readFully(InputStream in, byte[] data)
             throws IOException, Pack200Exception {
         int total = in.read(data);
         if (total == -1)
@@ -411,12 +419,4 @@
     public int getBandHeadersSize() {
         return bandHeadersSize;
     }
-
-    protected void debug(String message) {
-      if (System.getProperty("debug.pack200") != null) {
-          System.err.println(message);
-      }
-  }
-
-
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentUtils.java Wed Apr  9 04:01:14 2008
@@ -16,7 +16,9 @@
  */
 package org.apache.harmony.pack200;
 
-// TODO Write doc
+/**
+ * Utility class for unpack200
+ */
 public final class SegmentUtils {
 
 	public static int countArgs(String descriptor) {

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java Wed Apr  9 04:01:14 2008
@@ -83,6 +83,17 @@
         return false;
     }
 
+    /**
+     * Answer true if the receiver is a source file attribute
+     * (which gets special handling when the class is built);
+     * otherwise answer false.
+     *
+     * @return boolean source file attribute
+     */
+    public boolean isSourceFileAttribute() {
+        return false;
+    }
+
     public int hashCode() {
         final int PRIME = 31;
         int result = 1;

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/BCIRenumberedAttribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/BCIRenumberedAttribute.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/BCIRenumberedAttribute.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/BCIRenumberedAttribute.java Wed Apr  9 04:01:14 2008
@@ -20,6 +20,8 @@
 import java.io.IOException;
 import java.util.List;
 
+import org.apache.harmony.pack200.Pack200Exception;
+
 public abstract class BCIRenumberedAttribute extends Attribute {
 
     protected boolean renumbered = false;
@@ -50,7 +52,7 @@
      *
      * @param byteCodeOffsets List of Integer offsets of the bytecode array
      */
-    public void renumber(List byteCodeOffsets) {
+    public void renumber(List byteCodeOffsets) throws Pack200Exception {
         if(renumbered) {
             throw new Error("Trying to renumber a line number table that has already been renumbered");
         }

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java Wed Apr  9 04:01:14 2008
@@ -20,7 +20,6 @@
 import java.io.IOException;
 
 import org.apache.harmony.pack200.Segment;
-import org.apache.harmony.pack200.SegmentUtils;
 import org.apache.harmony.pack200.bytecode.forms.ByteCodeForm;
 
 public class ByteCode extends ClassFileEntry {
@@ -64,7 +63,7 @@
 		final ByteCode other = (ByteCode) obj;
 		if (getByteCodeForm() != other.getByteCodeForm())
 			return false;
-		if (!rewrite.equals(other.rewrite))
+		if (rewrite != other.rewrite)
 			return false;
 		return true;
 	}
@@ -133,21 +132,13 @@
 					setOperand2Bytes(pool.indexOf(nested[index]), getNestedPosition(index)[0]);
 					break;
 
-				case 4:
-					// TODO: need to handle wides?
-                    SegmentUtils.debug("Need to handle wides");
-                    throw new Error("Instruction argument not handled");
-					// figure out and if so, handle and put a break here.
-					// break;
-
 				default:
-					SegmentUtils.debug("Unhandled resolve " + this);
+					throw new Error("Unhandled resolve " + this);
 				}
 			}
 		}
 	}
 
-
 	/**
 	 * Given an array of ints which correspond to bytes in the
 	 * operand of the bytecode, set the rewrite bytes of the
@@ -322,7 +313,7 @@
      * up to point to the absolute position in the CodeAttribute
      * array. This method sets the targets.
      *
-     * @param byteCodeTarget int index in array
+     * @param byteCodeTargets int index in array
      */
     public void setByteCodeTargets(int[] byteCodeTargets) {
         this.byteCodeTargets = byteCodeTargets;

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPClass.java Wed Apr  9 04:01:14 2008
@@ -19,19 +19,27 @@
 import java.io.DataOutputStream;
 import java.io.IOException;
 
-
 public class CPClass extends ConstantPoolEntry {
+
 	private int index;
 
 	public String name;
 
-	private CPUTF8 utf8;
-    
+	private final CPUTF8 utf8;
+
+	/**
+	 * Creates a new CPClass
+	 * @param name
+	 * @throws NullPointerException if name is null
+	 */
     public CPClass(CPUTF8 name) {
 		super(ConstantPoolEntry.CP_Class);
 		this.name = name.underlyingString();
 		this.domain = ClassConstantPool.DOMAIN_CLASSREF;
 		this.utf8 = name;
+		if(name == null) {
+            throw new NullPointerException("Null arguments are not allowed");
+		}
 	}
 
     public boolean equals(Object obj) {
@@ -42,17 +50,7 @@
 		if (this.getClass() != obj.getClass())
 			return false;
 		final CPClass other = (CPClass) obj;
-		if (name == null) {
-			if (other.name != null)
-				return false;
-		} else if (!name.equals(other.name))
-			return false;
-		if (utf8 == null) {
-			if (other.utf8 != null)
-				return false;
-		} else if (!utf8.equals(other.utf8))
-			return false;
-		return true;
+		return utf8.equals(other.utf8);
 	}
 
 	protected ClassFileEntry[] getNestedClassFileEntries() {
@@ -61,11 +59,7 @@
 
 
 	public int hashCode() {
-		final int PRIME = 31;
-		int result = 1;
-		result = PRIME * result + ((name == null) ? 0 : name.hashCode());
-		result = PRIME * result + ((utf8 == null) ? 0 : utf8.hashCode());
-		return result;
+		return utf8.hashCode();
 	}
 
 	protected void resolve(ClassConstantPool pool) {
@@ -84,11 +78,4 @@
 	protected void writeBody(DataOutputStream dos) throws IOException {
 		dos.writeShort(index);
 	}
-
-   public String comparisonString() {
-       // TODO: what to do about inner classes?
-       if(name==null) {return "null:name (probably an inner class?)";};
-        return getName();
-   }
-
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPConstant.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPConstant.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPConstant.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPConstant.java Wed Apr  9 04:01:14 2008
@@ -19,14 +19,22 @@
 
 public abstract class CPConstant extends ConstantPoolEntry {
 
-	private Object value;
+	private final Object value;
 
+	/**
+	 * Create a new CPConstant
+	 * @param tag
+	 * @param value
+	 * @throws NullPointerException if value is null
+	 */
 	public CPConstant(byte tag, Object value) {
 		super(tag);
 		this.value = value;
+		if (value == null) {
+		    throw new NullPointerException("Null arguments are not allowed");
+		}
 	}
 
-
 	public boolean equals(Object obj) {
 		if (this == obj)
 			return true;
@@ -53,7 +61,4 @@
 	protected Object getValue() {
 		return value;
 	}
-
-
-
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java Wed Apr  9 04:01:14 2008
@@ -52,10 +52,6 @@
 		return "FieldRef: " + className + "#" + nameAndType;
 	}
 
-    public String comparisonString() {
-        return (className.getName() + Character.MAX_VALUE) + nameAndType.descriptor + Character.MAX_VALUE + nameAndType.name;
-    }
-
 	public int hashCode() {
 		final int PRIME = 31;
 		int result = 1;

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMember.java Wed Apr  9 04:01:14 2008
@@ -18,7 +18,7 @@
 
 import java.io.DataOutputStream;
 import java.io.IOException;
-import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 
@@ -28,14 +28,25 @@
 	short flags;
 	CPUTF8 name;
 	transient int nameIndex;
-	private CPUTF8 descriptor;
+	private final CPUTF8 descriptor;
 	transient int descriptorIndex;
 
+	/**
+	 * Create a new CPMember
+	 * @param name
+	 * @param descriptor
+	 * @param flags
+	 * @param attributes
+	 * @throws NullPointerException if name or descriptor is null
+	 */
 	public CPMember(CPUTF8 name, CPUTF8 descriptor, long flags, List attributes) {
 		this.name = name;
         this.descriptor = descriptor;
         this.flags = (short) flags;
-		this.attributes = (attributes == null ? new ArrayList() : attributes);
+		this.attributes = (attributes == null ? Collections.EMPTY_LIST : attributes);
+		if(name == null || descriptor == null) {
+            throw new NullPointerException("Null arguments are not allowed");
+		}
 	}
 
 	protected ClassFileEntry[] getNestedClassFileEntries() {
@@ -66,10 +77,10 @@
 	public int hashCode() {
 		final int PRIME = 31;
 		int result = 1;
-		result = PRIME * result + ((attributes == null) ? 0 : attributes.hashCode());
-		result = PRIME * result + ((descriptor == null) ? 0 : descriptor.hashCode());
+		result = PRIME * result + attributes.hashCode();
+		result = PRIME * result + descriptor.hashCode();
 		result = PRIME * result + flags;
-		result = PRIME * result + ((name == null) ? 0 : name.hashCode());
+		result = PRIME * result + name.hashCode();
 		return result;
 	}
 
@@ -81,22 +92,13 @@
 		if (getClass() != obj.getClass())
 			return false;
 		final CPMember other = (CPMember) obj;
-		if (attributes == null) {
-			if (other.attributes != null)
-				return false;
-		} else if (!attributes.equals(other.attributes))
+		if (!attributes.equals(other.attributes))
 			return false;
-		if (descriptor == null) {
-			if (other.descriptor != null)
-				return false;
-		} else if (!descriptor.equals(other.descriptor))
+		if (!descriptor.equals(other.descriptor))
 			return false;
 		if (flags != other.flags)
 			return false;
-		if (name == null) {
-			if (other.name != null)
-				return false;
-		} else if (!name.equals(other.name))
+		if (!name.equals(other.name))
 			return false;
 		return true;
 	}

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethod.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethod.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethod.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPMethod.java Wed Apr  9 04:01:14 2008
@@ -21,8 +21,7 @@
 public class CPMethod extends CPMember {
 
 	public CPMethod(CPUTF8 name, CPUTF8 descriptor, long flags, List attributes) {
-		// TODO Check that we only pass these on, or remap
-		super(name, descriptor, 0x7FFF & flags, attributes);
+		super(name, descriptor, flags, attributes);
 	}
 
 }



Mime
View raw message