You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by od...@apache.org on 2007/08/31 16:42:50 UTC

svn commit: r571482 - in /harmony/enhanced/classlib/trunk/modules/pack200/src: main/java/org/apache/harmony/pack200/ main/java/org/apache/harmony/pack200/bytecode/ test/java/

Author: odeakin
Date: Fri Aug 31 07:42:49 2007
New Revision: 571482

URL: http://svn.apache.org/viewvc?rev=571482&view=rev
Log:
Apply patch HARMONY-4712 ([classlib][pack200] Pack200 update - converted HARMONY-3290 to patch format)

Added:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java   (with props)
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/Unpack.java   (with props)
Modified:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayout.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayoutMap.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayout.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayout.java?rev=571482&r1=571481&r2=571482&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayout.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayout.java Fri Aug 31 07:42:49 2007
@@ -22,8 +22,12 @@
 // NOTE: Also, don't get rid of 'else' statements for the hell of it ...
 import org.apache.harmony.pack200.Segment.SegmentConstantPool;
 
-public class AttributeLayout {
+public class AttributeLayout implements IMatcher {
 	static class Key {
+		private final int context;
+
+		private final String name;
+
 		public Key(String name, int context) throws Pack200Exception {
 			if (name == null || name.length() == 0)
 				throw new Pack200Exception("Cannot have an unnamed layout");
@@ -36,20 +40,6 @@
 
 		}
 
-		private int context;
-
-		private String name;
-
-		
-		public int hashCode() {
-			final int PRIME = 31;
-			int result = 1;
-			result = PRIME * result + context;
-			result = PRIME * result + ((name == null) ? 0 : name.hashCode());
-			return result;
-		}
-
-		
 		public boolean equals(Object obj) {
 			if (this == obj)
 				return true;
@@ -68,120 +58,72 @@
 			return true;
 		}
 
+		public int hashCode() {
+			final int PRIME = 31;
+			int result = 1;
+			result = PRIME * result + context;
+			result = PRIME * result + ((name == null) ? 0 : name.hashCode());
+			return result;
+		}
+
 		public String toString() {
 			return contextNames[context] + ": " + name;
 		}
 
 	}
 
-	private String layout;
-
-	Key key;
-
-	private long mask;
-
-	public static final String ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations";
-
-	public static final String ATTRIBUTE_CLASS_FILE_VERSION = "class-file version";
-
-	public static final String ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = "RuntimeInvisibleParameterAnnotations";
-
-	public static final String ATTRIBUTE_ANNOTATION_DEFAULT = "AnnotationDefault";
-
-	public static final String ATTRIBUTE_CODE = "Code";
-
-	public static final String ATTRIBUTE_SOURCE_FILE = "SourceFile";
-
-	public static final String ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable";
-
-	public static final String ATTRIBUTE_LOCAL_VARIABLE_TABLE = "LocalVariableTable";
-
-	public static final String ATTRIBUTE_LINE_NUMBER_TABLE = "LineNumberTable";
-
-	public static final String ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = "RuntimeVisibleParameterAnnotations";
-
-	public static final String ATTRIBUTE_INNER_CLASSES = "InnerClasses";
-
-	public static final String ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations";
-
-	public static final String ATTRIBUTE_DEPRECATED = "Deprecated";
-
-	public static final String ATTRIBUTE_CONSTANT_VALUE = "ConstantValue";
-
-	public static final String ATTRIBUTE_ENCLOSING_METHOD = "EnclosingMethod";
-
-	public static final String ATTRIBUTE_EXCEPTIONS = "Exceptions";
-
-	public static final String ATTRIBUTE_SIGNATURE = "Signature";
-
-	public static final int CONTEXT_CODE = 1 << 4;
-
+	public static final String ACC_ABSTRACT = "ACC_ABSTRACT"; //$NON-NLS-1$
+	public static final String ACC_ANNOTATION = "ACC_ANNOTATION"; //$NON-NLS-1$
+	public static final String ACC_ENUM = "ACC_ENUM"; //$NON-NLS-1$
+	public static final String ACC_FINAL = "ACC_FINAL"; //$NON-NLS-1$
+	public static final String ACC_INTERFACE = "ACC_INTERFACE"; //$NON-NLS-1$
+	public static final String ACC_NATIVE = "ACC_NATIVE"; //$NON-NLS-1$
+	public static final String ACC_PRIVATE = "ACC_PRIVATE"; //$NON-NLS-1$
+	public static final String ACC_PROTECTED = "ACC_PROTECTED"; //$NON-NLS-1$
+	public static final String ACC_PUBLIC = "ACC_PUBLIC"; //$NON-NLS-1$
+	public static final String ACC_STATIC = "ACC_STATIC"; //$NON-NLS-1$
+	public static final String ACC_STRICT = "ACC_STRICT"; //$NON-NLS-1$
+	public static final String ACC_SYNCHRONIZED = "ACC_SYNCHRONIZED"; //$NON-NLS-1$
+	public static final String ACC_SYNTHETIC = "ACC_SYNTHETIC"; //$NON-NLS-1$
+	public static final String ACC_TRANSIENT = "ACC_TRANSIENT"; //$NON-NLS-1$
+	public static final String ACC_VOLATILE = "ACC_VOLATILE"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_ANNOTATION_DEFAULT = "AnnotationDefault"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_CLASS_FILE_VERSION = "class-file version"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_CODE = "Code"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_CONSTANT_VALUE = "ConstantValue"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_DEPRECATED = "Deprecated"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_ENCLOSING_METHOD = "EnclosingMethod"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_EXCEPTIONS = "Exceptions"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_INNER_CLASSES = "InnerClasses"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_LINE_NUMBER_TABLE = "LineNumberTable"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_LOCAL_VARIABLE_TABLE = "LocalVariableTable"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = "RuntimeInvisibleParameterAnnotations"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = "RuntimeVisibleParameterAnnotations"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_SIGNATURE = "Signature"; //$NON-NLS-1$
+	public static final String ATTRIBUTE_SOURCE_FILE = "SourceFile"; //$NON-NLS-1$
 	public static final int CONTEXT_CLASS = 1 << 0;
-
+	public static final int CONTEXT_CODE = 1 << 4;
 	public static final int CONTEXT_FIELD = 1 << 2;
-
 	public static final int CONTEXT_METHOD = 1 << 3;
-
-	private static final String[] contextNames = { "Class", "Field", "Method",
-			"Code", };
-
-	public Codec getCodec() {
-		if (layout.indexOf("O") >= 0) {
-			return Codec.BRANCH5;
-		} else if (layout.indexOf("P") >= 0) {
-			return Codec.BCI5;
-		} else if (layout.indexOf("S") >= 0 && layout.indexOf("KS") < 0
-				&& layout.indexOf("RS") < 0) {
-			return Codec.SIGNED5;
-		} else if (layout.indexOf("B") >= 0) {
-			return Codec.BYTE1;
-		}
-		/*
-		 * TODO Add this as a test (and don't commit since this is copyright
-		 * text) && ) If the layout contains 'O', use BRANCH5. Otherwise, if the
-		 * layout contains 'P', use BCI5. Otherwise, if the layout contains 'S'
-		 * but not 'KS' or 'RS', use SIGNED5. Otherwise, if the layout contains
-		 * 'B', use BYTE1. For all other layouts use UNSIGNED5.
-		 */
-		else {
-			return Codec.UNSIGNED5;
-		}
-	}
-
-	public Object getValue(long value, String type, Segment segment)
-			throws Pack200Exception {
-		// TODO This really needs to be better tested, esp. the different types
-		// TODO This should have the ability to deal with RUN stuff too, and unions
-		if (layout.startsWith("KQ")) {
-			if (type.equals("Ljava/lang/String;")) {
-				Object value2 = getValue("KS", value, segment);
-				return value2;
-			} else {
-				return getValue("K" + type + layout.substring(2), value,
-						segment);
-			}
-		} else {
-			return getValue(layout, value, segment);
-		}
-	}
-
-	public Object getValue(long value, Segment segment) throws Pack200Exception {
-		return getValue(layout, value, segment);
-	}
+	private static final String[] contextNames = { "Class", "Field", "Method", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			"Code", }; //$NON-NLS-1$
 
 	private static Object getValue(String layout, long value, Segment segment)
 			throws Pack200Exception {
 		SegmentConstantPool pool = segment.getConstantPool();
-		if (layout.startsWith("R")) {
+		if (layout.startsWith("R")) { //$NON-NLS-1$
 			// references
 			if (layout.indexOf('N') != -1)
 				value--;
-			if (layout.startsWith("RU")) {
+			if (layout.startsWith("RU")) { //$NON-NLS-1$
 				return pool.getValue(SegmentConstantPool.UTF_8, value);
-			} else if (layout.startsWith("RS")) {
+			} else if (layout.startsWith("RS")) { //$NON-NLS-1$
 				return pool.getValue(SegmentConstantPool.SIGNATURE, value);
 			}
-		} else if (layout.startsWith("K")) {
+		} else if (layout.startsWith("K")) { //$NON-NLS-1$
 			char type = layout.charAt(1);
 			switch (type) {
 			case 'S': // String
@@ -192,14 +134,20 @@
 			case 'F': // Float
 				return pool.getValue(SegmentConstantPool.CP_FLOAT, value);
 			case 'J': // Long
-				return pool.getValue(SegmentConstantPool.CP_LONG,value);
+				return pool.getValue(SegmentConstantPool.CP_LONG, value);
 			case 'D': // Double
-				return pool.getValue(SegmentConstantPool.CP_DOUBLE,value);
+				return pool.getValue(SegmentConstantPool.CP_DOUBLE, value);
 			}
 		}
 		throw new Pack200Exception("Unknown layout encoding: " + layout);
 	}
 
+	Key key;
+
+	private final String layout;
+
+	private long mask;
+
 	public AttributeLayout(String name, int context, String layout, int index)
 			throws Pack200Exception {
 		super();
@@ -214,31 +162,6 @@
 		this.layout = layout;
 	}
 
-	public boolean isCode() {
-		return key.context == CONTEXT_CODE;
-	}
-
-	public boolean isClass() {
-		return key.context == CONTEXT_CLASS;
-	}
-
-	public boolean isMethod() {
-		return key.context == CONTEXT_METHOD;
-	}
-
-	public boolean isField() {
-		return key.context == CONTEXT_FIELD;
-	}
-
-	public int hashCode() {
-		return key.hashCode();
-	}
-
-	public boolean matches(long value) {
-		return (value & mask) != 0;
-	}
-
-	
 	public boolean equals(Object obj) {
 		if (this == obj)
 			return true;
@@ -260,12 +183,84 @@
 		return true;
 	}
 
-	public String toString() {
-		return key.toString();
+	public Codec getCodec() {
+		if (layout.indexOf("O") >= 0) { //$NON-NLS-1$
+			return Codec.BRANCH5;
+		} else if (layout.indexOf("P") >= 0) { //$NON-NLS-1$
+			return Codec.BCI5;
+		} else if (layout.indexOf("S") >= 0 && layout.indexOf("KS") < 0 //$NON-NLS-1$ //$NON-NLS-2$
+				&& layout.indexOf("RS") < 0) { //$NON-NLS-1$
+			return Codec.SIGNED5;
+		} else if (layout.indexOf("B") >= 0) { //$NON-NLS-1$
+			return Codec.BYTE1;
+		}
+		/*
+		 * TODO Add this as a test (and don't commit since this is copyright
+		 * text) && ) If the layout contains 'O', use BRANCH5. Otherwise, if the
+		 * layout contains 'P', use BCI5. Otherwise, if the layout contains 'S'
+		 * but not 'KS' or 'RS', use SIGNED5. Otherwise, if the layout contains
+		 * 'B', use BYTE1. For all other layouts use UNSIGNED5.
+		 */
+		else {
+			return Codec.UNSIGNED5;
+		}
 	}
 
 	public String getLayout() {
 		return layout;
+	}
+
+	public Object getValue(long value, Segment segment) throws Pack200Exception {
+		return getValue(layout, value, segment);
+	}
+
+	public Object getValue(long value, String type, Segment segment)
+			throws Pack200Exception {
+		// TODO This really needs to be better tested, esp. the different types
+		// TODO This should have the ability to deal with RUN stuff too, and
+		// unions
+		if (layout.startsWith("KQ")) { //$NON-NLS-1$
+			if (type.equals("Ljava/lang/String;")) { //$NON-NLS-1$
+				Object value2 = getValue("KS", value, segment); //$NON-NLS-1$
+				return value2;
+			} else {
+				return getValue("K" + type + layout.substring(2), value, //$NON-NLS-1$
+						segment);
+			}
+		} else {
+			return getValue(layout, value, segment);
+		}
+	}
+
+	public int hashCode() {
+		return key.hashCode();
+	}
+
+	public boolean isClass() {
+		return key.context == CONTEXT_CLASS;
+	}
+
+	public boolean isCode() {
+		return key.context == CONTEXT_CODE;
+	}
+
+	public boolean isField() {
+		return key.context == CONTEXT_FIELD;
+	}
+
+	public boolean isMethod() {
+		return key.context == CONTEXT_METHOD;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.harmony.pack200.IMatches#matches(long)
+	 */
+	public boolean matches(long value) {
+		return (value & mask) != 0;
+	}
+
+	public String toString() {
+		return key.toString();
 	}
 
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayoutMap.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayoutMap.java?rev=571482&r1=571481&r2=571482&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayoutMap.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeLayoutMap.java Fri Aug 31 07:42:49 2007
@@ -15,9 +15,11 @@
  *  limitations under the License.
  */
 package org.apache.harmony.pack200;
-//NOTE: Do not use generics in this code; it needs to run on JVMs < 1.5
-//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 ...
+
+// NOTE: Do not use generics in this code; it needs to run on JVMs < 1.5
+// 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.util.HashMap;
 import java.util.Map;
 
@@ -31,26 +33,122 @@
 	private static AttributeLayout[] getDefaultAttributeLayouts()
 			throws Pack200Exception {
 		return new AttributeLayout[] {
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_LINE_NUMBER_TABLE,
+				new AttributeLayout(AttributeLayout.ACC_PUBLIC,
+						AttributeLayout.CONTEXT_CLASS, "", 0),
+				new AttributeLayout(AttributeLayout.ACC_PUBLIC,
+						AttributeLayout.CONTEXT_FIELD, "", 0),
+				new AttributeLayout(AttributeLayout.ACC_PUBLIC,
+						AttributeLayout.CONTEXT_METHOD, "", 0),
+				new AttributeLayout(AttributeLayout.ACC_PRIVATE,
+						AttributeLayout.CONTEXT_CLASS, "", 1),
+				new AttributeLayout(AttributeLayout.ACC_PRIVATE,
+						AttributeLayout.CONTEXT_FIELD, "", 1),
+				new AttributeLayout(AttributeLayout.ACC_PRIVATE,
+						AttributeLayout.CONTEXT_METHOD, "", 1),
+				new AttributeLayout(
+						AttributeLayout.ATTRIBUTE_LINE_NUMBER_TABLE,
 						AttributeLayout.CONTEXT_CODE, "NH[PHH]", 1),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TABLE,
+
+				new AttributeLayout(AttributeLayout.ACC_PROTECTED,
+						AttributeLayout.CONTEXT_CLASS, "", 2),
+				new AttributeLayout(AttributeLayout.ACC_PROTECTED,
+						AttributeLayout.CONTEXT_FIELD, "", 2),
+				new AttributeLayout(AttributeLayout.ACC_PROTECTED,
+						AttributeLayout.CONTEXT_METHOD, "", 2),
+				new AttributeLayout(
+						AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TABLE,
 						AttributeLayout.CONTEXT_CODE, "NH[PHOHRUHRSHH]", 2),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE,
+
+				new AttributeLayout(AttributeLayout.ACC_STATIC,
+						AttributeLayout.CONTEXT_CLASS, "", 3),
+				new AttributeLayout(AttributeLayout.ACC_STATIC,
+						AttributeLayout.CONTEXT_FIELD, "", 3),
+				new AttributeLayout(AttributeLayout.ACC_STATIC,
+						AttributeLayout.CONTEXT_METHOD, "", 3),
+				new AttributeLayout(
+						AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE,
 						AttributeLayout.CONTEXT_CODE, "NH[PHOHRUHRSHH]", 3),
+
+				new AttributeLayout(AttributeLayout.ACC_FINAL,
+						AttributeLayout.CONTEXT_CLASS, "", 4),
+				new AttributeLayout(AttributeLayout.ACC_FINAL,
+						AttributeLayout.CONTEXT_FIELD, "", 4),
+				new AttributeLayout(AttributeLayout.ACC_FINAL,
+						AttributeLayout.CONTEXT_METHOD, "", 4),
+				new AttributeLayout(AttributeLayout.ACC_SYNCHRONIZED,
+						AttributeLayout.CONTEXT_CLASS, "", 5),
+				new AttributeLayout(AttributeLayout.ACC_SYNCHRONIZED,
+						AttributeLayout.CONTEXT_FIELD, "", 5),
+				new AttributeLayout(AttributeLayout.ACC_SYNCHRONIZED,
+						AttributeLayout.CONTEXT_METHOD, "", 5),
+				new AttributeLayout(AttributeLayout.ACC_VOLATILE,
+						AttributeLayout.CONTEXT_CLASS, "", 6),
+				new AttributeLayout(AttributeLayout.ACC_VOLATILE,
+						AttributeLayout.CONTEXT_FIELD, "", 6),
+				new AttributeLayout(AttributeLayout.ACC_VOLATILE,
+						AttributeLayout.CONTEXT_METHOD, "", 6),
+				new AttributeLayout(AttributeLayout.ACC_TRANSIENT,
+						AttributeLayout.CONTEXT_CLASS, "", 7),
+				new AttributeLayout(AttributeLayout.ACC_TRANSIENT,
+						AttributeLayout.CONTEXT_FIELD, "", 7),
+				new AttributeLayout(AttributeLayout.ACC_TRANSIENT,
+						AttributeLayout.CONTEXT_METHOD, "", 7),
+				new AttributeLayout(AttributeLayout.ACC_NATIVE,
+						AttributeLayout.CONTEXT_CLASS, "", 8),
+				new AttributeLayout(AttributeLayout.ACC_NATIVE,
+						AttributeLayout.CONTEXT_FIELD, "", 8),
+				new AttributeLayout(AttributeLayout.ACC_NATIVE,
+						AttributeLayout.CONTEXT_METHOD, "", 8),
+				new AttributeLayout(AttributeLayout.ACC_INTERFACE,
+						AttributeLayout.CONTEXT_CLASS, "", 9),
+				new AttributeLayout(AttributeLayout.ACC_INTERFACE,
+						AttributeLayout.CONTEXT_FIELD, "", 9),
+				new AttributeLayout(AttributeLayout.ACC_INTERFACE,
+						AttributeLayout.CONTEXT_METHOD, "", 9),
+				new AttributeLayout(AttributeLayout.ACC_ABSTRACT,
+						AttributeLayout.CONTEXT_CLASS, "", 10),
+				new AttributeLayout(AttributeLayout.ACC_ABSTRACT,
+						AttributeLayout.CONTEXT_FIELD, "", 10),
+				new AttributeLayout(AttributeLayout.ACC_ABSTRACT,
+						AttributeLayout.CONTEXT_METHOD, "", 10),
+				new AttributeLayout(AttributeLayout.ACC_STRICT,
+						AttributeLayout.CONTEXT_CLASS, "", 11),
+				new AttributeLayout(AttributeLayout.ACC_STRICT,
+						AttributeLayout.CONTEXT_FIELD, "", 11),
+				new AttributeLayout(AttributeLayout.ACC_STRICT,
+						AttributeLayout.CONTEXT_METHOD, "", 11),
+				new AttributeLayout(AttributeLayout.ACC_SYNTHETIC,
+						AttributeLayout.CONTEXT_CLASS, "", 12),
+				new AttributeLayout(AttributeLayout.ACC_SYNTHETIC,
+						AttributeLayout.CONTEXT_FIELD, "", 12),
+				new AttributeLayout(AttributeLayout.ACC_SYNTHETIC,
+						AttributeLayout.CONTEXT_METHOD, "", 12),
+				new AttributeLayout(AttributeLayout.ACC_ANNOTATION,
+						AttributeLayout.CONTEXT_CLASS, "", 13),
+				new AttributeLayout(AttributeLayout.ACC_ANNOTATION,
+						AttributeLayout.CONTEXT_FIELD, "", 13),
+				new AttributeLayout(AttributeLayout.ACC_ANNOTATION,
+						AttributeLayout.CONTEXT_METHOD, "", 13),
+				new AttributeLayout(AttributeLayout.ACC_ENUM,
+						AttributeLayout.CONTEXT_CLASS, "", 14),
+				new AttributeLayout(AttributeLayout.ACC_ENUM,
+						AttributeLayout.CONTEXT_FIELD, "", 14),
+				new AttributeLayout(AttributeLayout.ACC_ENUM,
+						AttributeLayout.CONTEXT_METHOD, "", 14),
 				new AttributeLayout(AttributeLayout.ATTRIBUTE_SOURCE_FILE,
 						AttributeLayout.CONTEXT_CLASS, "RUNH", 17),
 				new AttributeLayout(AttributeLayout.ATTRIBUTE_CONSTANT_VALUE,
 						AttributeLayout.CONTEXT_FIELD, "KQH", 17),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_CODE, AttributeLayout.CONTEXT_METHOD,
-						"*", 17),
+				new AttributeLayout(AttributeLayout.ATTRIBUTE_CODE,
+						AttributeLayout.CONTEXT_METHOD, "*", 17),
 				new AttributeLayout(AttributeLayout.ATTRIBUTE_ENCLOSING_METHOD,
 						AttributeLayout.CONTEXT_CLASS, "RCHRDNH", 18),
 				new AttributeLayout(AttributeLayout.ATTRIBUTE_EXCEPTIONS,
 						AttributeLayout.CONTEXT_METHOD, "NH[RCH]", 18),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE, AttributeLayout.CONTEXT_CLASS,
-						"RSH", 19),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE, AttributeLayout.CONTEXT_FIELD,
-						"RSH", 19),
+				new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE,
+						AttributeLayout.CONTEXT_CLASS, "RSH", 19),
+				new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE,
+						AttributeLayout.CONTEXT_FIELD, "RSH", 19),
 				new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE,
 						AttributeLayout.CONTEXT_METHOD, "RSH", 19),
 				new AttributeLayout(AttributeLayout.ATTRIBUTE_DEPRECATED,
@@ -59,31 +157,41 @@
 						AttributeLayout.CONTEXT_FIELD, "", 20),
 				new AttributeLayout(AttributeLayout.ATTRIBUTE_DEPRECATED,
 						AttributeLayout.CONTEXT_METHOD, "", 20),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
+				new AttributeLayout(
+						AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
 						AttributeLayout.CONTEXT_CLASS, "*", 21),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
+				new AttributeLayout(
+						AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
 						AttributeLayout.CONTEXT_FIELD, "*", 21),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
+				new AttributeLayout(
+						AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
 						AttributeLayout.CONTEXT_METHOD, "*", 21),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS,
+				new AttributeLayout(
+						AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS,
 						AttributeLayout.CONTEXT_CLASS, "*", 22),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS,
+				new AttributeLayout(
+						AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS,
 						AttributeLayout.CONTEXT_FIELD, "*", 22),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS,
+				new AttributeLayout(
+						AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS,
 						AttributeLayout.CONTEXT_METHOD, "*", 22),
 				new AttributeLayout(AttributeLayout.ATTRIBUTE_INNER_CLASSES,
 						AttributeLayout.CONTEXT_CLASS, "*", 23),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS,
+				new AttributeLayout(
+						AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS,
 						AttributeLayout.CONTEXT_METHOD, "*", 23),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_CLASS_FILE_VERSION,
+				new AttributeLayout(
+						AttributeLayout.ATTRIBUTE_CLASS_FILE_VERSION,
 						AttributeLayout.CONTEXT_CLASS, "*", 24),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS,
+				new AttributeLayout(
+						AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS,
 						AttributeLayout.CONTEXT_METHOD, "*", 24),
-				new AttributeLayout(AttributeLayout.ATTRIBUTE_ANNOTATION_DEFAULT,
+				new AttributeLayout(
+						AttributeLayout.ATTRIBUTE_ANNOTATION_DEFAULT,
 						AttributeLayout.CONTEXT_METHOD, "*", 25) };
 	}
 
-	private Map layouts;
+	private final Map layouts;
 
 	public AttributeLayoutMap() throws Pack200Exception {
 		this.layouts = new HashMap();

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java?rev=571482&r1=571481&r2=571482&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java Fri Aug 31 07:42:49 2007
@@ -20,24 +20,27 @@
 // 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.BufferedInputStream;
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 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;
 
 import org.apache.harmony.pack200.bytecode.Attribute;
+import org.apache.harmony.pack200.bytecode.ByteCode;
 import org.apache.harmony.pack200.bytecode.CPClass;
 import org.apache.harmony.pack200.bytecode.CPField;
 import org.apache.harmony.pack200.bytecode.CPMethod;
 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.CodeAttribute;
 import org.apache.harmony.pack200.bytecode.ConstantValueAttribute;
 import org.apache.harmony.pack200.bytecode.ExceptionsAttribute;
 import org.apache.harmony.pack200.bytecode.SourceFileAttribute;
@@ -147,15 +150,17 @@
 			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;
@@ -228,6 +233,12 @@
 
 	private String[] classThis;
 
+	private int[] codeHandlerCount;
+
+	private int[] codeMaxNALocals;
+
+	private int[] codeMaxStack;
+
 	private String[] cpClass;
 
 	private int cpClassCount;
@@ -318,6 +329,8 @@
 
 	private ArrayList[][] methodAttributes;
 
+	private byte[][][] methodByteCodePacked;
+
 	private String[][] methodDescr;
 
 	private ExceptionsAttribute[][] methodExceptions;
@@ -332,7 +345,7 @@
 
 	private int segmentsRemaining;
 
-	private ClassFile buildClassFile(int classNum) {
+	private ClassFile buildClassFile(int classNum) throws Pack200Exception {
 		ClassFile classFile = new ClassFile();
 		classFile.major = defaultClassMajorVersion; // TODO If
 		// classVersionMajor[] use
@@ -347,9 +360,16 @@
 		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 = attributeDefinitionMap
+				.getAttributeLayout(AttributeLayout.ATTRIBUTE_SOURCE_FILE,
+						AttributeLayout.CONTEXT_CLASS);
+		if (SOURCE_FILE.matches(classFlags[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]));
@@ -467,22 +487,21 @@
 	 */
 	private long[] decodeBandLong(String name, InputStream in, BHSDCodec codec,
 			int count) throws IOException, Pack200Exception {
+		in.mark(count * codec.getB());
 		long[] result = codec.decode(count, in);
-		if (result.length > 0) {
+		if (result.length > 0 && !codec.equals(Codec.BYTE1)) {
 			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);
+				in.reset();
+				result = weShouldHaveUsed.decode(count, in);
 			} 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);
+				in.reset();
+				result = weShouldHaveUsed.decode(count, in);
 			}
 		}
 		// TODO Remove debugging code
@@ -653,6 +672,7 @@
 			for (int j = 0; j < methodFlags[i].length; j++) {
 				long flag = methodFlags[i][j];
 				if (layout.matches(flag)) {
+					// TODO This should be a decoeBand ...
 					numExceptions[i][j] = (int) codec.decode(in);
 				}
 			}
@@ -662,15 +682,17 @@
 			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]);
