Changes to dump annotation format

git-svn-id: https://smali.googlecode.com/svn/trunk@398 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2009-08-21 02:50:07 +00:00
parent d9dd571427
commit 4d68e05fb5
38 changed files with 697 additions and 135 deletions

View File

@ -177,25 +177,49 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(4, "class_annotations_off");
out.annotate(4, "annotated_fields_size");
out.annotate(4, "annotated_methods_size");
out.annotate(4, "annotated_parameters_size");
if (!isInternable() && parent != null) {
out.annotate(0, parent.getClassType().getTypeDescriptor());
}
if (classAnnotations != null) {
out.annotate(4, "class_annotations_off: 0x" + Integer.toHexString(classAnnotations.getOffset()));
} else {
out.annotate(4, "class_annotations_off:");
}
out.annotate(4, "annotated_fields_size: 0x" + Integer.toHexString(fieldAnnotations.length) + " (" +
fieldAnnotations.length + ")");
out.annotate(4, "annotated_methods_size: 0x" + Integer.toHexString(methodAnnotations.length) + " (" +
methodAnnotations.length + ")");
out.annotate(4, "annotated_parameters_size: 0x" + Integer.toHexString(parameterAnnotations.length) + " (" +
parameterAnnotations.length + ")");
int index = 0;
for (int i=0; i<fieldAnnotations.length; i++) {
out.annotate(4, "field_idx");
out.annotate(4, "annotations_off");
out.annotate(0, "[" + index++ + "] field_annotation");
out.indent();
out.annotate(4, "field: " + fieldAnnotationFields[i].getFieldName().getStringValue() + ":" +
fieldAnnotationFields[i].getFieldType().getTypeDescriptor());
out.annotate(4, "annotations_off: 0x" + Integer.toHexString(fieldAnnotations[i].getOffset()));
out.deindent();
}
index = 0;
for (int i=0; i<methodAnnotations.length; i++) {
out.annotate(4, "method_idx");
out.annotate(4, "annotations_off");
out.annotate(0, "[" + index++ + "] method_annotation");
out.indent();
out.annotate(4, "method: " + methodAnnotationMethods[i].getMethodString());
out.annotate(4, "annotations_off: 0x" + Integer.toHexString(methodAnnotations[i].getOffset()));
out.deindent();
}
index = 0;
for (int i=0; i<parameterAnnotations.length; i++) {
out.annotate(4, "method_idx");
out.annotate(4, "annotations_off");
out.annotate(0, "[" + index++ + "] parameter_annotation");
out.indent();
out.annotate(4, "method: " + parameterAnnotationMethods[i].getMethodString());
out.annotate(4, "annotations_off: 0x" + Integer.toHexString(parameterAnnotations[i].getOffset()));
}
}

View File

