You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by sj...@apache.org on 2008/10/08 15:05:44 UTC

svn commit: r702856 [2/3] - in /harmony/enhanced/classlib/trunk: ./ depends/files/ depends/manifests/asm-3.1/ make/ modules/pack200/META-INF/ modules/pack200/src/main/java/org/apache/harmony/pack200/ modules/pack200/src/test/java/org/apache/harmony/pac...

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java Wed Oct  8 06:05:43 2008
@@ -20,30 +20,17 @@
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
-import org.apache.bcel.Constants;
-import org.apache.bcel.classfile.Attribute;
-import org.apache.bcel.classfile.Code;
-import org.apache.bcel.classfile.CodeException;
-import org.apache.bcel.classfile.Constant;
-import org.apache.bcel.classfile.ConstantValue;
-import org.apache.bcel.classfile.Deprecated;
-import org.apache.bcel.classfile.ExceptionTable;
-import org.apache.bcel.classfile.Field;
-import org.apache.bcel.classfile.InnerClasses;
-import org.apache.bcel.classfile.JavaClass;
-import org.apache.bcel.classfile.LineNumberTable;
-import org.apache.bcel.classfile.LocalVariableTable;
-import org.apache.bcel.classfile.Method;
-import org.apache.bcel.classfile.Signature;
-import org.apache.bcel.classfile.SourceFile;
-import org.apache.bcel.classfile.Unknown;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.Label;
 
 public class ClassBands extends BandSet {
 
-    private SegmentHeader header;
+    private static final Integer ZERO = new Integer(0);
+    private final SegmentHeader header;
     private final CpBands cpBands;
-    private AttributeDefinitionBands attrBands;
+    private final AttributeDefinitionBands attrBands;
 
     private final CPClass[] class_this;
     private final CPClass[] class_super;
@@ -51,43 +38,61 @@
     private final int[] class_interface_count;
 
     private final int[] major_versions;
-    private final int[] minor_versions;
 
-    private long[] class_flags;
-    private List classSourceFile = new ArrayList();
-    private List classEnclosingMethod = new ArrayList();
-    private List classSignature = new ArrayList();
-
-    private List classFileVersionMinor = new ArrayList();
-    private List classFileVersionMajor = new ArrayList();
+    private final long[] class_flags;
+    private final List classSourceFile = new ArrayList();
+    private final List classEnclosingMethodClass = new ArrayList();
+    private final List classEnclosingMethodDesc = new ArrayList();
+    private final List classSignature = new ArrayList();
 
+    private final List classFileVersionMinor = new ArrayList();
+    private final List classFileVersionMajor = new ArrayList();
 
     private final int[] class_field_count;
     private final CPNameAndType[][] field_descr;
-    private List fieldFlags = new ArrayList();
-    private List fieldConstantValueKQ = new ArrayList();
-    private List fieldSignature = new ArrayList();
+    private final long[][] field_flags;
+    private final List fieldConstantValueKQ = new ArrayList();
+    private final List fieldSignature = new ArrayList();
 
     private final int[] class_method_count;
     private final CPNameAndType[][] method_descr;
-    private List methodFlags = new ArrayList();
-    private List methodSignature = new ArrayList();
-    private List methodExceptionNumber = new ArrayList();
-    private List methodExceptionClasses = new ArrayList();
-
-    private List codeHeaders = new ArrayList();
-    private List codeMaxStack = new ArrayList();
-    private List codeMaxLocals = new ArrayList();
-    private List codeHandlerCount = new ArrayList();
-    private List codeHandlerStartP = new ArrayList();
-    private List codeHandlerEndPO = new ArrayList();
-    private List codeHandlerCatchPO = new ArrayList();
-    private List codeHandlerClass = new ArrayList();
-    private List codeFlags = new ArrayList();
-
-
+    private final long[][] method_flags;
+    private final List methodSignature = new ArrayList();
+    private final List methodExceptionNumber = new ArrayList();
+    private final List methodExceptionClasses = new ArrayList();
+
+    private int[] codeHeaders;
+    private final List codeMaxStack = new ArrayList();
+    private final List codeMaxLocals = new ArrayList();
+    private final List codeHandlerCount = new ArrayList();
+    private final List codeHandlerStartP = new ArrayList();
+    private final List codeHandlerEndPO = new ArrayList();
+    private final List codeHandlerCatchPO = new ArrayList();
+    private final List codeHandlerClass = new ArrayList();
+    private final List codeFlags = new ArrayList();
+    private final List codeLineNumberTableN = new ArrayList();
+    private final List codeLineNumberTableBciP = new ArrayList();
+    private final List codeLineNumberTableLine = new ArrayList();
+    private final List codeLocalVariableTableN = new ArrayList();
+    private final List codeLocalVariableTableBciP = new ArrayList();
+    private final List codeLocalVariableTableSpanO = new ArrayList();
+    private final List codeLocalVariableTableNameRU = new ArrayList();
+    private final List codeLocalVariableTableTypeRS = new ArrayList();
+    private final List codeLocalVariableTableSlot = new ArrayList();
+    private final List codeLocalVariableTypeTableN = new ArrayList();
+    private final List codeLocalVariableTypeTableBciP = new ArrayList();
+    private final List codeLocalVariableTypeTableSpanO = new ArrayList();
+    private final List codeLocalVariableTypeTableNameRU = new ArrayList();
+    private final List codeLocalVariableTypeTableTypeRS = new ArrayList();
+    private final List codeLocalVariableTypeTableSlot = new ArrayList();
+
+    private final List tempFieldFlags = new ArrayList();
+    private final List tempFieldDesc = new ArrayList();
+    private final List tempMethodFlags = new ArrayList();
+    private final List tempMethodDesc = new ArrayList();
 
-    public ClassBands(SegmentHeader header, CpBands cpBands, AttributeDefinitionBands attrBands, int numClasses) {
+    public ClassBands(SegmentHeader header, CpBands cpBands,
+            AttributeDefinitionBands attrBands, int numClasses) {
         this.header = header;
         this.cpBands = cpBands;
         this.attrBands = attrBands;
@@ -98,307 +103,89 @@
         class_field_count = new int[numClasses];
         class_method_count = new int[numClasses];
         field_descr = new CPNameAndType[numClasses][];
+        field_flags = new long[numClasses][];
         method_descr = new CPNameAndType[numClasses][];
-        minor_versions = new int[numClasses];
+        method_flags = new long[numClasses][];
+        // minor_versions = new int[numClasses];
         major_versions = new int[numClasses];
         class_flags = new long[numClasses];
     }
 
     private int index = 0;
 
-    public void addClass(JavaClass obj) {
-        class_this[index] = cpBands.getCPClass(obj.getClassName());
-        class_super[index] = cpBands.getCPClass(obj.getSuperclassName());
-        String[] interfaces = obj.getInterfaceNames();
+    private int numMethodArgs = 0;
+
+    public void addClass(int major, int flags, String className,
+            String superName, String[] interfaces) {
+        class_this[index] = cpBands.getCPClass(className);
+        class_super[index] = cpBands.getCPClass(superName);
         class_interface_count[index] = interfaces.length;
+        class_interface[index] = new CPClass[interfaces.length];
         for (int i = 0; i < interfaces.length; i++) {
             class_interface[index][i] = cpBands.getCPClass(interfaces[i]);
         }
-        addClassAttributes(obj);
-
-        addFields(obj.getFields());
-
-        Method[] methods = obj.getMethods();
-        addMethods(methods);
-        addCode(methods);
-        index++;
-    }
-
-    private void addClassAttributes(JavaClass obj) {
-        int flags = obj.getAccessFlags();
-        Attribute[] attributes = obj.getAttributes();
-        for (int i = 0; i < attributes.length; i++) {
-            if(attributes[i] instanceof SourceFile) {
-                flags |= (1<<17);
-                String sourceFileName = ((SourceFile)attributes[i]).getSourceFileName();
-                if(isPredictableSourceFileName(obj.getClassName(), sourceFileName)) {
-                    classSourceFile.add(null);
-                } else {
-                    classSourceFile.add(cpBands.getCPUtf8(sourceFileName));
-                }
-//            } else if (attributes[i] instanceof EnclosingMethod) {
-//                flags |= (1<<18);
-            } else if (attributes[i] instanceof Signature) {
-                flags |= (1<<19);
-                classSignature.add(cpBands.getCPSignature(((Signature)attributes[i]).getSignature()));
-            } else if (attributes[i] instanceof Deprecated) {
-                flags |= (1<<20);
-//            } else if (attributes[i] instanceof RuntimeVisibleAnnotations) {
-//                flags |= (1<<21);
-//            } else if (attributes[i] instanceof RuntimeInvisibleAnnotations) {
-//                flags |= (1<<22);
-            } else if (attributes[i] instanceof InnerClasses) {
-                flags |= (1<<23);
-            } else if (attributes[i] instanceof Unknown) {
-                Unknown attr = (Unknown)attributes[i];
-                int index = attrBands.getIndex(attr);
-                flags |= (1<<index);
-
-            }
-        }
-        minor_versions[index] = obj.getMinor();
-        major_versions[index] = obj.getMajor();
+        major_versions[index] = major;
         class_flags[index] = flags;
-
-    }
-
-    private void addMethods(Method[] methods) {
-        class_method_count[index] = methods.length;
-        method_descr[index] = new CPNameAndType[methods.length];
-        for (int i = 0; i < methods.length; i++) {
-            method_descr[index][i] = cpBands.getCPNameAndType(methods[i]
-                    .getName(), methods[i].getSignature());
-
-            int flags = methods[i].getAccessFlags();
-            Attribute[] attributes = methods[i].getAttributes();
-            for (int j = 0; j < attributes.length; j++) {
-                if (attributes[j] instanceof Code) {
-                    flags |= (1<<17);
-                } else if (attributes[j] instanceof ExceptionTable) {
-                    flags |= (1<<18);
-                    String[] exceptionNames = ((ExceptionTable)attributes[j]).getExceptionNames();
-                    methodExceptionNumber.add(new Integer(exceptionNames.length));
-                    for (int k = 0; k < exceptionNames.length; k++) {
-                        methodExceptionClasses.add(cpBands.getCPClass(exceptionNames[k]));
-                    }
-                } else if (attributes[j] instanceof Signature) {
-                    flags |= (1<<19);
-                    methodSignature.add(cpBands.getCPSignature(((Signature)attributes[j]).getSignature()));
-                } else if (attributes[j] instanceof Deprecated) {
-                    flags |= (1<<20);
-//                } else if (attributes[j] instanceof RuntimeVisibleAnnotations) {
-//                    flags |= (1<<21);
-//                } else if (attributes[j] instanceof RuntimeInvisibleAnnotations) {
-//                    flags |= (1<<22);
-//                } else if (attributes[j] instanceof RuntimeVisibleParameterAnnotations) {
-//                    flags |= (1<<23);
-//                } else if (attributes[j] instanceof RuntimeInvisibleParameterAnnotations) {
-//                    flags |= (1<<24);
-//                } else if (attributes[j] instanceof AnnotationDefault) {
-//                    flags |= (1<<25);
-                } else if (attributes[j] instanceof Unknown) {
-                    Unknown attr = (Unknown)attributes[i];
-                    int index = attrBands.getIndex(attr);
-                    flags |= (1<<index);
-
-                }
-            }
-            methodFlags.add(new Long(flags));
-        }
-    }
-
-    private void addFields(Field[] fields) {
-        class_field_count[index] = fields.length;
-        field_descr[index] = new CPNameAndType[fields.length];
-        for (int i = 0; i < fields.length; i++) {
-            field_descr[index][i] = cpBands.getCPNameAndType(fields[i]
-                    .getName(), fields[i].getSignature());
-            int flags = fields[i].getAccessFlags();
-            Attribute[] attributes = fields[i].getAttributes();
-            for (int j = 0; j < attributes.length; j++) {
-                if (attributes[j] instanceof ConstantValue) {
-                    flags |= (1<<17);
-                    ConstantValue constV = ((ConstantValue)attributes[j]);
-                    Constant theConstant = constV.getConstantPool().getConstant(constV.getConstantValueIndex());
-                    CPConstant cpConstant = cpBands.getCPConstant(theConstant, constV.getConstantPool());
-                    fieldConstantValueKQ.add(cpConstant);
-                } else if (attributes[j] instanceof Signature) {
-                    flags |= (1<<19);
-                    fieldSignature.add(cpBands.getCPSignature(((Signature)attributes[j]).getSignature()));
-                } else if (attributes[j] instanceof Deprecated) {
-                    flags |= (1<<20);
-//                } else if (attributes[j] instanceof RuntimeVisibleAnnotations) {
-//                    flags |= (1<<21);
-//                } else if (attributes[j] instanceof RuntimeInvisibleAnnotations) {
-//                    flags |= (1<<22);
-                } else if (attributes[j] instanceof Unknown) {
-                    Unknown attr = (Unknown)attributes[i];
-                    int index = attrBands.getIndex(attr);
-                    flags |= (1<<index);
-
-                }
-            }
-            fieldFlags.add(new Long(flags));
-        }
-
-    }
-
-    private void addCode(Method[] methods) {
-
-        for (int i = 0; i < methods.length; i++) {
-            Code code = methods[i].getCode();
-            if(code != null) {
-                int header = 0;
-                int maxLocals = code.getMaxLocals();
-                int maxStack = code.getMaxStack();
-                CodeException[] exceptions = code.getExceptionTable();
-                int handlers = exceptions.length;
-                if(handlers <= 2) {
-                    if (handlers == 0) {
-                        if(maxLocals < 11 && maxStack < 11) {
-                            header = 12*maxLocals + maxStack + 1;
-                        }
-                    } else if (handlers == 1) {
-                        if(maxLocals < 7 && maxStack < 7) {
-                            header = 8*maxLocals + maxStack + 145;
-                        }
-                    } else if (handlers == 2) {
-                        if(maxLocals < 6 && maxStack < 6) {
-                            header = 7*maxLocals + maxStack + 209;
-                        }
-                    }
-                }
-                codeHeaders.add(new Integer(header));
-                if(header == 0) {
-                    codeMaxStack.add(new Integer(maxStack));
-                    codeMaxLocals.add(new Integer(maxLocals));
-                    codeHandlerCount.add(new Integer(handlers));
-                }
-                for (int j = 0; j < exceptions.length; j++) {
-                    int startPC = exceptions[j].getStartPC();
-                    int endPC = exceptions[j].getEndPC();
-                    int catchPC = exceptions[j].getHandlerPC();
-                    int[] renumbered = renumberBCI(code.getCode());
-                    int renumberedStart = renumbered[startPC];
-                    int renumberedEnd = renumbered[endPC] - renumberedStart;
-                    int renumberedCatch = renumbered[catchPC] - renumberedEnd;
-                    codeHandlerStartP.add(new Integer(renumberedStart));
-                    codeHandlerEndPO.add(new Integer(renumberedEnd));
-                    codeHandlerCatchPO.add(new Integer(renumberedCatch));
-                    int catchType = exceptions[j].getCatchType();
-                    if(catchType == 0) {
-                        codeHandlerClass.add(null);
-                    } else {
-                        String className = methods[i].getConstantPool().getConstantString(catchType, Constants.CONSTANT_Class);
-                        codeHandlerClass.add(cpBands.getCPClass(className));
-                    }
-                }
-
-                int flags = 0;
-                Attribute[] attributes = methods[i].getAttributes();
-                for (int j = 0; j < attributes.length; j++) {
-                    if (attributes[j] instanceof LineNumberTable) {
-                        flags |= (1<<1);
-                    } else if (attributes[j] instanceof LocalVariableTable) {
-                        flags |= (1<<2);
-//                    } else if (attributes[j] instanceof LocalVariableTypeTable) {
-//                        flags |= (1<<3);
-                    } else if (attributes[j] instanceof Unknown) {
-                        Unknown attr = (Unknown)attributes[i];
-                        int index = attrBands.getIndex(attr);
-                        flags |= (1<<index);
-
-                    }
-                }
-                codeFlags.add(new Long(flags));
-            }
-        }
     }
 
-    private int[] renumberBCI(byte[] code) {
-        int[] instructionBoundaries = getInstructionBoundaries(code);
-        int[] renumbered = new int[code.length];
-        int precedence = 1;
-        for (int i = 1; i < instructionBoundaries.length; i++) {
-            renumbered[instructionBoundaries[i]] = precedence;
-            precedence++;
-        }
-        for (int i = 1; i < renumbered.length; i++) {
-            if(renumbered[i] == 0) {
-                renumbered[i] = precedence;
-                precedence++;
-            }
-        }
-        return renumbered;
-    }
-
-    private int[] getInstructionBoundaries(byte[] code) {
-        List boundariesList = new ArrayList();
-        boolean wide = false;
-        for (int i = 0; i < code.length; i++) {
-            int b = code[i] & 0xFF;
-            boundariesList.add(new Integer(b));
-            if(b == Constants.WIDE) {
-                wide = true;
-            } else if (b == Constants.TABLESWITCH) {
-                int padding = (i + 1) % 4 == 0 ? 0 : 4 - i + 1;
-                i+= padding;
-                i+= 4;
-                byte b1 = code[i];
-                byte b2 = code[++i];
-                byte b3 = code[++i];
-                byte b4 = code[++i];
-                int low = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
-                b1 = code[++i];
-                b2 = code[++i];
-                b3 = code[++i];
-                b4 = code[++i];
-                int high = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
-                int jumpTableSize = 4 * (high - low + 1);
-                i += jumpTableSize;
-            } else if (b == Constants.LOOKUPSWITCH) {
-                int padding = (i + 1) % 4 == 0 ? 0 : 4 - i + 1;
-                i+= padding;
-                i+= 4;
-                byte b1 = code[i];
-                byte b2 = code[++i];
-                byte b3 = code[++i];
-                byte b4 = code[++i];
-                int npairs = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
-                i += 8 * npairs;
-            } else {
-                if(b == 16 || b == 18 || (b >= 21 && b <= 25) || (b >= 54 && b <= 58) || b == 188) {
-                    i++;
-                    if(wide) {
-                        i++;
-                        wide = false;
-                    }
-                } else if (b == 17 || b == 19 || b == 20 || b== 132 || (b >= 153 && b <= 168)|| (b >= 178 && b <= 184) || b == 187 || b == 188 || b == 192 || b == 193 || b == 198 || b == 199) {
-                    i+=2;
-//                    don't think we need this...
-//                    if(wide) {
-//                        i+=2;
-//                        wide = false;
-//                    }
-                } else if (b == 185 || b == 200 || b == 201) {
-                    i+=4;
-                }
-            }
+    public void addField(int flags, String name, String desc, String signature,
+            Object value) {
+        CPMethodOrField field = cpBands.addCPField(class_this[index], name,
+                desc);
+        tempFieldDesc.add(field.getDesc());
+        if (signature != null) {
+            fieldSignature.add(cpBands.getCPSignature(signature));
+            flags |= (1 << 19);
+        }
+        if (value != null) {
+            fieldConstantValueKQ.add(cpBands.getConstant(value));
+            flags |= (1 << 17);
         }
-        return listToArray(boundariesList);
+        tempFieldFlags.add(new Long(flags));
     }
 
     public void finaliseBands() {
-        int defaultMinorVersion = header.getDefaultMinorVersion();
         int defaultMajorVersion = header.getDefaultMajorVersion();
-
         for (int i = 0; i < class_flags.length; i++) {
             int major = major_versions[i];
-            int minor = minor_versions[i];
-            if(major != defaultMajorVersion || minor != defaultMinorVersion) {
+            if (major != defaultMajorVersion) {
                 class_flags[i] |= 1 << 24;
                 classFileVersionMajor.add(new Integer(major));
-                classFileVersionMinor.add(new Integer(minor));
+                classFileVersionMinor.add(ZERO);
+            }
+        }
+        // Calculate code headers
+        codeHeaders = new int[codeFlags.size()];
+        int removed = 0;
+        for (int i = 0; i < codeHeaders.length; i++) {
+            int numHandlers = ((Integer) codeHandlerCount.get(i - removed))
+                    .intValue();
+            int maxLocals = ((Integer) codeMaxLocals.get(i - removed))
+                    .intValue();
+            int maxStack = ((Integer) codeMaxStack.get(i - removed)).intValue();
+            if (numHandlers == 0) {
+                int header = maxLocals * 12 + maxStack + 1;
+                if (header < 145 && maxStack < 12) {
+                    codeHeaders[i] = header;
+                }
+            } else if (numHandlers == 1) {
+                int header = maxLocals * 8 + maxStack + 145;
+                if (header < 209 && maxStack < 8) {
+                    codeHeaders[i] = header;
+                }
+            } else if (numHandlers == 2) {
+                int header = maxLocals * 7 + maxStack + 209;
+                if (header < 256 && maxStack < 7) {
+                    codeHeaders[i] = header;
+                }
+            }
+            if (codeHeaders[i] != 0) { // Remove the redundant values from
+                                        // codeHandlerCount, codeMaxLocals and
+                                        // codeMaxStack
+                codeHandlerCount.remove(i - removed);
+                codeMaxLocals.remove(i - removed);
+                codeMaxStack.remove(i - removed);
+                removed++;
             }
         }
     }
@@ -408,20 +195,21 @@
         for (int i = 0; i < classThis.length; i++) {
             classThis[i] = class_this[i].getIndex();
         }
-        out.write(encodeBandInt(classThis, Codec.DELTA5));
+        out.write(encodeBandInt("class_this", classThis, Codec.DELTA5));
 
         int[] classSuper = new int[class_super.length];
         for (int i = 0; i < classSuper.length; i++) {
             classSuper[i] = class_super[i].getIndex();
         }
-        out.write(encodeBandInt(classSuper, Codec.DELTA5));
-        out.write(encodeBandInt(class_interface_count, Codec.DELTA5));
+        out.write(encodeBandInt("class_super", classSuper, Codec.DELTA5));
+        out.write(encodeBandInt("class_interface_count", class_interface_count,
+                Codec.DELTA5));
 
         int totalInterfaces = sum(class_interface_count);
         int[] classInterface = new int[totalInterfaces];
         int k = 0;
         for (int i = 0; i < class_interface.length; i++) {
-            if(class_interface[i] != null) {
+            if (class_interface[i] != null) {
                 for (int j = 0; j < class_interface[i].length; j++) {
                     CPClass cpClass = class_interface[i][j];
                     classInterface[k] = cpClass.getIndex();
@@ -429,9 +217,13 @@
                 }
             }
         }
-        out.write(encodeBandInt(classInterface, Codec.DELTA5));
-        out.write(encodeBandInt(class_field_count, Codec.DELTA5));
-        out.write(encodeBandInt(class_method_count, Codec.DELTA5));
+        out
+                .write(encodeBandInt("class_interface", classInterface,
+                        Codec.DELTA5));
+        out.write(encodeBandInt("class_field_count", class_field_count,
+                Codec.DELTA5));
+        out.write(encodeBandInt("class_method_count", class_method_count,
+                Codec.DELTA5));
 
         int totalFields = sum(class_field_count);
         int[] fieldDescr = new int[totalFields];
@@ -443,7 +235,7 @@
                 k++;
             }
         }
-        out.write(encodeBandInt(fieldDescr, Codec.DELTA5));
+        out.write(encodeBandInt("field_descr", fieldDescr, Codec.DELTA5));
         writeFieldAttributeBands(out);
 
         int totalMethods = sum(class_method_count);
@@ -456,7 +248,7 @@
                 k++;
             }
         }
-        out.write(encodeBandInt(methodDescr, Codec.DELTA5));
+        out.write(encodeBandInt("method_descr", methodDescr, Codec.MDELTA5));
 
         writeMethodAttributeBands(out);
         writeClassAttributeBands(out);
@@ -471,42 +263,332 @@
         return sum;
     }
 
-    private void writeFieldAttributeBands(OutputStream out) throws IOException, Pack200Exception {
-        out.write(encodeFlags(longListToArray(fieldFlags), Codec.UNSIGNED5, Codec.UNSIGNED5, header.have_field_flags_hi()));
-        out.write(encodeBandInt(cpEntryListToArray(fieldConstantValueKQ), Codec.UNSIGNED5));
-        out.write(encodeBandInt(cpEntryListToArray(fieldSignature), Codec.UNSIGNED5));
-    }
-
-    private void writeMethodAttributeBands(OutputStream out) throws IOException, Pack200Exception {
-        out.write(encodeFlags(longListToArray(methodFlags), Codec.UNSIGNED5, Codec.UNSIGNED5, header.have_method_flags_hi()));
-        out.write(encodeBandInt(listToArray(methodExceptionNumber), Codec.UNSIGNED5));
-        out.write(encodeBandInt(cpEntryListToArray(methodExceptionClasses), Codec.UNSIGNED5));
-        out.write(encodeBandInt(cpEntryListToArray(methodSignature), Codec.UNSIGNED5));
+    private void writeFieldAttributeBands(OutputStream out) throws IOException,
+            Pack200Exception {
+        out.write(encodeFlags("field_flags", field_flags, Codec.UNSIGNED5,
+                Codec.UNSIGNED5, header.have_field_flags_hi()));
+        out.write(encodeBandInt("fieldConstantValueKQ",
+                cpEntryListToArray(fieldConstantValueKQ), Codec.UNSIGNED5));
+        out.write(encodeBandInt("fieldSignature",
+                cpEntryListToArray(fieldSignature), Codec.UNSIGNED5));
+    }
+
+    private void writeMethodAttributeBands(OutputStream out)
+            throws IOException, Pack200Exception {
+        out.write(encodeFlags("method_flags", method_flags, Codec.UNSIGNED5,
+                Codec.UNSIGNED5, header.have_method_flags_hi()));
+        out.write(encodeBandInt("methodExceptionNumber",
+                listToArray(methodExceptionNumber), Codec.UNSIGNED5));
+        out.write(encodeBandInt("methodExceptionClasses",
+                cpEntryListToArray(methodExceptionClasses), Codec.UNSIGNED5));
+        out.write(encodeBandInt("methodSignature",
+                cpEntryListToArray(methodSignature), Codec.UNSIGNED5));
+    }
+
+    private void writeClassAttributeBands(OutputStream out) throws IOException,
+            Pack200Exception {
+        out.write(encodeFlags("class_flags", class_flags, Codec.UNSIGNED5,
+                Codec.UNSIGNED5, header.have_class_flags_hi()));
+        out.write(encodeBandInt("classSourceFile",
+                cpEntryOrNullListToArray(classSourceFile), Codec.UNSIGNED5));
+        out.write(encodeBandInt("classSignature",
+                cpEntryListToArray(classSignature), Codec.UNSIGNED5));
+        out.write(encodeBandInt("classFileVersionMinor",
+                listToArray(classFileVersionMinor), Codec.UNSIGNED5));
+        out.write(encodeBandInt("classFileVersionMajor",
+                listToArray(classFileVersionMajor), Codec.UNSIGNED5));
+    }
+
+    private void writeCodeBands(OutputStream out) throws IOException,
+            Pack200Exception {
+        out.write(encodeBandInt("codeHeaders", codeHeaders, Codec.BYTE1));
+        out.write(encodeBandInt("codeMaxStack", listToArray(codeMaxStack),
+                Codec.UNSIGNED5));
+        out.write(encodeBandInt("codeMaxLocals", listToArray(codeMaxLocals),
+                Codec.UNSIGNED5));
+        out.write(encodeBandInt("codeHandlerCount",
+                listToArray(codeHandlerCount), Codec.UNSIGNED5));
+        out.write(encodeBandInt("codeHandlerStartP",
+                listToArray(codeHandlerStartP), Codec.BCI5));
+        out.write(encodeBandInt("codeHandlerEndPO",
+                listToArray(codeHandlerEndPO), Codec.BRANCH5));
+        out.write(encodeBandInt("codeHandlerCatchPO",
+                listToArray(codeHandlerCatchPO), Codec.BRANCH5));
+        out.write(encodeBandInt("codeHandlerClass",
+                cpEntryOrNullListToArray(codeHandlerClass), Codec.UNSIGNED5));
+        writeCodeAttributeBands(out);
+    }
+
+    private void writeCodeAttributeBands(OutputStream out) throws IOException,
+            Pack200Exception {
+        out.write(encodeFlags("codeFlags", longListToArray(codeFlags),
+                Codec.UNSIGNED5, Codec.UNSIGNED5, header.have_code_flags_hi()));
+
+        // *code_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
+        // *code_attr_indexes :UNSIGNED5 [SUM(*code_attr_count)]
+        // *code_attr_calls :UNSIGNED5 [...]
+        out.write(encodeBandInt("code_LineNumberTable_N",
+                listToArray(codeLineNumberTableN), Codec.UNSIGNED5));
+        out.write(encodeBandInt("code_LineNumberTable_bci_P",
+                listToArray(codeLineNumberTableBciP), Codec.BCI5));
+        out.write(encodeBandInt("code_LineNumberTable_line",
+                listToArray(codeLineNumberTableLine), Codec.UNSIGNED5));
+        out.write(encodeBandInt("code_LocalVariableTable_N",
+                listToArray(codeLocalVariableTableN), Codec.UNSIGNED5));
+        out.write(encodeBandInt("code_LocalVariableTable_bci_P",
+                listToArray(codeLocalVariableTableBciP), Codec.BCI5));
+        out.write(encodeBandInt("code_LocalVariableTable_span_O",
+                listToArray(codeLocalVariableTableSpanO), Codec.BRANCH5)); // TODO:
+                                                                            // Difference
+        out.write(encodeBandInt("code_LocalVariableTable_name_RU",
+                cpEntryListToArray(codeLocalVariableTableNameRU),
+                Codec.UNSIGNED5));
+        out.write(encodeBandInt("code_LocalVariableTable_type_RS",
+                cpEntryListToArray(codeLocalVariableTableTypeRS),
+                Codec.UNSIGNED5));
+        out.write(encodeBandInt("code_LocalVariableTable_slot",
+                listToArray(codeLocalVariableTableSlot), Codec.UNSIGNED5));
+        out.write(encodeBandInt("code_LocalVariableTypeTable_N",
+                listToArray(codeLocalVariableTypeTableN), Codec.UNSIGNED5));
+        out.write(encodeBandInt("code_LocalVariableTypeTable_bci_P",
+                listToArray(codeLocalVariableTypeTableBciP), Codec.BCI5));
+        out.write(encodeBandInt("code_LocalVariableTypeTable_span_O",
+                listToArray(codeLocalVariableTypeTableSpanO), Codec.BRANCH5));
+        out.write(encodeBandInt("code_LocalVariableTypeTable_name_RU",
+                cpEntryListToArray(codeLocalVariableTypeTableNameRU),
+                Codec.UNSIGNED5));
+        out.write(encodeBandInt("code_LocalVariableTypeTable_type_RS",
+                cpEntryListToArray(codeLocalVariableTypeTableTypeRS),
+                Codec.UNSIGNED5));
+        out.write(encodeBandInt("code_LocalVariableTypeTable_slot",
+                listToArray(codeLocalVariableTypeTableSlot), Codec.UNSIGNED5));
 
     }
 
-    private void writeClassAttributeBands(OutputStream out) throws IOException, Pack200Exception {
-        out.write(encodeFlags(class_flags, Codec.UNSIGNED5, Codec.UNSIGNED5, header.have_class_flags_hi()));
-        out.write(encodeBandInt(cpEntryOrNullListToArray(classSourceFile), Codec.UNSIGNED5));
-        out.write(encodeBandInt(cpEntryListToArray(classSignature), Codec.UNSIGNED5));
-        out.write(encodeBandInt(listToArray(classFileVersionMinor), Codec.UNSIGNED5));
-        out.write(encodeBandInt(listToArray(classFileVersionMajor), Codec.UNSIGNED5));
-    }
-
-    private void writeCodeBands(OutputStream out) throws IOException, Pack200Exception {
-        out.write(encodeBandInt(listToArray(codeHeaders), Codec.BYTE1));
-        out.write(encodeBandInt(listToArray(codeMaxStack), Codec.UNSIGNED5));
-        out.write(encodeBandInt(listToArray(codeMaxLocals), Codec.UNSIGNED5));
-        out.write(encodeBandInt(listToArray(codeHandlerCount), Codec.UNSIGNED5));
-        out.write(encodeBandInt(listToArray(codeHandlerStartP), Codec.BCI5));
-        out.write(encodeBandInt(listToArray(codeHandlerEndPO), Codec.BRANCH5));
-        out.write(encodeBandInt(listToArray(codeHandlerCatchPO), Codec.BRANCH5));
-        out.write(encodeBandInt(cpEntryOrNullListToArray(codeHandlerClass), Codec.UNSIGNED5));
-        writeCodeAttributeBands(out);
+    public void addMethod(int flags, String name, String desc,
+            String signature, String[] exceptions) {
+        CPMethodOrField method = cpBands.addCPMethod(class_this[index], name,
+                desc);
+        tempMethodDesc.add(method.getDesc());
+        if (signature != null) {
+            methodSignature.add(cpBands.getCPSignature(signature));
+            flags |= (1 << 19);
+        }
+        if (exceptions != null) {
+            methodExceptionNumber.add(new Integer(exceptions.length));
+            for (int i = 0; i < exceptions.length; i++) {
+                methodExceptionClasses.add(cpBands.getCPClass(exceptions[i]));
+            }
+            flags |= (1 << 18);
+        }
+        tempMethodFlags.add(new Long(flags));
+        codeHandlerCount.add(ZERO);
+        numMethodArgs = countArgs(desc);
+    }
+
+    protected static int countArgs(String descriptor) {
+        int bra = descriptor.indexOf("(");
+        int ket = descriptor.indexOf(")");
+        if (bra == -1 || ket == -1 || ket < bra)
+            throw new IllegalArgumentException("No arguments");
+
+        boolean inType = false;
+        boolean consumingNextType = false;
+        int count = 0;
+        for (int i = bra + 1; i < ket; i++) {
+            char charAt = descriptor.charAt(i);
+            if (inType && charAt == ';') {
+                inType = false;
+                consumingNextType = false;
+            } else if (!inType && charAt == 'L') {
+                inType = true;
+                count++;
+            } else if (charAt == '[') {
+                consumingNextType = true;
+            } else if (inType) {
+                // NOP
+            } else {
+                if (consumingNextType) {
+                    count++;
+                    consumingNextType = false;
+                } else {
+                    if (charAt == 'D' || charAt == 'J') {
+                        count += 2;
+                    } else {
+                        count++;
+                    }
+                }
+            }
+        }
+        return count;
     }
 
-    private void writeCodeAttributeBands(OutputStream out) throws IOException, Pack200Exception {
-        out.write(encodeFlags(longListToArray(codeFlags), Codec.UNSIGNED5, Codec.UNSIGNED5, header.have_code_flags_hi()));
+    public void endOfClass() { // All the data for the current class has been
+                                // read
+        int numFields = tempFieldDesc.size();
+        class_field_count[index] = numFields;
+        field_descr[index] = new CPNameAndType[numFields];
+        field_flags[index] = new long[numFields];
+        for (int i = 0; i < numFields; i++) {
+            field_descr[index][i] = (CPNameAndType) tempFieldDesc.get(i);
+            field_flags[index][i] = ((Long) tempFieldFlags.get(i)).longValue();
+        }
+        int numMethods = tempMethodDesc.size();
+        class_method_count[index] = numMethods;
+        method_descr[index] = new CPNameAndType[numMethods];
+        method_flags[index] = new long[numMethods];
+        for (int i = 0; i < numMethods; i++) {
+            method_descr[index][i] = (CPNameAndType) tempMethodDesc.get(i);
+            method_flags[index][i] = ((Long) tempMethodFlags.get(i))
+                    .longValue();
+        }
+        tempFieldDesc.clear();
+        tempFieldFlags.clear();
+        tempMethodDesc.clear();
+        tempMethodFlags.clear();
+        index++;
     }
 
+    public void addSourceFile(String source) {
+        String implicitSourceFileName = class_this[index].toString();
+        implicitSourceFileName = implicitSourceFileName
+                .substring(implicitSourceFileName.lastIndexOf('/') + 1)
+                + ".java";
+        if (source.equals(implicitSourceFileName)) {
+            classSourceFile.add(null);
+        } else {
+            classSourceFile.add(cpBands.getCPUtf8(source));
+        }
+        class_flags[index] |= (1 << 17);
+    }
+
+    public void addEnclosingMethod(String owner, String name, String desc) {
+        class_flags[index] |= (1 << 18);
+        classEnclosingMethodClass.add(cpBands.getCPClass(owner));
+        classEnclosingMethodDesc.add(name == null ? null : cpBands
+                .getCPNameAndType(name, desc));
+    }
+
+    public void addUnknownFieldAttribute(Attribute arg0) {
+        // TODO Auto-generated method stub
+
+    }
+
+    public void addUnknownMethodAttribute(Attribute arg0) {
+        // TODO Auto-generated method stub
+
+    }
+
+    public void addMaxStack(int maxStack, int maxLocals) {
+        Long latestFlag = (Long) tempMethodFlags
+                .remove(tempMethodFlags.size() - 1);
+        Long newFlag = new Long(latestFlag.intValue() | (1 << 17));
+        tempMethodFlags.add(newFlag);
+        codeMaxStack.add(new Integer(maxStack));
+        if ((newFlag.longValue() & (1 << 3)) == 0) { // not static
+            maxLocals--; // minus 'this' local
+        }
+        maxLocals -= numMethodArgs;
+        codeMaxLocals.add(new Integer(maxLocals));
+    }
+
+    public void addCode() {
+        codeFlags.add(new Long(0));
+    }
+
+    public void addHandler(Label start, Label end, Label handler, String type) {
+        Long latestMethodFlag = (Long) tempMethodFlags.get(tempMethodFlags
+                .size() - 1);
+        if ((latestMethodFlag.longValue() & (1 << 18)) == 0) {
+            tempMethodFlags.remove(tempMethodFlags.size() - 1);
+            tempMethodFlags.add(new Long(latestMethodFlag.intValue()
+                    | (1 << 18)));
+        }
+        Integer handlers = (Integer) codeHandlerCount.remove(codeHandlerCount
+                .size() - 1);
+        codeHandlerCount.add(new Integer(handlers.intValue() + 1));
+        codeHandlerStartP.add(start);
+        codeHandlerEndPO.add(end);
+        codeHandlerCatchPO.add(handler);
+        codeHandlerClass.add(type == null ? null : cpBands.getCPClass(type));
+    }
+
+    public void addLineNumber(int line, Label start) {
+        Long latestCodeFlag = (Long) codeFlags.get(codeFlags.size() - 1);
+        if ((latestCodeFlag.intValue() & (1 << 1)) == 0) {
+            codeFlags.remove(codeFlags.size() - 1);
+            codeFlags.add(new Long(latestCodeFlag.intValue() | (1 << 1)));
+            codeLineNumberTableN.add(new Integer(1));
+        } else {
+            Integer numLines = (Integer) codeLineNumberTableN
+                    .remove(codeLineNumberTableN.size() - 1);
+            codeLineNumberTableN.add(new Integer(numLines.intValue() + 1));
+        }
+        codeLineNumberTableLine.add(new Integer(line));
+        codeLineNumberTableBciP.add(start);
+        // TODO: bci renumbering
+    }
+
+    public void addLocalVariable(String name, String desc, String signature,
+            Label start, Label end, int indx) {
+        if (signature != null) { // LocalVariableTypeTable attribute
+            Long latestCodeFlag = (Long) codeFlags.get(codeFlags.size() - 1);
+            if ((latestCodeFlag.intValue() & (1 << 3)) == 0) {
+                codeFlags.remove(codeFlags.size() - 1);
+                codeFlags.add(new Long(latestCodeFlag.intValue() | (1 << 3)));
+                codeLocalVariableTypeTableN.add(new Integer(1));
+            } else {
+                Integer numLocals = (Integer) codeLocalVariableTypeTableN
+                        .remove(codeLocalVariableTypeTableN.size() - 1);
+                codeLocalVariableTypeTableN.add(new Integer(numLocals
+                        .intValue() + 1));
+            }
+            codeLocalVariableTypeTableBciP.add(start);
+            codeLocalVariableTypeTableSpanO.add(end);
+            codeLocalVariableTypeTableNameRU.add(cpBands.getCPUtf8(name));
+            codeLocalVariableTypeTableTypeRS.add(cpBands
+                    .getCPSignature(signature));
+            codeLocalVariableTypeTableSlot.add(new Integer(indx));
+        }
+        // LocalVariableTable attribute
+        Long latestCodeFlag = (Long) codeFlags.get(codeFlags.size() - 1);
+        if ((latestCodeFlag.intValue() & (1 << 2)) == 0) {
+            codeFlags.remove(codeFlags.size() - 1);
+            codeFlags.add(new Long(latestCodeFlag.intValue() | (1 << 2)));
+            codeLocalVariableTableN.add(new Integer(1));
+        } else {
+            Integer numLocals = (Integer) codeLocalVariableTableN
+                    .remove(codeLocalVariableTableN.size() - 1);
+            codeLocalVariableTableN.add(new Integer(numLocals.intValue() + 1));
+        }
+        codeLocalVariableTableBciP.add(start);
+        codeLocalVariableTableSpanO.add(end);
+        codeLocalVariableTableNameRU.add(cpBands.getCPUtf8(name));
+        codeLocalVariableTableTypeRS.add(cpBands.getCPSignature(desc));
+        codeLocalVariableTableSlot.add(new Integer(indx));
+    }
+
+    public void doBciRenumbering(List bciRenumbering, Map labelsToOffsets) {
+        renumberBci(codeLineNumberTableBciP, bciRenumbering, labelsToOffsets);
+        renumberBci(codeLocalVariableTableBciP, bciRenumbering, labelsToOffsets);
+        renumberBci(codeLocalVariableTableSpanO, bciRenumbering,
+                labelsToOffsets);
+        renumberBci(codeLocalVariableTypeTableBciP, bciRenumbering,
+                labelsToOffsets);
+        renumberBci(codeLocalVariableTypeTableSpanO, bciRenumbering,
+                labelsToOffsets);
+    }
+
+    private void renumberBci(List list, List bciRenumbering, Map labelsToOffsets) {
+        for (int i = list.size() - 1; i >= 0; i--) {
+            Object label = list.get(i);
+            if (label instanceof Integer) {
+                break;
+            } else if (label instanceof Label) {
+                list.remove(i);
+                Integer offset = (Integer) labelsToOffsets.get(label);
+                list.add(i, bciRenumbering.get(offset.intValue()));
+            }
+        }
+    }
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java Wed Oct  8 06:05:43 2008
@@ -27,21 +27,6 @@
 import java.util.Set;
 import java.util.TreeSet;
 
-import org.apache.bcel.classfile.Constant;
-import org.apache.bcel.classfile.ConstantClass;
-import org.apache.bcel.classfile.ConstantDouble;
-import org.apache.bcel.classfile.ConstantFieldref;
-import org.apache.bcel.classfile.ConstantFloat;
-import org.apache.bcel.classfile.ConstantInteger;
-import org.apache.bcel.classfile.ConstantInterfaceMethodref;
-import org.apache.bcel.classfile.ConstantLong;
-import org.apache.bcel.classfile.ConstantMethodref;
-import org.apache.bcel.classfile.ConstantNameAndType;
-import org.apache.bcel.classfile.ConstantPool;
-import org.apache.bcel.classfile.ConstantString;
-import org.apache.bcel.classfile.ConstantUtf8;
-import org.apache.bcel.classfile.JavaClass;
-
 /**
  * Pack200 Constant Pool Bands
  */
@@ -67,15 +52,12 @@
 
     private final Map stringsToCpUtf8 = new HashMap();
     private final Map stringsToCpNameAndType = new HashMap();
-    // private final Map stringsToCpString = new HashMap();
     private final Map stringsToCpClass = new HashMap();
     private final Map stringsToCpSignature = new HashMap();
+    private final Map stringsToCpMethodOrField = new HashMap();
 
     private final Map objectsToCPConstant = new HashMap();
 
-    private ConstantPool currentConstantPool;
-    private JavaClass currentClass;
-
     public CpBands(SegmentHeader segmentHeader) {
         this.segmentHeader = segmentHeader;
         defaultAttributeNames.add("AnnotationDefault");
@@ -139,7 +121,7 @@
             currentStr = currentStr.substring(prefix);
             char[] suffix = currentStr.toCharArray();
             if (suffix.length > 100) { // big suffix (100 is arbitrary - can we
-                                        // do better?)
+                // do better?)
                 cpUtf8Suffix[i - 1] = 0;
                 bigSuffix.add(new Integer(suffix.length));
                 addCharacters(bigChars, suffix);
@@ -160,11 +142,14 @@
         for (int i = 0; i < cpUtf8BigChars.length; i++) {
             cpUtf8BigChars[i] = ((Character) bigChars.get(i)).charValue();
         }
-        out.write(encodeBandInt(cpUtf8Prefix, Codec.DELTA5));
-        out.write(encodeBandInt(cpUtf8Suffix, Codec.UNSIGNED5));
-        out.write(encodeBandInt(cpUtf8Chars, Codec.CHAR3));
-        out.write(encodeBandInt(cpUtf8BigSuffix, Codec.DELTA5));
-        out.write(encodeBandInt(cpUtf8BigChars, Codec.DELTA5));
+        out.write(encodeBandInt("cpUtf8Prefix", cpUtf8Prefix, Codec.DELTA5));
+        out.write(encodeBandInt("cpUtf8Suffix", cpUtf8Suffix, Codec.UNSIGNED5));
+        out.write(encodeBandInt("cpUtf8Chars", cpUtf8Chars, Codec.CHAR3));
+        out.write(encodeBandInt("cpUtf8BigSuffix", cpUtf8BigSuffix,
+                Codec.DELTA5));
+        out
+                .write(encodeBandInt("cpUtf8BigChars", cpUtf8BigChars,
+                        Codec.DELTA5));
     }
 
     private void addCharacters(List chars, char[] charArray) {
@@ -182,7 +167,7 @@
             cpInt[i] = integer.getInt();
             i++;
         }
-        out.write(encodeBandInt(cpInt, Codec.UDELTA5));
+        out.write(encodeBandInt("cpInt", cpInt, Codec.UDELTA5));
     }
 
     private void writeCpFloat(OutputStream out) throws IOException,
@@ -194,7 +179,7 @@
             cpFloat[i] = Float.floatToIntBits(fl.getFloat());
             i++;
         }
-        out.write(encodeBandInt(cpFloat, Codec.UDELTA5));
+        out.write(encodeBandInt("cpFloat", cpFloat, Codec.UDELTA5));
     }
 
     private void writeCpLong(OutputStream out) throws IOException,
@@ -209,8 +194,8 @@
             loBits[i] = (int) l;
             i++;
         }
-        out.write(encodeBandInt(highBits, Codec.UDELTA5));
-        out.write(encodeBandInt(loBits, Codec.DELTA5));
+        out.write(encodeBandInt("cp_Long_high", highBits, Codec.UDELTA5));
+        out.write(encodeBandInt("cp_Long_low", loBits, Codec.DELTA5));
     }
 
     private void writeCpDouble(OutputStream out) throws IOException,
@@ -225,8 +210,8 @@
             loBits[i] = (int) l;
             i++;
         }