+				if (n > 0) {
+					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]);
 				}
-				methodExceptions[i][j] = new ExceptionsAttribute(exceptions);
-				methodAttributes[i][j].add(methodExceptions[i][j]);
 			}
 		}
 	}
@@ -695,17 +717,146 @@
 		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)");
+		int count = SegmentUtils.countMatches(flags, layout);
+		if (count > 0)
+			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) throws IOException,
+			Pack200Exception {
+		int bcStringRefCount = 0;
+		int bcInitRefCount = 0;
+		int bcFieldRefCount = 0;
+		int bcThisFieldCount = 0;
+		int bcMethodRefCount = 0;
+		int bcIMethodRefCount = 0;
+
+		AttributeLayout abstractModifier = attributeDefinitionMap
+				.getAttributeLayout(AttributeLayout.ACC_ABSTRACT,
+						AttributeLayout.CONTEXT_METHOD);
+		AttributeLayout nativeModifier = attributeDefinitionMap
+				.getAttributeLayout(AttributeLayout.ACC_NATIVE,
+						AttributeLayout.CONTEXT_METHOD);
+		AttributeLayout staticModifier = attributeDefinitionMap
+				.getAttributeLayout(AttributeLayout.ACC_STATIC,
+						AttributeLayout.CONTEXT_METHOD);
+		methodByteCodePacked = new byte[classCount][][];
+		int bcParsed = 0;
+		for (int c = 0; c < classCount; c++) {
+			int numberOfMethods = methodFlags[c].length;
+			methodByteCodePacked[c] = new byte[numberOfMethods][];
+			for (int m = 0; m < numberOfMethods; m++) {
+				long methodFlag = methodFlags[c][m];
+				if (!abstractModifier.matches(methodFlag)
+						&& !nativeModifier.matches(methodFlag)) {
+					ByteArrayOutputStream codeBytes = new ByteArrayOutputStream();
+					byte code;
+					while ((code = (byte) (0xff & in.read())) != -1)
+						codeBytes.write(code);
+					methodByteCodePacked[c][m] = codeBytes.toByteArray();
+					bcParsed += methodByteCodePacked[c][m].length;
+					for (int i = 0; i < methodByteCodePacked[c][m].length; i++) {
+						int codePacked = 0xff & methodByteCodePacked[c][m][i];
+						// TODO a lot of this needs to be encapsulated in the
+						// place that
+						// calculates what the arguments are, since (a) it will
+						// need
+						// to know where to get them, and (b) what to do with
+						// them
+						// once they've been gotten. But that's for another
+						// time.
+						switch (codePacked) {
+						case 18: // (a)ldc
+							bcStringRefCount++;
+							break;
+						case 178: // getstatic
+						case 179: // putstatic
+						case 180: // getfield
+						case 181: // putfield
+							bcFieldRefCount++;
+							break;
+						case 182: // invokevirtual
+						case 183: // invokespecial
+						case 184: // invokestatic
+							bcMethodRefCount++;
+							break;
+						case 185: // invokeinterface
+							bcIMethodRefCount++;
+							break;
+						case 202: // getstatic_this
+						case 203: // putstatic_this
+						case 204: // getfield_this
+						case 205: // putfield_this
+							bcThisFieldCount++;
+							break;
+						case 231: // invoke_special_init
+							bcInitRefCount++;
+							break;
+
+						default: // unhandled specifically at this stage
+							debug("Found unhandled "
+									+ ByteCode.getByteCode(codePacked));
+						}
+					}
+				}
+			}
+		}
+		// other bytecode bands
+		debug("Parsed *bc_codes (" + bcParsed + ")");
+		debug("unimplemented bc_case_count");
+		debug("unimplemented bc_case_value");
+		debug("unimplemented bc_byte");
+		debug("unimplemented bc_short");
+		debug("unimplemented bc_local");
+		debug("unimplemented bc_label");
+		debug("unimplemented bc_intref");
+		debug("unimplemented bc_floatref");
+		debug("unimplemented bc_longref");
+		debug("unimplemented bc_doubleref");
+		int[] bcStringRef = decodeBandInt("bc_stringref", in, Codec.DELTA5,
+				bcStringRefCount);
+		debug("unimplemented bc_classref");
+		int[] bcFieldRef = decodeBandInt("bc_fieldref", in, Codec.DELTA5,
+				bcFieldRefCount);
+		int[] bcMethodRef = decodeBandInt("bc_methodref", in, Codec.UNSIGNED5,
+				bcMethodRefCount);
+		int[] bcIMethodRef = decodeBandInt("bc_imethodref", in, Codec.DELTA5,
+				bcIMethodRefCount);
+		int[] bcThisField = decodeBandInt("bc_thisfield", in, Codec.UNSIGNED5,
+				bcThisFieldCount);
+		debug("unimplemented bc_superfield");
+		debug("unimplemented bc_thismethod");
+		debug("unimplemented bc_supermethod");
+		debug("unimplemented bc_initref");
+		int[] bcInitRef = decodeBandInt("bc_initref", in, Codec.UNSIGNED5,
+				bcInitRefCount);
+		debug("unimplemented bc_escref");
+		debug("unimplemented bc_escrefsize");
+		debug("unimplemented bc_escsize");
+		debug("unimplemented bc_escbyte");
+		int i = 0;
+		for (int c = 0; c < classCount; c++) {
+			int numberOfMethods = methodFlags[c].length;
+			for (int m = 0; m < numberOfMethods; m++) {
+				long methodFlag = methodFlags[c][m];
+				if (!abstractModifier.matches(methodFlag)
+						&& !nativeModifier.matches(methodFlag)) {
+					int maxStack = codeMaxStack[i];
+					int maxLocal = codeMaxNALocals[i];
+					if (!staticModifier.matches(methodFlag))
+						maxLocal++; // one for 'this' parameter
+					maxLocal += SegmentUtils.countArgs(methodDescr[c][m]);
+					// TODO Move creation of code attribute until after constant
+					// pool resolved
+					CodeAttribute attr = new CodeAttribute(maxStack, maxLocal,
+							methodByteCodePacked[c][m]);
+					methodAttributes[c][m].add(attr);
+					i++;
+				}
 			}
 		}
-	}
 