@ -88,9 +88,8 @@ public class AnnotationItem extends Item<AnnotationItem> {
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate("visibility");
out.annotate("visibility: " + visibility.name());
out.writeByte(visibility.value);
out.annotate("annotation");
annotationValue.writeValue(out);
}else {
out.writeByte(visibility.value);

View File

@ -84,9 +84,10 @@ public class AnnotationSetItem extends Item<AnnotationSetItem> {
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(4, "size");
for (int i=0; i<annotations.length; i++) {
out.annotate(4, "annotation_off");
out.annotate(4, "size: 0x" + Integer.toHexString(annotations.length) + " (" + annotations.length + ")");
for (AnnotationItem annotationItem: annotations) {
out.annotate(4, "annotation_off: 0x" + Integer.toHexString(annotationItem.getOffset()) + " - " +
annotationItem.getEncodedAnnotation().annotationType.getTypeDescriptor());
}
}
out.writeInt(annotations.length);

View File

@ -85,9 +85,10 @@ public class AnnotationSetRefList extends Item<AnnotationSetRefList> {
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(4, "size");
out.annotate(4, "size: 0x" + Integer.toHexString(annotationSets.length) + " (" + annotationSets.length +
")");
for (AnnotationSetItem annotationSetItem: annotationSets) {
out.annotate(4, "annotation_set_off");
out.annotate(4, "annotation_set_off: 0x" + Integer.toHexString(annotationSetItem.getOffset()));
}
}
out.writeInt(annotationSets.length);

View File

@ -147,36 +147,56 @@ public class ClassDataItem extends Item<ClassDataItem> {
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate("static_fields_size");
out.annotate("static_fields_size: 0x" + Integer.toHexString(staticFields.length) + " (" +
staticFields.length + ")");
out.writeUnsignedLeb128(staticFields.length);
out.annotate("instance_fields_size");
out.annotate("instance_fields_size: 0x" + Integer.toHexString(instanceFields.length) + " (" +
instanceFields.length + ")");
out.writeUnsignedLeb128(instanceFields.length);
out.annotate("direct_methods_size");
out.annotate("direct_methods_size: 0x" + Integer.toHexString(directMethods.length) + " (" +
directMethods.length + ")");
out.writeUnsignedLeb128(directMethods.length);
out.annotate("virtual_methods_size");
out.annotate("virtual_methods_size: 0x" + Integer.toHexString(virtualMethods.length) + " (" +
virtualMethods.length + ")");
out.writeUnsignedLeb128(virtualMethods.length);
int index = 0;
EncodedField previousEncodedField = null;
for (EncodedField encodedField: staticFields) {
out.annotate("[" + index++ + "] static_field");
out.indent();
encodedField.writeTo(out, previousEncodedField);
out.deindent();
previousEncodedField = encodedField;
}
index = 0;
previousEncodedField = null;
for (EncodedField encodedField: instanceFields) {
out.annotate("[" + index++ + "] instance_field");
out.indent();
encodedField.writeTo(out, previousEncodedField);
out.deindent();
previousEncodedField = encodedField;
}
index = 0;
EncodedMethod previousEncodedMethod = null;
for (EncodedMethod encodedMethod: directMethods) {
out.annotate("[" + index++ + "] direct_method");
out.indent();
encodedMethod.writeTo(out, previousEncodedMethod);
out.deindent();
previousEncodedMethod = encodedMethod;
}
index = 0;
previousEncodedMethod = null;
for (EncodedMethod encodedMethod: virtualMethods) {
out.annotate("[" + index++ + "] virtual_method");
out.indent();
encodedMethod.writeTo(out, previousEncodedMethod);
out.deindent();
previousEncodedMethod = encodedMethod;
}
} else {
@ -315,9 +335,9 @@ public class ClassDataItem extends Item<ClassDataItem> {
int previousIndex = previousEncodedField==null?0:previousEncodedField.field.getIndex();
if (out.annotates()) {
out.annotate("field_idx_diff");
out.annotate("field: " + field.getFieldString());
out.writeUnsignedLeb128(field.getIndex() - previousIndex);
out.annotate("access_flags");
out.annotate("access_flags: " + AccessFlags.formatAccessFlagsForField(accessFlags));
out.writeUnsignedLeb128(accessFlags);
}else {
out.writeUnsignedLeb128(field.getIndex() - previousIndex);
@ -422,12 +442,17 @@ public class ClassDataItem extends Item<ClassDataItem> {
int previousIndex = previousEncodedMethod==null?0:previousEncodedMethod.method.getIndex();
if (out.annotates()) {
out.annotate("method_idx_diff");
out.annotate("method: " + method.getMethodString());
out.writeUnsignedLeb128(method.getIndex() - previousIndex);
out.annotate("access_flags");
out.annotate("access_flags: " + AccessFlags.formatAccessFlagsForMethod(accessFlags));
out.writeUnsignedLeb128(accessFlags);
out.annotate("code_off");
out.writeUnsignedLeb128(codeItem==null?0:codeItem.getOffset());
if (codeItem != null) {
out.annotate("code_off: 0x" + codeItem.getOffset());
out.writeUnsignedLeb128(codeItem.getOffset());
} else {
out.annotate("code_off: 0x0");
out.writeUnsignedLeb128(0);
}
}else {
out.writeUnsignedLeb128(method.getIndex() - previousIndex);
out.writeUnsignedLeb128(accessFlags);

View File

@ -30,6 +30,7 @@ package org.jf.dexlib;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.AccessFlags;
import java.util.*;
@ -139,14 +140,18 @@ public class ClassDefItem extends Item<ClassDefItem> {
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(4, "class_idx");
out.annotate(4, "access_flags");
out.annotate(4, "superclass_idx");
out.annotate(4, "interfaces_off");
out.annotate(4, "source_file_idx");
out.annotate(4, "annotations_off");
out.annotate(4, "class_data_off");
out.annotate(4, "static_values_off");
out.annotate(4, "class_type: " + classType.getTypeDescriptor());
out.annotate(4, "access_flags: " + AccessFlags.formatAccessFlagsForClass(accessFlags));
out.annotate(4, "superclass_type: " + (superType==null?"":superType.getTypeDescriptor()));
out.annotate(4, "interfaces: " +
(implementedInterfaces==null?"":implementedInterfaces.getTypeListString(" ")));
out.annotate(4, "source_file: " + (sourceFile==null?"":sourceFile.getStringValue()));
out.annotate(4, "annotations_off: " +
(annotations==null?"":"0x"+Integer.toHexString(annotations.getOffset())));
out.annotate(4, "class_data_off:" +
(classData==null?"":"0x"+Integer.toHexString(classData.getOffset())));
out.annotate(4, "static_values_off: " +
(staticFieldInitializers==null?"":"0x"+Integer.toHexString(staticFieldInitializers.getOffset())));
}
out.writeInt(classType.getIndex());
out.writeInt(accessFlags);

View File

@ -186,33 +186,46 @@ public class CodeItem extends Item<CodeItem> {
/** {@inheritDoc} */
protected void writeItem(final AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(2, "registers_size");
out.annotate(2, "ins_size");
out.annotate(2, "outs_size");
out.annotate(2, "tries_size");
out.annotate(4, "debug_info_off");
out.annotate(4, "insns_size");
out.annotate(0, parent.method.getMethodString());
out.annotate(2, "registers_size: 0x" + Integer.toHexString(registerCount) + " (" + registerCount + ")");
out.annotate(2, "ins_size: 0x" + Integer.toHexString(inWords) + " (" + inWords + ")");
out.annotate(2, "outs_size: 0x" + Integer.toHexString(outWords) + " (" + outWords + ")");
int triesLength = tries==null?0:tries.length;
out.annotate(2, "tries_size: 0x" + Integer.toHexString(triesLength) + " (" + triesLength + ")");
if (debugInfo == null) {
out.annotate(4, "debug_info_off:");
} else {
out.annotate(4, "debug_info_off: 0x" + debugInfo.getOffset());
}
out.annotate(4, "insns_size: 0x" + Integer.toHexString(encodedInstructions.length / 2) + " (" +
(encodedInstructions.length / 2) + ")");
InstructionIterator.IterateInstructions(encodedInstructions,
new InstructionIterator.ProcessRawInstructionDelegate() {
public void ProcessNormalInstruction(Opcode opcode, int index) {
out.annotate(opcode.format.size, opcode.name + " instruction");
out.annotate(opcode.format.size, "[0x" + Integer.toHexString(index/2) + "] " + opcode.name +
" instruction");
}
public void ProcessReferenceInstruction(Opcode opcode, int index) {
out.annotate(opcode.format.size, opcode.name + " instruction");
out.annotate(opcode.format.size, "[0x" + Integer.toHexString(index/2) + "] " + opcode.name +
" instruction");
}
public void ProcessPackedSwitchInstruction(int index, int targetCount, int instructionLength) {
out.annotate(instructionLength, "packed_switch instruction");
out.annotate(instructionLength, "[0x" + Integer.toHexString(index/2) + "] " +
"packed_switch instruction");
}
public void ProcessSparseSwitchInstruction(int index, int targetCount, int instructionLength) {
out.annotate(instructionLength, "sparse_switch instruction");
out.annotate(instructionLength, "[0x" + Integer.toHexString(index/2) + "] " +
"sparse_switch instruction");
}
public void ProcessFillArrayDataInstruction(int index, int elementWidth, int elementCount, int instructionLength) {
out.annotate(instructionLength, "fill_array_data instruction");
public void ProcessFillArrayDataInstruction(int index, int elementWidth, int elementCount,
int instructionLength) {
out.annotate(instructionLength, "[0x" + Integer.toHexString(index/2) + "] " +
"fill_array_data instruction");
}
});
if (tries != null && (tries.length % 2 == 1)) {
@ -237,6 +250,32 @@ public class CodeItem extends Item<CodeItem> {
InstructionWriter.writeInstructions(encodedInstructions, referencedItems, out);
if (tries != null && tries.length > 0) {
if (out.annotates()) {
if ((encodedInstructions.length % 4) != 0) {
out.annotate("padding");
out.writeShort(0);
}
int index = 0;
for (TryItem tryItem: tries) {
out.annotate(0, "[0x" + Integer.toHexString(index++) + "] try_item");
out.indent();
tryItem.writeTo(out);
out.deindent();
}
out.annotate("handler_count: 0x" + Integer.toHexString(encodedCatchHandlers.length) + "(" +
encodedCatchHandlers.length + ")");
out.writeUnsignedLeb128(encodedCatchHandlers.length);
index = 0;
for (EncodedCatchHandler encodedCatchHandler: encodedCatchHandlers) {
out.annotate(0, "[" + Integer.toHexString(index++) + "] encoded_catch_handler");
out.indent();
encodedCatchHandler.writeTo(out);
out.deindent();
}
} else {
if ((encodedInstructions.length % 4) != 0) {
out.writeShort(0);
}
@ -252,6 +291,7 @@ public class CodeItem extends Item<CodeItem> {
}
}
}
}
/** {@inheritDoc} */
public ItemType getItemType() {
@ -373,9 +413,10 @@ public class CodeItem extends Item<CodeItem> {
*/
private void writeTo(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(4, "start_addr");
out.annotate(2, "insn_count");
out.annotate(2, "handler_off");
out.annotate(4, "start_addr: 0x" + Integer.toHexString(startAddress));
out.annotate(2, "insn_count: 0x" + Integer.toHexString(instructionCount) + " (" + instructionCount +
")");
out.annotate(2, "handler_off: 0x" + Integer.toHexString(encodedCatchHandler.getOffsetInList()));
}
out.writeInt(startAddress);
@ -476,7 +517,7 @@ public class CodeItem extends Item<CodeItem> {
*/
private void writeTo(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate("size");
out.annotate("size: 0x" + Integer.toHexString(handlers.length) + " (" + handlers.length + ")");
int size = handlers.length;
if (catchAllHandlerAddress < 0) {
@ -484,12 +525,16 @@ public class CodeItem extends Item<CodeItem> {
}
out.writeSignedLeb128(size);
int index = 0;
for (EncodedTypeAddrPair handler: handlers) {
out.annotate(0, "[" + index++ + "] encoded_type_addr_pair");
out.indent();
handler.writeTo(out);
out.deindent();
}
if (catchAllHandlerAddress > -1) {
out.annotate("catch_all_addr");
out.annotate("catch_all_addr: 0x" + Integer.toHexString(catchAllHandlerAddress));
out.writeUnsignedLeb128(catchAllHandlerAddress);
}
} else {
@ -556,10 +601,10 @@ public class CodeItem extends Item<CodeItem> {
*/
private void writeTo(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate("type_idx");
out.annotate("exception_type: " + exceptionType.getTypeDescriptor());
out.writeUnsignedLeb128(exceptionType.getIndex());
out.annotate("addr");
out.annotate("handler_addr: 0x" + Integer.toHexString(handlerAddress));
out.writeUnsignedLeb128(handlerAddress);
} else {
out.writeUnsignedLeb128(exceptionType.getIndex());

View File

@ -266,15 +266,15 @@ public class DebugInstructionIterator {
{
//TODO: add javadocs
public void ProcessEndSequence(int startOffset) {
ProcessStaticOpcode(startOffset, 1);
ProcessStaticOpcode(DebugOpcode.DBG_END_SEQUENCE, startOffset, 1);
}
public void ProcessAdvancePC(int startOffset, int length, int addressDiff) {
ProcessStaticOpcode(startOffset, length);
ProcessStaticOpcode(DebugOpcode.DBG_ADVANCE_PC, startOffset, length);
}
public void ProcessAdvanceLine(int startOffset, int length, int lineDiff) {
ProcessStaticOpcode(startOffset, length);
ProcessStaticOpcode(DebugOpcode.DBG_ADVANCE_LINE, startOffset, length);
}
public void ProcessStartLocal(int startOffset, int length, int registerNum, int nameIndex, int typeIndex,
@ -286,29 +286,29 @@ public class DebugInstructionIterator {
}
public void ProcessEndLocal(int startOffset, int length, int registerNum, boolean registerIsSigned) {
ProcessStaticOpcode(startOffset, length);
ProcessStaticOpcode(DebugOpcode.DBG_END_LOCAL, startOffset, length);
}
public void ProcessRestartLocal(int startOffset, int length, int registerNum, boolean registerIsSigned) {
ProcessStaticOpcode(startOffset, length);
ProcessStaticOpcode(DebugOpcode.DBG_RESTART_LOCAL, startOffset, length);
}
public void ProcessSetPrologueEnd(int startOffset) {
ProcessStaticOpcode(startOffset, 1);
ProcessStaticOpcode(DebugOpcode.DBG_SET_PROLOGUE_END, startOffset, 1);
}
public void ProcessSetEpilogueBegin(int startOffset) {
ProcessStaticOpcode(startOffset, 1);
ProcessStaticOpcode(DebugOpcode.DBG_SET_EPILOGUE_BEGIN, startOffset, 1);
}
public void ProcessSetFile(int startOffset, int length, int nameIndex) {
}
public void ProcessSpecialOpcode(int startOffset, int debugOpcode, int lineDiff, int addressDiff) {
ProcessStaticOpcode(startOffset, 1);
ProcessStaticOpcode(DebugOpcode.DBG_SPECIAL_OPCODE, startOffset, 1);
}
public void ProcessStaticOpcode(int startOffset, int length) {
public void ProcessStaticOpcode(DebugOpcode debugOpcode, int startOffset, int length) {
}
}

View File

@ -37,7 +37,7 @@ public enum DebugOpcode {
DBG_END_LOCAL((byte)0x05),
DBG_RESTART_LOCAL((byte)0x06),
DBG_SET_PROLOGUE_END((byte)0x07),
DBG_SET_EPILOGUE_END((byte)0x08),
DBG_SET_EPILOGUE_BEGIN((byte)0x08),
DBG_SET_FILE((byte)0x09),
DBG_SPECIAL_OPCODE((byte)0x0A);

View File

@ -187,7 +187,7 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
private int referencedItemsPosition = 0;
@Override
public void ProcessStaticOpcode(int startOffset, int length) {
public void ProcessStaticOpcode(DebugOpcode opcode, int startOffset, int length) {
this.length+=length;
}
@ -261,6 +261,19 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
/** {@inheritDoc} */
protected void writeItem(final AnnotatedOutput out) {
if (out.annotates()) {
writeItemWithAnnotations(out);
} else {
writeItemWithNoAnnotations(out);
}
}
/**
* Helper method that writes the item, without writing annotations
* @param out the AnnotatedOutput object
*/
private void writeItemWithNoAnnotations(final AnnotatedOutput out) {
out.writeUnsignedLeb128(lineStart);
out.writeUnsignedLeb128(parameterNames.length);
for (StringIdItem parameterName: parameterNames) {
@ -278,7 +291,7 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
private int referencedItemsPosition = 0;
@Override
public void ProcessStaticOpcode(int startOffset, int length) {
public void ProcessStaticOpcode(DebugOpcode opcode, int startOffset, int length) {
out.write(encodedDebugInfo, startOffset, length);
}
@ -342,6 +355,200 @@ public class DebugInfoItem extends Item<DebugInfoItem> {
});
}
/**
* Helper method that writes and annotates the item
* @param out the AnnotatedOutput object
*/
private void writeItemWithAnnotations(final AnnotatedOutput out) {
out.annotate(0, parent.getParent().method.getMethodString());
out.annotate("line_start: 0x" + Integer.toHexString(lineStart) + " (" + lineStart + ")");
out.writeUnsignedLeb128(lineStart);
out.annotate("parameters_size: 0x" + Integer.toHexString(parameterNames.length) + " (" + parameterNames.length
+ ")");
out.writeUnsignedLeb128(parameterNames.length);
int index = 0;
for (StringIdItem parameterName: parameterNames) {
int indexp1;
if (parameterName == null) {
out.annotate("[" + index++ +"] parameterName: ");
indexp1 = 0;
} else {
out.annotate("[" + index++ +"] parameterName: " + parameterName.getStringValue());
indexp1 = parameterName.getIndex() + 1;
}
out.writeUnsignedLeb128(indexp1);
}
DebugInstructionIterator.IterateInstructions(new ByteArrayInput(encodedDebugInfo),
new DebugInstructionIterator.ProcessRawDebugInstructionDelegate() {
private int referencedItemsPosition = 0;
@Override
public void ProcessEndSequence(int startOffset) {
out.annotate("DBG_END_SEQUENCE");
out.writeByte(DebugOpcode.DBG_END_SEQUENCE.value);
}
@Override
public void ProcessAdvancePC(int startOffset, int length, int addressDiff) {
out.annotate("DBG_ADVANCE_PC");
out.writeByte(DebugOpcode.DBG_ADVANCE_PC.value);
out.indent();
out.annotate("addr_diff: 0x" + Integer.toHexString(addressDiff) + " (" + addressDiff + ")");
out.writeUnsignedLeb128(addressDiff);
out.deindent();
}
@Override
public void ProcessAdvanceLine(int startOffset, int length, int lineDiff) {
out.annotate("DBG_ADVANCE_LINE");
out.writeByte(DebugOpcode.DBG_ADVANCE_LINE.value);
out.indent();
out.annotate("line_diff: 0x" + Integer.toHexString(lineDiff) + " (" + lineDiff + ")");
out.writeSignedLeb128(lineDiff);
out.deindent();
}
@Override
public void ProcessStartLocal(int startOffset, int length, int registerNum, int nameIndex,
int typeIndex, boolean registerIsSigned) {
out.annotate("DBG_START_LOCAL");
out.writeByte(DebugOpcode.DBG_START_LOCAL.value);
out.indent();
out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")");
if (dexFile.getPreserveSignedRegisters() && registerIsSigned) {
out.writeSignedLeb128(registerNum);
} else {
out.writeUnsignedLeb128(registerNum);
}
if (nameIndex != -1) {
Item nameItem = referencedItems[referencedItemsPosition++];
assert nameItem instanceof StringIdItem;
out.annotate("name: " + ((StringIdItem)nameItem).getStringValue());
out.writeUnsignedLeb128(nameItem.getIndex() + 1);
} else {
out.annotate("name: ");
out.writeByte(0);
}
if (typeIndex != -1) {
Item typeItem = referencedItems[referencedItemsPosition++];
assert typeItem instanceof TypeIdItem;
out.annotate("type: " + ((TypeIdItem)typeItem).getTypeDescriptor());
out.writeUnsignedLeb128(typeItem.getIndex() + 1);
} else {
out.annotate("type: ");
out.writeByte(0);
}
out.deindent();
}
@Override
public void ProcessStartLocalExtended(int startOffset, int length, int registerNum, int nameIndex,
int typeIndex, int signatureIndex,
boolean registerIsSigned) {
out.annotate("DBG_START_LOCAL_EXTENDED");
out.writeByte(DebugOpcode.DBG_START_LOCAL_EXTENDED.value);
out.indent();
out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")");
if (dexFile.getPreserveSignedRegisters() && registerIsSigned) {
out.writeSignedLeb128(registerNum);
} else {
out.writeUnsignedLeb128(registerNum);
}
if (nameIndex != -1) {
Item nameItem = referencedItems[referencedItemsPosition++];
assert nameItem instanceof StringIdItem;
out.annotate("name: " + ((StringIdItem)nameItem).getStringValue());
out.writeUnsignedLeb128(nameItem.getIndex() + 1);
} else {
out.annotate("name: ");
out.writeByte(0);
}
if (typeIndex != -1) {
Item typeItem = referencedItems[referencedItemsPosition++];
assert typeItem instanceof TypeIdItem;
out.annotate("type: " + ((TypeIdItem)typeItem).getTypeDescriptor());
out.writeUnsignedLeb128(typeItem.getIndex() + 1);
} else {
out.annotate("type: ");
out.writeByte(0);
}
if (signatureIndex != -1) {
Item signatureItem = referencedItems[referencedItemsPosition++];
assert signatureItem instanceof StringIdItem;
out.annotate("signature: " + ((StringIdItem)signatureItem).getStringValue());
out.writeUnsignedLeb128(signatureItem.getIndex() + 1);
} else {
out.annotate("signature: ");
out.writeByte(0);
}
out.deindent();
}
@Override
public void ProcessEndLocal(int startOffset, int length, int registerNum, boolean registerIsSigned) {
out.annotate("DBG_END_LOCAL");
out.writeByte(DebugOpcode.DBG_END_LOCAL.value);
out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")");
if (registerIsSigned) {
out.writeSignedLeb128(registerNum);
} else {
out.writeUnsignedLeb128(registerNum);
}
}
@Override
public void ProcessRestartLocal(int startOffset, int length, int registerNum, boolean registerIsSigned) {
out.annotate("DBG_RESTART_LOCAL");
out.writeByte(DebugOpcode.DBG_RESTART_LOCAL.value);
out.annotate("register_num: 0x" + Integer.toHexString(registerNum) + " (" + registerNum + ")");
if (registerIsSigned) {
out.writeSignedLeb128(registerNum);
} else {
out.writeUnsignedLeb128(registerNum);
}
}
@Override
public void ProcessSetPrologueEnd(int startOffset) {
out.annotate("DBG_SET_PROLOGUE_END");
out.writeByte(DebugOpcode.DBG_SET_PROLOGUE_END.value);
}
@Override
public void ProcessSetEpilogueBegin(int startOffset) {
out.annotate("DBG_SET_EPILOGUE_BEGIN");
out.writeByte(DebugOpcode.DBG_SET_EPILOGUE_BEGIN.value);
}
@Override
public void ProcessSetFile(int startOffset, int length, int nameIndex) {
out.annotate("DBG_SET_FILE");
out.writeByte(DebugOpcode.DBG_SET_FILE.value);
if (nameIndex != -1) {
Item sourceItem = referencedItems[referencedItemsPosition++];
assert sourceItem instanceof StringIdItem;
out.annotate("source_file: \"" + ((StringIdItem)sourceItem).getStringValue() + "\"");
out.writeUnsignedLeb128(sourceItem.getIndex() + 1);
} else {
out.annotate("source_file: ");
out.writeByte(0);
}
}
@Override
public void ProcessSpecialOpcode(int startOffset, int debugOpcode, int lineDiff, int addressDiff) {
out.annotate("DBG_SPECIAL_OPCODE: line_diff=0x" + Integer.toHexString(lineDiff) + "(" +
lineDiff +"),addressDiff=0x" + Integer.toHexString(addressDiff) + "(" + addressDiff +
")");
out.writeByte(debugOpcode);
}
});
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_DEBUG_INFO_ITEM;

View File

@ -526,6 +526,8 @@ public class DexFile
out.annotate(0, " ");
HeaderItem.writeTo(out);
out.annotate(0, " ");
int sectionsPosition = 0;
Section[] sections;
if (this.inplace) {
@ -542,6 +544,12 @@ public class DexFile
}
out.alignTo(MapItem.getItemType().ItemAlignment);
out.annotate(0, " ");
out.annotate(0, "-----------------------------");
out.annotate(0, "map item");
out.annotate(0, "-----------------------------");
out.annotate(0, " ");
MapItem.writeTo(out);
}

View File

@ -79,9 +79,6 @@ public class EncodedArrayItem extends Item<EncodedArrayItem> {
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate("encoded_array");
}
encodedArray.writeValue(out);
}

View File

@ -81,12 +81,21 @@ public class AnnotationEncodedSubValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
out.annotate("annotation_type: " + annotationType.getTypeDescriptor());
out.writeUnsignedLeb128(annotationType.getIndex());
out.annotate("element_count: 0x" + Integer.toHexString(names.length) + " (" + names.length + ")");
out.writeUnsignedLeb128(names.length);
for (int i=0; i<names.length; i++) {
out.annotate(0, "[" + i + "] annotation_element");
out.indent();
out.annotate("element_name: " + names[i].getStringValue());
out.writeUnsignedLeb128(names[i].getIndex());
out.annotate(0, "element_value:");
out.indent();
values[i].writeValue(out);
out.deindent();
out.deindent();
}
}

View File

@ -58,6 +58,9 @@ public class AnnotationEncodedValue extends AnnotationEncodedSubValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate("value_type=" + ValueType.VALUE_ANNOTATION.name() + ",value_arg=0");
}
out.writeByte(ValueType.VALUE_ANNOTATION.value);
super.writeValue(out);
}

View File

@ -66,11 +66,24 @@ public class ArrayEncodedSubValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
if (out.annotates())
{
out.annotate("array_size: 0x" + Integer.toHexString(values.length) + " (" + values.length + ")");
out.writeUnsignedLeb128(values.length);
int index = 0;
for (EncodedValue encodedValue: values) {
out.annotate(0, "[" + index++ + "] array_element");
out.indent();
encodedValue.writeValue(out);
out.deindent();
}
} else {
out.writeUnsignedLeb128(values.length);
for (EncodedValue encodedValue: values) {
encodedValue.writeValue(out);
}
}
}
/** {@inheritDoc} */
public int placeValue(int offset) {

View File

@ -53,6 +53,9 @@ public class ArrayEncodedValue extends ArrayEncodedSubValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate("value_type=" + ValueType.VALUE_ARRAY.name() + ",value_arg=0");
}
out.writeByte(ValueType.VALUE_ARRAY.value);
super.writeValue(out);
}

View File

@ -76,6 +76,9 @@ public class BooleanEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate("value_type=" + ValueType.VALUE_BOOLEAN.name() + ",value=" + Boolean.toString(value));
}
out.writeByte(ValueType.VALUE_BOOLEAN.value | (value?1:0 << 5));
}

View File

@ -54,6 +54,10 @@ public class ByteEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(1, "value_type=" + ValueType.VALUE_BYTE.name() + ",value_arg=0");
out.annotate(1, "value: 0x" + Integer.toHexString(value) + " (" + value + ")");
}
out.writeByte(ValueType.VALUE_BYTE.value);
out.writeByte(value);
}

View File

@ -57,6 +57,14 @@ public class CharEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value);
if (out.annotates()) {
out.annotate(1, "value_type=" + ValueType.VALUE_CHAR.name() + ",value_arg=" + (bytes.length - 1));
char[] c = Character.toChars(value);
assert c.length > 0;
out.annotate(bytes.length, "value: 0x" + Integer.toHexString(value) + " '" + c[0] + "'");
}
out.writeByte(ValueType.VALUE_CHAR.value | ((bytes.length - 1) << 5));
out.write(bytes);
}

View File

@ -58,6 +58,12 @@ public class DoubleEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeRightZeroExtendedValue(Double.doubleToRawLongBits(value));
if (out.annotates()) {
out.annotate(1, "value_type=" + ValueType.VALUE_DOUBLE.name() + ",value_arg=" + (bytes.length - 1));
out.annotate(bytes.length, "value: " + value);
}
out.writeByte(ValueType.VALUE_DOUBLE.value | ((bytes.length - 1) << 5));
out.write(bytes);
}

View File

@ -61,6 +61,12 @@ public class EnumEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex());
if (out.annotates()) {
out.annotate(1, "value_type=" + ValueType.VALUE_ENUM.name() + ",value_arg=" + (bytes.length - 1));
out.annotate(bytes.length, "value: " + value.getFieldString());
}
out.writeByte(ValueType.VALUE_ENUM.value | ((bytes.length - 1) << 5));
out.write(bytes);
}

View File

@ -61,6 +61,12 @@ public class FieldEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex());
if (out.annotates()) {
out.annotate(1, "value_type=" + ValueType.VALUE_FIELD.name() + ",value_arg=" + (bytes.length - 1));
out.annotate(bytes.length, "value: " + value.getFieldString());
}
out.writeByte(ValueType.VALUE_FIELD.value | ((bytes.length - 1) << 5));
out.write(bytes);
}

View File

@ -58,6 +58,12 @@ public class FloatEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeRightZeroExtendedValue(((long)Float.floatToRawIntBits(value)) << 32);
if (out.annotates()) {
out.annotate(1, "value_type=" + ValueType.VALUE_FLOAT.name() + ",value_arg=" + (bytes.length - 1));
out.annotate(bytes.length, "value: " + value);
}
out.writeByte(ValueType.VALUE_FLOAT.value | ((bytes.length - 1) << 5));
out.write(bytes);
}

View File

@ -57,6 +57,12 @@ public class IntEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeSignedIntegralValue(value);
if (out.annotates()) {
out.annotate(1, "value_type=" + ValueType.VALUE_INT.name() + ",value_arg=" + (bytes.length - 1));
out.annotate(bytes.length, "value: 0x" + Integer.toHexString(value) + " (" + value + ")");
}
out.writeByte(ValueType.VALUE_INT.value | ((bytes.length - 1) << 5));
out.write(bytes);
}

View File

@ -57,6 +57,12 @@ public class LongEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeSignedIntegralValue(value);
if (out.annotates()) {
out.annotate(1, "value_type=" + ValueType.VALUE_LONG.name() + ",value_arg=" + (bytes.length - 1));
out.annotate(bytes.length, "value: 0x" + Long.toHexString(value) + " (" + value + ")");
}
out.writeByte(ValueType.VALUE_LONG.value | ((bytes.length - 1) << 5));
out.write(bytes);
}

View File

@ -61,6 +61,12 @@ public class MethodEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex());
if (out.annotates()) {
out.annotate(1, "value_type=" + ValueType.VALUE_METHOD.name() + ",value_arg=" + (bytes.length - 1));
out.annotate(bytes.length, "value: " + value.getMethodString());
}
out.writeByte(ValueType.VALUE_METHOD.value | ((bytes.length - 1) << 5));
out.write(bytes);
}