-        out.write(encodeBandInt(highBits, Codec.UDELTA5));
-        out.write(encodeBandInt(loBits, Codec.DELTA5));
+        out.write(encodeBandInt("cp_Double_high", highBits, Codec.UDELTA5));
+        out.write(encodeBandInt("cp_Double_low", loBits, Codec.DELTA5));
     }
 
     private void writeCpString(OutputStream out) throws IOException,
@@ -238,7 +223,7 @@
             cpString[i] = cpStr.getIndexInCpUtf8();
             i++;
         }
-        out.write(encodeBandInt(cpString, Codec.UDELTA5));
+        out.write(encodeBandInt("cpString", cpString, Codec.UDELTA5));
     }
 
     private void writeCpClass(OutputStream out) throws IOException,
@@ -250,7 +235,7 @@
             cpClass[i] = cpCl.getIndexInCpUtf8();
             i++;
         }
-        out.write(encodeBandInt(cpClass, Codec.UDELTA5));
+        out.write(encodeBandInt("cpClass", cpClass, Codec.UDELTA5));
     }
 
     private void writeCpSignature(OutputStream out) throws IOException,
@@ -268,8 +253,10 @@
         for (int j = 0; j < cpSignatureClasses.length; j++) {
             cpSignatureClasses[j] = ((CPClass) classes.get(j)).getIndex();
         }