-	private void parseBcBands(InputStream in) {
-		debug("Unimplemented bc_bands");
 	}
 
 	private void parseClassAttrBands(InputStream in) throws IOException,
@@ -740,7 +891,7 @@
 		debug("unimplemented class_EnclosingMethod_RC");
 		debug("unimplemented class_EnclosingMethod_RDN");
 		debug("unimplemented class_Signature_RS");
-		parseMetadataBands("class");
+		parseMetadataBands(AttributeLayout.CONTEXT_CLASS);
 		debug("unimplemented class_InnerClasses_N");
 		debug("unimplemented class_InnerClasses_RC");
 		debug("unimplemented class_InnerClasses_F");
@@ -759,10 +910,8 @@
 		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,
@@ -803,23 +952,55 @@
 		}
 	}
 
-	private void parseCodeBands(InputStream in) throws Pack200Exception {
-		// look through each method
-		int codeBands = 0;
+	private void parseCodeBands(InputStream in) throws Pack200Exception,
+			IOException {
 		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++;
+		int codeBands = SegmentUtils.countMatches(methodFlags, layout);
+		int[] codeHeaders = decodeBandInt("code_headers", in, Codec.BYTE1,
+				codeBands);
+		int codeSpecialHeader = 0;
+		for (int i = 0; i < codeBands; i++) {
+			if (codeHeaders[i] == 0)
+				codeSpecialHeader++;
+		}
+		int[] codeMaxStackSpecials = decodeBandInt("code_max_stack", in,
+				Codec.UNSIGNED5, codeSpecialHeader);
+		int[] codeMaxNALocalsSpecials = decodeBandInt("code_max_na_locals", in,
+				Codec.UNSIGNED5, codeSpecialHeader);
+		int[] codeHandlerCountSpecials = decodeBandInt("code_handler_count",
+				in, Codec.UNSIGNED5, codeSpecialHeader);
+
+		codeMaxStack = new int[codeBands];
+		codeMaxNALocals = new int[codeBands];
+		codeHandlerCount = new int[codeBands];
+		int special = 0;
+		for (int i = 0; i < codeBands; i++) {
+			int header = 0xff & codeHeaders[i];
+			if (header < 0) {
+				throw new IllegalStateException("Shouldn't get here");
+			} else if (header == 0) {
+				codeMaxStack[i] = codeMaxStackSpecials[special];
+				codeMaxNALocals[i] = codeMaxNALocalsSpecials[special];
+				codeHandlerCount[i] = codeHandlerCountSpecials[special];
+				special++;
+			} else if (header <= 144) {
+				codeMaxStack[i] = (header - 1) % 12;
+				codeMaxNALocals[i] = (header - 1) / 12;
+				codeHandlerCount[i] = 0;
+			} else if (header <= 208) {
+				codeMaxStack[i] = (header - 145) % 8;
+				codeMaxNALocals[i] = (header - 145) / 8;
+				codeHandlerCount[i] = 1;
+			} else if (header <= 255) {
+				codeMaxStack[i] = (header - 209) % 7;
+				codeMaxNALocals[i] = (header - 209) / 7;
+				codeHandlerCount[i] = 2;
+			} else {
+				throw new IllegalStateException("Shouldn't get here either");
 			}
 		}
-		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");
@@ -1176,7 +1357,7 @@
 			}
 		}
 		debug("unimplemented field_Signature_RS");