View File

@ -44,6 +44,9 @@ public class NullEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate("value_type=" + ValueType.VALUE_NULL.name() + ",value_arg=0");
}
out.writeByte(ValueType.VALUE_NULL.value);
}

View File

@ -57,6 +57,12 @@ public class ShortEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeSignedIntegralValue(value);
if (out.annotates()) {
out.annotate(1, "value_type=" + ValueType.VALUE_SHORT.name() + ",value_arg=" + (bytes.length - 1));
out.annotate(bytes.length, "value: 0x" + Integer.toHexString(value) + " (" + value + ")");
}
out.writeByte(ValueType.VALUE_SHORT.value | ((bytes.length - 1) << 5));
out.write(bytes);
}

View File

@ -31,6 +31,7 @@ package org.jf.dexlib.EncodedValue;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.EncodedValueUtils;
import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.Utf8Utils;
import org.jf.dexlib.StringIdItem;
import org.jf.dexlib.DexFile;
@ -61,6 +62,12 @@ public class StringEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex());
if (out.annotates()) {
out.annotate(1, "value_type=" + ValueType.VALUE_STRING.name() + ",value_arg=" + (bytes.length - 1));
out.annotate(bytes.length, "value: \"" + Utf8Utils.escapeString(value.getStringValue()) + "\"");
}
out.writeByte(ValueType.VALUE_STRING.value | ((bytes.length - 1) << 5));
out.write(bytes);
}