-        out.write(encodeBandInt(cpSignatureForm, Codec.DELTA5));
-        out.write(encodeBandInt(cpSignatureClasses, Codec.UDELTA5));
+        out.write(encodeBandInt("cpSignatureForm", cpSignatureForm,
+                Codec.DELTA5));
+        out.write(encodeBandInt("cpSignatureClasses", cpSignatureClasses,
+                Codec.UDELTA5));
     }
 
     private void writeCpDescr(OutputStream out) throws IOException,
@@ -283,8 +270,8 @@
             cpDescrType[i] = nameAndType.getTypeIndex();
             i++;
         }
-        out.write(encodeBandInt(cpDescrName, Codec.DELTA5));
-        out.write(encodeBandInt(cpDescrType, Codec.UDELTA5));
+        out.write(encodeBandInt("cpDescrName", cpDescrName, Codec.DELTA5));
+        out.write(encodeBandInt("cpDescrType", cpDescrType, Codec.UDELTA5));
     }
 
     private void writeCpMethodOrField(Set cp, OutputStream out)
@@ -298,13 +285,10 @@
             cp_methodOrField_desc[i] = mOrF.getDescIndex();
             i++;
         }
-        out.write(encodeBandInt(cp_methodOrField_class, Codec.DELTA5));
-        out.write(encodeBandInt(cp_methodOrField_desc, Codec.UDELTA5));
-    }
-
-    public void setCurrentClass(JavaClass javaClass) {
-        this.currentClass = javaClass;
-        this.currentConstantPool = javaClass.getConstantPool();
+        out.write(encodeBandInt("cp_methodOrField_class",
+                cp_methodOrField_class, Codec.DELTA5));
+        out.write(encodeBandInt("cp_methodOrField_desc", cp_methodOrField_desc,
+                Codec.UDELTA5));
     }
 
     public void finaliseBands() {
@@ -338,8 +322,9 @@
     }
 
     private void addIndices() {
-        Set[] sets = new Set[] { cp_Utf8, cp_String, cp_Class, cp_Signature,
-                cp_Descr };
+        Set[] sets = new Set[] { cp_Utf8, cp_Int, cp_Float, cp_Long, cp_Double,
+                cp_String, cp_Class, cp_Signature, cp_Descr, cp_Field,
+                cp_Method, cp_Imethod };
         for (int i = 0; i < sets.length; i++) {
             int j = 0;
             for (Iterator iterator = sets[i].iterator(); iterator.hasNext();) {
@@ -348,6 +333,34 @@
                 j++;
             }
         }
+        Map classNameToIndex = new HashMap();
+        for (Iterator iterator = cp_Field.iterator(); iterator.hasNext();) {
+            CPMethodOrField mOrF = (CPMethodOrField) iterator.next();
+            CPClass className = mOrF.getClassName();
+            Integer index = (Integer) classNameToIndex.get(className);
+            if (index == null) {
+                classNameToIndex.put(className, new Integer(1));
+                mOrF.setIndexInClass(0);
+            } else {
+                int theIndex = index.intValue();
+                mOrF.setIndexInClass(theIndex);
+                classNameToIndex.put(className, new Integer(theIndex + 1));
+            }
+        }
+        classNameToIndex.clear();
+        for (Iterator iterator = cp_Method.iterator(); iterator.hasNext();) {
+            CPMethodOrField mOrF = (CPMethodOrField) iterator.next();
+            CPClass className = mOrF.getClassName();
+            Integer index = (Integer) classNameToIndex.get(className);
+            if (index == null) {
+                classNameToIndex.put(className, new Integer(1));
+                mOrF.setIndexInClass(0);
+            } else {
+                int theIndex = index.intValue();
+                mOrF.setIndexInClass(theIndex);
+                classNameToIndex.put(className, new Integer(theIndex + 1));
+            }
+        }
     }
 
     private void removeCpUtf8(String string) {
@@ -358,115 +371,6 @@
         }
     }
 