-		parseMetadataBands("field");
+		parseMetadataBands(AttributeLayout.CONTEXT_FIELD);
 	}
 
 	/**
@@ -1197,15 +1378,15 @@
 	 */
 	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;
-		}
+		// 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);
@@ -1298,39 +1479,49 @@
 				cpUTF8);
 	}
 
-	private void parseMetadataBands(String unit) throws Pack200Exception {
+	private void parseMetadataBands(int context) throws Pack200Exception {
 		String[] RxA;
-		if ("method".equals(unit)) {
+		if (AttributeLayout.CONTEXT_METHOD == context) {
 			RxA = new String[] { "RVA", "RIA", "RVPA", "RIPA", "AD" };
-		} else if ("field".equals(unit) || "class".equals(unit)) {
+		} else if (AttributeLayout.CONTEXT_FIELD == context
+				|| AttributeLayout.CONTEXT_CLASS == context) {
 			RxA = new String[] { "RVA", "RIA" };
 		} else {
-			throw new Pack200Exception("Unknown type of metadata unit " + unit);
+			throw new Pack200Exception("Unknown type of metadata unit "
+					+ context);
 		}
+		// AttributeLayout layout =
+		// map.get(RuntimeVisibleAnnotations,class/field/method as int)
+		// foreachheader ...
+		// if layout.matches(header[n] or whatever)
+		String contextName = (AttributeLayout.CONTEXT_METHOD == context ? "method"
+				: (AttributeLayout.CONTEXT_FIELD == context ? "field"
+						: (AttributeLayout.CONTEXT_CLASS == context ? "class"
+								: "unkowon")));
 		for (int i = 0; i < RxA.length; i++) {
 			String rxa = RxA[i];
 			if (rxa.indexOf("P") >= 0) {
-				debug("unimplemented " + unit + "_" + rxa + "_param_NB");
+				debug("unimplemented " + contextName + "_" + 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");
+				debug("unimplemented " + contextName + "_" + rxa + "_anno_N");
+				debug("unimplemented " + contextName + "_" + rxa + "_type_RS");
+				debug("unimplemented " + contextName + "_" + rxa + "_pair_N");
+				debug("unimplemented " + contextName + "_" + rxa + "_name_RU");
+			}
+			debug("unimplemented " + contextName + "_" + rxa + "_T");
+			debug("unimplemented " + contextName + "_" + rxa + "_caseI_KI");
+			debug("unimplemented " + contextName + "_" + rxa + "_caseD_KD");
+			debug("unimplemented " + contextName + "_" + rxa + "_caseF_KF");
+			debug("unimplemented " + contextName + "_" + rxa + "_caseJ_KJ");
+			debug("unimplemented " + contextName + "_" + rxa + "_casec_RS");
+			debug("unimplemented " + contextName + "_" + rxa + "_caseet_RS");
+			debug("unimplemented " + contextName + "_" + rxa + "_caseec_RU");
+			debug("unimplemented " + contextName + "_" + rxa + "_cases_RU");
+			debug("unimplemented " + contextName + "_" + rxa + "_casearray_N");
+			debug("unimplemented " + contextName + "_" + rxa + "_nesttype_RS");
+			debug("unimplemented " + contextName + "_" + rxa + "_nestpair_N");
+			debug("unimplemented " + contextName + "_" + rxa + "_nestname_RU");
 		}
 	}
 
@@ -1363,7 +1554,7 @@
 		}
 		parseAttributeMethodExceptions(in);
 		parseAttributeMethodSignature(in);
-		parseMetadataBands("method");
+		parseMetadataBands(AttributeLayout.CONTEXT_METHOD);
 	}
 
 	/**
@@ -1669,6 +1860,24 @@
 		return archiveMajor + archiveMinor + cpLong.hashCode()
 				+ icName.hashCode() + icOuterClass.hashCode()
 				+ icThisClass.hashCode();
+	}
+
+	/**
+	 * 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);
 	}
 
 	/**

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java?rev=571482&r1=571481&r2=571482&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/ByteCode.java Fri Aug 31 07:42:49 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/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java?rev=571482&r1=571481&r2=571482&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CPFieldRef.java Fri Aug 31 07:42:49 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;
 	}
 
 }

Added: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java?rev=571482&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java (added)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java Fri Aug 31 07:42:49 2007
@@ -0,0 +1,100 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.harmony.pack200.bytecode;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class CodeAttribute extends Attribute {
+	public List attributes = new ArrayList();
+	public List byteCodes = new ArrayList();
+	public int codeLength;
+	public List exceptionTable = new ArrayList(); // of ExceptionTableEntry
+	// instances
+	public int maxLocals;
+	public int maxStack;
+
+	public CodeAttribute(int maxStack, int maxLocals, byte codePacked[]) {
+		super("Code"); //$NON-NLS-1$
+		this.maxLocals = maxLocals;
+		this.maxStack = maxStack;
+		this.codeLength = 0;
+		for (int i = 0; i < codePacked.length; i++) {
+			ByteCode byteCode = ByteCode.getByteCode(codePacked[i]);
+			byteCodes.add(byteCode);
+			this.codeLength += byteCode.getLength();
+		}
+	}
+
+	protected int getLength() {
+		int attributesSize = 0;
+		Iterator it = attributes.iterator();
+		while (it.hasNext()) {
+			Attribute attribute = (Attribute) it.next();
+			attributesSize += attribute.getLength();
+		}
+		return 2 + 2 + 4 + codeLength + exceptionTable.size() * (2 + 2 + 2 + 2)
+				+ 2 + attributesSize;
+	}
+
+	protected void resolve(ClassConstantPool pool) {
+		super.resolve(pool);
+		Iterator it = attributes.iterator();
+		while (it.hasNext()) {
+			Attribute attribute = (Attribute) it.next();
+			attribute.resolve(pool);
+		}
+		it = byteCodes.iterator();
+		while (it.hasNext()) {
+			ByteCode byteCode = (ByteCode) it.next();
+			byteCode.resolve(pool);
+		}
+	}
+
+	public String toString() {
+		// TODO More Info here later
+		return "Code: " + getLength() + " bytes";
+	}
+
+	protected void writeBody(DataOutputStream dos) throws IOException {
+		dos.writeShort(maxStack);
+		dos.writeShort(maxLocals);
+		dos.writeInt(codeLength);
+		Iterator it = byteCodes.iterator();
+		while (it.hasNext()) {
+			ByteCode byteCode = (ByteCode) it.next();
+			byteCode.write(dos);
+		}
+		dos.writeShort(exceptionTable.size());
+		Iterator exceptionTableEntries = exceptionTable.iterator();
+		while (exceptionTableEntries.hasNext()) {
+			ExceptionTableEntry entry = (ExceptionTableEntry) exceptionTableEntries
+					.next();
+			entry.write(dos);
+		}
+		dos.writeShort(attributes.size());
+		it = attributes.iterator();
+		while (it.hasNext()) {
+			Attribute attribute = (Attribute) it.next();
+			attribute.write(dos);
+		}
+	}
+
+}

Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/bytecode/CodeAttribute.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/Unpack.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/Unpack.java?rev=571482&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/Unpack.java (added)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/Unpack.java Fri Aug 31 07:42:49 2007
@@ -0,0 +1,38 @@
+/*
++ *  Licensed to the Apache Software Foundation (ASF) under one or more
++ *  contributor license agreements.  See the NOTICE file distributed with
++ *  this work for additional information regarding copyright ownership.
++ *  The ASF licenses this file to You under the Apache License, Version 2.0
++ *  (the "License"); you may not use this file except in compliance with
++ *  the License.  You may obtain a copy of the License at
++ *
++ *     http://www.apache.org/licenses/LICENSE-2.0
++ *
++ *  Unless required by applicable law or agreed to in writing, software
++ *  distributed under the License is distributed on an "AS IS" BASIS,
++ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ *  See the License for the specific language governing permissions and
++ *  limitations under the License.
++ */
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.jar.JarOutputStream;
+
+import org.apache.harmony.pack200.Pack200Exception;
+import org.apache.harmony.pack200.Segment;
+
+public class Unpack {
+	public static void main(String[] args) throws IOException, Pack200Exception {
+		BufferedInputStream in = new BufferedInputStream(
+				args.length > 0 ? new FileInputStream(args[0]) : System.in);
+		JarOutputStream out = new JarOutputStream(
+				args.length > 1 ? (OutputStream) new FileOutputStream(args[1])
+						: (OutputStream) new BufferedOutputStream(System.out));
+		Segment.parse(in).writeJar(out, in);
+	}
+}

Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/Unpack.java
------------------------------------------------------------------------------
    svn:eol-style = native