View File

@ -61,6 +61,12 @@ public class TypeEncodedValue extends EncodedValue {
/** {@inheritDoc} */
public void writeValue(AnnotatedOutput out) {
byte[] bytes = EncodedValueUtils.encodeUnsignedIntegralValue(value.getIndex());
if (out.annotates()) {
out.annotate(1, "value_type=" + ValueType.VALUE_TYPE.name() + ",value_arg=" + (bytes.length - 1));
out.annotate(bytes.length, "value: " + value.getTypeDescriptor());
}
out.writeByte(ValueType.VALUE_TYPE.value | ((bytes.length - 1) << 5));
out.write(bytes);
}

View File

@ -96,9 +96,9 @@ public class FieldIdItem extends Item<FieldIdItem> {
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(2, classType.getConciseIdentity());
out.annotate(2, fieldType.getConciseIdentity());
out.annotate(4, fieldName.getConciseIdentity());
out.annotate(2, "class_type: " + classType.getTypeDescriptor());
out.annotate(2, "field_type: " + fieldType.getTypeDescriptor());
out.annotate(4, "field_name: " + fieldName.getStringValue());
}
out.writeShort(classType.getIndex());
@ -157,6 +157,27 @@ public class FieldIdItem extends Item<FieldIdItem> {
return fieldName;
}
String cachedFieldString = null;
/**
* @return a string formatted like LclassName;->fieldName:fieldType
*/
public String getFieldString() {
if (cachedFieldString == null) {
String typeDescriptor = classType.getTypeDescriptor();
String fieldName = this.fieldName.getStringValue();
String fieldType = this.fieldType.getTypeDescriptor();
StringBuffer sb = new StringBuffer(typeDescriptor.length() + fieldName.length() + fieldType.length() + 3);
sb.append(typeDescriptor);
sb.append("->");
sb.append(fieldName);
sb.append(":");
sb.append(fieldType);
cachedFieldString = sb.toString();
}
return cachedFieldString;
}
/**
* calculate and cache the hashcode
*/

View File

@ -86,21 +86,31 @@ public class MapItem extends Item<MapItem> {
protected void writeItem(AnnotatedOutput out) {
Assert.assertTrue(getOffset() > 0);
int index = 0;
out.annotate(0, "[" + index++ + "]");
out.indent();
writeSectionInfo(out, ItemType.TYPE_HEADER_ITEM, 1, 0);
out.deindent();
for (Section section: dexFile.getOrderedSections()) {
out.annotate(0, "[" + index++ + "]");
out.indent();
writeSectionInfo(out, section.ItemType, section.getItems().size(), section.getOffset());
out.deindent();
}
out.annotate(0, "[" + index++ + "]");
out.indent();
writeSectionInfo(out, ItemType.TYPE_MAP_LIST, 1, dexFile.MapItem.getOffset());
out.deindent();
}
private void writeSectionInfo(AnnotatedOutput out, ItemType itemType, int sectionSize, int sectionOffset) {
if (out.annotates()) {
out.annotate(2, "ItemType: " + itemType);
out.annotate(2, "item_type: " + itemType);
out.annotate(2, "unused");
out.annotate(4, "Section Size: " + sectionSize);
out.annotate(4, "Section Offset: " + Hex.u4(sectionOffset));
out.annotate(4, "section_size: 0x" + Integer.toHexString(sectionSize) + " (" + sectionSize + ")");
out.annotate(4, "section_off: 0x" + Integer.toHexString(sectionOffset));
}
out.writeShort(itemType.MapValue);

View File

@ -91,9 +91,9 @@ public class MethodIdItem extends Item<MethodIdItem> {
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(2, classType.getConciseIdentity());
out.annotate(2, methodPrototype.getConciseIdentity());
out.annotate(4, methodName.getConciseIdentity());
out.annotate(2, "class_type: " + classType.getTypeDescriptor());
out.annotate(2, "method_prototype: " + methodPrototype.getPrototypeString());
out.annotate(4, "method_name: " + methodName.getStringValue());
}
out.writeShort(classType.getIndex());
@ -132,8 +132,17 @@ public class MethodIdItem extends Item<MethodIdItem> {
*/
public String getMethodString() {
if (cachedMethodString == null) {
cachedMethodString = classType.getTypeDescriptor() + "->" + methodName.getStringValue() +
methodPrototype.getPrototypeString();
String classType = this.classType.getTypeDescriptor();
String methodName = this.methodName.getStringValue();
String prototypeString = methodPrototype.getPrototypeString();
StringBuilder sb = new StringBuilder(classType.length() + methodName.length() + prototypeString.length() +
2);
sb.append(classType);
sb.append("->");
sb.append(methodName);
sb.append(prototypeString);
cachedMethodString = sb.toString();
}
return cachedMethodString;
}

View File

@ -99,7 +99,7 @@ public class ProtoIdItem extends Item<ProtoIdItem> {
if (parameters == null) {
out.annotate(4, "parameters:");
} else {
out.annotate(4, "parameters: " + parameters.getTypeListString());
out.annotate(4, "parameters: " + parameters.getTypeListString(""));
}
}
@ -145,7 +145,7 @@ public class ProtoIdItem extends Item<ProtoIdItem> {
if (cachedPrototypeString == null) {
StringBuilder sb = new StringBuilder("(");
if (parameters != null) {
sb.append(parameters.getTypeListString());
sb.append(parameters.getTypeListString(""));
}
sb.append(")");
sb.append(returnType.getTypeDescriptor());

View File

@ -83,11 +83,14 @@ public class StringDataItem extends Item<StringDataItem> {
protected void writeItem(AnnotatedOutput out) {
byte[] encodedValue = Utf8Utils.stringToUtf8Bytes(stringValue);
if (out.annotates()) {
out.annotate(stringValue.length(), "string_size");
out.annotate(encodedValue.length + 1, "string_data (" + Utf8Utils.escapeString(stringValue) + ")");
}
out.annotate("string_size: 0x" + Integer.toHexString(stringValue.length()) + " (" + stringValue.length() +
")");
out.writeUnsignedLeb128(stringValue.length());
out.annotate(encodedValue.length + 1, "string_data: \"" + Utf8Utils.escapeString(stringValue) + "\"");
} else {
out.writeUnsignedLeb128(stringValue.length());
}
out.write(encodedValue);
out.writeByte(0);
}
@ -99,7 +102,7 @@ public class StringDataItem extends Item<StringDataItem> {
/** {@inheritDoc} */
public String getConciseIdentity() {
return "string_data_item: " + Utf8Utils.escapeString(getStringValue());
return "string_data_item: \"" + Utf8Utils.escapeString(getStringValue()) + "\"";
}
/** {@inheritDoc} */

View File

@ -30,6 +30,7 @@ package org.jf.dexlib;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.ReadOnlyArrayList;
import java.util.List;
@ -91,21 +92,17 @@ public class TypeListItem extends Item<TypeListItem> {
//yes, the code to write the item is duplicated. This eliminates the need to iterate over the list twice
if (out.annotates()) {
out.annotate(4, "size: " + typeList.length);
out.writeInt(typeList.length);
out.annotate(4, "size: 0x" + Integer.toHexString(typeList.length) + " (" + typeList.length +")");
for (TypeIdItem typeIdItem: typeList) {
out.annotate(2, typeIdItem.getConciseIdentity());
out.writeShort(typeIdItem.getIndex());
out.annotate(2, "type_id_item: " + typeIdItem.getTypeDescriptor());
}
}
} else {
out.writeInt(typeList.length);
for (TypeIdItem typeIdItem: typeList) {
out.writeShort(typeIdItem.getIndex());
}
}
}
/** {@inheritDoc} */
public ItemType getItemType() {
@ -114,7 +111,7 @@ public class TypeListItem extends Item<TypeListItem> {
/** {@inheritDoc} */
public String getConciseIdentity() {
return "type_list: " + getTypeListString();
return "type_list: " + getTypeListString("");
}
/** {@inheritDoc} */
@ -154,22 +151,27 @@ public class TypeListItem extends Item<TypeListItem> {
return wordCount;
}
private String cachedTypeListString = null;
/**
* @return a string consisting of the type descriptors in this <code>TypeListItem</code>
* that are directly concatenated together
* that are separated by the given separator
* @param separator the separator between each type
*/
public String getTypeListString() {
if (cachedTypeListString == null) {
StringBuilder sb = new StringBuilder();
public String getTypeListString(String separator) {
int size = 0;
for (TypeIdItem typeIdItem: typeList) {
size += typeIdItem.getTypeDescriptor().length();
size += separator.length();
}
StringBuilder sb = new StringBuilder(size);
for (TypeIdItem typeIdItem: typeList) {
sb.append(typeIdItem.getTypeDescriptor());
sb.append(separator);
}
cachedTypeListString = sb.toString();
if (typeList.length > 0) {
sb.delete(sb.length() - separator.length(), sb.length());
}
return cachedTypeListString;
return sb.toString();
}
/**
@ -202,8 +204,8 @@ public class TypeListItem extends Item<TypeListItem> {
/**
* @return an array of the <code>TypeIdItems</code> in this <code>TypeListItem</code>
*/
public TypeIdItem[] getTypes() {
return typeList.clone();
public List<TypeIdItem> getTypes() {
return new ReadOnlyArrayList<TypeIdItem>(typeList);
}
/**

View File

@ -78,39 +78,89 @@ public enum AccessFlags
this.validForField = validForField;
}
public static List<AccessFlags> getAccessFlagsForClass(int accessFlagValue) {
ArrayList<AccessFlags> accessFlags = new ArrayList<AccessFlags>();
public static AccessFlags[] getAccessFlagsForClass(int accessFlagValue) {
int size = 0;
for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
accessFlags.add(accessFlag);
size++;
}
}
AccessFlags[] accessFlags = new AccessFlags[size];
int accessFlagsPosition = 0;
for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
accessFlags[accessFlagsPosition++] = accessFlag;
}
}
return accessFlags;
}
public static List<AccessFlags> getAccessFlagsForMethod(int accessFlagValue) {
ArrayList<AccessFlags> accessFlags = new ArrayList<AccessFlags>();
private static String formatAccessFlags(AccessFlags[] accessFlags) {
int size = 0;
for (AccessFlags accessFlag: accessFlags) {
size += accessFlag.toString().length() + 1;
}
StringBuilder sb = new StringBuilder(size);
for (AccessFlags accessFlag: accessFlags) {
sb.append(accessFlag.toString());
sb.append(" ");
}
if (accessFlags.length > 0) {
sb.delete(sb.length() - 1, sb.length());
}
return sb.toString();
}
public static String formatAccessFlagsForClass(int accessFlagValue) {
return formatAccessFlags(getAccessFlagsForClass(accessFlagValue));
}
public static AccessFlags[] getAccessFlagsForMethod(int accessFlagValue) {
int size = 0;
for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) {
accessFlags.add(accessFlag);
size++;
}
}
AccessFlags[] accessFlags = new AccessFlags[size];
int accessFlagsPosition = 0;
for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) {
accessFlags[accessFlagsPosition++] = accessFlag;
}
}
return accessFlags;
}
public static List<AccessFlags> getAccessFlagsForField(int accessFlagValue) {
ArrayList<AccessFlags> accessFlags = new ArrayList<AccessFlags>();
public static String formatAccessFlagsForMethod(int accessFlagValue) {
return formatAccessFlags(getAccessFlagsForMethod(accessFlagValue));
}
public static AccessFlags[] getAccessFlagsForField(int accessFlagValue) {
int size = 0;
for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) {
accessFlags.add(accessFlag);
size++;
}
}
AccessFlags[] accessFlags = new AccessFlags[size];
int accessFlagsPosition = 0;
for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) {
accessFlags[accessFlagsPosition++] = accessFlag;
}
}
return accessFlags;
}
public static String formatAccessFlagsForField(int accessFlagValue) {
return formatAccessFlags(getAccessFlagsForField(accessFlagValue));
}
public static AccessFlags getAccessFlag(String accessFlag) {
return accessFlagsByName.get(accessFlag);
}

View File

@ -0,0 +1,48 @@
/*
* [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib.Util;
import java.util.AbstractList;
import java.util.RandomAccess;
public class ReadOnlyArrayList<T> extends AbstractList<T> implements RandomAccess {
private final T[] arr;
public ReadOnlyArrayList(T[] arr) {
this.arr = arr;
}
public int size() {
return arr.length;
}
public T get(int i) {
return arr[i];
}
}