-    public void addConstantClass(ConstantClass constant) {
-        String className = constant.getBytes(currentConstantPool);
-        addCPClass(className);
-    }
-
-    public void addConstantDouble(ConstantDouble constant) {
-        double d = (constant).getBytes();
-        Double bigD = new Double(d);
-        CPDouble cpd = (CPDouble) objectsToCPConstant.get(bigD);
-        if(cpd == null) {
-            cpd = new CPDouble(d);
-            cp_Double.add(cpd);
-            objectsToCPConstant.put(bigD, cpd);
-        }
-    }
-
-    public void addConstantFieldref(ConstantFieldref constant) {
-        ConstantFieldref cf = constant;
-        ConstantNameAndType cnat = (ConstantNameAndType) currentConstantPool
-                .getConstant(cf.getNameAndTypeIndex());
-        CPNameAndType nat = getCPNameAndType(cnat.getName(currentConstantPool),
-                cnat.getSignature(currentConstantPool));
-        cp_Field.add(new CPMethodOrField(getCPClass(cf
-                .getClass(currentConstantPool)), nat));
-    }
-
-    public void addConstantFloat(ConstantFloat constant) {
-        float f = (constant).getBytes();
-        Float bigF = new Float(f);
-        CPFloat cpf = (CPFloat) objectsToCPConstant.get(bigF);
-        if(cpf == null) {
-            cpf = new CPFloat(f);
-            cp_Float.add(cpf);
-            objectsToCPConstant.put(bigF, cpf);
-        }
-    }
-
-    public void addConstantInteger(ConstantInteger constant) {
-        int i = (constant).getBytes();
-        Integer bigI = new Integer(i);
-        CPInt cpi = (CPInt) objectsToCPConstant.get(bigI);
-        if(cpi == null) {
-            cpi = new CPInt(i);
-            cp_Int.add(cpi);
-            objectsToCPConstant.put(bigI, cpi);
-        }
-    }
-
-    public void addConstantInterfaceMethodref(
-            ConstantInterfaceMethodref constant) {
-        ConstantNameAndType cnat = (ConstantNameAndType) currentConstantPool
-                .getConstant(constant.getNameAndTypeIndex());
-        String signature = cnat.getSignature(currentConstantPool);
-        CPNameAndType nat = getCPNameAndType(cnat.getName(currentConstantPool),
-                signature);
-        cp_Imethod.add(new CPMethodOrField(getCPClass(constant
-                .getClass(currentConstantPool)), nat));
-    }
-
-    public void addConstantLong(ConstantLong constant) {
-        long l = (constant).getBytes();
-        Long bigL = new Long(l);
-        CPLong cpl = (CPLong) objectsToCPConstant.get(bigL);
-        if(cpl == null) {
-            cpl = new CPLong(l);
-            cp_Long.add(cpl);
-            objectsToCPConstant.put(bigL, cpl);
-        }
-    }
-
-    public void addConstantMethodref(ConstantMethodref constant) {
-        ConstantNameAndType cnat = (ConstantNameAndType) currentConstantPool
-                .getConstant(constant.getNameAndTypeIndex());
-        String signature = cnat.getSignature(currentConstantPool);
-        CPNameAndType nat = getCPNameAndType(cnat.getName(currentConstantPool),
-                signature);
-        cp_Method.add(new CPMethodOrField(getCPClass(constant
-                .getClass(currentConstantPool)), nat));
-    }
-
-    public void addConstantNameAndType(ConstantNameAndType constant) {
-        String name = constant.getName(currentConstantPool);
-        String signature = constant.getSignature(currentConstantPool);
-        addCPNameAndType(name, signature);
-    }
-
-    public void addConstantString(ConstantString constant) {
-        String string = constant.getBytes(currentConstantPool);
-        CPString cpString = (CPString) objectsToCPConstant.get(string);
-        if (cpString == null) {
-            cpString = new CPString(getCPUtf8(string));
-            cp_String.add(cpString);
-            objectsToCPConstant.put(string, cpString);
-        }
-    }
-
-    public void addConstantUtf8(ConstantUtf8 constant) {
-        String utf8 = constant.getBytes();
-        if (!defaultAttributeNames.contains(utf8)) {
-            if (utf8.endsWith(".java")) {
-                if (!isPredictableSourceFileName(currentClass.getClassName(), utf8)) {
-                    addCPUtf8(utf8);
-                }
-            } else {
-                addCPUtf8(utf8);
-            }
-        }
-    }
-
     private void addCPUtf8(String utf8) {
         getCPUtf8(utf8);
     }
