You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by qi...@apache.org on 2008/11/27 06:10:42 UTC

svn commit: r721077 [10/12] - in /harmony/enhanced/classlib/branches/java6: ./ depends/files/ depends/jars/ depends/manifests/asm-3.1/ depends/manifests/asm-3.1/META-INF/ depends/manifests/bcel-5.2/ make/ modules/accessibility/ modules/accessibility/sr...

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java?rev=721077&r1=721076&r2=721077&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java Wed Nov 26 21:10:32 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,372 @@
         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("class_enclosing_method_RC",
+                 cpEntryListToArray(classEnclosingMethodClass),
+                 Codec.UNSIGNED5));
+        out.write(encodeBandInt("class_EnclosingMethod_RDN",
+                cpEntryOrNullListToArray(classEnclosingMethodDesc),
+                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) {
+        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);
+        renumberOffsetBci(codeLocalVariableTableBciP,
+                codeLocalVariableTableSpanO, bciRenumbering, labelsToOffsets);
+        renumberBci(codeLocalVariableTypeTableBciP, bciRenumbering,
+                labelsToOffsets);
+        renumberOffsetBci(codeLocalVariableTypeTableBciP,
+                codeLocalVariableTypeTableSpanO, bciRenumbering,
+                labelsToOffsets);
+        renumberBci(codeHandlerStartP, bciRenumbering, labelsToOffsets);
+        renumberOffsetBci(codeHandlerStartP, codeHandlerEndPO,
+                bciRenumbering, labelsToOffsets);
+        renumberDoubleOffsetBci(codeHandlerStartP, codeHandlerEndPO, codeHandlerCatchPO,
+                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 bytecodeIndex = (Integer) labelsToOffsets.get(label);
+                list.add(i, bciRenumbering.get(bytecodeIndex.intValue()));
+            }
+        }
+    }
+
+    private void renumberOffsetBci(List relative, 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 bytecodeIndex = (Integer) labelsToOffsets.get(label);
+                Integer renumberedOffset = new Integer(((Integer) bciRenumbering
+                        .get(bytecodeIndex.intValue())).intValue()
+                        - ((Integer) relative.get(i)).intValue());
+                list.add(i, renumberedOffset);
+            }
+        }
+    }
+
+    private void renumberDoubleOffsetBci(List relative, List firstOffset, List list,
+            List bciRenumbering, Map labelsToOffsets) {
+        // TODO: There's probably a nicer way of doing this...
+        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 bytecodeIndex = (Integer) labelsToOffsets.get(label);
+                Integer renumberedOffset = new Integer(((Integer) bciRenumbering
+                        .get(bytecodeIndex.intValue())).intValue()
+                        - ((Integer) relative.get(i)).intValue() - ((Integer) firstOffset.get(i)).intValue());
+                list.add(i, renumberedOffset);
+            }
+        }
+    }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java?rev=721077&r1=721076&r2=721077&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java Wed Nov 26 21:10:32 2008
@@ -19,6 +19,8 @@
 import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
 
 
 /**
@@ -91,6 +93,9 @@
             new BHSDCodec(4, 240, 1, 1), new BHSDCodec(4, 248, 0, 1),
             new BHSDCodec(4, 248, 1, 1) };
 
+    private static Map canonicalCodecsToSpecifiers;
+
+
     /**
      * Returns the codec specified by the given value byte and optional byte
      * header. If the value is >=116, then bytes may be consumed from the
@@ -208,4 +213,14 @@
                     + ") found");
         }
     }
+
+    public static int getSpecifierForDefaultCodec(BHSDCodec defaultCodec) {
+        if(canonicalCodecsToSpecifiers == null) {
+            canonicalCodecsToSpecifiers = new HashMap();
+            for (int i = 0; i < canonicalCodec.length; i++) {
+                canonicalCodecsToSpecifiers.put(canonicalCodec[i], new Integer(i));
+            }
+        }
+        return ((Integer)canonicalCodecsToSpecifiers.get(defaultCodec)).intValue();
+    }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java?rev=721077&r1=721076&r2=721077&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java Wed Nov 26 21:10:32 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,121 +333,42 @@
                 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) {
         CPUTF8 utf8 = (CPUTF8) stringsToCpUtf8.get(string);
         if (utf8 != null) {
-            stringsToCpUtf8.remove(string);
-            cp_Utf8.remove(utf8);
-        }
-    }
-
-    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);
+            if(stringsToCpClass.get(string) == null) { // don't remove if strings are also in cpclass
+                stringsToCpUtf8.remove(string);
+                cp_Utf8.remove(utf8);
             }
         }
     }
@@ -472,6 +378,9 @@
     }
 
     public CPUTF8 getCPUtf8(String utf8) {
+        if(utf8 == null) {
+            return null;
+        }
         CPUTF8 cpUtf8 = (CPUTF8) stringsToCpUtf8.get(utf8);
         if (cpUtf8 == null) {
             cpUtf8 = new CPUTF8(utf8);
@@ -494,7 +403,7 @@
         if (cpS == null) {
             List cpClasses = new ArrayList();
             CPUTF8 signatureUTF8;
-            if (signature.length() > 1 && signature.indexOf("L") != -1) {
+            if (signature.length() > 1 && signature.indexOf('L') != -1) {
                 List classes = new ArrayList();
                 char[] chars = signature.toCharArray();
                 StringBuffer signatureString = new StringBuffer();
@@ -505,7 +414,7 @@
                         for (int j = i + 1; j < chars.length; j++) {
                             char c = chars[j];
                             if (Character.isLetter(c) || Character.isDigit(c)
-                                    || c == '/') {
+                                    || c == '/' || c == '$' || c == '_') {
                                 className.append(c);
                             } else {
                                 classes.add(className.toString());
@@ -533,6 +442,9 @@
     }
 
     public CPClass getCPClass(String className) {
+        if(className == null) {
+            return null;
+        }
         className = className.replace('.', '/');
         CPClass cpClass = (CPClass) stringsToCpClass.get(className);
         if (cpClass == null) {
@@ -561,59 +473,106 @@
         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);
+            stringsToCpMethodOrField.put(key, 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);
+            stringsToCpMethodOrField.put(key, 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);
+            stringsToCpMethodOrField.put(key, 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/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java?rev=721077&r1=721076&r2=721077&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java Wed Nov 26 21:10:32 2008
@@ -16,27 +16,85 @@
  */
 package org.apache.harmony.pack200;
 
