harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From telli...@apache.org
Subject svn commit: r572907 [4/5] - in /harmony/enhanced/classlib/branches/java6: depends/files/ modules/awt/src/main/java/common/java/awt/ modules/awt/src/main/java/common/java/awt/geom/ modules/awt/src/main/java/common/org/apache/harmony/awt/gl/ modules/awt/...
Date Wed, 05 Sep 2007 09:14:06 GMT
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=572907&r1=572906&r2=572907&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 Sep  5 02:14:01 2007
@@ -20,13 +20,10 @@
 // NOTE: Do not extract strings as messages; this code is still a
 // work-in-progress
 // NOTE: Also, don't get rid of 'else' statements for the hell of it ...
-import java.io.ByteArrayInputStream;
+import java.io.BufferedInputStream;
 import java.io.DataOutputStream;
-import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.jar.JarEntry;
 import java.util.jar.JarOutputStream;
 import java.util.zip.GZIPInputStream;
@@ -38,8 +35,6 @@
 import org.apache.harmony.pack200.bytecode.ClassConstantPool;
 import org.apache.harmony.pack200.bytecode.ClassFile;
 import org.apache.harmony.pack200.bytecode.ClassFileEntry;
-import org.apache.harmony.pack200.bytecode.ConstantValueAttribute;
-import org.apache.harmony.pack200.bytecode.ExceptionsAttribute;
 import org.apache.harmony.pack200.bytecode.SourceFileAttribute;
 
 /**
@@ -74,57 +69,7 @@
  * @version $Revision: $
  */
 public class Segment {
-	public class SegmentConstantPool {
-		public static final int ALL = 0;
 
-		public static final int CP_DOUBLE = 7;
-
-		// define in archive order
-
-		public static final int CP_FLOAT = 4; // TODO Check this
-
-		public static final int CP_INT = 3;
-
-		public static final int CP_LONG = 6;
-
-		public static final int CP_STRING = 5;
-
-		public static final int SIGNATURE = 2; // TODO and more to come --
-
-		public static final int UTF_8 = 1;
-
-		public Object getValue(int cp, long value) throws Pack200Exception {
-			int index = (int) value;
-			if (index == -1) {
-				return null;
-			} else if (index < 0) {
-				throw new Pack200Exception("Cannot have a negative range");
-			} else if (cp == UTF_8) {
-				return cpUTF8[index];
-			} else if (cp == CP_STRING) {
-				return cpString[index];
-			} else if (cp == SIGNATURE) {
-				return cpSignature[index];
-			} else if (cp == CP_INT) {
-				return new Integer(cpInt[index]);
-			} else if (cp == CP_FLOAT) {
-				return new Float(cpFloat[index]);
-			} else if (cp == CP_DOUBLE) {
-				return new Double(cpDouble[index]);
-			} else if (cp == CP_LONG) {
-				return new Long(cpLong[index]);
-			} else {
-				// etc
-				throw new Error("Get value incomplete");
-			}
-		}
-	}
-
-	/**
-	 * The magic header for a Pack200 Segment is 0xCAFED00D. I wonder where they
-	 * get their inspiration from ...
-	 */
-	private static final int[] magic = { 0xCA, 0xFE, 0xD0, 0x0D };
 
 	/**
 	 * Decode a segment from the given input stream. This does not attempt to
@@ -147,230 +92,83 @@
 			Pack200Exception {
 		Segment segment = new Segment();
 		// See if file is GZip compressed
-		if (in.markSupported()) {
-			in.mark(2);
-			if (((in.read() & 0xFF) | (in.read() & 0xFF) << 8) == GZIPInputStream.GZIP_MAGIC) {
-				in.reset();
-				in = new GZIPInputStream(in);
-			} else {
-				in.reset();
-			}
-
+		if (!in.markSupported()) {
+			in = new BufferedInputStream(in);
+			if (!in.markSupported())
+				throw new IllegalStateException();
+		}
+		in.mark(2);
+		if (((in.read() & 0xFF) | (in.read() & 0xFF) << 8) == GZIPInputStream.GZIP_MAGIC) {
+			in.reset();
+			in = new BufferedInputStream(new GZIPInputStream(in));
+		} else {
+			in.reset();
 		}
 		segment.parseSegment(in);
 		return segment;
 	}
 
-	/**
-	 * Completely reads in a byte array, akin to the implementation in
-	 * {@link java.lang.DataInputStream}. TODO Refactor out into a separate
-	 * InputStream handling class
-	 * 
-	 * @param in
-	 *            the input stream to read from
-	 * @param data
-	 *            the byte array to read into
-	 * @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
-	 */
-	private static void readFully(InputStream in, byte[] data)
-			throws IOException, Pack200Exception {
-		int total = in.read(data);
-		if (total == -1)
-			throw new EOFException("Failed to read any data from input stream");
-		while (total < data.length) {
-			int delta = in.read(data, total, data.length - total);
-			if (delta == -1)
-				throw new EOFException(
-						"Failed to read some data from input stream");
-			total += delta;
-		}
-	}
-
-	private int archiveMajor;
-
-	private int archiveMinor;
-
-	private long archiveModtime;
-
-	private long archiveSize;
-
-	private int attributeDefinitionCount;
-
-	private int[] attributeDefinitionHeader;
-
-	private String[] attributeDefinitionLayout;
-
-	private AttributeLayoutMap attributeDefinitionMap;
-
-	private String[] attributeDefinitionName;
-
-	private InputStream bandHeadersInputStream;
-
-	private int bandHeadersSize;
-
-	private int classAttrCount;
-
-	private int classCount;
-
-	private int[] classFieldCount;
-
-	private long[] classFlags;
-
-	private String[][] classInterfaces;
-
-	private int[] classMethodCount;
-
-	private String[] classSuper;
-
-	private String[] classThis;
-
-	private String[] cpClass;
-
-	private int cpClassCount;
-
-	private String[] cpDescriptor;
-
-	private int cpDescriptorCount;
-
-	private double[] cpDouble;
-
-	private int cpDoubleCount;
-
-	private String[] cpFieldClass;
-
-	private int cpFieldCount;
-
-	private Object cpFieldDescriptor;
-
-	private float[] cpFloat;
-
-	private int cpFloatCount;
-
-	private String[] cpIMethodClass;
-
-	private int cpIMethodCount;
-
-	private String[] cpIMethodDescriptor;
-
-	private int[] cpInt;
-
-	private int cpIntCount;
-
-	private long[] cpLong;
-
-	private int cpLongCount;
 
-	private String[] cpMethodClass;
+    private SegmentHeader header;
 
-	private int cpMethodCount;
+    private CpBands cpBands;
+    
+    private AttrDefinitionBands attrDefinitionBands;
 
-	private String[] cpMethodDescriptor;
+    private IcBands icBands;
 
-	private String[] cpSignature;
+    private ClassBands classBands;
 
-	private int cpSignatureCount;
+    private BcBands bcBands;
 
-	private String[] cpString;
+    private FileBands fileBands;
 
-	private int cpStringCount;
-
-	private String[] cpUTF8;
-
-	private int cpUTF8Count;
-
-	private int defaultClassMajorVersion;
-
-	private int defaultClassMinorVersion;
-
-	private int fieldAttrCount;
-
-	private ArrayList[][] fieldAttributes;
-
-	private String[][] fieldDescr;
-
-	private long[][] fieldFlags;
-
-	private byte[][] fileBits;
-
-	private long[] fileModtime;
-
-	private String[] fileName;
-
-	private long[] fileOptions;
-
-	private long[] fileSize;
-
-	private int[] icFlags;
-
-	private Object icName;
-
-	private String[] icOuterClass;
-
-	private String[] icThisClass;
-
-	private int innerClassCount;
-
-	private int methodAttrCount;
-
-	private ArrayList[][] methodAttributes;
-
-	private String[][] methodDescr;
-
-	private ExceptionsAttribute[][] methodExceptions;
-
-	private long[][] methodFlags;
-
-	private int numberOfFiles;
-
-	private SegmentOptions options;
-
-	private final SegmentConstantPool pool = new SegmentConstantPool();
-
-	private int segmentsRemaining;
-
-	private ClassFile buildClassFile(int classNum) {
+	private ClassFile buildClassFile(int classNum) throws Pack200Exception {
 		ClassFile classFile = new ClassFile();
-		classFile.major = defaultClassMajorVersion; // TODO If
+		classFile.major = header.getDefaultClassMajorVersion(); // TODO If
 		// classVersionMajor[] use
 		// that instead
-		classFile.minor = defaultClassMinorVersion; // TODO if
+		classFile.minor = header.getDefaultClassMinorVersion(); // TODO if
 		// classVersionMinor[] use
 		// that instead
 		// build constant pool
 		ClassConstantPool cp = classFile.pool;
-		String fullName = classThis[classNum];
+		String fullName = classBands.getClassThis()[classNum];
 		// SourceFile attribute
 		int i = fullName.lastIndexOf("/") + 1; // if lastIndexOf==-1, then
 		// -1+1=0, so str.substring(0)
 		// == str
-		String fileName = fullName.substring(i) + ".java";
-		classFile.attributes = new Attribute[] { (Attribute) cp
-				.add(new SourceFileAttribute(fileName)) };
+		AttributeLayout SOURCE_FILE = attrDefinitionBands.getAttributeDefinitionMap()
+				.getAttributeLayout(AttributeLayout.ATTRIBUTE_SOURCE_FILE,
+						AttributeLayout.CONTEXT_CLASS);
+		if (SOURCE_FILE.matches(classBands.getClassFlags()[classNum])) {
+			String fileName = fullName.substring(i) + ".java";
+			classFile.attributes = new Attribute[] { (Attribute) cp
+					.add(new SourceFileAttribute(fileName)) };
+		} else {
+			classFile.attributes = new Attribute[] {};
+		}
 		// this/superclass
 		ClassFileEntry cfThis = cp.add(new CPClass(fullName));
-		ClassFileEntry cfSuper = cp.add(new CPClass(classSuper[classNum]));
+		ClassFileEntry cfSuper = cp.add(new CPClass(classBands.getClassSuper()[classNum]));
 		// add interfaces
-		ClassFileEntry cfInterfaces[] = new ClassFileEntry[classInterfaces[classNum].length];
+		ClassFileEntry cfInterfaces[] = new ClassFileEntry[classBands.getClassInterfaces()[classNum].length];
 		for (i = 0; i < cfInterfaces.length; i++) {
-			cfInterfaces[i] = cp.add(new CPClass(classInterfaces[classNum][i]));
+			cfInterfaces[i] = cp.add(new CPClass(classBands.getClassInterfaces()[classNum][i]));
 		}
 		// add fields
-		ClassFileEntry cfFields[] = new ClassFileEntry[classFieldCount[classNum]];
+		ClassFileEntry cfFields[] = new ClassFileEntry[classBands.getClassFieldCount()[classNum]];
 		// fieldDescr and fieldFlags used to create this
 		for (i = 0; i < cfFields.length; i++) {
-			cfFields[i] = cp.add(new CPField(fieldDescr[classNum][i],
-					fieldFlags[classNum][i], fieldAttributes[classNum][i]));
+			cfFields[i] = cp.add(new CPField(classBands.getFieldDescr()[classNum][i],
+                    classBands.getFieldFlags()[classNum][i], classBands.getFieldAttributes()[classNum][i]));
 		}
 		// add methods
-		ClassFileEntry cfMethods[] = new ClassFileEntry[classMethodCount[classNum]];
+		ClassFileEntry cfMethods[] = new ClassFileEntry[classBands.getClassMethodCount()[classNum]];
 		// fieldDescr and fieldFlags used to create this
 		for (i = 0; i < cfMethods.length; i++) {
-			cfMethods[i] = cp.add(new CPMethod(methodDescr[classNum][i],
-					methodFlags[classNum][i], methodAttributes[classNum][i]));
+			cfMethods[i] = cp.add(new CPMethod(classBands.getMethodDescr()[classNum][i],
+                    classBands.getMethodFlags()[classNum][i], classBands.getMethodAttributes()[classNum][i]));
 		}
 		// sort CP according to cp_All
 		cp.resolve();
@@ -381,7 +179,7 @@
 		}
 		// NOTE the indexOf is only valid after the cp.resolve()
 		// build up remainder of file
-		classFile.accessFlags = (int) classFlags[classNum];
+		classFile.accessFlags = (int) classBands.getClassFlags()[classNum];
 		classFile.thisClass = cp.indexOf(cfThis);
 		classFile.superClass = cp.indexOf(cfSuper);
 		// TODO placate format of file for writing purposes
@@ -394,1340 +192,184 @@
 		return classFile;
 	}
 
-	/**
-	 * 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
-	 */
-	private void debug(String message) {
-		if (System.getProperty("debug.pack200") != null) {
-			System.err.println(message);
-		}
-	}
 
 	/**
-	 * Decode a band and return an array of <code>int[]</code> values
+	 * This performs the actual work of parsing against a non-static instance of
+	 * Segment.
 	 * 
-	 * @param name
-	 *            the name of the band (primarily for logging/debugging
-	 *            purposes)
 	 * @param in
-	 *            the InputStream to decode from
-	 * @param defaultCodec
-	 *            the default codec for this band
-	 * @param count
-	 *            the number of elements to read
-	 * @return an array of decoded <code>int[]</code> values
+	 *            the input stream to read from
 	 * @throws IOException
-	 *             if there is a problem reading from the underlying input
-	 *             stream
+	 *             if a problem occurs during reading from the underlying stream
 	 * @throws Pack200Exception
-	 *             if there is a problem decoding the value or that the value is
-	 *             invalid
+	 *             if a problem occurs with an unexpected value or unsupported
+	 *             codec
 	 */
-	private int[] decodeBandInt(String name, InputStream in,
-			BHSDCodec defaultCodec, int count) throws IOException,
+	private void parseSegment(InputStream in) throws IOException,
 			Pack200Exception {
-		// TODO Might be able to improve this directly.
-		int[] result = new int[count];
+		debug("-------");
+        header = new SegmentHeader();
+        header.unpack(in);        
+        cpBands = new CpBands(this);
+        cpBands.unpack(in);
+        attrDefinitionBands = new AttrDefinitionBands(this);
+        attrDefinitionBands.unpack(in);
+        icBands = new IcBands(this);
+        icBands.unpack(in);
+        classBands = new ClassBands(this);
+        classBands.unpack(in);
+        bcBands = new BcBands(this);
+        bcBands.unpack(in);
+        fileBands = new FileBands(this);
+        fileBands.unpack(in);
+	}
+    
+    /**
+     * Unpacks a packed stream (either .pack. or .pack.gz) into a corresponding
+     * JarOuputStream.
+     * 
+     * @throws Pack200Exception
+     *             if there is a problem unpacking
+     * @throws IOException
+     *             if there is a problem with I/O during unpacking
+     */
+    public void unpack(InputStream in, JarOutputStream out) throws IOException,
+            Pack200Exception {
+        if (!in.markSupported())
+            in = new BufferedInputStream(in);
+        // TODO Can handle multiple concatenated streams, so should deal with
+        // that possibility
+        parse(in).unpack(in, 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);
+        }
+    }
 