@@ -561,59 +465,103 @@
         return nameAndType;
     }
 
-    public CPConstant getCPConstant(Constant theConstant, ConstantPool cp) {
-        CPConstant cpC;
-        if(theConstant instanceof ConstantDouble) {
-            Double key = new Double(((ConstantDouble)theConstant).getBytes());
-            cpC = (CPConstant) objectsToCPConstant.get(key);
-            if(cpC == null) {
-                cpC = new CPDouble(key.doubleValue());
-                cp_Double.add(cpC);
-                objectsToCPConstant.put(key, cpC);
-            }
-        } else if (theConstant instanceof ConstantFloat) {
-            Float key = new Float(((ConstantFloat)theConstant).getBytes());
-            cpC = (CPConstant) objectsToCPConstant.get(key);
-            if(cpC == null) {
-                cpC = new CPFloat(key.floatValue());
-                cp_Float.add(cpC);
-                objectsToCPConstant.put(key, cpC);
-            }
-        } else if (theConstant instanceof ConstantInteger) {
-            Integer key = new Integer(((ConstantInteger)theConstant).getBytes());
-            cpC = (CPConstant) objectsToCPConstant.get(key);
-            if(cpC == null) {
-                cpC = new CPInt(key.intValue());
-                cp_Int.add(cpC);
-                objectsToCPConstant.put(key, cpC);
-            }
-        } else if (theConstant instanceof ConstantLong) {
-            Long key = new Long(((ConstantLong)theConstant).getBytes());
-            cpC = (CPConstant) objectsToCPConstant.get(key);
-            if(cpC == null) {
-                cpC = new CPLong(key.longValue());
-                cp_Long.add(cpC);
-                objectsToCPConstant.put(key, cpC);
-            }
-        } else if (theConstant instanceof ConstantString) {
-            String key = ((ConstantString)theConstant).getBytes(cp);
-            cpC = (CPConstant) objectsToCPConstant.get(key);
-            if(cpC == null) {
-                cpC = new CPString(getCPUtf8(key));
-                cp_String.add(cpC);
-                objectsToCPConstant.put(key, cpC);
-            }
-        } else if (theConstant instanceof ConstantClass) {
-            cpC = getCPClass(((ConstantClass)theConstant).getBytes(cp));
-        } else {
-            throw new RuntimeException("Unexpected constant type: " + theConstant.getClass());
+    public CPMethodOrField getCPField(CPClass cpClass, String name, String desc) {
+        String key = cpClass.toString() + ":" + name + ":" + desc;
+        CPMethodOrField cpF = (CPMethodOrField) stringsToCpMethodOrField
+                .get(key);
+        if (cpF == null) {
+            CPNameAndType nAndT = getCPNameAndType(name, desc);
+            cpF = new CPMethodOrField(cpClass, nAndT);
+            cp_Field.add(cpF);
+        }
+        return cpF;
+    }
+
+    public CPConstant getConstant(Object value) {
+        CPConstant constant = (CPConstant) objectsToCPConstant.get(value);
+        if (constant == null) {
+            if (value instanceof Integer) {
+                constant = new CPInt(((Integer) value).intValue());
+                cp_Int.add(constant);
+            } else if (value instanceof Long) {
+                constant = new CPLong(((Long) value).longValue());
+                cp_Long.add(constant);
+            } else if (value instanceof Float) {
+                constant = new CPFloat(((Float) value).floatValue());
+                cp_Float.add(constant);
+            } else if (value instanceof Double) {
+                constant = new CPDouble(((Double) value).doubleValue());
+                cp_Double.add(constant);
+            } else if (value instanceof String) {
+                constant = new CPString(getCPUtf8((String) value));
+                cp_String.add(constant);
+            }
+            objectsToCPConstant.put(value, constant);
+        }
+        return constant;
+    }
+
+    public CPMethodOrField getCPMethod(CPClass cpClass, String name, String desc) {
+        String key = cpClass.toString() + ":" + name + ":" + desc;
+        CPMethodOrField cpM = (CPMethodOrField) stringsToCpMethodOrField
+                .get(key);
+        if (cpM == null) {
+            CPNameAndType nAndT = getCPNameAndType(name, desc);
+            cpM = new CPMethodOrField(cpClass, nAndT);
+            cp_Method.add(cpM);
+        }
+        return cpM;
+    }
+
+    public CPMethodOrField getCPIMethod(CPClass cpClass, String name,
+            String desc) {
+        String key = cpClass.toString() + ":" + name + ":" + desc;
+        CPMethodOrField cpIM = (CPMethodOrField) stringsToCpMethodOrField
+                .get(key);
+        if (cpIM == null) {
+            CPNameAndType nAndT = getCPNameAndType(name, desc);
+            cpIM = new CPMethodOrField(cpClass, nAndT);
+            cp_Imethod.add(cpIM);
+        }
+        return cpIM;
+    }
+
+    public CPMethodOrField getCPField(String owner, String name, String desc) {
+        return getCPField(getCPClass(owner), name, desc);
+    }
+
+    public CPMethodOrField getCPMethod(String owner, String name, String desc) {
+        return getCPMethod(getCPClass(owner), name, desc);
+    }
+
+    public CPMethodOrField getCPIMethod(String owner, String name, String desc) {
+        return getCPIMethod(getCPClass(owner), name, desc);
+    }
+
+    public CPMethodOrField addCPMethod(CPClass cpClass, String name, String desc) {
+        String key = cpClass.toString() + ":" + name + ":" + desc;
+        CPMethodOrField cpM = (CPMethodOrField) stringsToCpMethodOrField
+                .get(key);
+        if (cpM == null) {
+            CPNameAndType nAndT = getCPNameAndType(name, desc);
+            cpM = new CPMethodOrField(cpClass, nAndT);
+            stringsToCpMethodOrField.put(key, cpM);
+            cp_Method.add(cpM);
+        }
+        return cpM;
+    }
+
+    public CPMethodOrField addCPField(CPClass cpClass, String name, String desc) {
+        String key = cpClass.toString() + ":" + name + ":" + desc;
+        CPMethodOrField cpF = (CPMethodOrField) stringsToCpMethodOrField
+                .get(key);
+        if (cpF == null) {
+            CPNameAndType nAndT = getCPNameAndType(name, desc);
+            cpF = new CPMethodOrField(cpClass, nAndT);
+            stringsToCpMethodOrField.put(key, cpF);
+            cp_Field.add(cpF);
         }
-        return cpC;
-    }
-
-    public CPMethodOrField getCPMethodOrField(Constant constant) {
-        // TODO Auto-generated method stub
-        return null;
+        return cpF;
     }
 
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java Wed Oct  8 06:05:43 2008
@@ -16,26 +16,64 @@
  */
 package org.apache.harmony.pack200;
 
+import java.io.IOException;
 import java.io.OutputStream;
 import java.util.List;
 
-
 public class FileBands extends BandSet {
 
     private final List files;
     private final SegmentHeader segmentHeader;
+    private final CPUTF8[] fileName;
+    private int[] file_name;
+    private final long[] file_modtime;
+    private final long[] file_size;
+    private final int[] file_options;
+    private final int[] file_bits;
 
-    public FileBands(SegmentHeader segmentHeader, List files) {
+    public FileBands(CpBands cpBands, SegmentHeader segmentHeader,
+            List classNames, List classModTimes, List files) {
         this.segmentHeader = segmentHeader;
         this.files = files;
-        int size = files.size();
-        if(size > 0) {
+        int numClasses = classNames.size();
+        int size = /* files.size() + */numClasses;
+        fileName = new CPUTF8[size];
+        file_modtime = new long[size];
+        file_size = new long[size];
+        file_options = new int[size];
+        CPUTF8 emptyString = cpBands.getCPUtf8("");
+        for (int i = 0; i < numClasses; i++) {
+            fileName[i] = emptyString;
+            file_options[i] |= (1 << 1);
+        }
+        file_bits = new int[0];
+        // for (int i = 0; i < files.size(); i++) {
+        // fileNames[i + numClasses] = ?
+        // }
+        // for (int i = 0; i < array.length; i++) {
+        //
+        // }
+    }
 
+    public void finaliseBands() {
+        file_name = new int[fileName.length];
+        for (int i = 0; i < file_name.length; i++) {
+            file_name[i] = fileName[i].getIndex();
         }
     }
 
-    public void pack(OutputStream out) {
-        // TODO Auto-generated method stub
+    public void pack(OutputStream out) throws IOException, Pack200Exception {
+        out.write(encodeBandInt("file_name", file_name, Codec.UNSIGNED5));
+        out.write(encodeFlags("file_size", file_size, Codec.UNSIGNED5,
+                Codec.UNSIGNED5, segmentHeader.have_file_size_hi()));
+        if (segmentHeader.have_file_modtime()) {
+            out.write(encodeBandInt("file_modtime", file_name, Codec.DELTA5));
+        }
+        if (segmentHeader.have_file_options()) {
+            out.write(encodeBandInt("file_options", file_options,
+                    Codec.UNSIGNED5));
+        }
+        out.write(encodeBandInt("file_bits", file_bits, Codec.BYTE1));
 
     }
 

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java Wed Oct  8 06:05:43 2008
@@ -20,9 +20,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.bcel.classfile.InnerClasses;
-
-
 public class IcBands extends BandSet {
 
     private final List innerClasses = new ArrayList();
@@ -41,8 +38,10 @@
 
     }
 
-    public void addInnerClasses(InnerClasses obj) {
-        innerClasses.add(obj);
+    public void addInnerClass(String name, String outerName, String innerName,
+            int flags) {
+        // TODO Auto-generated method stub
+
     }
 
 }

Added: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Pack200ClassReader.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Pack200ClassReader.java?rev=702856&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Pack200ClassReader.java (added)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Pack200ClassReader.java Wed Oct  8 06:05:43 2008
@@ -0,0 +1,73 @@
+/*
+ *  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;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.objectweb.asm.ClassReader;
+
+/**
+ * Wrapper for ClassReader than enables pack200 to obtain extra class file
+ * information
+ */
+public class Pack200ClassReader extends ClassReader {
+
+    private boolean lastConstantHadWideIndex;
+
+    /**
+     * @param b
+     */
+    public Pack200ClassReader(byte[] b) {
+        super(b);
+    }
+
+    /**
+     * @param is
+     * @throws IOException
+     */
+    public Pack200ClassReader(InputStream is) throws IOException {
+        super(is);
+    }
+
+    /**
+     * @param name
+     * @throws IOException
+     */
+    public Pack200ClassReader(String name) throws IOException {
+        super(name);
+    }
+
+    public Object readConst(int item, char[] buf) {
+        lastConstantHadWideIndex = item > Byte.MAX_VALUE;
+        return super.readConst(item, buf);
+    }
+
+    /**
+     * @param b
+     * @param off
+     * @param len
+     */
+    public Pack200ClassReader(byte[] b, int off, int len) {
+        super(b, off, len);
+    }
+
+    public boolean lastConstantHadWideIndex() {
+        return lastConstantHadWideIndex;
+    }
+
+}

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

Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Pack200ClassReader.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

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=702856&r1=702855&r2=702856&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 Wed Oct  8 06:05:43 2008
@@ -21,44 +21,14 @@
 import java.util.Iterator;
 import java.util.List;
 
-import org.apache.bcel.classfile.Attribute;
-import org.apache.bcel.classfile.Code;
-import org.apache.bcel.classfile.CodeException;
-import org.apache.bcel.classfile.ConstantClass;
-import org.apache.bcel.classfile.ConstantDouble;
-import org.apache.bcel.classfile.ConstantFieldref;
-import org.apache.bcel.classfile.ConstantFloat;
-import org.apache.bcel.classfile.ConstantInteger;
-import org.apache.bcel.classfile.ConstantInterfaceMethodref;
-import org.apache.bcel.classfile.ConstantLong;
-import org.apache.bcel.classfile.ConstantMethodref;
-import org.apache.bcel.classfile.ConstantNameAndType;
-import org.apache.bcel.classfile.ConstantPool;
-import org.apache.bcel.classfile.ConstantString;
-import org.apache.bcel.classfile.ConstantUtf8;
-import org.apache.bcel.classfile.ConstantValue;
-import org.apache.bcel.classfile.Deprecated;
-import org.apache.bcel.classfile.DescendingVisitor;
-import org.apache.bcel.classfile.ExceptionTable;
-import org.apache.bcel.classfile.Field;
-import org.apache.bcel.classfile.InnerClass;
-import org.apache.bcel.classfile.InnerClasses;
-import org.apache.bcel.classfile.JavaClass;
-import org.apache.bcel.classfile.LineNumber;
-import org.apache.bcel.classfile.LineNumberTable;
-import org.apache.bcel.classfile.LocalVariable;
-import org.apache.bcel.classfile.LocalVariableTable;
-import org.apache.bcel.classfile.Method;
-import org.apache.bcel.classfile.Signature;
-import org.apache.bcel.classfile.SourceFile;
-import org.apache.bcel.classfile.StackMap;
-import org.apache.bcel.classfile.StackMapEntry;
-import org.apache.bcel.classfile.Synthetic;
-import org.apache.bcel.classfile.Unknown;
-import org.apache.bcel.classfile.Visitor;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
 
-
-public class Segment implements Visitor {
+public class Segment implements ClassVisitor {
 
     private SegmentHeader segmentHeader;
     private CpBands cpBands;
@@ -72,15 +42,25 @@
     private String currentClass;
     private String superClass;
 
+    private final SegmentFieldVisitor fieldVisitor = new SegmentFieldVisitor();
+    private final SegmentMethodVisitor methodVisitor = new SegmentMethodVisitor();
+    private final SegmentAnnotationVisitor annotationVisitor = new SegmentAnnotationVisitor();
+    private Pack200ClassReader currentClassReader;
 
-    public void pack(List classes, List files, OutputStream out) throws IOException, Pack200Exception {
+    public void pack(List classes, List classNames, List classModTimes,
+            List files, OutputStream out) throws IOException, Pack200Exception {
         segmentHeader = new SegmentHeader();
+        segmentHeader.setFile_count(classes.size() + files.size()); // TODO:
+                                                                    // files
         cpBands = new CpBands(segmentHeader);
-        attributeDefinitionBands = new AttributeDefinitionBands(segmentHeader, cpBands);
+        attributeDefinitionBands = new AttributeDefinitionBands(segmentHeader,
+                cpBands);
         icBands = new IcBands(segmentHeader);
-        classBands = new ClassBands(segmentHeader, cpBands, attributeDefinitionBands, classes.size());
-        bcBands = new BcBands(cpBands);
-        fileBands = new FileBands(segmentHeader, files);
+        classBands = new ClassBands(segmentHeader, cpBands,
+                attributeDefinitionBands, classes.size());
+        bcBands = new BcBands(cpBands, this);
+        fileBands = new FileBands(cpBands, segmentHeader, classNames,
+                classModTimes, files);
 
         processClasses(classes);
 
@@ -89,6 +69,7 @@
         icBands.finaliseBands();
         classBands.finaliseBands();
         bcBands.finaliseBands();
+        fileBands.finaliseBands();
 
         segmentHeader.pack(out);
         cpBands.pack(out);
@@ -102,172 +83,224 @@
     private void processClasses(List classes) {
         segmentHeader.setClass_count(classes.size());
         for (Iterator iterator = classes.iterator(); iterator.hasNext();) {
-            JavaClass javaClass = (JavaClass) iterator.next();
-            new DescendingVisitor(javaClass, this).visit();
-        }
-    }
-
-    public void visitCode(Code obj) {
-        bcBands.addCode(obj, currentClass, superClass);
-        Attribute[] attributes = obj.getAttributes();
-        for (int i = 0; i < attributes.length; i++) {
-            if(attributes[i] instanceof Unknown) {
-                attributeDefinitionBands.addUnknownAttribute((Unknown)attributes[i], obj);
-            }
+            Pack200ClassReader classReader = (Pack200ClassReader) iterator
+                    .next();
+            currentClassReader = classReader;
+            classReader.accept(this, 0);
         }
     }
 
-    public void visitCodeException(CodeException obj) {
-        // TODO Auto-generated method stub
-
+    public void visit(int version, int access, String name, String signature,
+            String superName, String[] interfaces) {
+        System.out.println("visit " + name + " " + version + " " + access);
+        currentClass = name;
+        superClass = superName;
+        bcBands.setCurrentClass(name);
+        bcBands.setSuperClass(superName);
+        segmentHeader.addMajorVersion(version);
+        classBands.addClass(version, access, name, superName, interfaces);
     }
 
-    public void visitConstantClass(ConstantClass obj) {
-        cpBands.addConstantClass(obj);
+    public void visitSource(String source, String debug) {
+        classBands.addSourceFile(source);
     }
 
-    public void visitConstantDouble(ConstantDouble obj) {
-        cpBands.addConstantDouble(obj);
+    public void visitOuterClass(String owner, String name, String desc) {
+        classBands.addEnclosingMethod(owner, name, desc);
 
     }
 
-    public void visitConstantFieldref(ConstantFieldref obj) {
-        cpBands.addConstantFieldref(obj);
+    public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) {
+        return annotationVisitor;
     }
 
-    public void visitConstantFloat(ConstantFloat obj) {
-        cpBands.addConstantFloat(obj);
+    public void visitAttribute(Attribute arg0) {
+        System.out.println("visitAttribute");
     }
 
-    public void visitConstantInteger(ConstantInteger obj) {
-        cpBands.addConstantInteger(obj);
+    public void visitInnerClass(String name, String outerName,
+            String innerName, int flags) {
+        icBands.addInnerClass(name, outerName, innerName, flags);
     }
 
-    public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj) {
-        cpBands.addConstantInterfaceMethodref(obj);
+    public FieldVisitor visitField(int flags, String name, String desc,
+            String signature, Object value) {
+        classBands.addField(flags, name, desc, signature, value);
+        return fieldVisitor;
     }
 
-    public void visitConstantLong(ConstantLong obj) {
-        cpBands.addConstantLong(obj);
+    public MethodVisitor visitMethod(int flags, String name, String desc,
+            String signature, String[] exceptions) {
+        classBands.addMethod(flags, name, desc, signature, exceptions);
+        return methodVisitor;
     }
 
-    public void visitConstantMethodref(ConstantMethodref obj) {
-        cpBands.addConstantMethodref(obj);
+    public void visitEnd() {
+        classBands.endOfClass();
     }
 
-    public void visitConstantNameAndType(ConstantNameAndType obj) {
-        cpBands.addConstantNameAndType(obj);
-    }
+    /*
+     * This class delegates to BcBands for bytecode related visits and to
+     * ClassBands for everything else
+     */
+    public class SegmentMethodVisitor implements MethodVisitor {
 
-    public void visitConstantPool(ConstantPool obj) {
-    }
+        public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) {
+            return annotationVisitor;
+        }
 
-    public void visitConstantString(ConstantString obj) {
-        cpBands.addConstantString(obj);
-    }
+        public AnnotationVisitor visitAnnotationDefault() {
+            return annotationVisitor;
+        }
 
-    public void visitConstantUtf8(ConstantUtf8 obj) {
-        cpBands.addConstantUtf8(obj);
-    }
+        public void visitAttribute(Attribute arg0) {
+            classBands.addUnknownMethodAttribute(arg0);
+        }
 
-    public void visitConstantValue(ConstantValue obj) {
+        public void visitCode() {
+            classBands.addCode();
+        }
 
-    }
+        public void visitFrame(int arg0, int arg1, Object[] arg2, int arg3,
+                Object[] arg4) {
+            // TODO Auto-generated method stub
 
-    public void visitDeprecated(Deprecated obj) {
-        // TODO Auto-generated method stub
-    }
+        }
 
-    public void visitExceptionTable(ExceptionTable obj) {
-        // TODO Auto-generated method stub
-    }
+        public void visitLabel(Label label) {
+            bcBands.visitLabel(label);
+        }
 
-    public void visitField(Field obj) {
-        cpBands.addCPNameAndType(obj.getName(), obj.getSignature());
-        Attribute[] attributes = obj.getAttributes();
-        for (int i = 0; i < attributes.length; i++) {
-            if(attributes[i] instanceof Unknown) {
-                attributeDefinitionBands.addUnknownAttribute((Unknown)attributes[i], obj);
-            }
+        public void visitLineNumber(int line, Label start) {
+            classBands.addLineNumber(line, start);
         }
-    }
 
-    public void visitInnerClass(InnerClass obj) {
+        public void visitLocalVariable(String name, String desc,
+                String signature, Label start, Label end, int index) {
+            classBands.addLocalVariable(name, desc, signature, start, end,
+                    index);
+        }
 
-    }
+        public void visitMaxs(int maxStack, int maxLocals) {
+            classBands.addMaxStack(maxStack, maxLocals);
+        }
 
-    public void visitInnerClasses(InnerClasses obj) {
-        icBands.addInnerClasses(obj);
-    }
+        public AnnotationVisitor visitParameterAnnotation(int arg0,
+                String arg1, boolean arg2) {
+            return annotationVisitor;
+        }
 
-    public void visitJavaClass(JavaClass obj) {
-        cpBands.setCurrentClass(obj);
-        currentClass = obj.getClassName();
-        superClass = obj.getSuperclassName();
-        classBands.addClass(obj);
-        segmentHeader.addMinorVersion(obj.getMinor());
-        segmentHeader.addMajorVersion(obj.getMajor());
-        Attribute[] attributes = obj.getAttributes();
-        for (int i = 0; i < attributes.length; i++) {
-            if(attributes[i] instanceof Unknown) {
-                attributeDefinitionBands.addUnknownAttribute((Unknown)attributes[i], obj);
-            }
+        public void visitTryCatchBlock(Label start, Label end, Label handler,
+                String type) {
+            classBands.addHandler(start, end, handler, type);
         }
-    }
 
-    public void visitLineNumber(LineNumber obj) {
-        // TODO Auto-generated method stub
+        public void visitEnd() {
+            bcBands.visitEnd();
+        }
 
-    }
+        public void visitFieldInsn(int opcode, String owner, String name,
+                String desc) {
+            bcBands.visitFieldInsn(opcode, owner, name, desc);
+        }
 
-    public void visitLineNumberTable(LineNumberTable obj) {
-        // TODO Auto-generated method stub
+        public void visitIincInsn(int var, int increment) {
+            bcBands.visitIincInsn(var, increment);
+        }
 
-    }
+        public void visitInsn(int opcode) {
+            bcBands.visitInsn(opcode);
+        }
 
-    public void visitLocalVariable(LocalVariable obj) {
-        cpBands.addCPSignature(obj.getSignature());
-    }
+        public void visitIntInsn(int opcode, int operand) {
+            bcBands.visitIntInsn(opcode, operand);
+        }
 
-    public void visitLocalVariableTable(LocalVariableTable obj) {
-        // TODO Auto-generated method stub
+        public void visitJumpInsn(int opcode, Label label) {
+            bcBands.visitJumpInsn(opcode, label);
+        }
 
-    }
+        public void visitLdcInsn(Object cst) {
+            bcBands.visitLdcInsn(cst);
+        }
 
-    public void visitMethod(Method obj) {
-        cpBands.addCPNameAndType(obj.getName(), obj.getSignature());
-        Attribute[] attributes = obj.getAttributes();
-        for (int i = 0; i < attributes.length; i++) {
-            if(attributes[i] instanceof Unknown) {
-                attributeDefinitionBands.addUnknownAttribute((Unknown)attributes[i], obj);
-            }
+        public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+            bcBands.visitLookupSwitchInsn(dflt, keys, labels);
+        }
+
+        public void visitMethodInsn(int opcode, String owner, String name,
+                String desc) {
+            bcBands.visitMethodInsn(opcode, owner, name, desc);
+        }
+
+        public void visitMultiANewArrayInsn(String desc, int dimensions) {
+            bcBands.visitMultiANewArrayInsn(desc, dimensions);
+        }
+
+        public void visitTableSwitchInsn(int min, int max, Label dflt,
+                Label[] labels) {
+            bcBands.visitTableSwitchInsn(min, max, dflt, labels);
+        }
+
+        public void visitTypeInsn(int opcode, String type) {
+            bcBands.visitTypeInsn(opcode, type);
         }
-    }
 
-    public void visitSignature(Signature obj) {
+        public void visitVarInsn(int opcode, int var) {
+            bcBands.visitVarInsn(opcode, var);
+        }
 
     }
 
-    public void visitSourceFile(SourceFile obj) {
-        // TODO Auto-generated method stub
+    public ClassBands getClassBands() {
+        return classBands;
     }
 
-    public void visitStackMap(StackMap obj) {
-        // TODO Auto-generated method stub
+    public class SegmentAnnotationVisitor implements AnnotationVisitor {
 
-    }
+        public void visit(String arg0, Object arg1) {
+            // TODO Auto-generated method stub
+
+        }
 
-    public void visitStackMapEntry(StackMapEntry obj) {
-        // TODO Auto-generated method stub
+        public AnnotationVisitor visitAnnotation(String arg0, String arg1) {
+            // TODO Auto-generated method stub
+            return null;
+        }
 
-    }
+        public AnnotationVisitor visitArray(String arg0) {
+            // TODO Auto-generated method stub
+            return null;
+        }
 
-    public void visitSynthetic(Synthetic obj) {
-        // TODO Auto-generated method stub
+        public void visitEnd() {
+            // TODO Auto-generated method stub
 
+        }
+
+        public void visitEnum(String arg0, String arg1, String arg2) {
+            // TODO Auto-generated method stub
+
+        }
     }
 
-    public void visitUnknown(Unknown obj) {
+    public class SegmentFieldVisitor implements FieldVisitor {
+
+        public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) {
+            return annotationVisitor;
+        }
+
+        public void visitAttribute(Attribute arg0) {
+            classBands.addUnknownFieldAttribute(arg0);
+        }
+
+        public void visitEnd() {
+            // TODO Auto-generated method stub
+
+        }
     }
 
+    public boolean lastConstantHadWideIndex() {
+        return currentClassReader.lastConstantHadWideIndex();
+    }
 }