Index: src/main/java/org/apache/harmony/pack200/NewAttributeBands.java =================================================================== --- src/main/java/org/apache/harmony/pack200/NewAttributeBands.java (revision 608803) +++ src/main/java/org/apache/harmony/pack200/NewAttributeBands.java (working copy) @@ -391,11 +391,11 @@ } else if (tag.startsWith("PO")) { char uint_type = tag.substring(2).toCharArray()[0]; int length = getLength(uint_type); - attribute.addBCOffset(length, value); + attribute.addBCOffset(length, (int) value); } else if (tag.startsWith("P")) { char uint_type = tag.substring(1).toCharArray()[0]; int length = getLength(uint_type); - attribute.addBCIndex(length, value); + attribute.addBCIndex(length, (int) value); } else if (tag.startsWith("OS")) { char uint_type = tag.substring(1).toCharArray()[0]; int length = getLength(uint_type); @@ -406,11 +406,11 @@ } else if(length == 4) { value = (int)value; } - attribute.addBCLength(length, value); + attribute.addBCLength(length, (int) value); } else if (tag.startsWith("O")) { char uint_type = tag.substring(1).toCharArray()[0]; int length = getLength(uint_type); - attribute.addBCLength(length, value); + attribute.addBCLength(length, (int) value); } } Index: src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java =================================================================== --- src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java (revision 608794) +++ src/main/java/org/apache/harmony/pack200/bytecode/Attribute.java (working copy) @@ -20,7 +20,7 @@ import java.io.IOException; public abstract class Attribute extends ClassFileEntry { - private final CPUTF8 attributeName; + protected final CPUTF8 attributeName; private int attributeNameIndex; Index: src/main/java/org/apache/harmony/pack200/bytecode/LineNumberTableAttribute.java =================================================================== --- src/main/java/org/apache/harmony/pack200/bytecode/LineNumberTableAttribute.java (revision 608794) +++ src/main/java/org/apache/harmony/pack200/bytecode/LineNumberTableAttribute.java (working copy) @@ -18,7 +18,6 @@ import java.io.DataOutputStream; import java.io.IOException; -import java.util.List; public class LineNumberTableAttribute extends BCIRenumberedAttribute { Index: src/main/java/org/apache/harmony/pack200/bytecode/NewAttribute.java =================================================================== --- src/main/java/org/apache/harmony/pack200/bytecode/NewAttribute.java (revision 608803) +++ src/main/java/org/apache/harmony/pack200/bytecode/NewAttribute.java (working copy) @@ -18,6 +18,9 @@ import java.io.DataOutputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; /** * A New (i.e. non-predefined) Class File attribute @@ -22,11 +25,14 @@ /** * A New (i.e. non-predefined) Class File attribute */ -public class NewAttribute extends Attribute { +public class NewAttribute extends BCIRenumberedAttribute { + + private List lengths = new ArrayList(); // List of Integers + private List body = new ArrayList(); + private ClassConstantPool pool; public NewAttribute(String attributeName) { super(attributeName); - // TODO Auto-generated constructor stub } /* (non-Javadoc) @@ -33,8 +39,11 @@ * @see org.apache.harmony.pack200.bytecode.Attribute#getLength() */ protected int getLength() { - // TODO Auto-generated method stub - return 0; + int length = 0; + for (Iterator iter = lengths.iterator(); iter.hasNext();) { + length += ((Integer) iter.next()).intValue(); + } + return length; } /* (non-Javadoc) @@ -41,8 +50,28 @@ * @see org.apache.harmony.pack200.bytecode.Attribute#writeBody(java.io.DataOutputStream) */ protected void writeBody(DataOutputStream dos) throws IOException { - // TODO Auto-generated method stub - + for (int i = 0; i < lengths.size(); i++) { + int length = ((Integer) lengths.get(i)).intValue(); + Object obj = body.get(i); + long value = 0; + if(obj instanceof Long) { + value = ((Long)obj).longValue(); + } else if (obj instanceof ClassFileEntry) { + value = pool.indexOf(((ClassFileEntry)obj)); + } else if (obj instanceof BCValue) { + value = ((BCValue)obj).actualValue; + } + // Write + if(length == 1) { + dos.writeByte((int)value); + } else if (length == 2) { + dos.writeShort((int)value); + } else if (length == 4) { + dos.writeInt((int)value); + } else if (length == 8) { + dos.writeLong(value); + } + } } /* (non-Javadoc) @@ -49,65 +78,158 @@ * @see org.apache.harmony.pack200.bytecode.ClassFileEntry#toString() */ public String toString() { - // TODO Auto-generated method stub - return null; + return attributeName.underlyingString(); } public void addInteger(int length, long value) { - + lengths.add(new Integer(length)); + body.add(new Long(value)); } - public void addBCOffset(int length, long value) { - // TODO Auto-generated method stub - + public void addBCOffset(int length, int value) { + lengths.add(new Integer(length)); + body.add(new BCOffset(value)); } - public void addBCIndex(int length, long value) { - // TODO Auto-generated method stub - + public void addBCIndex(int length, int value) { + lengths.add(new Integer(length)); + body.add(new BCIndex(value)); } - public void addBCLength(int length, long value) { - // TODO Auto-generated method stub - + public void addBCLength(int length, int value) { + lengths.add(new Integer(length)); + body.add(new BCLength(value)); } public void addCPConstant(int length, CPConstant constant) { - // TODO Auto-generated method stub - + lengths.add(new Integer(length)); + body.add(constant); } public void addCPClass(int length, CPClass class1) { - // TODO Auto-generated method stub - + lengths.add(new Integer(length)); + body.add(class1); } public void addCPUTF8(int length, CPUTF8 cputf8) { - // TODO Auto-generated method stub - + lengths.add(new Integer(length)); + body.add(cputf8); } public void addCPNameAndType(int length, CPNameAndType type) { - // TODO Auto-generated method stub - + lengths.add(new Integer(length)); + body.add(type); } public void addCPFieldRef(int length, CPFieldRef ref) { - // TODO Auto-generated method stub - + lengths.add(new Integer(length)); + body.add(ref); } public void addCPMethodRef(int length, CPMethodRef ref) { - // TODO Auto-generated method stub - + lengths.add(new Integer(length)); + body.add(ref); } public void addCPIMethodRef(int length, CPInterfaceMethodRef ref) { - // TODO Auto-generated method stub + lengths.add(new Integer(length)); + body.add(ref); + } + + protected void resolve(ClassConstantPool pool) { + super.resolve(pool); + for (Iterator iter = body.iterator(); iter.hasNext();) { + Object element = (Object) iter.next(); + if(element instanceof ClassFileEntry) { + ((ClassFileEntry)element).resolve(pool); + } + } + this.pool = pool; + } + + private static class BCOffset extends BCValue { + private int offset; + private int index; + + public BCOffset(int offset) { + this.offset = offset; + } + + public void setIndex(int index) { + this.index = index; + } + } + private static class BCIndex extends BCValue { + + private int index; + + public BCIndex(int index) { + this.index = index; + } + } + + private static class BCLength extends BCValue { + + private int length; + + public BCLength(int length) { + this.length = length; + } + } + // Bytecode-related value (either a bytecode index or a length) + private static abstract class BCValue { + + int actualValue; + + public void setActualValue(int value) { + this.actualValue = value; + } + + } + + protected int[] getStartPCs() { + // Don't need to return anything here as we've overridden renumber + return null; + } + public void renumber(List byteCodeOffsets) { + if(!renumbered) { + Object previous = null; + for (Iterator iter = body.iterator(); iter.hasNext();) { + Object obj = (Object) iter.next(); + if(obj instanceof BCIndex) { + BCIndex bcIndex = (BCIndex) obj; + bcIndex.setActualValue(((Integer)byteCodeOffsets.get(bcIndex.index)).intValue()); + } else if (obj instanceof BCOffset) { + BCOffset bcOffset = (BCOffset)obj; + if(previous instanceof BCIndex) { + int index = ((BCIndex)previous).index + bcOffset.offset; + bcOffset.setIndex(index); + bcOffset.setActualValue(((Integer)byteCodeOffsets.get(index)).intValue()); + } else if(previous instanceof BCOffset) { + int index = ((BCOffset)previous).index + bcOffset.offset; + bcOffset.setIndex(index); + bcOffset.setActualValue(((Integer)byteCodeOffsets.get(index)).intValue()); + } else { + // Not sure if this should be able to happen + bcOffset.setActualValue(((Integer)byteCodeOffsets.get(bcOffset.offset)).intValue()); + } + } else if (obj instanceof BCLength) { + // previous must be a BCIndex + BCLength bcLength = (BCLength) obj; + BCIndex prevIndex = (BCIndex) previous; + int index = prevIndex.index + bcLength.length; + int actualLength = ((Integer)byteCodeOffsets.get(index)).intValue() - prevIndex.actualValue; + bcLength.setActualValue(actualLength); + } + previous = obj; + } + renumbered = true; + } + } }