-		// TODO We need to muck around in the scenario where the first value
-		// read indicates
-		// an uber-codec
-		long[] longResult = decodeBandLong(name, in, defaultCodec, count);
-		for (int i = 0; i < count; i++) {
-			result[i] = (int) longResult[i];
-		}
-		return result;
-	}
 
-	/**
-	 * Decode a band and return an array of <code>long[]</code> values
-	 * 
-	 * @param name
-	 *            the name of the band (primarily for logging/debugging
-	 *            purposes)
-	 * @param in
-	 *            the InputStream to decode from
-	 * @param codec
-	 *            the default codec for this band
-	 * @param count
-	 *            the number of elements to read
-	 * @return an array of decoded <code>long[]</code> values
-	 * @throws IOException
-	 *             if there is a problem reading from the underlying input
-	 *             stream
-	 * @throws Pack200Exception
-	 *             if there is a problem decoding the value or that the value is
-	 *             invalid
-	 */
-	private long[] decodeBandLong(String name, InputStream in, BHSDCodec codec,
-			int count) throws IOException, Pack200Exception {
-		long[] result = codec.decode(count, in);
-		if (result.length > 0) {
-			int first = (int) result[0];
-			if (codec.isSigned() && first >= -256 && first <= -1) {
-				// TODO Well, switch codecs then ...
-				Codec weShouldHaveUsed = CodecEncoding.getCodec(-1 - first,
-						getBandHeadersInputStream(), codec);
-				throw new Error("Bugger. We should have switched codec to "
-						+ weShouldHaveUsed);
-			} else if (!codec.isSigned() && first >= codec.getL()
-					&& first <= codec.getL() + 255) {
-				Codec weShouldHaveUsed = CodecEncoding.getCodec(first
-						- codec.getL(), getBandHeadersInputStream(), codec);
-				// TODO Well, switch codecs then ...
-				throw new Error("Bugger. We should have switched codec to "
-						+ weShouldHaveUsed);
-			}
-		}
-		// TODO Remove debugging code
-		debug("Parsed *" + name + " (" + result.length + ")");
-		return result;
-	}
 
 	/**
-	 * Decode a scalar from the band file. A scalar is like a band, but does not
-	 * perform any band code switching.
+	 * Writes the segment to an output stream. The output stream should be
+	 * pre-buffered for efficiency. Also takes the same input stream for
+	 * reading, since the file bits may not be loaded and thus just copied from
+	 * one stream to another. Doesn't close the output stream when finished, in
+	 * case there are more entries (e.g. further segments) to be written.
 	 * 
-	 * @param name
-	 *            the name of the scalar (primarily for logging/debugging
-	 *            purposes)
+	 * @param out
+	 *            the JarOutputStream to write data to
 	 * @param in
-	 *            the input stream to read from
-	 * @param codec
-	 *            the codec for this scalar
-	 * @return the decoded value
+	 *            the same InputStream that was used to parse the segment
 	 * @throws IOException
-	 *             if there is a problem reading from the underlying input
-	 *             stream
+	 *             if an error occurs whilst reading or writing to the streams
 	 * @throws Pack200Exception
-	 *             if there is a problem decoding the value or that the value is
-	 *             invalid
+	 *             if an error occurs whilst unpacking data
 	 */