+import java.io.IOException;
 import java.io.OutputStream;
 import java.util.List;
 
+import org.apache.harmony.pack200.Archive.File;
 
 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 byte[][] file_bits;
 
-    public FileBands(SegmentHeader segmentHeader, List files) {
+    public FileBands(CpBands cpBands, SegmentHeader segmentHeader,
+            List files) {
         this.segmentHeader = segmentHeader;
-        this.files = files;
-        int size = files.size();
-        if(size > 0) {
+        int size =  files.size();
+        fileName = new CPUTF8[size];
+        file_modtime = new long[size];
+        file_size = new long[size];
+        file_options = new int[size];
+        CPUTF8 emptyString = cpBands.getCPUtf8("");
+        int totalSize = 0;
+        file_bits = new byte[files.size()][];
+         for (int i = 0; i < files.size(); i++) {
+             File file = (File)files.get(i);
+             String name = file.getName();
+             fileName[i] = cpBands.getCPUtf8(name); // TODO: sometimes this can be the empty string
+             if(name.endsWith(".class")) {
+//                 fileName[i] = emptyString;
+                 file_options[i] |= (1 << 1);
+//             } else {
+//                 fileName[i] = cpBands.getCPUtf8(name);
+             }
+             byte[] bytes = file.getContents();
+             file_size[i] = bytes.length;
+             totalSize += file_size[i];
+             file_modtime[i] = file.getModtime();
+             file_bits[i] = file.getContents();
+         }
+    }
 
+    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", flatten(file_bits), Codec.BYTE1));
+    }
 
+    private int[] flatten(byte[][] bytes) {
+        int total = 0;
+        for (int i = 0; i < bytes.length; i++) {
+            total += bytes[i].length;
+        }
+        int[] band = new int[total];
+        int index = 0;
+        for (int i = 0; i < bytes.length; i++) {
+            for (int j = 0; j < bytes[i].length; j++) {
+                band[index++] = bytes[i][j];
+            }
+        }
+        return band;
     }
 
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java?rev=721077&r1=721076&r2=721077&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java Wed Nov 26 21:10:32 2008
@@ -16,33 +16,91 @@
  */
 package org.apache.harmony.pack200;
 
+import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
-
-import org.apache.bcel.classfile.InnerClasses;
-
+import java.util.Set;
 
 public class IcBands extends BandSet {
 
-    private final List innerClasses = new ArrayList();
+    private final Set innerClasses = new HashSet();
     private final SegmentHeader segmentHeader;
+    private final CpBands cpBands;
+    private int bit16Count = 0;
 
-    public IcBands(SegmentHeader segmentHeader) {
+    public IcBands(SegmentHeader segmentHeader, CpBands cpBands) {
         this.segmentHeader = segmentHeader;
+        this.cpBands = cpBands;
     }
 
     public void finaliseBands() {
         segmentHeader.setIc_count(innerClasses.size());
     }
 
-    public void pack(OutputStream out) {
-        // TODO Auto-generated method stub
+    public void pack(OutputStream out) throws IOException, Pack200Exception {
+        int[] ic_this_class = new int[innerClasses.size()];
+        int[] ic_flags = new int[innerClasses.size()];
+        int[] ic_outer_class = new int[bit16Count];
+        int[] ic_name = new int[bit16Count];
+
+        int index2 = 0;
+        List innerClassesList = new ArrayList(innerClasses);
+        for (int i = 0; i < ic_this_class.length; i++) {
+            IcTuple icTuple = (IcTuple) innerClassesList.get(i);
+            ic_this_class[i] = icTuple.C.getIndex();
+            ic_flags[i] = icTuple.F;
+            if((icTuple.F & (1<<16)) != 0) {
+                ic_outer_class[index2] = icTuple.C2 == null ? 0 : icTuple.C2.getIndex() + 1;
+                ic_name[index2] = icTuple.N == null ? 0 : icTuple.N.getIndex() + 1;
+                index2++;
+            }
+        }
+        out.write(encodeBandInt("ic_this_class", ic_this_class, Codec.UDELTA5));
+        out.write(encodeBandInt("ic_flags", ic_flags, Codec.UNSIGNED5));
+        out.write(encodeBandInt("ic_outer_class", ic_outer_class, Codec.DELTA5));
+        out.write(encodeBandInt("ic_name", ic_name, Codec.DELTA5));
+    }
 
+    public void addInnerClass(String name, String outerName, String innerName,
+            int flags) {
+        if(outerName != null || innerName != null) {
+            flags |= (1<<16);
+            boolean added = innerClasses.add(new IcTuple(cpBands.getCPClass(name), flags, cpBands.getCPClass(outerName), cpBands.getCPUtf8(innerName)));
+            if(added) {
+                bit16Count++;
+            }
+        } else {
+            innerClasses.add(new IcTuple(cpBands.getCPClass(name), flags, cpBands.getCPClass(outerName), cpBands.getCPUtf8(innerName)));
+        }
     }
 
-    public void addInnerClasses(InnerClasses obj) {
-        innerClasses.add(obj);
+    private class IcTuple {
+
+        protected CPClass C; // this class
+        protected int F; // flags
+        protected CPClass C2; // outer class
+        protected CPUTF8 N; // name
+
+        public IcTuple(CPClass C, int F, CPClass C2, CPUTF8 N) {
+            this.C = C;
+            this.F = F;
+            this.C2 = C2;
+            this.N = N;
+        }
+
+        public boolean equals(Object o) {
+            if(o instanceof IcTuple) {
+                IcTuple icT = (IcTuple)o;
+                return C.equals(icT.C) && F == icT.F && C2 != null ? C2.equals(icT.C2) : icT.C2 == null && N != null ? N.equals(icT.N) : icT.N == null;
+            }
+            return false;
+        }
+
+        public int hashCode() {
+            return (C.hashCode() * 37) + F;
+        }
     }
 
 }