-	private long decodeScalar(String name, InputStream in, BHSDCodec codec)
+	public void writeJar(JarOutputStream out, InputStream in)
 			throws IOException, Pack200Exception {
-		debug("Parsed #" + name + " (1)");
-		return codec.decode(in);
-	}
-
-	/**
-	 * Decode a number of scalars from the band file. A scalar is like a band,
-	 * but does not perform any band code switching.
-	 * 
-	 * @param name
-	 *            the name of the scalar (primarily for logging/debugging
-	 *            purposes)
-	 * @param in
-	 *            the input stream to read from
-	 * @param codec
-	 *            the codec for this scalar
-	 * @return an array of decoded <code>long[]</code> values
-	 * @throws IOException
-	 *             if there is a problem reading from the underlying input
-	 *             stream
-	 * @throws Pack200Exception
-	 *             if there is a problem decoding the value or that the value is
-	 *             invalid
-	 */
-	private long[] decodeScalar(String name, InputStream in, BHSDCodec codec,
-			int n) throws IOException, Pack200Exception {
-		// TODO Remove debugging code
-		debug("Parsed #" + name + " (" + n + ")");
-		return codec.decode(n, in);
-	}
-
-	public long getArchiveModtime() {
-		return archiveModtime;
-	}
-
-	public long getArchiveSize() {
-		return archiveSize;
-	}
+		fileBands.processFileBits(in);
+		DataOutputStream dos = new DataOutputStream(out);
+        String[] fileName = fileBands.getFileName();
+        long[] fileModtime = fileBands.getFileModtime();
+        long[] fileOptions = fileBands.getFileOptions();
+        long[] fileSize = fileBands.getFileSize();
+        byte[][] fileBits = fileBands.getFileBits();
+       
+		// out.setLevel(JarEntry.DEFLATED)
+		// now write the files out
+		int classNum = 0;
+        int numberOfFiles = header.getNumberOfFiles();
+        long archiveModtime = header.getArchiveModtime();
+        SegmentOptions options = header.getOptions();
+		for (int i = 0; i < numberOfFiles; i++) {
+			String name = fileName[i];
+			long modtime = archiveModtime + fileModtime[i];
+			boolean deflate = (fileOptions[i] & 1) == 1
+					|| options.shouldDeflate();
+			boolean isClass = (fileOptions[i] & 2) == 2 || name == null
+					|| name.equals("");
+			if (isClass) {
+				// pull from headers
+				if (name == null || name.equals(""))
+					name = classBands.getClassThis()[classNum] + ".class";
+			}
+			JarEntry entry = new JarEntry(name);
+			if (deflate)
+				entry.setMethod(JarEntry.DEFLATED);
+			entry.setTime(modtime);
+			out.putNextEntry(entry);
 
-	/**
-	 * Obtain the band headers data as an input stream. If no band headers are
-	 * present, this will return an empty input stream to prevent any further
-	 * reads taking place.
-	 * 
-	 * Note that as a stream, data consumed from this input stream can't be
-	 * re-used. Data is only read from this stream if the encoding is such that
-	 * additional information needs to be decoded from the stream itself.
-	 * 
-	 * @return the band headers input stream
-	 */
-	public InputStream getBandHeadersInputStream() {
-		if (bandHeadersInputStream == null) {
-			bandHeadersInputStream = new ByteArrayInputStream(new byte[0]);
+			if (isClass) {
+				// write to dos
+				ClassFile classFile = buildClassFile(classNum);
+				classFile.write(dos);
+				dos.flush();
+				classNum++;
+			} else {
+				long size = fileSize[i];
+				entry.setSize(size);
+				// TODO pull from in
+				byte[] data = fileBits[i];
+				out.write(data);
+			}
 		}
-		return bandHeadersInputStream;
-
+		dos.flush();
+		out.finish();
+		out.flush();
 	}
 
-	public SegmentConstantPool getConstantPool() {
-		return pool;
-	}
+    public SegmentConstantPool getConstantPool() {
+        return cpBands.getConstantPool();
+    }
 
-	public int getNumberOfFiles() {
-		return numberOfFiles;
-	}
 
-	private SegmentOptions getOptions() {
-		return options;
-	}
+    public SegmentHeader getSegmentHeader() {
+        return header;
+    }
 
-	public int getSegmentsRemaining() {
-		return segmentsRemaining;
-	}
 
-	private void parseArchiveFileCounts(InputStream in) throws IOException,
-			Pack200Exception {
-		if (getOptions().hasArchiveFileCounts()) {
-			setArchiveSize(decodeScalar("archive_size_hi", in, Codec.UNSIGNED5) << 32
-					| decodeScalar("archive_size_lo", in, Codec.UNSIGNED5));
-			setSegmentsRemaining(decodeScalar("archive_next_count", in,
-					Codec.UNSIGNED5));
-			setArchiveModtime(decodeScalar("archive_modtime", in,
-					Codec.UNSIGNED5));
-			setNumberOfFiles(decodeScalar("file_count", in, Codec.UNSIGNED5));
-		}
-	}
+    protected AttrDefinitionBands getAttrDefinitionBands() {
+        return attrDefinitionBands;
+    }
 
-	private void parseArchiveSpecialCounts(InputStream in) throws IOException,
-			Pack200Exception {
-		if (getOptions().hasSpecialFormats()) {
-			setBandHeadersSize(decodeScalar("band_headers_size", in,
-					Codec.UNSIGNED5));
-			setAttributeDefinitionCount(decodeScalar("attr_definition_count",
-					in, Codec.UNSIGNED5));
-		}
-	}
 
-	/**
-	 * Reads {@link #attributeDefinitionCount} attribute definitions from the
-	 * stream, into {@link #attributeDefinitionHeader},
-	 * {@link #attributeDefinitionName} and {@link #attributeDefinitionLayout}.
-	 * This affects the codecs that are used to parse non-standard bands. TODO
-	 * Currently, these values if present cause a failure in the parsing.
-	 * 
-	 * @param in
-	 *            the input stream to read from
-	 * @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
-	 */
-	private void parseAttributeDefinition(InputStream in) throws IOException,
-			Pack200Exception {
-		attributeDefinitionHeader = decodeBandInt("attr_definition_headers",
-				in, Codec.BYTE1, attributeDefinitionCount);
-		attributeDefinitionName = parseReferences("attr_definition_name", in,
-				Codec.UNSIGNED5, attributeDefinitionCount, cpUTF8);
-		attributeDefinitionLayout = parseReferences("attr_definition_layout",
-				in, Codec.UNSIGNED5, attributeDefinitionCount, cpUTF8);
-		if (attributeDefinitionCount > 0)
-			throw new Error("No idea what the adc is for yet");
-		attributeDefinitionMap = new AttributeLayoutMap();
-	}
+    protected BcBands getBcBands() {
+        return bcBands;
+    }
 
-	/**
-	 * @param in
-	 * @throws Pack200Exception
-	 * @throws IOException
-	 */
-	private void parseAttributeMethodExceptions(InputStream in)
-			throws Pack200Exception, IOException {
-		// TODO Should refactor this stuff into the layout somehow
-		AttributeLayout layout = attributeDefinitionMap.getAttributeLayout(
-				"Exceptions", AttributeLayout.CONTEXT_METHOD);
-		Codec codec = layout.getCodec();
-		methodExceptions = new ExceptionsAttribute[classCount][];
-		int[][] numExceptions = new int[classCount][];
-		for (int i = 0; i < classCount; i++) {
-			numExceptions[i] = new int[methodFlags[i].length];
-			for (int j = 0; j < methodFlags[i].length; j++) {
-				long flag = methodFlags[i][j];
-				if (layout.matches(flag)) {
-					numExceptions[i][j] = (int) codec.decode(in);
-				}
-			}
-		}
-		for (int i = 0; i < classCount; i++) {
-			methodExceptions[i] = new ExceptionsAttribute[methodFlags[i].length];
-			for (int j = 0; j < methodFlags[i].length; j++) {
-				long flag = methodFlags[i][j];
-				int n = numExceptions[i][j];
-				CPClass[] exceptions = new CPClass[n];
-				if (layout.matches(flag)) {
-					for (int k = 0; k < n; k++) {
-						long result = codec.decode(in);
-						exceptions[k] = new CPClass(cpClass[(int) result]);
-					}
-				}
-				methodExceptions[i][j] = new ExceptionsAttribute(exceptions);
-				methodAttributes[i][j].add(methodExceptions[i][j]);
-			}
-		}
-	}
 
-	/**
-	 * @param in
-	 * 
-	 */
-	private void parseAttributeMethodSignature(InputStream in)
-			throws Pack200Exception, IOException {
-		parseAttributeUnknown(AttributeLayout.ATTRIBUTE_SIGNATURE,
-				AttributeLayout.CONTEXT_METHOD, methodFlags);
-	}
+    protected ClassBands getClassBands() {
+        return classBands;
+    }
 
-	/**
-	 * @param name
-	 * @param flags
-	 * @throws Pack200Exception
-	 */
-	private void parseAttributeUnknown(String name, int context, long[][] flags)
-			throws Pack200Exception {
-		debug("Parsing unknown attributes for " + name);
-		AttributeLayout layout = attributeDefinitionMap.getAttributeLayout(
-				name, context);
-		for (int i = 0; i < flags.length; i++) {
-			for (int j = 0; j < flags[i].length; j++) {
-				if (layout.matches(flags[i][j]))
-					throw new Error("We've got data for " + name
-							+ " and we don't know what to do with it (yet)");
-			}
-		}
-	}
 
-	private void parseBcBands(InputStream in) {
-		debug("Unimplemented bc_bands");
-	}
+    protected CpBands getCpBands() {
+        return cpBands;
+    }
 
-	private void parseClassAttrBands(InputStream in) throws IOException,
-			Pack200Exception {
-		classFlags = parseFlags("class_flags", in, classCount, Codec.UNSIGNED5,
-				options.hasClassFlagsHi());
-		for (int i = 0; i < classCount; i++) {
-			long flag = classFlags[i];
-			if ((flag & (1 << 16)) != 0)
-				classAttrCount++;
-		}
-		if (classAttrCount > 0)
-			throw new Error(
-					"There are attribute flags, and I don't know what to do with them");
-		debug("unimplemented class_attr_count");
-		debug("unimplemented class_attr_indexes");
-		debug("unimplemented class_attr_calls");
-		AttributeLayout layout = attributeDefinitionMap.getAttributeLayout(
-				AttributeLayout.ATTRIBUTE_SOURCE_FILE,
-				AttributeLayout.CONTEXT_CLASS);
-		for (int i = 0; i < classCount; i++) {
-			long flag = classFlags[i];
-			if (layout.matches(flag)) {
-				// we've got a value to read
-				// TODO File this as a sourcefile attribute and don't generate
-				// everything below
-				long result = layout.getCodec().decode(in);
-				Object value = layout.getValue(result, this);
-				debug("Processed value " + value + " for SourceFile");
-			}
-		}
-		debug("unimplemented class_EnclosingMethod_RC");
-		debug("unimplemented class_EnclosingMethod_RDN");
-		debug("unimplemented class_Signature_RS");
-		parseMetadataBands("class");
-		debug("unimplemented class_InnerClasses_N");
-		debug("unimplemented class_InnerClasses_RC");
-		debug("unimplemented class_InnerClasses_F");
-		debug("unimplemented class_InnerClasses_outer_RCN");
-		debug("unimplemented class_InnerClasses_inner_RCN");
-		debug("unimplemented class_file_version_minor_H");
-		debug("unimplemented class_file_version_major_H");
-	}
 
-	private void parseClassBands(InputStream in) throws IOException,
-			Pack200Exception {
-		classThis = parseReferences("class_this", in, Codec.DELTA5, classCount,
-				cpClass);
-		classSuper = parseReferences("class_super", in, Codec.DELTA5,
-				classCount, cpClass);
-		classInterfaces = new String[classCount][];
-		int[] classInterfaceLengths = decodeBandInt("class_interface_count",
-				in, Codec.DELTA5, classCount);
-		// for (int i = 0; i < classCount; i++) {
-		classInterfaces = parseReferences("class_interface", in, Codec.DELTA5,
-				classCount, classInterfaceLengths, cpClass);
-		// }
-		classFieldCount = decodeBandInt("class_field_count", in, Codec.DELTA5,
-				classCount);
-		classMethodCount = decodeBandInt("class_method_count", in,
-				Codec.DELTA5, classCount);
-		parseFieldBands(in);
-		parseMethodBands(in);
-		parseClassAttrBands(in);
-		parseCodeBands(in);
-	}
+    protected FileBands getFileBands() {
+        return fileBands;
+    }
 
-	private void parseClassCounts(InputStream in) throws IOException,
-			Pack200Exception {
-		setInnerClassCount(decodeScalar("ic_count", in, Codec.UNSIGNED5));
-		setDefaultClassMinorVersion(decodeScalar("default_class_minver", in,
-				Codec.UNSIGNED5));
-		setDefaultClassMajorVersion(decodeScalar("default_class_majver", in,
-				Codec.UNSIGNED5));
-		setClassCount(decodeScalar("class_count", in, Codec.UNSIGNED5));
-	}
 
-	private void parseCodeAttrBands(InputStream in) {
-		debug("unimplemented code_flags");
-		debug("unimplemented code_attr_count");
-		debug("unimplemented code_attr_indexes");
-		debug("unimplemented code_attr_calls");
-		debug("unimplemented code_LineNumberTable_N");
-		debug("unimplemented code_LineNumberTable_bci_P");
-		debug("unimplemented code_LineNumberTable_line");
-		String[] types = { "LocalVariableTable", "LocalVariableTypeTable" };
-		for (int i = 0; i < types.length; i++) {
-			String type = types[i];
-			debug("unimplemented code_" + type + "_N");
-			debug("unimplemented code_" + type + "_bci_P");
-			debug("unimplemented code_" + type + "_span_O");
-			debug("unimplemented code_" + type + "_name_RU");
-			debug("unimplemented code_" + type + "_type_RS");
-			debug("unimplemented code_" + type + "_slot");
-		}
-	}
+    protected SegmentHeader getHeader() {
+        return header;
+    }
 
-	private void parseCodeBands(InputStream in) throws Pack200Exception {
-		// look through each method
-		int codeBands = 0;
-		AttributeLayout layout = attributeDefinitionMap.getAttributeLayout(
-				AttributeLayout.ATTRIBUTE_CODE, AttributeLayout.CONTEXT_METHOD);
-
-		for (int i = 0; i < classCount; i++) {
-			for (int j = 0; j < methodFlags[i].length; j++) {
-				long flag = methodFlags[i][j];
-				if (layout.matches(flag))
-					codeBands++;
-			}
-		}
-		if (codeBands > 0)
-			throw new Error(
-					"Can't handle non-abstract, non-native methods/initializers at the moment (found "
-							+ codeBands + " code bands)");
-		debug("unimplemented code_headers");
-		debug("unimplemented code_max_stack");
-		debug("unimplemented code_max_na_locals");
-		debug("unimplemented code_hander_count");
-		debug("unimplemented code_hander_start_P");
-		debug("unimplemented code_hander_end_PO");
-		debug("unimplemented code_hander_catch_PO");
-		debug("unimplemented code_hander_class_RC");
-		parseCodeAttrBands(in);
-	}
 
-	/**
-	 * Parses the constant pool class names, using {@link #cpClassCount} to
-	 * populate {@link #cpClass} from {@link #cpUTF8}.
-	 * 
-	 * @param in
-	 *            the input stream to read from
-	 * @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
-	 */
-	private void parseCpClass(InputStream in) throws IOException,
-			Pack200Exception {
-		cpClass = parseReferences("cp_Class", in, Codec.UDELTA5, cpClassCount,
-				cpUTF8);
-	}
+    protected IcBands getIcBands() {
+        return icBands;
+    }
 
-	private void parseCpCounts(InputStream in) throws IOException,
-			Pack200Exception {
-		setCPUtf8Count(decodeScalar("cp_Utf8_count", in, Codec.UNSIGNED5));
-		if (getOptions().hasCPNumberCounts()) {
-			setCPIntCount(decodeScalar("cp_Int_count", in, Codec.UNSIGNED5));
-			setCPFloatCount(decodeScalar("cp_Float_count", in, Codec.UNSIGNED5));
-			setCPLongCount(decodeScalar("cp_Long_count", in, Codec.UNSIGNED5));
-			setCPDoubleCount(decodeScalar("cp_Double_count", in,
-					Codec.UNSIGNED5));
-		}
-		setCPStringCount(decodeScalar("cp_String_count", in, Codec.UNSIGNED5));
-		setCPClassCount(decodeScalar("cp_Class_count", in, Codec.UNSIGNED5));
-		setCPSignatureCount(decodeScalar("cp_Signature_count", in,
-				Codec.UNSIGNED5));
-		setCPDescriptorCount(decodeScalar("cp_Descr_count", in, Codec.UNSIGNED5));
-		setCPFieldCount(decodeScalar("cp_Field_count", in, Codec.UNSIGNED5));
-		setCPMethodCount(decodeScalar("cp_Method_count", in, Codec.UNSIGNED5));
-		setCPIMethodCount(decodeScalar("cp_Imethod_count", in, Codec.UNSIGNED5));
-	}
-
-	/**
-	 * Parses the constant pool descriptor definitions, using
-	 * {@link #cpDescriptorCount} to populate {@link #cpDescriptor}. For ease
-	 * of use, the cpDescriptor is stored as a string of the form <i>name:type</i>,
-	 * largely to make it easier for representing field and method descriptors
-	 * (e.g. <code>out:java.lang.PrintStream</code>) in a way that is
-	 * compatible with passing String arrays.
-	 * 
-	 * @param in
-	 *            the input stream to read from
-	 * @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
-	 */
-	private void parseCpDescriptor(InputStream in) throws IOException,
-			Pack200Exception {
-		String[] cpDescriptorNames = parseReferences("cp_Descr_name", in,
-				Codec.DELTA5, cpDescriptorCount, cpUTF8);
-		String[] cpDescriptorTypes = parseReferences("cp_Descr_type", in,
-				Codec.UDELTA5, cpDescriptorCount, cpSignature);
-		cpDescriptor = new String[cpDescriptorCount];
-		for (int i = 0; i < cpDescriptorCount; i++) {
-			cpDescriptor[i] = cpDescriptorNames[i] + ":" + cpDescriptorTypes[i]; //$NON-NLS-1$
-		}
-	}
-
-	private void parseCpDouble(InputStream in) throws IOException,
-			Pack200Exception {
-		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]);
-		}
-	}
-
-	/**
-	 * Parses the constant pool field definitions, using {@link #cpFieldCount}
-	 * to populate {@link #cpFieldClass} and {@link #cpFieldDescriptor}.
-	 * 
-	 * @param in
-	 *            the input stream to read from
-	 * @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
-	 */
-	private void parseCpField(InputStream in) throws IOException,
-			Pack200Exception {
-		cpFieldClass = parseReferences("cp_Field_class", in, Codec.DELTA5,
-				cpFieldCount, cpClass);
-		cpFieldDescriptor = parseReferences("cp_Field_desc", in, Codec.UDELTA5,
-				cpFieldCount, cpDescriptor);
-	}
-
-	private void parseCpFloat(InputStream in) throws IOException,
-			Pack200Exception {
-		cpFloat = new float[cpFloatCount];
-		int floatBits[] = decodeBandInt("cp_Float", in, Codec.UDELTA5,
-				cpFloatCount);
-		for (int i = 0; i < cpFloatCount; i++) {
-			cpFloat[i] = Float.intBitsToFloat(floatBits[i]);
-		}
-	}
-
-	/**
-	 * Parses the constant pool interface method definitions, using
-	 * {@link #cpIMethodCount} to populate {@link #cpIMethodClass} and
-	 * {@link #cpIMethodDescriptor}.
-	 * 
-	 * @param in
-	 *            the input stream to read from
-	 * @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
-	 */
-	private void parseCpIMethod(InputStream in) throws IOException,
-			Pack200Exception {
-		cpIMethodClass = parseReferences("cp_Imethod_class", in, Codec.DELTA5,
-				cpIMethodCount, cpClass);
-		cpIMethodDescriptor = parseReferences("cp_Imethod_desc", in,
-				Codec.UDELTA5, cpIMethodCount, cpDescriptor);
-	}
-
-	private void parseCpInt(InputStream in) throws IOException,
-			Pack200Exception {
-		cpInt = new int[cpIntCount];
-		long last = 0;
-		for (int i = 0; i < cpIntCount; i++) {
-			last = Codec.UDELTA5.decode(in, last);
-			cpInt[i] = (int) last;
-		}
-	}
-
-	private void parseCpLong(InputStream in) throws IOException,
-			Pack200Exception {
-		cpLong = parseFlags("cp_Long", in, cpLongCount, new int[] { 1 },
-				Codec.UDELTA5, Codec.DELTA5)[0];
-	}
-
-	/**
-	 * Parses the constant pool method definitions, using {@link #cpMethodCount}
-	 * to populate {@link #cpMethodClass} and {@link #cpMethodDescriptor}.
-	 * 
-	 * @param in
-	 *            the input stream to read from
-	 * @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
-	 */
-	private void parseCpMethod(InputStream in) throws IOException,
-			Pack200Exception {
-		cpMethodClass = parseReferences("cp_Method_class", in, Codec.DELTA5,
-				cpMethodCount, cpClass);
-		cpMethodDescriptor = parseReferences("cp_Method_desc", in,
-				Codec.UDELTA5, cpMethodCount, cpDescriptor);
-	}
-
-	/**
-	 * Parses the constant pool signature classes, using
-	 * {@link #cpSignatureCount} to populate {@link #cpSignature}. A signature
-	 * form is akin to the bytecode representation of a class; Z for boolean, I
-	 * for int, [ for array etc. However, although classes are started with L,
-	 * the classname does not follow the form; instead, there is a separate
-	 * array of classes. So an array corresponding to
-	 * <code>public static void main(String args[])</code> has a form of
-	 * <code>[L(V)</code> and a classes array of
-	 * <code>[java.lang.String]</code>. The {@link #cpSignature} is a string
-	 * representation identical to the bytecode equivalent
-	 * <code>[Ljava/lang/String;(V)</code> TODO Check that the form is as
-	 * above and update other types e.g. J
-	 * 
-	 * @param in
-	 *            the input stream to read from
-	 * @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
-	 */
-	private void parseCpSignature(InputStream in) throws IOException,
-			Pack200Exception {
-		String[] cpSignatureForm = parseReferences("cp_Signature_form", in,
-				Codec.DELTA5, cpSignatureCount, cpUTF8);
-		cpSignature = new String[cpSignatureCount];
-		long last = 0;
-		for (int i = 0; i < cpSignatureCount; i++) {
-			String form = cpSignatureForm[i];
-			int len = form.length();
-			StringBuffer signature = new StringBuffer(64);
-			ArrayList list = new ArrayList();
-			for (int j = 0; j < len; j++) {
-				char c = form.charAt(j);
-				signature.append(c);
-				if (c == 'L') {
-					int index = (int) (last = Codec.UDELTA5.decode(in, last));
-					String className = cpClass[index];
-					list.add(className);
-					signature.append(className);
-				}
-			}
-			cpSignature[i] = signature.toString();
-		}
-	}
-
-	/**
-	 * Parses the constant pool strings, using {@link #cpStringCount} to
-	 * populate {@link #cpString} from indexes into {@link #cpUTF8}.
-	 * 
-	 * @param in
-	 *            the input stream to read from
-	 * @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
-	 */
-	private void parseCpString(InputStream in) throws IOException,
-			Pack200Exception {
-		cpString = new String[cpStringCount];
-		long last = 0;
-		for (int i = 0; i < cpStringCount; i++) {
-			int index = (int) (last = Codec.UDELTA5.decode(in, last));
-			cpString[i] = cpUTF8[index];
-		}
-	}
-
-	private void parseCpUtf8(InputStream in) throws IOException,
-			Pack200Exception {
-		// TODO Update codec.decode -> decodeScalar
-		cpUTF8 = new String[cpUTF8Count];
-		cpUTF8[0] = ""; //$NON-NLS-1$
-		int[] prefix = new int[cpUTF8Count];
-		int[] suffix = new int[cpUTF8Count];
-		if (cpUTF8Count > 0) {
-			prefix[0] = 0;
-			suffix[0] = 0;
-			if (cpUTF8Count > 1)
-				prefix[1] = 0;
-		}
-		long last = 0;
-		for (int i = 2; i < cpUTF8Count; i++) {
-			last = prefix[i] = (int) Codec.DELTA5.decode(in, last);
-		}
-		int chars = 0;
-		int bigSuffix = 0;
-		for (int i = 1; i < cpUTF8Count; i++) {
-			last = suffix[i] = (int) Codec.UNSIGNED5.decode(in);
-			if (last == 0) {
-				bigSuffix++;
-			} else {
-				chars += last;
-			}
-		}
-		char data[] = new char[chars];
-		for (int i = 0; i < data.length; i++) {
-			data[i] = (char) Codec.CHAR3.decode(in);
-		}
-		// read in the big suffix data
-		char bigSuffixData[][] = new char[bigSuffix][];
-		last = 0;
-		for (int i = 0; i < bigSuffix; i++) {
-			last = (int) Codec.DELTA5.decode(in, last);
-			bigSuffixData[i] = new char[(int) last];
-		}
-		// initialize big suffix data
-		for (int i = 0; i < bigSuffix; i++) {
-			char[] singleBigSuffixData = bigSuffixData[i];
-			last = 0;
-			for (int j = 0; j < singleBigSuffixData.length; j++) {
-				last = singleBigSuffixData[j] = (char) Codec.DELTA5.decode(in,
-						last);
-			}
-		}
-		// go through the strings
-		chars = 0;
-		bigSuffix = 0;
-		for (int i = 1; i < cpUTF8Count; i++) {
-			String lastString = cpUTF8[i - 1];
-			if (suffix[i] == 0) {
-				// The big suffix stuff hasn't been tested, and I'll be
-				// surprised if it works first time w/o errors ...
-				cpUTF8[i] = lastString.substring(0, prefix[i])
-						+ new String(bigSuffixData[bigSuffix++]);
-			} else {
-				cpUTF8[i] = lastString.substring(0, prefix[i])
-						+ new String(data, chars, suffix[i]);
-				chars += suffix[i];
-			}
-		}
-	}
-
-	private void parseFieldBands(InputStream in) throws IOException,
-			Pack200Exception {
-		fieldDescr = parseReferences("field_descr", in, Codec.DELTA5,
-				classCount, classFieldCount, cpDescriptor);
-		fieldFlags = parseFlags("field_flags", in, classCount, classFieldCount,
-				Codec.UNSIGNED5, options.hasFieldFlagsHi());
-		for (int i = 0; i < classCount; i++) {
-			for (int j = 0; j < 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");
-		debug("unimplemented field_attr_indexes");
-		debug("unimplemented field_attr_calls");
-		AttributeLayout layout = attributeDefinitionMap.getAttributeLayout(
-				"ConstantValue", AttributeLayout.CONTEXT_FIELD);
-		Codec codec = layout.getCodec();
-		fieldAttributes = new ArrayList[classCount][];
-		for (int i = 0; i < classCount; i++) {
-			fieldAttributes[i] = new ArrayList[fieldFlags[i].length];
-			for (int j = 0; j < fieldFlags[i].length; j++) {
-				fieldAttributes[i][j] = new ArrayList();
-				long flag = fieldFlags[i][j];
-				if (layout.matches(flag)) {
-					// we've got a value to read
-					long result = codec.decode(in);
-					String desc = fieldDescr[i][j];
-					int colon = desc.indexOf(':');
-					// String name = desc.substring(0, colon);
-					String type = desc.substring(colon + 1);
-					// TODO Got to get better at this ... in any case, it should
-					// be e.g. KIB or KIH
-					if (type.equals("B") || type.equals("H"))
-						type = "I";
-					Object value = layout.getValue(result, type, this);
-					fieldAttributes[i][j]
-							.add(new ConstantValueAttribute(value));
-					debug("Processed value " + value + " for ConstantValue");
-				}
-			}
-		}
-		debug("unimplemented field_Signature_RS");
-		parseMetadataBands("field");
-	}
-
-	/**
-	 * Parses the file band headers (not including the actual bits themselves).
-	 * At the end of this parse call, the input stream will be positioned at the
-	 * start of the file_bits themselves, and there will be Sum(file_size) bits
-	 * remaining in the stream with BYTE1 compression. A decent implementation
-	 * will probably just stream the bytes out to the reconstituted Jar rather
-	 * than caching them.
-	 * 
-	 * @param in
-	 *            the input stream to read from
-	 * @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
-	 */
-	private void parseFileBands(InputStream in) throws IOException,
-			Pack200Exception {
-		if (false && System.getProperty("debug.pack200") != null) {
-			// TODO HACK
-			fileSize = new long[numberOfFiles];
-			fileModtime = new long[numberOfFiles];
-			fileOptions = new long[numberOfFiles];
-			fileName = new String[numberOfFiles];
-			Arrays.fill(fileName, "");
-			return;
-		}
-		long last;
-		fileName = parseReferences("file_name", in, Codec.UNSIGNED5,
-				numberOfFiles, cpUTF8);
-		fileSize = new long[numberOfFiles];
-		if (options.hasFileSizeHi()) {
-			last = 0;
-			for (int i = 0; i < numberOfFiles; i++) {
-				fileSize[i] = (last = Codec.UNSIGNED5.decode(in, last)) << 32;
-			}
-		}
-		last = 0;
-		for (int i = 0; i < numberOfFiles; i++) {
-			fileSize[i] |= (last = Codec.UNSIGNED5.decode(in, last));
-		}
-		fileModtime = new long[numberOfFiles];
-		if (options.hasFileModtime()) {
-			last = 0;
-			for (int i = 0; i < numberOfFiles; i++) {
-				fileModtime[i] |= (last = Codec.DELTA5.decode(in, last));
-			}
-		}
-		fileOptions = new long[numberOfFiles];
-		if (options.hasFileOptions()) {
-			last = 0;
-			for (int i = 0; i < numberOfFiles; i++) {
-				fileOptions[i] |= (last = Codec.UNSIGNED5.decode(in, last));
-			}
-		}
-	}
-
-	private long[] parseFlags(String name, InputStream in, int count,
-			Codec codec, boolean hasHi) throws IOException, Pack200Exception {
-		return parseFlags(name, in, 1, new int[] { count }, (hasHi ? codec
-				: null), codec)[0];
-	}
-
-	private long[][] parseFlags(String name, InputStream in, int count,
-			int counts[], Codec codec, boolean hasHi) throws IOException,
-			Pack200Exception {
-		return parseFlags(name, in, count, counts, (hasHi ? codec : null),
-				codec);
-	}
-
-	private long[][] parseFlags(String name, InputStream in, int count,
-			int counts[], Codec hiCodec, Codec loCodec) throws IOException,
-			Pack200Exception {
-		// TODO Move away from decoding into a parseBand type structure
-		if (count == 0) {
-			return new long[][] { {} };
-		}
-		long[][] result = new long[count][];
-		// TODO What happens when the decode here indicates a different
-		// encoding?
-		// TODO Move this to a decodeBandInt
-		long last = 0;
-		for (int j = 0; j < count; j++) {
-			result[j] = new long[counts[j]];
-			for (int i = 0; i < counts[j] && hiCodec != null; i++) {
-				last = hiCodec.decode(in, last);
-				result[j][i] = last << 32;
-			}
-		}
-		last = 0;
-		for (int j = 0; j < count; j++)
-			for (int i = 0; i < counts[j]; i++) {
-				last = loCodec.decode(in, last);
-				result[j][i] = result[j][i] | last;
-			}
-		// TODO Remove debugging code
-		debug("Parsed *" + name + " (" + result.length + ")");
-		return result;
-	}
-
-	private void parseIcBands(InputStream in) throws IOException,
-			Pack200Exception {
-		icThisClass = parseReferences("ic_this_class", in, Codec.UDELTA5,
-				innerClassCount, cpClass);
-		icFlags = new int[innerClassCount];
-		long last = 0;
-		int outerClasses = 0;
-		// ic_flags
-		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("ic_outer_class", in, Codec.DELTA5,
-				outerClasses, cpClass);
-		icName = parseReferences("ic_name", in, Codec.DELTA5, outerClasses,
-				cpUTF8);
-	}
-
-	private void parseMetadataBands(String unit) throws Pack200Exception {
-		String[] RxA;
-		if ("method".equals(unit)) {
-			RxA = new String[] { "RVA", "RIA", "RVPA", "RIPA", "AD" };
-		} else if ("field".equals(unit) || "class".equals(unit)) {
-			RxA = new String[] { "RVA", "RIA" };
-		} else {
-			throw new Pack200Exception("Unknown type of metadata unit " + unit);
-		}
-		for (int i = 0; i < RxA.length; i++) {
-			String rxa = RxA[i];
-			if (rxa.indexOf("P") >= 0) {
-				debug("unimplemented " + unit + "_" + rxa + "_param_NB");
-			}
-			if (!rxa.equals("AD")) {
-				debug("unimplemented " + unit + "_" + rxa + "_anno_N");
-				debug("unimplemented " + unit + "_" + rxa + "_type_RS");
-				debug("unimplemented " + unit + "_" + rxa + "_pair_N");
-				debug("unimplemented " + unit + "_" + rxa + "_name_RU");
-			}
-			debug("unimplemented " + unit + "_" + rxa + "_T");
-			debug("unimplemented " + unit + "_" + rxa + "_caseI_KI");
-			debug("unimplemented " + unit + "_" + rxa + "_caseD_KD");
-			debug("unimplemented " + unit + "_" + rxa + "_caseF_KF");
-			debug("unimplemented " + unit + "_" + rxa + "_caseJ_KJ");
-			debug("unimplemented " + unit + "_" + rxa + "_casec_RS");
-			debug("unimplemented " + unit + "_" + rxa + "_caseet_RS");
-			debug("unimplemented " + unit + "_" + rxa + "_caseec_RU");
-			debug("unimplemented " + unit + "_" + rxa + "_cases_RU");
-			debug("unimplemented " + unit + "_" + rxa + "_casearray_N");
-			debug("unimplemented " + unit + "_" + rxa + "_nesttype_RS");
-			debug("unimplemented " + unit + "_" + rxa + "_nestpair_N");
-			debug("unimplemented " + unit + "_" + rxa + "_nestname_RU");
-		}
-	}
-
-	private void parseMethodBands(InputStream in) throws IOException,
-			Pack200Exception {
-		methodDescr = parseReferences("method_descr", in, Codec.MDELTA5,
-				classCount, classMethodCount, cpDescriptor);
-		methodFlags = parseFlags("method_flags", in, classCount,
-				classMethodCount, Codec.UNSIGNED5, options.hasMethodFlagsHi());
-		for (int i = 0; i < classCount; i++) {
-			for (int j = 0; j < methodFlags[i].length; j++) {
-				long flag = methodFlags[i][j];
-				if ((flag & (1 << 16)) != 0)
-					methodAttrCount++;
-			}
-		}
-		if (methodAttrCount > 0)
-			throw new Error(
-					"There are method attribute flags, and I don't know what to do with them");
-		debug("unimplemented method_attr_count");
-		debug("unimplemented method_attr_indexes");
-		debug("unimplemented method_attr_calls");
-		// assign empty method attributes
-		methodAttributes = new ArrayList[classCount][];
-		for (int i = 0; i < classCount; i++) {
-			methodAttributes[i] = new ArrayList[methodFlags[i].length];
-			for (int j = 0; j < methodFlags[i].length; j++) {
-				methodAttributes[i][j] = new ArrayList();
-			}
-		}
-		parseAttributeMethodExceptions(in);
-		parseAttributeMethodSignature(in);
-		parseMetadataBands("method");
-	}
-
-	/**
-	 * Helper method to parse <i>count</i> references from <code>in</code>,
-	 * using <code>codec</code> to decode the values as indexes into
-	 * <code>reference</code> (which is populated prior to this call). An
-	 * exception is thrown if a decoded index falls outside the range
-	 * [0..reference.length-1]. Unlike the other parseReferences, this
-	 * post-processes the result into an array of results.
-	 * 
-	 * @param name
-	 *            TODO
-	 * @param in
-	 *            the input stream to read from
-	 * @param codec
-	 *            the codec to use for decoding
-	 * @param count
-	 *            the number of references to decode
-	 * @param reference
-	 *            the array of values to use for the indexes; often
-	 *            {@link #cpUTF8}
-	 * 
-	 * @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
-	 */
-	private String[][] parseReferences(String name, InputStream in,
-			BHSDCodec codec, int count, int counts[], String[] reference)
-			throws IOException, Pack200Exception {
-		if (count == 0) {
-			return new String[][] { {} };
-		}
-		String[][] result = new String[count][];
-		int sum = 0;
-		for (int i = 0; i < count; i++) {
-			result[i] = new String[counts[i]];
-			sum += counts[i];
-		}
-		// TODO Merge the decode and parsing of a multiple structure into one
-		String[] result1 = new String[sum];
-		int[] decode = decodeBandInt(name, in, codec, sum);
-		for (int i1 = 0; i1 < sum; i1++) {
-			int index = decode[i1];
-			if (index < 0 || index >= reference.length)
-				throw new Pack200Exception(
-						"Something has gone wrong during parsing references");
-			result1[i1] = reference[index];
-		}
-		String[] refs = result1;
-		// TODO Merge the decode and parsing of a multiple structure into one
-		int pos = 0;
-		for (int i = 0; i < count; i++) {
-			int num = counts[i];
-			result[i] = new String[num];
-			System.arraycopy(refs, pos, result[i], 0, num);
-			pos += num;
-		}
-		return result;
-	}
-
-	/**
-	 * Helper method to parse <i>count</i> references from <code>in</code>,
-	 * using <code>codec</code> to decode the values as indexes into
-	 * <code>reference</code> (which is populated prior to this call). An
-	 * exception is thrown if a decoded index falls outside the range
-	 * [0..reference.length-1].
-	 * 
-	 * @param name
-	 *            TODO
-	 * @param in
-	 *            the input stream to read from
-	 * @param codec
-	 *            the codec to use for decoding
-	 * @param count
-	 *            the number of references to decode
-	 * @param reference
-	 *            the array of values to use for the indexes; often
-	 *            {@link #cpUTF8}
-	 * 
-	 * @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
-	 */
-	private String[] parseReferences(String name, InputStream in,
-			BHSDCodec codec, int count, String[] reference) throws IOException,
-			Pack200Exception {
-		return parseReferences(name, in, codec, 1, new int[] { count },
-				reference)[0];
-	}
-
-	/**
-	 * This performs the actual work of parsing against a non-static instance of
-	 * Segment.
-	 * 
-	 * @param in
-	 *            the input stream to read from
-	 * @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
-	 */
-	private void parseSegment(InputStream in) throws IOException,
-			Pack200Exception {
-		debug("-------");
-		parseSegmentHeader(in);
-		if (bandHeadersSize > 0) {
-			byte[] bandHeaders = new byte[(int) bandHeadersSize];
-			readFully(in, bandHeaders);
-			setBandHeadersData(bandHeaders);
-		}
-		parseCpUtf8(in);
-		parseCpInt(in);
-		parseCpFloat(in);
-		parseCpLong(in);
-		parseCpDouble(in);
-		parseCpString(in);
-		parseCpClass(in);
-		parseCpSignature(in);
-		parseCpDescriptor(in);
-		parseCpField(in);
-		parseCpMethod(in);
-		parseCpIMethod(in);
-		parseAttributeDefinition(in);
-		parseIcBands(in);
-		parseClassBands(in);
-		parseBcBands(in);
-		parseFileBands(in);
-	}
-
-	private void parseSegmentHeader(InputStream in) throws IOException,
-			Pack200Exception, Error, Pack200Exception {
-		long word[] = decodeScalar("archive_magic_word", in, Codec.BYTE1,
-				magic.length);
-		for (int m = 0; m < magic.length; m++)
-			if (word[m] != magic[m])
-				throw new Error("Bad header");
-		setArchiveMinorVersion((int) decodeScalar("archive_minver", in,
-				Codec.UNSIGNED5));
-		setArchiveMajorVersion((int) decodeScalar("archive_majver", in,
-				Codec.UNSIGNED5));
-		setOptions(new SegmentOptions((int) decodeScalar("archive_options", in,
-				Codec.UNSIGNED5)));
-		parseArchiveFileCounts(in);
-		parseArchiveSpecialCounts(in);
-		parseCpCounts(in);
-		parseClassCounts(in);
-	}
-
-	private void processFileBits(InputStream in) throws IOException,
-			Pack200Exception {
-		// now read in the bytes
-		fileBits = new byte[numberOfFiles][];
-		for (int i = 0; i < numberOfFiles; i++) {
-			int size = (int) fileSize[i];
-			// TODO This buggers up if file_size > 2^32. Probably an array is
-			// not the right choice, and
-			// we should just serialize the bugger here?
-			fileBits[i] = new byte[size];
-			for (int j = 0; j < size; j++) {
-				fileBits[i][j] = (byte) Codec.BYTE1.decode(in);
-			}
-		}
-	}
-
-	/**
-	 * Sets the major version of this archive.
-	 * 
-	 * @param version
-	 *            the minor version of the archive
-	 * @throws Pack200Exception
-	 *             if the major version is not 150
-	 */
-	private void setArchiveMajorVersion(int version) throws Pack200Exception {
-		if (version != 150)
-			throw new Pack200Exception("Invalid segment major version");
-		archiveMajor = version;
-	}
-
-	/**
-	 * Sets the minor version of this archive
-	 * 
-	 * @param version
-	 *            the minor version of the archive
-	 * @throws Pack200Exception
-	 *             if the minor version is not 7
-	 */
-	private void setArchiveMinorVersion(int version) throws Pack200Exception {
-		if (version != 7)
-			throw new Pack200Exception("Invalid segment minor version");
-		archiveMinor = version;
-	}
-
-	public void setArchiveModtime(long archiveModtime) {
-		this.archiveModtime = archiveModtime;
-	}
-
-	public void setArchiveSize(long archiveSize) {
-		this.archiveSize = archiveSize;
-	}
-
-	private void setAttributeDefinitionCount(long valuie) {
-		this.attributeDefinitionCount = (int) valuie;
-	}
-
-	private void setBandHeadersData(byte[] bandHeaders) {
-		this.bandHeadersInputStream = new ByteArrayInputStream(bandHeaders);
-	}
-
-	private void setBandHeadersSize(long value) {
-		this.bandHeadersSize = (int) value;
-	}
-
-	private void setClassCount(long value) {
-		classCount = (int) value;
-	}
-
-	private void setCPClassCount(long value) {
-		cpClassCount = (int) value;
-	}
-
-	private void setCPDescriptorCount(long value) {
-		cpDescriptorCount = (int) value;
-	}
-
-	private void setCPDoubleCount(long value) {
-		cpDoubleCount = (int) value;
-	}
-
-	private void setCPFieldCount(long value) {
-		cpFieldCount = (int) value;
-	}
-
-	private void setCPFloatCount(long value) {
-		cpFloatCount = (int) value;
-	}
-
-	private void setCPIMethodCount(long value) {
-		cpIMethodCount = (int) value;
-	}
-
-	private void setCPIntCount(long value) {
-		cpIntCount = (int) value;
-	}
-
-	private void setCPLongCount(long value) {
-		cpLongCount = (int) value;
-	}
-
-	private void setCPMethodCount(long value) {
-		cpMethodCount = (int) value;
-	}
-
-	private void setCPSignatureCount(long value) {
-		cpSignatureCount = (int) value;
-	}
-
-	private void setCPStringCount(long value) {
-		cpStringCount = (int) value;
-	}
-
-	private void setCPUtf8Count(long value) {
-		cpUTF8Count = (int) value;
-	}
-
-	private void setDefaultClassMajorVersion(long value) {
-		defaultClassMajorVersion = (int) value;
-	}
-
-	private void setDefaultClassMinorVersion(long value) {
-		defaultClassMinorVersion = (int) value;
-	}
-
-	private void setInnerClassCount(long value) {
-		innerClassCount = (int) value;
-	}
-
-	public void setNumberOfFiles(long value) {
-		numberOfFiles = (int) value;
-	}
-
-	private void setOptions(SegmentOptions options) {
-		this.options = options;
-	}
-
-	public void setSegmentsRemaining(long value) {
-		segmentsRemaining = (int) value;
-	}
-
-	/**
-	 * This is only here to provide a mechanism to turn off the warnings (and to
-	 * prevent anyone from accidentally removing them from the file)
-	 * 
-	 * @deprecated this will be deleted in the future, once I've started to use
-	 *             them
-	 * 
-	 */
-	int shutUpAboutTheStupidNotReadVariablesYetIHaventImplementedIt() {
-		return archiveMajor + archiveMinor + cpLong.hashCode()
-				+ icName.hashCode() + icOuterClass.hashCode()
-				+ icThisClass.hashCode();
-	}
-
-	/**
-	 * Writes the segment to an output stream. The output stream should be
-	 * pre-buffered for efficiency. Also takes the same input stream for
-	 * reading, since the file bits may not be loaded and thus just copied from
-	 * one stream to another. Doesn't close the output stream when finished, in
-	 * case there are more entries (e.g. further segments) to be written.
-	 * 
-	 * @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
-	 * @throws Pack200Exception
-	 *             if an error occurs whilst unpacking data
-	 */
-	public void writeJar(JarOutputStream out, InputStream in)
-			throws IOException, Pack200Exception {
-		processFileBits(in);
-		DataOutputStream dos = new DataOutputStream(out);
-		// out.setLevel(JarEntry.DEFLATED)
-		// now write the files out
-		int classNum = 0;
-		for (int i = 0; i < numberOfFiles; i++) {
-			String name = fileName[i];
-			long modtime = archiveModtime + fileModtime[i];
-			boolean deflate = (fileOptions[i] & 1) == 1
-					|| options.shouldDeflate();
-			boolean isClass = (fileOptions[i] & 2) == 2 || name == null
-					|| name.equals("");
-			if (isClass) {
-				// pull from headers
-				if (name == null || name.equals(""))
-					name = classThis[classNum] + ".class";
-			}
-			JarEntry entry = new JarEntry(name);
-			if (deflate)
-				entry.setMethod(JarEntry.DEFLATED);
-			entry.setTime(modtime);
-			out.putNextEntry(entry);
-
-			if (isClass) {
-				// write to dos
-				ClassFile classFile = buildClassFile(classNum);
-				classFile.write(dos);
-				dos.flush();
-				classNum++;
-			} else {
-				long size = fileSize[i];
-				entry.setSize(size);
-				// TODO pull from in
-				byte[] data = fileBits[i];
-				out.write(data);
-			}
-		}
-		dos.flush();
-		out.finish();
-		out.flush();
-	}
 }

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=572907&r1=572906&r2=572907&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 Sep  5 02:14:01 2007
@@ -289,10 +289,7 @@
 	protected void doWrite(DataOutputStream dos) throws IOException {
 		// TODO operands?
 		for (int i = 0; i < rewrite.length; i++) {
-			if (opcode == 231 && i == 2)
-				dos.writeByte(8);
-			else
-				dos.writeByte(rewrite[i]);
+			dos.writeByte(rewrite[i]);
 		}
 	}
 
@@ -318,11 +315,7 @@
 	}
 
 	protected ClassFileEntry[] getNestedClassFileEntries() {
-		if (opcode == 231) // TODO HACK
-			return new ClassFileEntry[] { new CPMethodRef("java/lang/Object",
-					"<init>:()V") };
-		else
-			return nested;
+		return nested;
 	}
 
 	public int getOpcode() {
@@ -334,6 +327,11 @@
 		int result = 1;
 		result = prime * result + opcode;
 		return result;
+	}
+
+	protected void resolve(ClassConstantPool pool) {
+		// TODO Auto-generated method stub
+		super.resolve(pool);
 	}
 
 	public String toString() {

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=572907&r1=572906&r2=572907&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 Sep  5 02:14:01 2007
@@ -16,10 +16,82 @@
  */
 package org.apache.harmony.pack200.bytecode;
 
-public class CPFieldRef extends CPRef {
+import java.io.DataOutputStream;
+import java.io.IOException;
 
+
+public class CPFieldRef extends ConstantPoolEntry {
+
+	CPClass className;
+	transient int classNameIndex;
+
+
+	private CPNameAndType nameAndType;
+	transient int nameAndTypeIndex;
 	public CPFieldRef(String className, String descriptor) {
-		super(ConstantPoolEntry.CP_Fieldref, className, descriptor);
+		super(ConstantPoolEntry.CP_Fieldref);
+		this.className = new CPClass(className);
+		this.nameAndType = new CPNameAndType(descriptor);
+	}
+
+
+	
+	protected ClassFileEntry[] getNestedClassFileEntries() {
+		ClassFileEntry[] entries = new ClassFileEntry[2];
+		entries[0] = className;
+		entries[1] = nameAndType;
+		return entries;
+	}
+
+
+	
+	protected void resolve(ClassConstantPool pool) {
+		super.resolve(pool);
+		nameAndTypeIndex = pool.indexOf(nameAndType);
+		classNameIndex = pool.indexOf(className);
+	}
+
+	protected void writeBody(DataOutputStream dos) throws IOException {
+		dos.writeShort(classNameIndex);
+		dos.writeShort(nameAndTypeIndex);
+	}
+
+	
+	public String toString() {
+		return "FieldRef: " + className + "#" + nameAndType;
+	}
+
+
+	
+	public int hashCode() {
+		final int PRIME = 31;
+		int result = 1;
+		result = PRIME * result + ((className == null) ? 0 : className.hashCode());
+		result = PRIME * result + ((nameAndType == null) ? 0 : nameAndType.hashCode());
+		return result;
+	}
+
+
+	
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		final CPFieldRef other = (CPFieldRef) obj;
+		if (className == null) {
+			if (other.className != null)
+				return false;
+		} else if (!className.equals(other.className))
+			return false;
+		if (nameAndType == null) {
+			if (other.nameAndType != null)
+				return false;
+		} else if (!nameAndType.equals(other.nameAndType))
+			return false;
+		return true;
 	}
 
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/AttributeLayoutTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/AttributeLayoutTest.java?rev=572907&r1=572906&r2=572907&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/AttributeLayoutTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/AttributeLayoutTest.java Wed Sep  5 02:14:01 2007
@@ -23,6 +23,7 @@
 import org.apache.harmony.pack200.AttributeLayout;
 import org.apache.harmony.pack200.Pack200Exception;
 import org.apache.harmony.pack200.Segment;
+import org.apache.harmony.pack200.SegmentConstantPool;
 
 public class AttributeLayoutTest extends TestCase {
 	public class TestSegment extends Segment {
@@ -32,7 +33,7 @@
 					{ "Zero", "One" }, // UTF-8
 					{ "Ein", "Zwei" }, // Signature
 			};
-			return new SegmentConstantPool() {
+			return new SegmentConstantPool(null) {
 				public Object getValue(int cp, long index) {
 					if (index == -1)
 						return null;
@@ -55,30 +56,30 @@
 	public void testLayoutRU() throws Pack200Exception {
 		AttributeLayout layout = new AttributeLayout("RU",AttributeLayout.CONTEXT_CLASS,"RU", 1);
 		Segment segment = new TestSegment();
-		assertNull(layout.getValue(-1, segment));
-		assertEquals("Zero",layout.getValue(0, segment));
-		assertEquals("One",layout.getValue(1, segment));
+		assertNull(layout.getValue(-1, segment.getConstantPool()));
+		assertEquals("Zero",layout.getValue(0, segment.getConstantPool()));
+		assertEquals("One",layout.getValue(1, segment.getConstantPool()));
 	}
 	public void testLayoutRUN() throws Pack200Exception {
 		AttributeLayout layout = new AttributeLayout("RUN",AttributeLayout.CONTEXT_CLASS,"RUN", 1);
 		Segment segment = new TestSegment();
-		assertNull(layout.getValue(0, segment));
-		assertEquals("Zero",layout.getValue(1, segment));
-		assertEquals("One",layout.getValue(2, segment));
+		assertNull(layout.getValue(0, segment.getConstantPool()));
+		assertEquals("Zero",layout.getValue(1, segment.getConstantPool()));
+		assertEquals("One",layout.getValue(2, segment.getConstantPool()));
 	}
 	public void testLayoutRS() throws Pack200Exception {
 		AttributeLayout layout = new AttributeLayout("RS",AttributeLayout.CONTEXT_CLASS,"RS", 1);
 		Segment segment = new TestSegment();
-		assertNull(layout.getValue(-1, segment));
-		assertEquals("Ein",layout.getValue(0, segment));
-		assertEquals("Zwei",layout.getValue(1, segment));
+		assertNull(layout.getValue(-1, segment.getConstantPool()));
+		assertEquals("Ein",layout.getValue(0, segment.getConstantPool()));
+		assertEquals("Zwei",layout.getValue(1, segment.getConstantPool()));
 	}
 	public void testLayoutRSN() throws Pack200Exception {
 		AttributeLayout layout = new AttributeLayout("RSN",AttributeLayout.CONTEXT_CLASS,"RSN", 1);
 		Segment segment = new TestSegment();
-		assertNull(layout.getValue(0, segment));
-		assertEquals("Ein",layout.getValue(1, segment));
-		assertEquals("Zwei",layout.getValue(2, segment));
+		assertNull(layout.getValue(0, segment.getConstantPool()));
+		assertEquals("Ein",layout.getValue(1, segment.getConstantPool()));
+		assertEquals("Zwei",layout.getValue(2, segment.getConstantPool()));
 	}
 	public boolean throwsException(String name, int context, String layout) {
 		try {

Modified: harmony/enhanced/classlib/branches/java6/modules/prefs/src/main/native/prefs/windows/PreferencesImpl.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/prefs/src/main/native/prefs/windows/PreferencesImpl.c?rev=572907&r1=572906&r2=572907&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/prefs/src/main/native/prefs/windows/PreferencesImpl.c (original)
+++ harmony/enhanced/classlib/branches/java6/modules/prefs/src/main/native/prefs/windows/PreferencesImpl.c Wed Sep  5 02:14:01 2007
@@ -124,8 +124,8 @@
   localErrorCode = checkErrorCode (errorCode);
   RegCloseKey (hKey);
   hymem_free_memory (keyStr);
-  (*env)->ReleasePrimitiveArrayCritical (env, jErrorCode, err, 0);
   err[java_util_prefs_RegistryPreferencesImpl_ERROR_CODE] = localErrorCode;
+  (*env)->ReleasePrimitiveArrayCritical (env, jErrorCode, err, 0);
   if (localErrorCode !=
       java_util_prefs_RegistryPreferencesImpl_RETURN_SUCCESS)
     {

Modified: harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties?rev=572907&r1=572906&r2=572907&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties (original)
+++ harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties Wed Sep  5 02:14:01 2007
@@ -62,3 +62,5 @@
 
 rowset.0=Not a valid position
 rowset.1=Not a valid column name
+rowset.2=Negative page size
+rowset.3=Table name should not be null

Modified: harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRow.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRow.java?rev=572907&r1=572906&r2=572907&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRow.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRow.java Wed Sep  5 02:14:01 2007
@@ -23,12 +23,46 @@
 
     private BitSet mask;
 
+    private boolean isDelete;
+
+    private boolean insert;
+
     public CachedRow(Object[] columnData) {
         this.columnData = columnData;
         mask = new BitSet(columnData.length);
     }
 
-    public boolean setUpdateMask(int i) {
+    public boolean getUpdateMask(int i) {
         return mask.get(i);
+    }
+
+    public void setUpdateMask(int i) {
+        mask.set(i);
+    }
+
+    public void setDelete() {
+        this.isDelete = true;
+    }
+
+    public boolean getDelete() {
+        return isDelete;
+    }
+
+    public void setInsert() {
+        this.insert = true;
+    }
+
+    public boolean getInsert() {
+        return this.insert;
+    }
+
+    public void updateString(int columnIndex, String x) {
+        this.columnData[columnIndex - 1] = x;
+        setUpdateMask(columnIndex - 1);
+    }
+
+    public void updateInt(int columnIndex, int x) {
+        this.columnData[columnIndex - 1] = x;
+        setUpdateMask(columnIndex - 1);
     }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetImpl.java?rev=572907&r1=572906&r2=572907&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetImpl.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetImpl.java Wed Sep  5 02:14:01 2007
@@ -50,8 +50,19 @@
 
     private int currentRowIndex;
 
-    public void setRows(ArrayList<CachedRow> data) {
+    private int pageSize;
+
+    private String tableName;
+
+    private int rememberedCursorPosition;
+
+    private CachedRow insertRow;
+
+    private int columnCount;
+
+    public void setRows(ArrayList<CachedRow> data, int cloumnCount) {
         this.rows = data;
+        this.columnCount = cloumnCount;
     }
 
     public void acceptChanges() throws SyncProviderException {
@@ -67,7 +78,7 @@
             // rowset.0 = Not a valid position
             throw new SQLException(Messages.getString("rowset.0"));
         }
-        return currentRow.setUpdateMask(idx - 1);
+        return currentRow.getUpdateMask(idx - 1);
     }
 
     public boolean columnUpdated(String columnName) throws SQLException {
@@ -76,7 +87,7 @@
 
     private int getIndexByName(String columnName) throws SQLException {
         for (int i = 1; i <= meta.getColumnCount(); i++) {
-            if (columnName.equals(meta.getColumnName(i))) {
+            if (columnName.equalsIgnoreCase(meta.getColumnName(i))) {
                 return i;
             }
         }
@@ -121,7 +132,7 @@
     }
 
     public int getPageSize() {
-        throw new NotImplementedException();
+        return pageSize;
     }
 
     public RowSetWarning getRowSetWarnings() throws SQLException {
@@ -133,7 +144,7 @@
     }
 
     public String getTableName() throws SQLException {
-        throw new NotImplementedException();
+        return tableName;
     }
 
     public boolean nextPage() throws SQLException {
@@ -198,7 +209,11 @@
     }
 
     public void setPageSize(int size) throws SQLException {
-        throw new NotImplementedException();
+        if (size < 0) {
+            // rowset.2=Negative page size
+            throw new SQLException(Messages.getString("rowset.2"));
+        }
+        this.pageSize = size;
     }
 
     public void setSyncProvider(String provider) throws SQLException {
@@ -206,11 +221,15 @@
     }
 
     public void setTableName(String tabName) throws SQLException {
-        throw new NotImplementedException();
+        if (tabName == null) {
+            // rowset.3=Table name should not be null
+            throw new SQLException("rowset.3");
+        }
+        this.tableName = tabName;
     }
 
     public int size() {
-        throw new NotImplementedException();
+        return rows.size();
     }
 
     public Collection<?> toCollection() throws SQLException {
@@ -302,7 +321,15 @@
     }
 
     public void deleteRow() throws SQLException {
-        throw new NotImplementedException();
+        checkValidRow();
+        currentRow.setDelete();
+    }
+
+    private void checkValidRow() throws SQLException {
+        if (currentRow == null) {
+            // rowset.0 = Not a valid position
+            throw new SQLException(Messages.getString("rowset.0"));
+        }
     }
 
     public int findColumn(String columnName) throws SQLException {
@@ -564,7 +591,13 @@
     }
 
     public void insertRow() throws SQLException {
-        throw new NotImplementedException();
+        checkValidRow();
+        if (currentRow != insertRow) {
+            throw new SQLException();
+        }
+        currentRow.setInsert();
+        rows.add(insertRow);
+        currentRowIndex++;
     }
 
     public boolean isAfterLast() throws SQLException {
@@ -588,11 +621,14 @@
     }
 
     public void moveToCurrentRow() throws SQLException {
-        throw new NotImplementedException();
+        this.currentRowIndex = rememberedCursorPosition;
+        this.currentRow = rows.get(currentRowIndex);
     }
 
     public void moveToInsertRow() throws SQLException {
-        throw new NotImplementedException();
+        insertRow = new CachedRow(new Object[columnCount]);
+        this.currentRow = insertRow;
+        this.currentRowIndex = rows.size();
     }
 
     public boolean next() throws SQLException {
@@ -617,7 +653,8 @@
     }
 
     public boolean rowDeleted() throws SQLException {
-        throw new NotImplementedException();
+        checkValidRow();
+        return currentRow.getDelete();
     }
 
     public boolean rowInserted() throws SQLException {
@@ -741,11 +778,11 @@
     }
 
     public void updateInt(int columnIndex, int x) throws SQLException {
-        throw new NotImplementedException();
+        currentRow.updateInt(columnIndex, x);
     }
 
     public void updateInt(String columnName, int x) throws SQLException {
-        throw new NotImplementedException();
+        currentRow.updateInt(getIndexByName(columnName), x);
     }
 
     public void updateLong(int columnIndex, long x) throws SQLException {
@@ -803,11 +840,11 @@
     }
 
     public void updateString(int columnIndex, String x) throws SQLException {
-        throw new NotImplementedException();
+        currentRow.updateString(columnIndex, x);
     }
 
     public void updateString(String columnName, String x) throws SQLException {
-        throw new NotImplementedException();
+        currentRow.updateString(getIndexByName(columnName), x);
     }
 
     public void updateTime(int columnIndex, Time x) throws SQLException {

Modified: harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetReader.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetReader.java?rev=572907&r1=572906&r2=572907&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetReader.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetReader.java Wed Sep  5 02:14:01 2007
@@ -40,14 +40,14 @@
 
     public void readData(RowSetInternal theCaller) throws SQLException {
         ArrayList<CachedRow> data = new ArrayList<CachedRow>();
+        int columnCount = metadata.getColumnCount();
         while (rs.next()) {
-            int columnCount = metadata.getColumnCount();
             Object[] columnData = new Object[columnCount];
             for (int i = 0; i < columnCount; i++) {
                 columnData[i] = rs.getObject(i+1);
             }
             data.add(new CachedRow(columnData));
         }
-        ((CachedRowSetImpl) theCaller).setRows(data);
+        ((CachedRowSetImpl) theCaller).setRows(data, columnCount);
     }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/CachedRowSetImplTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/CachedRowSetImplTest.java?rev=572907&r1=572906&r2=572907&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/CachedRowSetImplTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/CachedRowSetImplTest.java Wed Sep  5 02:14:01 2007
@@ -112,6 +112,88 @@
         assertFalse(crset.columnUpdated("NAME"));
     }
 
+    public void testGetPageSize() throws SQLException {
+        assertEquals(0, crset.getPageSize());
+        crset.setPageSize(1);
+        assertEquals(1, crset.getPageSize());
+    }
+
+    public void testSetPageSize() throws SQLException {
+        try {
+            crset.setPageSize(-1);
+            fail("should throw SQLException");
+        } catch (SQLException e) {
+            // expected;
+        }
+        crset.setPageSize(0);
+        crset.setPageSize(Integer.MAX_VALUE);
+        assertEquals(Integer.MAX_VALUE, crset.getPageSize());
+    }
+
+    public void testGetTableName() throws SQLException {
+        assertEquals(null, crset.getTableName());
+        crset.setTableName("USER");
+        assertEquals("USER", crset.getTableName());
+    }
+
+    public void testSetTableName() throws SQLException {
+        try {
+            crset.setTableName(null);
+            fail("should throw SQLException");
+        } catch (SQLException e) {
+            // expected;
+        }
+    }
+
+    public void testSize() {
+        assertEquals(2, crset.size());
+    }
+
+    public void testDeleteRow() throws SQLException {
+        try {
+            crset.deleteRow();
+            fail("should throw SQLException");
+        } catch (SQLException e) {
+            // expected;
+        }
+        crset.next();
+        assertFalse(crset.rowDeleted());
+        crset.deleteRow();
+        assertEquals(2, crset.size());
+        assertTrue(crset.rowDeleted());
+    }
+    
+    public void testRowDeleted() throws SQLException{
+        try {
+            crset.rowDeleted();
+            fail("should throw SQLException");
+        } catch (SQLException e) {
+            // expected;
+        }
+    }
+    
+    public void testInsertRow() throws SQLException{
+        try {
+            crset.insertRow();
+            fail("should throw SQLException");
+        } catch (SQLException e) {
+            // expected;
+        }
+        crset.next();
+        try {
+            crset.insertRow();
+            fail("should throw SQLException");
+        } catch (SQLException e) {
+            // expected;
+        }
+        crset.moveToInsertRow();
+        crset.updateString("Name", "TonyWu");
+        crset.updateInt("ID", 3);
+        crset.insertRow();
+//        crset.moveToCurrentRow();
+//        assertTrue(crset.rowInserted());
+    }
+
     public void testAcceptChanges() throws SQLException {
         // rs.next();
         // assertEquals(1, rs.getInt(1));



Mime
View raw message