line ending and trailing whitespace cleanup

git-svn-id: https://smali.googlecode.com/svn/trunk@500 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2009-12-23 05:25:59 +00:00
parent eb78b7fa64
commit 5867263eb5
81 changed files with 12149 additions and 12151 deletions

View File

@ -39,7 +39,7 @@ import java.util.List;
import java.util.ArrayList;
public abstract class AnnotationEncodedValueAdaptor {
public static StringTemplate makeTemplate(StringTemplateGroup stg, AnnotationEncodedSubValue encodedAnnotation) {
StringTemplate template = stg.getInstanceOf("AnnotationEncodedValue");
template.setAttribute("AnnotationType", TypeReference.makeTemplate(stg, encodedAnnotation.annotationType));

View File

@ -58,7 +58,7 @@ public abstract class EncodedValueAdaptor {
return SimpleEncodedValueAdaptor.makeTemplate(stg, ((FloatEncodedValue)encodedValue).value);
case VALUE_INT:
return SimpleEncodedValueAdaptor.makeTemplate(stg, ((IntEncodedValue)encodedValue).value);
case VALUE_LONG:
case VALUE_LONG:
return SimpleEncodedValueAdaptor.makeTemplate(stg, ((LongEncodedValue)encodedValue).value);
case VALUE_METHOD:
return EncodedIndexedItemAdaptor.makeTemplate(stg, MethodReference.makeTemplate(stg,

View File

@ -63,13 +63,13 @@ public class FieldDefinition {
fieldTypeDescriptor.length() == 1 ||
initialValue != NullEncodedValue.NullValue
)) {
template.setAttribute("Comments",
new String[]{"the value of this static final field might be set in the static constructor"});
} else {
template.setAttribute("Comments", null);
}
if (initialValue != null) {
template.setAttribute("InitialValue", EncodedValueAdaptor.make(stg, initialValue));
}
@ -96,7 +96,7 @@ public class FieldDefinition {
if (annotationSet == null) {
return null;
}
List<StringTemplate> annotationAdaptors = new ArrayList<StringTemplate>();
for (AnnotationItem annotationItem: annotationSet.getAnnotations()) {

View File

@ -61,7 +61,7 @@ public class MethodDefinition {
template.setAttribute("Annotations", getAnnotations(stg, annotationSet));
template.setAttribute("MethodItems", getMethodItems(encodedMethod.method.getDexFile(), stg, codeItem));
return template;
return template;
}
private static int getRegisterCount(ClassDataItem.EncodedMethod encodedMethod)
@ -83,7 +83,7 @@ public class MethodDefinition {
for (AccessFlags accessFlag: AccessFlags.getAccessFlagsForMethod(encodedMethod.accessFlags)) {
accessFlags.add(accessFlag.toString());
}
return accessFlags;
}
@ -281,7 +281,7 @@ public class MethodDefinition {
}
});
}
blanks.remove(blanks.size()-1);
addTries();
@ -334,7 +334,7 @@ public class MethodDefinition {
addInstructionMethodItem(
new Instruction11xMethodItem(codeItem, offset, stg, (Instruction11x)instruction),
commentedOut);
return;
return;
case Format12x:
addInstructionMethodItem(
new Instruction12xMethodItem(codeItem, offset, stg, (Instruction12x)instruction),

View File

@ -53,7 +53,7 @@ public class RegisterFormatter {
int registerCount = codeItem.getRegisterCount();
assert startRegister <= lastRegister;
if (startRegister >= registerCount - parameterRegisterCount) {
return new String[] {"p" + (startRegister - (registerCount - parameterRegisterCount)),
"p" + (lastRegister - (registerCount - parameterRegisterCount))};

View File

@ -42,7 +42,7 @@ public class ByteRenderer implements AttributeRenderer {
public String toString(Object o, String s) {
if (s.equals("unsigned")) {
Byte b = (Byte)o;
return "0x" + Integer.toHexString(b & 0xFF) + "t";
return "0x" + Integer.toHexString(b & 0xFF) + "t";
}
return toString(o);
}

View File

@ -57,7 +57,7 @@ public class baksmali {
if (deodexerant != null) {
baksmali.deodexUtil = new DeodexUtil(deodexerant);
}
File outputDirectoryFile = new File(outputDirectory);
if (!outputDirectoryFile.exists()) {
if (!outputDirectoryFile.mkdirs()) {
@ -76,7 +76,7 @@ public class baksmali {
templates.registerRenderer(Float.class, new FloatRenderer());
templates.registerRenderer(Character.class, new CharRenderer());
templates.registerRenderer(StringIdItem.class, new StringIdItemRenderer());
for (ClassDefItem classDefItem: dexFile.ClassDefsSection.getItems()) {
/**

View File

@ -40,7 +40,7 @@ public class dump {
if (sort) {
//sort all items, to guarantee a unique ordering
dexFile.setSortAllItems(true);
dexFile.setSortAllItems(true);
} else {
//don't change the order
dexFile.setInplace(true);

View File

@ -97,7 +97,7 @@
const-string v0, "testing\n123"
goto switch:
sget v0, Lbaksmali/test/class;->staticField:I
switch:
@ -194,7 +194,7 @@
.source "somefile.java"
.line 101
nop

View File

@ -28,13 +28,13 @@
invoke-virtual {v0}, Lrandomclass;->getSuperclass()Lsuperclass;
move-result-object v1
#a branch to outside the dead code. The branch label should not
#be commented out, because there is a non-dead instruction
#that branches to it
if-eqz v0, :here2
#a branch to inside the dead code. the branch label should be
#commented out
if-eqz v0, :here
@ -61,14 +61,14 @@
#but still commented out
invoke-virtual {v2}, Lsuperclass;->somemethod()V
:here2
#and we're back to the non-dead code
invoke-virtual {v2}, Lsuperclass;->somemethod()V
if-nez v0, :here3
return-void
.end method

View File

@ -6,11 +6,11 @@
.registers 6
const v2, 0
const v3, 1
const v4, 0
new-array v1, v3, [Lsubclass1;
new-array v1, v3, [Lsubclass1;
new-instance v0, Lsubclass1;
invoke-direct {v0}, Lsubclass1;-><init>()V
aput-object v0, v1, v4

View File

@ -297,17 +297,17 @@ int dumpFields(char *classType, FILE *clientOut)
clazz = dvmFindArrayClass(classType, NULL);
else
clazz = dvmFindSystemClassNoInit(classType);
if (clazz == NULL)
return 0;
int i;
do
{
InstField *pField = clazz->ifields;
for (i=0; i<clazz->ifieldCount; i++, pField++)
fprintf(clientOut, "field: %d %s:%s\n", pField->byteOffset, pField->field.name, pField->field.signature);
clazz = clazz->super;
} while (clazz != NULL);
@ -318,15 +318,15 @@ int dumpInlineMethods(FILE *clientOut)
{
const InlineOperation *inlineTable = dvmGetInlineOpsTable();
int count = dvmGetInlineOpsTableLength();
int i;
for (i=0; i<count; i++) {
const InlineOperation *inlineOp = &inlineTable[i];
ClassObject *clazz = dvmFindSystemClassNoInit(inlineOp->classDescriptor);
if (clazz == NULL)
return 0;
char *methodType;
Method *method = dvmFindDirectMethodByDescriptor(clazz, inlineOp->methodName, inlineOp->methodSignature);
if (method == NULL)
@ -339,13 +339,13 @@ int dumpInlineMethods(FILE *clientOut)
else
methodType = "direct";
}
if (method == NULL)
return 0;
fprintf(clientOut, "inline: %s %s->%s%s\n", methodType, method->clazz->descriptor, method->name, dexProtoGetMethodDescriptor(&method->prototype, &stringCache));
}
return 1;
}
@ -356,14 +356,14 @@ int dumpVirtualMethods(char *classType, FILE *clientOut)
clazz = dvmFindArrayClass(classType, NULL);
else
clazz = dvmFindSystemClassNoInit(classType);
if (clazz == NULL)
{
fprintf(clientOut, "err: could not find class %s\n", classType);
return 0;
}
//interface classes don't have virtual methods, by definition. But it's possible
//to call virtual methods defined on the Object class via an interface type
if (dvmIsInterfaceClass(clazz))
@ -389,10 +389,10 @@ int dumpVirtualMethods(char *classType, FILE *clientOut)
ClassObject *lookupSuperclass(char *classType)
{
ClassObject *clazz = dvmFindSystemClassNoInit(classType);
if (clazz == NULL)
return NULL;
return clazz->super;
}
@ -428,7 +428,7 @@ int main(int argc, char* const argv[])
fprintf(stderr, "Unable to open '%s': %s\n", inputFileName, strerror(errno));
return 1;
}
int port = atoi(argv[2]);
int socketFd = socket(AF_INET, SOCK_STREAM, 0);
if (socketFd < 0)
@ -436,7 +436,7 @@ int main(int argc, char* const argv[])
fprintf(stderr, "Unable to open socket\n");
return 1;
}
struct sockaddr_in serverAddress, clientAddress;
bzero((char *)&serverAddress, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
@ -446,14 +446,14 @@ int main(int argc, char* const argv[])
{
fprintf(stderr, "Unable to bind socket\n");
return 1;
}
}
const char* bcp = getenv("BOOTCLASSPATH");
if (bcp == NULL) {
fprintf(stderr, "BOOTCLASSPATH not set\n");
return 1;
}
DexClassVerifyMode verifyMode = VERIFY_MODE_ALL;
DexOptimizerMode dexOptMode = OPTIMIZE_MODE_VERIFIED;
@ -498,12 +498,12 @@ int main(int argc, char* const argv[])
fprintf(stderr, "error while loading classes\n");
return 1;
}
listen(socketFd, 1);
int clientSocketLength = sizeof(clientAddress);
int clientFd = accept(socketFd, (struct sockaddr *) &clientAddress, &clientSocketLength);
if (clientFd < 0)
@ -511,14 +511,14 @@ int main(int argc, char* const argv[])
fprintf(stderr, "Unable to accept incomming connection\n");
return 1;
}
FILE *clientIn = fdopen(clientFd, "r");
if (clientIn == 0)
{
fprintf(stderr, "Unable to fdopen socket to get input stream\n");
return 1;
}
FILE *clientOut = fdopen(dup(clientFd), "w");
if (clientOut == 0)
{
@ -536,7 +536,7 @@ int main(int argc, char* const argv[])
char *buf = malloc(len+1);
memcpy(buf, command, len);
buf[len] = 0;
//printf("%s\n", buf);
char *cmd = strtok(buf, " ");
@ -557,14 +557,14 @@ int main(int argc, char* const argv[])
fflush(clientOut);
break;
}
if (!dumpFields(classType, clientOut))
{
fprintf(clientOut, "err: error while dumping fields\n");
fflush(clientOut);
break;
}
fprintf(clientOut, "done\n");
fflush(clientOut);
break;
@ -577,7 +577,7 @@ int main(int argc, char* const argv[])
fflush(clientOut);
break;
}
fprintf(clientOut, "done\n");
fflush(clientOut);
break;
@ -591,13 +591,13 @@ int main(int argc, char* const argv[])
fflush(clientOut);
break;
}
if (!dumpVirtualMethods(classType, clientOut)) {
fprintf(clientOut, "err: error encountered while dumping virtual methods\n");
fflush(clientOut);
break;
}
fprintf(clientOut, "done\n");
fflush(clientOut);
break;
@ -611,7 +611,7 @@ int main(int argc, char* const argv[])
fflush(clientOut);
break;
}
ClassObject *clazz = lookupSuperclass(classType);
if (clazz == NULL)
{
@ -633,20 +633,20 @@ int main(int argc, char* const argv[])
fflush(clientOut);
break;
}
ClassObject *clazz1;
if (classType1[0] == '[')
clazz1 = dvmFindArrayClass(classType1, NULL);
else
clazz1 = dvmFindSystemClassNoInit(classType1);
if (clazz1 == NULL)
{
fprintf(clientOut, "err: class %s could not be found for common superclass lookup. This can be caused if a library the odex depends on is not in the BOOTCLASSPATH environment variable\n", classType1);
fflush(clientOut);
break;
}
}
char *classType2 = strtok(NULL, " ");
if (classType2 == NULL)
{
@ -654,20 +654,20 @@ int main(int argc, char* const argv[])
fflush(clientOut);
break;
}
ClassObject *clazz2;
if (classType2[0] == '[')
clazz2 = dvmFindArrayClass(classType2, NULL);
else
clazz2 = dvmFindSystemClassNoInit(classType2);
if (clazz2 == NULL)
{
fprintf(clientOut, "err: class %s could not be found for common superclass lookup\n", classType2);
fflush(clientOut);
break;
}
}
ClassObject *clazz = findCommonSuperclass(clazz1, clazz2);
fprintf(clientOut, "class: %s\n", clazz->descriptor);
fflush(clientOut);
@ -677,12 +677,12 @@ int main(int argc, char* const argv[])
fprintf(clientOut, "err: not a valid command\n");
fflush(clientOut);
}
/*gettimeofday(&tv, NULL);
/*gettimeofday(&tv, NULL);
printf("end %07d\n", tv.tv_usec);*/
}
return 0;

View File

@ -1,473 +1,473 @@
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
import java.util.Collections;
import java.util.List;
public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
private AnnotationSetItem classAnnotations;
private FieldIdItem[] fieldAnnotationFields;
private AnnotationSetItem[] fieldAnnotations;
private MethodIdItem[] methodAnnotationMethods;
private AnnotationSetItem[] methodAnnotations;
private MethodIdItem[] parameterAnnotationMethods;
private AnnotationSetRefList[] parameterAnnotations;
/**
* typically each AnnotationDirectoryItem will have a distinct parent. The only case that isn't true is when
* the AnnotationDirectoryItem *only* contains class annotations, with no other type of annotation. In that
* case, the same AnnotationDirectoryItem could be referenced from multiple classes.
* This isn't a problem though, because this field is only used in compareTo to determine the sort order,
* which handles it as a special case
*/
private ClassDefItem parent = null;
/**
* Creates a new uninitialized <code>AnnotationDirectoryItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected AnnotationDirectoryItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>AnnotationDirectoryItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classAnnotations The annotations associated with the overall class
* @param fieldAnnotationFields An array of <code>FieldIdItem</code> objects that the annotations in
* <code>fieldAnnotations</code> are associated with
* @param fieldAnnotations An array of <code>AnnotationSetItem</code> objects that contain the annotations for the
* fields in <code>fieldAnnotationFields</code>
* @param methodAnnotationMethods An array of <code>MethodIdItem</code> objects that the annotations in
* <code>methodAnnotations</code> are associated with
* @param methodAnnotations An array of <code>AnnotationSetItem</code> objects that contain the annotations for the
* methods in <code>methodAnnotationMethods</code>
* @param parameterAnnotationMethods An array of <code>MethodIdItem</code> objects that the annotations in
* <code>parameterAnnotations</code> are associated with
* @param parameterAnnotations An array of <code>AnnotationSetRefList</code> objects that contain the parameter
* annotations for the methods in <code>parameterAnnotationMethods</code>
*/
private AnnotationDirectoryItem(DexFile dexFile, AnnotationSetItem classAnnotations,
FieldIdItem[] fieldAnnotationFields, AnnotationSetItem[] fieldAnnotations,
MethodIdItem[] methodAnnotationMethods, AnnotationSetItem[] methodAnnotations,
MethodIdItem[] parameterAnnotationMethods,
AnnotationSetRefList[] parameterAnnotations) {
super(dexFile);
this.classAnnotations = classAnnotations;
this.fieldAnnotationFields = fieldAnnotationFields;
this.fieldAnnotations = fieldAnnotations;
this.methodAnnotationMethods = methodAnnotationMethods;
this.methodAnnotations = methodAnnotations;
this.parameterAnnotationMethods = parameterAnnotationMethods;
this.parameterAnnotations = parameterAnnotations;
}
/**
* Returns an <code>AnnotationDirectoryItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classAnnotations The annotations associated with the class
* @param fieldAnnotations A list of <code>FieldAnnotation</code> objects containing the field annotations
* @param methodAnnotations A list of <code>MethodAnnotation</code> objects containing the method annotations
* @param parameterAnnotations A list of <code>ParameterAnnotation</code> objects containin the parameter
* annotations
* @return an <code>AnnotationItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
*/
public static AnnotationDirectoryItem getInternedAnnotationDirectoryItem(DexFile dexFile,
AnnotationSetItem classAnnotations,
List<FieldAnnotation> fieldAnnotations,
List<MethodAnnotation> methodAnnotations,
List<ParameterAnnotation> parameterAnnotations) {
FieldIdItem[] fieldAnnotationFields = null;
AnnotationSetItem[] fieldAnnotationsArray = null;
MethodIdItem[] methodAnnotationMethods = null;
AnnotationSetItem[] methodAnnotationsArray = null;
MethodIdItem[] parameterAnnotationMethods = null;
AnnotationSetRefList[] parameterAnnotationsArray = null;
if (fieldAnnotations != null && fieldAnnotations.size() > 0) {
fieldAnnotationFields = new FieldIdItem[fieldAnnotations.size()];
fieldAnnotationsArray = new AnnotationSetItem[fieldAnnotations.size()];
Collections.sort(fieldAnnotations);
int index = 0;
for (FieldAnnotation fieldAnnotation: fieldAnnotations) {
fieldAnnotationFields[index] = fieldAnnotation.field;
fieldAnnotationsArray[index++] = fieldAnnotation.annotationSet;
}
}
if (methodAnnotations != null && methodAnnotations.size() > 0) {
methodAnnotationMethods = new MethodIdItem[methodAnnotations.size()];
methodAnnotationsArray = new AnnotationSetItem[methodAnnotations.size()];
Collections.sort(methodAnnotations);
int index = 0;
for (MethodAnnotation methodAnnotation: methodAnnotations) {
methodAnnotationMethods[index] = methodAnnotation.method;
methodAnnotationsArray[index++] = methodAnnotation.annotationSet;
}
}
if (parameterAnnotations != null && parameterAnnotations.size() > 0) {
parameterAnnotationMethods = new MethodIdItem[parameterAnnotations.size()];
parameterAnnotationsArray = new AnnotationSetRefList[parameterAnnotations.size()];
Collections.sort(parameterAnnotations);
int index = 0;
for (ParameterAnnotation parameterAnnotation: parameterAnnotations) {
parameterAnnotationMethods[index] = parameterAnnotation.method;
parameterAnnotationsArray[index++] = parameterAnnotation.annotationSet;
}
}
AnnotationDirectoryItem annotationDirectoryItem = new AnnotationDirectoryItem(dexFile, classAnnotations,
fieldAnnotationFields, fieldAnnotationsArray, methodAnnotationMethods, methodAnnotationsArray,
parameterAnnotationMethods, parameterAnnotationsArray);
return dexFile.AnnotationDirectoriesSection.intern(annotationDirectoryItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
classAnnotations = (AnnotationSetItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_ANNOTATION_SET_ITEM,
in.readInt());
fieldAnnotationFields = new FieldIdItem[in.readInt()];
fieldAnnotations = new AnnotationSetItem[fieldAnnotationFields.length];
methodAnnotationMethods = new MethodIdItem[in.readInt()];
methodAnnotations = new AnnotationSetItem[methodAnnotationMethods.length];
parameterAnnotationMethods = new MethodIdItem[in.readInt()];
parameterAnnotations = new AnnotationSetRefList[parameterAnnotationMethods.length];
for (int i=0; i<fieldAnnotations.length; i++) {
fieldAnnotationFields[i] = dexFile.FieldIdsSection.getItemByIndex(in.readInt());
fieldAnnotations[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
}
for (int i=0; i<methodAnnotations.length; i++) {
methodAnnotationMethods[i] = dexFile.MethodIdsSection.getItemByIndex(in.readInt());
methodAnnotations[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
}
for (int i=0; i<parameterAnnotations.length; i++) {
parameterAnnotationMethods[i] = dexFile.MethodIdsSection.getItemByIndex(in.readInt());
parameterAnnotations[i] = (AnnotationSetRefList)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATION_SET_REF_LIST, in.readInt());
}
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 16 + (
(fieldAnnotations==null?0:fieldAnnotations.length) +
(methodAnnotations==null?0:methodAnnotations.length) +
(parameterAnnotations==null?0:parameterAnnotations.length)) * 8;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
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:");
}
int length = fieldAnnotations==null?0:fieldAnnotations.length;
out.annotate(4, "annotated_fields_size: 0x" + Integer.toHexString(length) + " (" +
length + ")");
length = methodAnnotations==null?0:methodAnnotations.length;
out.annotate(4, "annotated_methods_size: 0x" + Integer.toHexString(length) + " (" +
length + ")");
length = parameterAnnotations==null?0:parameterAnnotations.length;
out.annotate(4, "annotated_parameters_size: 0x" + Integer.toHexString(length) + " (" +
length + ")");
int index;
if (fieldAnnotations != null) {
index = 0;
for (int i=0; i<fieldAnnotations.length; i++) {
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();
}
}
if (methodAnnotations != null) {
index = 0;
for (int i=0; i<methodAnnotations.length; i++) {
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();
}
}
if (parameterAnnotations != null) {
index = 0;
for (int i=0; i<parameterAnnotations.length; i++) {
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()));
}
}
}
out.writeInt(classAnnotations==null?0:classAnnotations.getOffset());
out.writeInt(fieldAnnotations==null?0:fieldAnnotations.length);
out.writeInt(methodAnnotations==null?0:methodAnnotations.length);
out.writeInt(parameterAnnotations==null?0:parameterAnnotations.length);
if (fieldAnnotations != null) {
for (int i=0; i<fieldAnnotations.length; i++) {
out.writeInt(fieldAnnotationFields[i].getIndex());
out.writeInt(fieldAnnotations[i].getOffset());
}
}
if (methodAnnotations != null) {
for (int i=0; i<methodAnnotations.length; i++) {
out.writeInt(methodAnnotationMethods[i].getIndex());
out.writeInt(methodAnnotations[i].getOffset());
}
}
if (parameterAnnotations != null) {
for (int i=0; i<parameterAnnotations.length; i++) {
out.writeInt(parameterAnnotationMethods[i].getIndex());
out.writeInt(parameterAnnotations[i].getOffset());
}
}
}
/** {@inheritDoc} */public ItemType getItemType() {
return ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "annotation_directory_item @0x" + Integer.toHexString(getOffset());
}
/** {@inheritDoc} */
public int compareTo(AnnotationDirectoryItem o) {
if (!isInternable()) {
if (!o.isInternable()) {
return parent.compareTo(o.parent);
}
return -1;
}
if (!o.isInternable()) {
return 1;
}
return classAnnotations.compareTo(o.classAnnotations);
}
/**
* @return The annotations associated with the class
*/
public AnnotationSetItem getClassAnnotations() {
return classAnnotations;
}
/**
* Iterates over the field annotations, calling delegate.processFieldAnnotations for each
* @param delegate the delegate to call
*/
public void iterateFieldAnnotations(FieldAnnotationIteratorDelegate delegate) {
for (int i=0; i<fieldAnnotationFields.length; i++) {
delegate.processFieldAnnotations(fieldAnnotationFields[i], fieldAnnotations[i]);
}
}
public static interface FieldAnnotationIteratorDelegate {
void processFieldAnnotations(FieldIdItem field, AnnotationSetItem fieldAnnotations);
}
/**
* @return the number of field annotations in this <code>AnnotationDirectoryItem</code>
*/
public int getFieldAnnotationCount() {
return fieldAnnotationFields.length;
}
/**
* Iterates over the method annotations, calling delegate.processMethodAnnotations for each
* @param delegate the delegate to call
*/
public void iterateMethodAnnotations(MethodAnnotationIteratorDelegate delegate) {
for (int i=0; i<methodAnnotationMethods.length; i++) {
delegate.processMethodAnnotations(methodAnnotationMethods[i], methodAnnotations[i]);
}
}
public static interface MethodAnnotationIteratorDelegate {
void processMethodAnnotations(MethodIdItem method, AnnotationSetItem methodAnnotations);
}
/**
* @return the number of method annotations in this <code>AnnotationDirectoryItem</code>
*/
public int getMethodAnnotationCount() {
return methodAnnotationMethods.length;
}
/**
* Iterates over the parameter annotations, calling delegate.processParameterAnnotations for each
* @param delegate the delegate to call
*/
public void iterateParameterAnnotations(ParameterAnnotationIteratorDelegate delegate) {
for (int i=0; i<parameterAnnotationMethods.length; i++) {
delegate.processParameterAnnotations(parameterAnnotationMethods[i], parameterAnnotations[i]);
}
}
public static interface ParameterAnnotationIteratorDelegate {
void processParameterAnnotations(MethodIdItem method, AnnotationSetRefList parameterAnnotations);
}
/**
* @return the number of parameter annotations in this <code>AnnotationDirectoryItem</code>
*/
public int getParameterAnnotationCount() {
return parameterAnnotationMethods.length;
}
/**
* @return true if this <code>AnnotationDirectoryItem</code> is internable. It is only internable if it has
* only class annotations, but no field, method or parameter annotations
*/
private boolean isInternable() {
return classAnnotations != null &&
(fieldAnnotations == null || fieldAnnotations.length == 0) &&
(methodAnnotations == null || methodAnnotations.length == 0) &&
(parameterAnnotations == null || parameterAnnotations.length == 0);
}
/**
* Sets the <code>ClassDefItem</code> that this <code>AnnotationDirectoryItem</code> is associated with.
* This is only applicable if this AnnotationDirectoryItem contains only class annotations, and no field, method
* or parameter annotations.
* @param classDefItem the <code>ClassDefItem</code> that this <code>AnnotationDirectoryItem</code> is associated
* with
*/
protected void setParent(ClassDefItem classDefItem) {
this.parent = classDefItem;
}
@Override
public int hashCode() {
//an instance is only internable if it has only class annotations, but
//no other type of annotation
if (!isInternable()) {
return super.hashCode();
}
return classAnnotations.hashCode();
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
AnnotationDirectoryItem other = (AnnotationDirectoryItem)o;
return (this.compareTo(other) == 0);
}
public static class FieldAnnotation implements Comparable<FieldAnnotation> {
public final FieldIdItem field;
public final AnnotationSetItem annotationSet;
public FieldAnnotation(FieldIdItem field, AnnotationSetItem annotationSet) {
this.field = field;
this.annotationSet = annotationSet;
}
public int compareTo(FieldAnnotation other) {
return field.compareTo(other.field);
}
}
public static class MethodAnnotation implements Comparable<MethodAnnotation> {
public final MethodIdItem method;
public final AnnotationSetItem annotationSet;
public MethodAnnotation(MethodIdItem method, AnnotationSetItem annotationSet) {
this.method = method;
this.annotationSet = annotationSet;
}
public int compareTo(MethodAnnotation other) {
return method.compareTo(other.method);
}
}
public static class ParameterAnnotation implements Comparable<ParameterAnnotation> {
public final MethodIdItem method;
public final AnnotationSetRefList annotationSet;
public ParameterAnnotation(MethodIdItem method, AnnotationSetRefList annotationSet) {
this.method = method;
this.annotationSet = annotationSet;
}
public int compareTo(ParameterAnnotation other) {
return method.compareTo(other.method);
}
}
}
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
import java.util.Collections;
import java.util.List;
public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
private AnnotationSetItem classAnnotations;
private FieldIdItem[] fieldAnnotationFields;
private AnnotationSetItem[] fieldAnnotations;
private MethodIdItem[] methodAnnotationMethods;
private AnnotationSetItem[] methodAnnotations;
private MethodIdItem[] parameterAnnotationMethods;
private AnnotationSetRefList[] parameterAnnotations;
/**
* typically each AnnotationDirectoryItem will have a distinct parent. The only case that isn't true is when
* the AnnotationDirectoryItem *only* contains class annotations, with no other type of annotation. In that
* case, the same AnnotationDirectoryItem could be referenced from multiple classes.
* This isn't a problem though, because this field is only used in compareTo to determine the sort order,
* which handles it as a special case
*/
private ClassDefItem parent = null;
/**
* Creates a new uninitialized <code>AnnotationDirectoryItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected AnnotationDirectoryItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>AnnotationDirectoryItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classAnnotations The annotations associated with the overall class
* @param fieldAnnotationFields An array of <code>FieldIdItem</code> objects that the annotations in
* <code>fieldAnnotations</code> are associated with
* @param fieldAnnotations An array of <code>AnnotationSetItem</code> objects that contain the annotations for the
* fields in <code>fieldAnnotationFields</code>
* @param methodAnnotationMethods An array of <code>MethodIdItem</code> objects that the annotations in
* <code>methodAnnotations</code> are associated with
* @param methodAnnotations An array of <code>AnnotationSetItem</code> objects that contain the annotations for the
* methods in <code>methodAnnotationMethods</code>
* @param parameterAnnotationMethods An array of <code>MethodIdItem</code> objects that the annotations in
* <code>parameterAnnotations</code> are associated with
* @param parameterAnnotations An array of <code>AnnotationSetRefList</code> objects that contain the parameter
* annotations for the methods in <code>parameterAnnotationMethods</code>
*/
private AnnotationDirectoryItem(DexFile dexFile, AnnotationSetItem classAnnotations,
FieldIdItem[] fieldAnnotationFields, AnnotationSetItem[] fieldAnnotations,
MethodIdItem[] methodAnnotationMethods, AnnotationSetItem[] methodAnnotations,
MethodIdItem[] parameterAnnotationMethods,
AnnotationSetRefList[] parameterAnnotations) {
super(dexFile);
this.classAnnotations = classAnnotations;
this.fieldAnnotationFields = fieldAnnotationFields;
this.fieldAnnotations = fieldAnnotations;
this.methodAnnotationMethods = methodAnnotationMethods;
this.methodAnnotations = methodAnnotations;
this.parameterAnnotationMethods = parameterAnnotationMethods;
this.parameterAnnotations = parameterAnnotations;
}
/**
* Returns an <code>AnnotationDirectoryItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classAnnotations The annotations associated with the class
* @param fieldAnnotations A list of <code>FieldAnnotation</code> objects containing the field annotations
* @param methodAnnotations A list of <code>MethodAnnotation</code> objects containing the method annotations
* @param parameterAnnotations A list of <code>ParameterAnnotation</code> objects containin the parameter
* annotations
* @return an <code>AnnotationItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
*/
public static AnnotationDirectoryItem getInternedAnnotationDirectoryItem(DexFile dexFile,
AnnotationSetItem classAnnotations,
List<FieldAnnotation> fieldAnnotations,
List<MethodAnnotation> methodAnnotations,
List<ParameterAnnotation> parameterAnnotations) {
FieldIdItem[] fieldAnnotationFields = null;
AnnotationSetItem[] fieldAnnotationsArray = null;
MethodIdItem[] methodAnnotationMethods = null;
AnnotationSetItem[] methodAnnotationsArray = null;
MethodIdItem[] parameterAnnotationMethods = null;
AnnotationSetRefList[] parameterAnnotationsArray = null;
if (fieldAnnotations != null && fieldAnnotations.size() > 0) {
fieldAnnotationFields = new FieldIdItem[fieldAnnotations.size()];
fieldAnnotationsArray = new AnnotationSetItem[fieldAnnotations.size()];
Collections.sort(fieldAnnotations);
int index = 0;
for (FieldAnnotation fieldAnnotation: fieldAnnotations) {
fieldAnnotationFields[index] = fieldAnnotation.field;
fieldAnnotationsArray[index++] = fieldAnnotation.annotationSet;
}
}
if (methodAnnotations != null && methodAnnotations.size() > 0) {
methodAnnotationMethods = new MethodIdItem[methodAnnotations.size()];
methodAnnotationsArray = new AnnotationSetItem[methodAnnotations.size()];
Collections.sort(methodAnnotations);
int index = 0;
for (MethodAnnotation methodAnnotation: methodAnnotations) {
methodAnnotationMethods[index] = methodAnnotation.method;
methodAnnotationsArray[index++] = methodAnnotation.annotationSet;
}
}
if (parameterAnnotations != null && parameterAnnotations.size() > 0) {
parameterAnnotationMethods = new MethodIdItem[parameterAnnotations.size()];
parameterAnnotationsArray = new AnnotationSetRefList[parameterAnnotations.size()];
Collections.sort(parameterAnnotations);
int index = 0;
for (ParameterAnnotation parameterAnnotation: parameterAnnotations) {
parameterAnnotationMethods[index] = parameterAnnotation.method;
parameterAnnotationsArray[index++] = parameterAnnotation.annotationSet;
}
}
AnnotationDirectoryItem annotationDirectoryItem = new AnnotationDirectoryItem(dexFile, classAnnotations,
fieldAnnotationFields, fieldAnnotationsArray, methodAnnotationMethods, methodAnnotationsArray,
parameterAnnotationMethods, parameterAnnotationsArray);
return dexFile.AnnotationDirectoriesSection.intern(annotationDirectoryItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
classAnnotations = (AnnotationSetItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_ANNOTATION_SET_ITEM,
in.readInt());
fieldAnnotationFields = new FieldIdItem[in.readInt()];
fieldAnnotations = new AnnotationSetItem[fieldAnnotationFields.length];
methodAnnotationMethods = new MethodIdItem[in.readInt()];
methodAnnotations = new AnnotationSetItem[methodAnnotationMethods.length];
parameterAnnotationMethods = new MethodIdItem[in.readInt()];
parameterAnnotations = new AnnotationSetRefList[parameterAnnotationMethods.length];
for (int i=0; i<fieldAnnotations.length; i++) {
fieldAnnotationFields[i] = dexFile.FieldIdsSection.getItemByIndex(in.readInt());
fieldAnnotations[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
}
for (int i=0; i<methodAnnotations.length; i++) {
methodAnnotationMethods[i] = dexFile.MethodIdsSection.getItemByIndex(in.readInt());
methodAnnotations[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
}
for (int i=0; i<parameterAnnotations.length; i++) {
parameterAnnotationMethods[i] = dexFile.MethodIdsSection.getItemByIndex(in.readInt());
parameterAnnotations[i] = (AnnotationSetRefList)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATION_SET_REF_LIST, in.readInt());
}
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 16 + (
(fieldAnnotations==null?0:fieldAnnotations.length) +
(methodAnnotations==null?0:methodAnnotations.length) +
(parameterAnnotations==null?0:parameterAnnotations.length)) * 8;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
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:");
}
int length = fieldAnnotations==null?0:fieldAnnotations.length;
out.annotate(4, "annotated_fields_size: 0x" + Integer.toHexString(length) + " (" +
length + ")");
length = methodAnnotations==null?0:methodAnnotations.length;
out.annotate(4, "annotated_methods_size: 0x" + Integer.toHexString(length) + " (" +
length + ")");
length = parameterAnnotations==null?0:parameterAnnotations.length;
out.annotate(4, "annotated_parameters_size: 0x" + Integer.toHexString(length) + " (" +
length + ")");
int index;
if (fieldAnnotations != null) {
index = 0;
for (int i=0; i<fieldAnnotations.length; i++) {
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();
}
}
if (methodAnnotations != null) {
index = 0;
for (int i=0; i<methodAnnotations.length; i++) {
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();
}
}
if (parameterAnnotations != null) {
index = 0;
for (int i=0; i<parameterAnnotations.length; i++) {
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()));
}
}
}
out.writeInt(classAnnotations==null?0:classAnnotations.getOffset());
out.writeInt(fieldAnnotations==null?0:fieldAnnotations.length);
out.writeInt(methodAnnotations==null?0:methodAnnotations.length);
out.writeInt(parameterAnnotations==null?0:parameterAnnotations.length);
if (fieldAnnotations != null) {
for (int i=0; i<fieldAnnotations.length; i++) {
out.writeInt(fieldAnnotationFields[i].getIndex());
out.writeInt(fieldAnnotations[i].getOffset());
}
}
if (methodAnnotations != null) {
for (int i=0; i<methodAnnotations.length; i++) {
out.writeInt(methodAnnotationMethods[i].getIndex());
out.writeInt(methodAnnotations[i].getOffset());
}
}
if (parameterAnnotations != null) {
for (int i=0; i<parameterAnnotations.length; i++) {
out.writeInt(parameterAnnotationMethods[i].getIndex());
out.writeInt(parameterAnnotations[i].getOffset());
}
}
}
/** {@inheritDoc} */public ItemType getItemType() {
return ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "annotation_directory_item @0x" + Integer.toHexString(getOffset());
}
/** {@inheritDoc} */
public int compareTo(AnnotationDirectoryItem o) {
if (!isInternable()) {
if (!o.isInternable()) {
return parent.compareTo(o.parent);
}
return -1;
}
if (!o.isInternable()) {
return 1;
}
return classAnnotations.compareTo(o.classAnnotations);
}
/**
* @return The annotations associated with the class
*/
public AnnotationSetItem getClassAnnotations() {
return classAnnotations;
}
/**
* Iterates over the field annotations, calling delegate.processFieldAnnotations for each
* @param delegate the delegate to call
*/
public void iterateFieldAnnotations(FieldAnnotationIteratorDelegate delegate) {
for (int i=0; i<fieldAnnotationFields.length; i++) {
delegate.processFieldAnnotations(fieldAnnotationFields[i], fieldAnnotations[i]);
}
}
public static interface FieldAnnotationIteratorDelegate {
void processFieldAnnotations(FieldIdItem field, AnnotationSetItem fieldAnnotations);
}
/**
* @return the number of field annotations in this <code>AnnotationDirectoryItem</code>
*/
public int getFieldAnnotationCount() {
return fieldAnnotationFields.length;
}
/**
* Iterates over the method annotations, calling delegate.processMethodAnnotations for each
* @param delegate the delegate to call
*/
public void iterateMethodAnnotations(MethodAnnotationIteratorDelegate delegate) {
for (int i=0; i<methodAnnotationMethods.length; i++) {
delegate.processMethodAnnotations(methodAnnotationMethods[i], methodAnnotations[i]);
}
}
public static interface MethodAnnotationIteratorDelegate {
void processMethodAnnotations(MethodIdItem method, AnnotationSetItem methodAnnotations);
}
/**
* @return the number of method annotations in this <code>AnnotationDirectoryItem</code>
*/
public int getMethodAnnotationCount() {
return methodAnnotationMethods.length;
}
/**
* Iterates over the parameter annotations, calling delegate.processParameterAnnotations for each
* @param delegate the delegate to call
*/
public void iterateParameterAnnotations(ParameterAnnotationIteratorDelegate delegate) {
for (int i=0; i<parameterAnnotationMethods.length; i++) {
delegate.processParameterAnnotations(parameterAnnotationMethods[i], parameterAnnotations[i]);
}
}
public static interface ParameterAnnotationIteratorDelegate {
void processParameterAnnotations(MethodIdItem method, AnnotationSetRefList parameterAnnotations);
}
/**
* @return the number of parameter annotations in this <code>AnnotationDirectoryItem</code>
*/
public int getParameterAnnotationCount() {
return parameterAnnotationMethods.length;
}
/**
* @return true if this <code>AnnotationDirectoryItem</code> is internable. It is only internable if it has
* only class annotations, but no field, method or parameter annotations
*/
private boolean isInternable() {
return classAnnotations != null &&
(fieldAnnotations == null || fieldAnnotations.length == 0) &&
(methodAnnotations == null || methodAnnotations.length == 0) &&
(parameterAnnotations == null || parameterAnnotations.length == 0);
}
/**
* Sets the <code>ClassDefItem</code> that this <code>AnnotationDirectoryItem</code> is associated with.
* This is only applicable if this AnnotationDirectoryItem contains only class annotations, and no field, method
* or parameter annotations.
* @param classDefItem the <code>ClassDefItem</code> that this <code>AnnotationDirectoryItem</code> is associated
* with
*/
protected void setParent(ClassDefItem classDefItem) {
this.parent = classDefItem;
}
@Override
public int hashCode() {
//an instance is only internable if it has only class annotations, but
//no other type of annotation
if (!isInternable()) {
return super.hashCode();
}
return classAnnotations.hashCode();
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
AnnotationDirectoryItem other = (AnnotationDirectoryItem)o;
return (this.compareTo(other) == 0);
}
public static class FieldAnnotation implements Comparable<FieldAnnotation> {
public final FieldIdItem field;
public final AnnotationSetItem annotationSet;
public FieldAnnotation(FieldIdItem field, AnnotationSetItem annotationSet) {
this.field = field;
this.annotationSet = annotationSet;
}
public int compareTo(FieldAnnotation other) {
return field.compareTo(other.field);
}
}
public static class MethodAnnotation implements Comparable<MethodAnnotation> {
public final MethodIdItem method;
public final AnnotationSetItem annotationSet;
public MethodAnnotation(MethodIdItem method, AnnotationSetItem annotationSet) {
this.method = method;
this.annotationSet = annotationSet;
}
public int compareTo(MethodAnnotation other) {
return method.compareTo(other.method);
}
}
public static class ParameterAnnotation implements Comparable<ParameterAnnotation> {
public final MethodIdItem method;
public final AnnotationSetRefList annotationSet;
public ParameterAnnotation(MethodIdItem method, AnnotationSetRefList annotationSet) {
this.method = method;
this.annotationSet = annotationSet;
}
public int compareTo(ParameterAnnotation other) {
return method.compareTo(other.method);
}
}
}

View File

@ -1,162 +1,162 @@
/*
* [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;
import org.jf.dexlib.EncodedValue.AnnotationEncodedSubValue;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class AnnotationItem extends Item<AnnotationItem> {
private int hashCode = 0;
private AnnotationVisibility visibility;
private AnnotationEncodedSubValue annotationValue;
/**
* Creates a new uninitialized <code>AnnotationItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected AnnotationItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>AnnotationItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param visibility The visibility of this annotation
* @param annotationValue The value of this annotation
*/
private AnnotationItem(DexFile dexFile, AnnotationVisibility visibility,
AnnotationEncodedSubValue annotationValue) {
super(dexFile);
this.visibility = visibility;
this.annotationValue = annotationValue;
}
/**
* Returns an <code>AnnotationItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param visibility The visibility of this annotation
* @param annotationValue The value of this annotation
* @return an <code>AnnotationItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
*/
public static AnnotationItem getInternedAnnotationItem(DexFile dexFile, AnnotationVisibility visibility,
AnnotationEncodedSubValue annotationValue) {
AnnotationItem annotationItem = new AnnotationItem(dexFile, visibility, annotationValue);
return dexFile.AnnotationsSection.intern(annotationItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
visibility = AnnotationVisibility.fromByte(in.readByte());
annotationValue = new AnnotationEncodedSubValue(dexFile, in);
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return annotationValue.placeValue(offset + 1);
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate("visibility: " + visibility.name());
out.writeByte(visibility.value);
annotationValue.writeValue(out);
}else {
out.writeByte(visibility.value);
annotationValue.writeValue(out);
}
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_ANNOTATION_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "annotation_item @0x" + Integer.toHexString(getOffset());
}
/** {@inheritDoc} */
public int compareTo(AnnotationItem o) {
int comp = visibility.value - o.visibility.value;
if (comp == 0) {
comp = annotationValue.compareTo(o.annotationValue);
}
return comp;
}
/**
* @return The visibility of this annotation
*/
public AnnotationVisibility getVisibility() {
return visibility;
}
/**
* @return The encoded annotation value of this annotation
*/
public AnnotationEncodedSubValue getEncodedAnnotation() {
return annotationValue;
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = visibility.value;
hashCode = hashCode * 31 + annotationValue.hashCode();
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
AnnotationItem other = (AnnotationItem)o;
return visibility == other.visibility && annotationValue.equals(other.annotationValue);
}
}
/*
* [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;
import org.jf.dexlib.EncodedValue.AnnotationEncodedSubValue;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class AnnotationItem extends Item<AnnotationItem> {
private int hashCode = 0;
private AnnotationVisibility visibility;
private AnnotationEncodedSubValue annotationValue;
/**
* Creates a new uninitialized <code>AnnotationItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected AnnotationItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>AnnotationItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param visibility The visibility of this annotation
* @param annotationValue The value of this annotation
*/
private AnnotationItem(DexFile dexFile, AnnotationVisibility visibility,
AnnotationEncodedSubValue annotationValue) {
super(dexFile);
this.visibility = visibility;
this.annotationValue = annotationValue;
}
/**
* Returns an <code>AnnotationItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param visibility The visibility of this annotation
* @param annotationValue The value of this annotation
* @return an <code>AnnotationItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
*/
public static AnnotationItem getInternedAnnotationItem(DexFile dexFile, AnnotationVisibility visibility,
AnnotationEncodedSubValue annotationValue) {
AnnotationItem annotationItem = new AnnotationItem(dexFile, visibility, annotationValue);
return dexFile.AnnotationsSection.intern(annotationItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
visibility = AnnotationVisibility.fromByte(in.readByte());
annotationValue = new AnnotationEncodedSubValue(dexFile, in);
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return annotationValue.placeValue(offset + 1);
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate("visibility: " + visibility.name());
out.writeByte(visibility.value);
annotationValue.writeValue(out);
}else {
out.writeByte(visibility.value);
annotationValue.writeValue(out);
}
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_ANNOTATION_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "annotation_item @0x" + Integer.toHexString(getOffset());
}
/** {@inheritDoc} */
public int compareTo(AnnotationItem o) {
int comp = visibility.value - o.visibility.value;
if (comp == 0) {
comp = annotationValue.compareTo(o.annotationValue);
}
return comp;
}
/**
* @return The visibility of this annotation
*/
public AnnotationVisibility getVisibility() {
return visibility;
}
/**
* @return The encoded annotation value of this annotation
*/
public AnnotationEncodedSubValue getEncodedAnnotation() {
return annotationValue;
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = visibility.value;
hashCode = hashCode * 31 + annotationValue.hashCode();
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
AnnotationItem other = (AnnotationItem)o;
return visibility == other.visibility && annotationValue.equals(other.annotationValue);
}
}

View File

@ -1,169 +1,169 @@
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
import java.util.List;
public class AnnotationSetItem extends Item<AnnotationSetItem> {
private int hashCode = 0;
private AnnotationItem[] annotations;
/**
* Creates a new uninitialized <code>AnnotationSetItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected AnnotationSetItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>AnnotationSetItem</code> for the given annotations
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param annotations The annotations for this <code>AnnotationSetItem</code>
*/
private AnnotationSetItem(DexFile dexFile, AnnotationItem[] annotations) {
super(dexFile);
this.annotations = annotations;
}
/**
* Returns an <code>AnnotationSetItem</code> for the given annotations, and that has been interned into the given
* <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param annotations The annotations for this <code>AnnotationSetItem</code>
* @return an <code>AnnotationSetItem</code> for the given annotations
*/
public static AnnotationSetItem getInternedAnnotationSetItem(DexFile dexFile, List<AnnotationItem> annotations) {
AnnotationItem[] annotationsArray = new AnnotationItem[annotations.size()];
annotations.toArray(annotationsArray);
AnnotationSetItem annotationSetItem = new AnnotationSetItem(dexFile, annotationsArray);
return dexFile.AnnotationSetsSection.intern(annotationSetItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
annotations = new AnnotationItem[in.readInt()];
for (int i=0; i<annotations.length; i++) {
annotations[i] = (AnnotationItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_ANNOTATION_ITEM,
in.readInt());
}
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 4 + annotations.length * 4;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
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);
for (AnnotationItem annotationItem: annotations) {
out.writeInt(annotationItem.getOffset());
}
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_ANNOTATION_SET_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "annotation_set_item @0x" + Integer.toHexString(getOffset());
}
/** {@inheritDoc} */
public int compareTo(AnnotationSetItem o) {
if (o == null) {
return 1;
}
int comp = annotations.length - o.annotations.length;
if (comp == 0) {
for (int i=0; i<annotations.length; i++) {
comp = annotations[i].compareTo(o.annotations[i]);
if (comp != 0) {
return comp;
}
}
}
return comp;
}
/**
* @return An array of the <code>AnnotationItem</code> objects in this <code>AnnotationSetItem</code>
*/
public AnnotationItem[] getAnnotations() {
return annotations;
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = 0;
for (AnnotationItem annotationItem: annotations) {
hashCode = hashCode * 31 + annotationItem.hashCode();
}
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
AnnotationSetItem other = (AnnotationSetItem)o;
return (this.compareTo(other) == 0);
}
}
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
import java.util.List;
public class AnnotationSetItem extends Item<AnnotationSetItem> {
private int hashCode = 0;
private AnnotationItem[] annotations;
/**
* Creates a new uninitialized <code>AnnotationSetItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected AnnotationSetItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>AnnotationSetItem</code> for the given annotations
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param annotations The annotations for this <code>AnnotationSetItem</code>
*/
private AnnotationSetItem(DexFile dexFile, AnnotationItem[] annotations) {
super(dexFile);
this.annotations = annotations;
}
/**
* Returns an <code>AnnotationSetItem</code> for the given annotations, and that has been interned into the given
* <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param annotations The annotations for this <code>AnnotationSetItem</code>
* @return an <code>AnnotationSetItem</code> for the given annotations
*/
public static AnnotationSetItem getInternedAnnotationSetItem(DexFile dexFile, List<AnnotationItem> annotations) {
AnnotationItem[] annotationsArray = new AnnotationItem[annotations.size()];
annotations.toArray(annotationsArray);
AnnotationSetItem annotationSetItem = new AnnotationSetItem(dexFile, annotationsArray);
return dexFile.AnnotationSetsSection.intern(annotationSetItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
annotations = new AnnotationItem[in.readInt()];
for (int i=0; i<annotations.length; i++) {
annotations[i] = (AnnotationItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_ANNOTATION_ITEM,
in.readInt());
}
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 4 + annotations.length * 4;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
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);
for (AnnotationItem annotationItem: annotations) {
out.writeInt(annotationItem.getOffset());
}
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_ANNOTATION_SET_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "annotation_set_item @0x" + Integer.toHexString(getOffset());
}
/** {@inheritDoc} */
public int compareTo(AnnotationSetItem o) {
if (o == null) {
return 1;
}
int comp = annotations.length - o.annotations.length;
if (comp == 0) {
for (int i=0; i<annotations.length; i++) {
comp = annotations[i].compareTo(o.annotations[i]);
if (comp != 0) {
return comp;
}
}
}
return comp;
}
/**
* @return An array of the <code>AnnotationItem</code> objects in this <code>AnnotationSetItem</code>
*/
public AnnotationItem[] getAnnotations() {
return annotations;
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = 0;
for (AnnotationItem annotationItem: annotations) {
hashCode = hashCode * 31 + annotationItem.hashCode();
}
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
AnnotationSetItem other = (AnnotationSetItem)o;
return (this.compareTo(other) == 0);
}
}

View File

@ -1,170 +1,170 @@
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
import java.util.List;
public class AnnotationSetRefList extends Item<AnnotationSetRefList> {
private int hashCode = 0;
private AnnotationSetItem[] annotationSets;
/**
* Creates a new uninitialized <code>AnnotationSetRefList</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected AnnotationSetRefList(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>AnnotationSetRefList</code> for the given annotation sets
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param annotationSets The annotationSets for this <code>AnnotationSetRefList</code>
*/
private AnnotationSetRefList(DexFile dexFile, AnnotationSetItem[] annotationSets) {
super(dexFile);
this.annotationSets = annotationSets;
}
/**
* Returns an <code>AnnotationSetRefList</code> for the given annotation sets, and that has been interned into the
* given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param annotationSets The annotation sets for this <code>AnnotationSetRefList</code>
* @return an <code>AnnotationSetItem</code> for the given annotations
*/
public static AnnotationSetRefList getInternedAnnotationSetRefList(DexFile dexFile,
List<AnnotationSetItem> annotationSets) {
AnnotationSetItem[] annotationSetsArray = new AnnotationSetItem[annotationSets.size()];
annotationSets.toArray(annotationSetsArray);
AnnotationSetRefList annotationSetRefList = new AnnotationSetRefList(dexFile, annotationSetsArray);
return dexFile.AnnotationSetRefListsSection.intern(annotationSetRefList);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
annotationSets = new AnnotationSetItem[in.readInt()];
for (int i=0; i<annotationSets.length; i++) {
annotationSets[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
}
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 4 + annotationSets.length * 4;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(4, "size: 0x" + Integer.toHexString(annotationSets.length) + " (" + annotationSets.length +
")");
for (AnnotationSetItem annotationSetItem: annotationSets) {
out.annotate(4, "annotation_set_off: 0x" + Integer.toHexString(annotationSetItem.getOffset()));
}
}
out.writeInt(annotationSets.length);
for (AnnotationSetItem annotationSetItem: annotationSets) {
out.writeInt(annotationSetItem.getOffset());
}
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_ANNOTATION_SET_REF_LIST;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "annotation_set_item @0x" + Integer.toHexString(getOffset());
}
/** {@inheritDoc} */
public int compareTo(AnnotationSetRefList o) {
int comp = annotationSets.length - o.annotationSets.length;
if (comp != 0) {
return comp;
}
for (int i=0; i<annotationSets.length; i++) {
comp = annotationSets[i].compareTo(o.annotationSets[i]);
if (comp != 0) {
return comp;
}
}
return comp;
}
/**
* @return An array of the <code>AnnotationSetItem</code> objects that make up this
* <code>AnnotationSetRefList</code>
*/
public AnnotationSetItem[] getAnnotationSets() {
return annotationSets;
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = 0;
for (AnnotationSetItem annotationSetItem: annotationSets) {
hashCode = hashCode * 31 + annotationSetItem.hashCode();
}
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
AnnotationSetRefList other = (AnnotationSetRefList)o;
return (this.compareTo(other) == 0);
}
}
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
import java.util.List;
public class AnnotationSetRefList extends Item<AnnotationSetRefList> {
private int hashCode = 0;
private AnnotationSetItem[] annotationSets;
/**
* Creates a new uninitialized <code>AnnotationSetRefList</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected AnnotationSetRefList(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>AnnotationSetRefList</code> for the given annotation sets
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param annotationSets The annotationSets for this <code>AnnotationSetRefList</code>
*/
private AnnotationSetRefList(DexFile dexFile, AnnotationSetItem[] annotationSets) {
super(dexFile);
this.annotationSets = annotationSets;
}
/**
* Returns an <code>AnnotationSetRefList</code> for the given annotation sets, and that has been interned into the
* given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param annotationSets The annotation sets for this <code>AnnotationSetRefList</code>
* @return an <code>AnnotationSetItem</code> for the given annotations
*/
public static AnnotationSetRefList getInternedAnnotationSetRefList(DexFile dexFile,
List<AnnotationSetItem> annotationSets) {
AnnotationSetItem[] annotationSetsArray = new AnnotationSetItem[annotationSets.size()];
annotationSets.toArray(annotationSetsArray);
AnnotationSetRefList annotationSetRefList = new AnnotationSetRefList(dexFile, annotationSetsArray);
return dexFile.AnnotationSetRefListsSection.intern(annotationSetRefList);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
annotationSets = new AnnotationSetItem[in.readInt()];
for (int i=0; i<annotationSets.length; i++) {
annotationSets[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
}
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 4 + annotationSets.length * 4;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(4, "size: 0x" + Integer.toHexString(annotationSets.length) + " (" + annotationSets.length +
")");
for (AnnotationSetItem annotationSetItem: annotationSets) {
out.annotate(4, "annotation_set_off: 0x" + Integer.toHexString(annotationSetItem.getOffset()));
}
}
out.writeInt(annotationSets.length);
for (AnnotationSetItem annotationSetItem: annotationSets) {
out.writeInt(annotationSetItem.getOffset());
}
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_ANNOTATION_SET_REF_LIST;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "annotation_set_item @0x" + Integer.toHexString(getOffset());
}
/** {@inheritDoc} */
public int compareTo(AnnotationSetRefList o) {
int comp = annotationSets.length - o.annotationSets.length;
if (comp != 0) {
return comp;
}
for (int i=0; i<annotationSets.length; i++) {
comp = annotationSets[i].compareTo(o.annotationSets[i]);
if (comp != 0) {
return comp;
}
}
return comp;
}
/**
* @return An array of the <code>AnnotationSetItem</code> objects that make up this
* <code>AnnotationSetRefList</code>
*/
public AnnotationSetItem[] getAnnotationSets() {
return annotationSets;
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = 0;
for (AnnotationSetItem annotationSetItem: annotationSets) {
hashCode = hashCode * 31 + annotationSetItem.hashCode();
}
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
AnnotationSetRefList other = (AnnotationSetRefList)o;
return (this.compareTo(other) == 0);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,377 +1,377 @@
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.AccessFlags;
import org.jf.dexlib.Util.TypeUtils;
import org.jf.dexlib.EncodedValue.EncodedValue;
import org.jf.dexlib.EncodedValue.ArrayEncodedSubValue;
import java.util.*;
public class ClassDefItem extends Item<ClassDefItem> {
private TypeIdItem classType;
private int accessFlags;
private TypeIdItem superType;
private TypeListItem implementedInterfaces;
private StringIdItem sourceFile;
private AnnotationDirectoryItem annotations;
private ClassDataItem classData;
private EncodedArrayItem staticFieldInitializers;
/**
* Creates a new uninitialized <code>ClassDefItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected ClassDefItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>ClassDefItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType The type of this class
* @param accessFlags The access flags of this class
* @param superType The superclass of this class, or null if none (only valid for java.lang.Object)
* @param implementedInterfaces A list of the interfaces that this class implements, or null if none
* @param sourceFile The main source file that this class is defined in, or null if not available
* @param annotations The annotations for this class and its fields, methods and method parameters, or null if none
* @param classData The <code>ClassDataItem</code> containing the method and field definitions for this class
* @param staticFieldInitializers The initial values for this class's static fields, or null if none. The initial
* values should be in the same order as the static fields in the <code>ClassDataItem</code>. It can contain
* fewer items than static fields, in which case the remaining static fields will be initialized with a default
* value of null/0. The initial value for any fields that don't specifically have a value can be either the
* type-appropriate null/0 encoded value, or null.
*/
private ClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags, TypeIdItem superType,
TypeListItem implementedInterfaces, StringIdItem sourceFile,
AnnotationDirectoryItem annotations, ClassDataItem classData,
EncodedArrayItem staticFieldInitializers) {
super(dexFile);
this.classType = classType;
this.accessFlags = accessFlags;
this.superType = superType;
this.implementedInterfaces = implementedInterfaces;
this.sourceFile = sourceFile;
this.annotations = annotations;
this.classData = classData;
this.staticFieldInitializers = staticFieldInitializers;
if (classData != null) {
classData.setParent(this);
}
if (annotations != null) {
annotations.setParent(this);
}
}
/**
* Returns a <code>ClassDefItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType The type of this class
* @param accessFlags The access flags of this class
* @param superType The superclass of this class, or null if none (only valid for java.lang.Object)
* @param implementedInterfaces A list of the interfaces that this class implements, or null if none
* @param sourceFile The main source file that this class is defined in, or null if not available
* @param annotations The annotations for this class and its fields, methods and method parameters, or null if none
* @param classData The <code>ClassDataItem</code> containing the method and field definitions for this class
* @param staticFieldInitializers The initial values for this class's static fields, or null if none. If it is not
* null, it must contain the same number of items as the number of static fields in this class. The value in the
* <code>StaticFieldInitializer</code> for any field that doesn't have an explicit initial value can either be null
* or be the type-appropriate null/0 value.
* @return a <code>ClassDefItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
*/
public static ClassDefItem getInternedClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags,
TypeIdItem superType, TypeListItem implementedInterfaces, StringIdItem sourceFile,
AnnotationDirectoryItem annotations, ClassDataItem classData,
List<StaticFieldInitializer> staticFieldInitializers) {
EncodedArrayItem encodedArrayItem = null;
if(!dexFile.getInplace() && staticFieldInitializers != null && staticFieldInitializers.size() > 0) {
assert classData != null;
assert staticFieldInitializers.size() == classData.getStaticFields().length;
encodedArrayItem = makeStaticFieldInitializersItem(dexFile, staticFieldInitializers);
}
ClassDefItem classDefItem = new ClassDefItem(dexFile, classType, accessFlags, superType, implementedInterfaces,
sourceFile, annotations, classData, encodedArrayItem);
return dexFile.ClassDefsSection.intern(classDefItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
classType = dexFile.TypeIdsSection.getItemByIndex(in.readInt());
accessFlags = in.readInt();
superType = dexFile.TypeIdsSection.getItemByIndex(in.readInt());
implementedInterfaces = (TypeListItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_TYPE_LIST,
in.readInt());
sourceFile = dexFile.StringIdsSection.getItemByIndex(in.readInt());
annotations = (AnnotationDirectoryItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM, in.readInt());
classData = (ClassDataItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_CLASS_DATA_ITEM, in.readInt());
staticFieldInitializers = (EncodedArrayItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ENCODED_ARRAY_ITEM, in.readInt());
if (classData != null) {
classData.setParent(this);
}
if (annotations != null) {
annotations.setParent(this);
}
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 32;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
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);
out.writeInt(superType==null?-1:superType.getIndex());
out.writeInt(implementedInterfaces==null?0:implementedInterfaces.getOffset());
out.writeInt(sourceFile==null?-1:sourceFile.getIndex());
out.writeInt(annotations==null?0:annotations.getOffset());
out.writeInt(classData==null?0:classData.getOffset());
out.writeInt(staticFieldInitializers==null?0:staticFieldInitializers.getOffset());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_CLASS_DEF_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "class_def_item: " + classType.getTypeDescriptor();
}
/** {@inheritDoc} */
public int compareTo(ClassDefItem o) {
//The actual sorting for this class is implemented in SortClassDefItemSection.
//This method is just used for sorting the associated ClassDataItem items, so
//we can just do the comparison based on the offsets of the items
return this.getOffset() - o.getOffset();
}
public TypeIdItem getClassType() {
return classType;
}
public int getAccessFlags() {
return accessFlags;
}
public TypeIdItem getSuperclass() {
return superType;
}
public TypeListItem getInterfaces() {
return implementedInterfaces;
}
public StringIdItem getSourceFile() {
return sourceFile;
}
public AnnotationDirectoryItem getAnnotations() {
return annotations;
}
public ClassDataItem getClassData() {
return classData;
}
public EncodedArrayItem getStaticFieldInitializers() {
return staticFieldInitializers;
}
public static int placeClassDefItems(IndexedSection<ClassDefItem> section, int offset) {
ClassDefPlacer cdp = new ClassDefPlacer(section);
return cdp.placeSection(offset);
}
/**
* This class places the items within a ClassDefItem section, such that superclasses and interfaces are
* placed before sub/implementing classes
*/
private static class ClassDefPlacer {
private final IndexedSection<ClassDefItem> section;
private final HashMap<TypeIdItem, ClassDefItem> unplacedClassDefsByType =
new HashMap<TypeIdItem, ClassDefItem>();
private int currentIndex = 0;
private int currentOffset;
public ClassDefPlacer(IndexedSection<ClassDefItem> section) {
this.section = section;
for (ClassDefItem classDefItem: section.items) {
TypeIdItem typeIdItem = classDefItem.classType;
unplacedClassDefsByType.put(typeIdItem, classDefItem);
}
}
public int placeSection(int offset) {
currentOffset = offset;
if (section.DexFile.getSortAllItems()) {
//presort the list, to guarantee a unique ordering
Collections.sort(section.items, new Comparator<ClassDefItem>() {
public int compare(ClassDefItem a, ClassDefItem b) {
return a.getClassType().compareTo(b.getClassType());
}
});
}
//we need to initialize the offset for all the classes to -1, so we can tell which ones
//have been placed
for (ClassDefItem classDefItem: section.items) {
classDefItem.offset = -1;
}
for (ClassDefItem classDefItem: section.items) {
placeClass(classDefItem);
}
for (ClassDefItem classDefItem: unplacedClassDefsByType.values()) {
section.items.set(classDefItem.getIndex(), classDefItem);
}
return currentOffset;
}
private void placeClass(ClassDefItem classDefItem) {
if (classDefItem.getOffset() == -1) {
TypeIdItem superType = classDefItem.superType;
ClassDefItem superClassDefItem = unplacedClassDefsByType.get(superType);
if (superClassDefItem != null) {
placeClass(superClassDefItem);
}
TypeListItem interfaces = classDefItem.implementedInterfaces;
if (interfaces != null) {
for (TypeIdItem interfaceType: interfaces.getTypes()) {
ClassDefItem interfaceClass = unplacedClassDefsByType.get(interfaceType);
if (interfaceClass != null) {
placeClass(interfaceClass);
}
}
}
currentOffset = classDefItem.placeAt(currentOffset, currentIndex++);
unplacedClassDefsByType.remove(classDefItem.classType);
}
}
}
public static class StaticFieldInitializer implements Comparable<StaticFieldInitializer> {
public final EncodedValue value;
public final ClassDataItem.EncodedField field;
public StaticFieldInitializer(EncodedValue value, ClassDataItem.EncodedField field) {
this.value = value;
this.field = field;
}
public int compareTo(StaticFieldInitializer other) {
return field.compareTo(other.field);
}
}
/**
* A helper method to sort the static field initializers and populate the default values as needed
* @param dexFile the <code>DexFile</code>
* @param staticFieldInitializers the initial values
* @return an interned EncodedArrayItem containing the static field initializers
*/
private static EncodedArrayItem makeStaticFieldInitializersItem(DexFile dexFile,
List<StaticFieldInitializer> staticFieldInitializers) {
if (staticFieldInitializers == null || staticFieldInitializers.size() == 0) {
return null;
}
int len = staticFieldInitializers.size();
Collections.sort(staticFieldInitializers);
int lastIndex = -1;
for (int i=len-1; i>=0; i--) {
StaticFieldInitializer staticFieldInitializer = staticFieldInitializers.get(i);
if (staticFieldInitializer.value != null &&
(staticFieldInitializer.value.compareTo(TypeUtils.makeDefaultValueForType(dexFile,
staticFieldInitializer.field.field.getFieldType().getTypeDescriptor())) != 0)) {
lastIndex = i;
break;
}
}
//we don't have any non-null/non-default values, so we don't need to create an EncodedArrayItem
if (lastIndex == -1) {
return null;
}
EncodedValue[] values = new EncodedValue[lastIndex+1];
for (int i=0; i<=lastIndex; i++) {
StaticFieldInitializer staticFieldInitializer = staticFieldInitializers.get(i);
EncodedValue encodedValue = staticFieldInitializer.value;
if (encodedValue == null) {
encodedValue = TypeUtils.makeDefaultValueForType(dexFile,
staticFieldInitializer.field.field.getFieldType().getTypeDescriptor());
}
values[i] = encodedValue;
}
ArrayEncodedSubValue encodedArrayValue = new ArrayEncodedSubValue(values);
return EncodedArrayItem.getInternedEncodedArrayItem(dexFile, encodedArrayValue);
}
}
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.AccessFlags;
import org.jf.dexlib.Util.TypeUtils;
import org.jf.dexlib.EncodedValue.EncodedValue;
import org.jf.dexlib.EncodedValue.ArrayEncodedSubValue;
import java.util.*;
public class ClassDefItem extends Item<ClassDefItem> {
private TypeIdItem classType;
private int accessFlags;
private TypeIdItem superType;
private TypeListItem implementedInterfaces;
private StringIdItem sourceFile;
private AnnotationDirectoryItem annotations;
private ClassDataItem classData;
private EncodedArrayItem staticFieldInitializers;
/**
* Creates a new uninitialized <code>ClassDefItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected ClassDefItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>ClassDefItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType The type of this class
* @param accessFlags The access flags of this class
* @param superType The superclass of this class, or null if none (only valid for java.lang.Object)
* @param implementedInterfaces A list of the interfaces that this class implements, or null if none
* @param sourceFile The main source file that this class is defined in, or null if not available
* @param annotations The annotations for this class and its fields, methods and method parameters, or null if none
* @param classData The <code>ClassDataItem</code> containing the method and field definitions for this class
* @param staticFieldInitializers The initial values for this class's static fields, or null if none. The initial
* values should be in the same order as the static fields in the <code>ClassDataItem</code>. It can contain
* fewer items than static fields, in which case the remaining static fields will be initialized with a default
* value of null/0. The initial value for any fields that don't specifically have a value can be either the
* type-appropriate null/0 encoded value, or null.
*/
private ClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags, TypeIdItem superType,
TypeListItem implementedInterfaces, StringIdItem sourceFile,
AnnotationDirectoryItem annotations, ClassDataItem classData,
EncodedArrayItem staticFieldInitializers) {
super(dexFile);
this.classType = classType;
this.accessFlags = accessFlags;
this.superType = superType;
this.implementedInterfaces = implementedInterfaces;
this.sourceFile = sourceFile;
this.annotations = annotations;
this.classData = classData;
this.staticFieldInitializers = staticFieldInitializers;
if (classData != null) {
classData.setParent(this);
}
if (annotations != null) {
annotations.setParent(this);
}
}
/**
* Returns a <code>ClassDefItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType The type of this class
* @param accessFlags The access flags of this class
* @param superType The superclass of this class, or null if none (only valid for java.lang.Object)
* @param implementedInterfaces A list of the interfaces that this class implements, or null if none
* @param sourceFile The main source file that this class is defined in, or null if not available
* @param annotations The annotations for this class and its fields, methods and method parameters, or null if none
* @param classData The <code>ClassDataItem</code> containing the method and field definitions for this class
* @param staticFieldInitializers The initial values for this class's static fields, or null if none. If it is not
* null, it must contain the same number of items as the number of static fields in this class. The value in the
* <code>StaticFieldInitializer</code> for any field that doesn't have an explicit initial value can either be null
* or be the type-appropriate null/0 value.
* @return a <code>ClassDefItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
*/
public static ClassDefItem getInternedClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags,
TypeIdItem superType, TypeListItem implementedInterfaces, StringIdItem sourceFile,
AnnotationDirectoryItem annotations, ClassDataItem classData,
List<StaticFieldInitializer> staticFieldInitializers) {
EncodedArrayItem encodedArrayItem = null;
if(!dexFile.getInplace() && staticFieldInitializers != null && staticFieldInitializers.size() > 0) {
assert classData != null;
assert staticFieldInitializers.size() == classData.getStaticFields().length;
encodedArrayItem = makeStaticFieldInitializersItem(dexFile, staticFieldInitializers);
}
ClassDefItem classDefItem = new ClassDefItem(dexFile, classType, accessFlags, superType, implementedInterfaces,
sourceFile, annotations, classData, encodedArrayItem);
return dexFile.ClassDefsSection.intern(classDefItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
classType = dexFile.TypeIdsSection.getItemByIndex(in.readInt());
accessFlags = in.readInt();
superType = dexFile.TypeIdsSection.getItemByIndex(in.readInt());
implementedInterfaces = (TypeListItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_TYPE_LIST,
in.readInt());
sourceFile = dexFile.StringIdsSection.getItemByIndex(in.readInt());
annotations = (AnnotationDirectoryItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM, in.readInt());
classData = (ClassDataItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_CLASS_DATA_ITEM, in.readInt());
staticFieldInitializers = (EncodedArrayItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ENCODED_ARRAY_ITEM, in.readInt());
if (classData != null) {
classData.setParent(this);
}
if (annotations != null) {
annotations.setParent(this);
}
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 32;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
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);
out.writeInt(superType==null?-1:superType.getIndex());
out.writeInt(implementedInterfaces==null?0:implementedInterfaces.getOffset());
out.writeInt(sourceFile==null?-1:sourceFile.getIndex());
out.writeInt(annotations==null?0:annotations.getOffset());
out.writeInt(classData==null?0:classData.getOffset());
out.writeInt(staticFieldInitializers==null?0:staticFieldInitializers.getOffset());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_CLASS_DEF_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "class_def_item: " + classType.getTypeDescriptor();
}
/** {@inheritDoc} */
public int compareTo(ClassDefItem o) {
//The actual sorting for this class is implemented in SortClassDefItemSection.
//This method is just used for sorting the associated ClassDataItem items, so
//we can just do the comparison based on the offsets of the items
return this.getOffset() - o.getOffset();
}
public TypeIdItem getClassType() {
return classType;
}
public int getAccessFlags() {
return accessFlags;
}
public TypeIdItem getSuperclass() {
return superType;
}
public TypeListItem getInterfaces() {
return implementedInterfaces;
}
public StringIdItem getSourceFile() {
return sourceFile;
}
public AnnotationDirectoryItem getAnnotations() {
return annotations;
}
public ClassDataItem getClassData() {
return classData;
}
public EncodedArrayItem getStaticFieldInitializers() {
return staticFieldInitializers;
}
public static int placeClassDefItems(IndexedSection<ClassDefItem> section, int offset) {
ClassDefPlacer cdp = new ClassDefPlacer(section);
return cdp.placeSection(offset);
}
/**
* This class places the items within a ClassDefItem section, such that superclasses and interfaces are
* placed before sub/implementing classes
*/
private static class ClassDefPlacer {
private final IndexedSection<ClassDefItem> section;
private final HashMap<TypeIdItem, ClassDefItem> unplacedClassDefsByType =
new HashMap<TypeIdItem, ClassDefItem>();
private int currentIndex = 0;
private int currentOffset;
public ClassDefPlacer(IndexedSection<ClassDefItem> section) {
this.section = section;
for (ClassDefItem classDefItem: section.items) {
TypeIdItem typeIdItem = classDefItem.classType;
unplacedClassDefsByType.put(typeIdItem, classDefItem);
}
}
public int placeSection(int offset) {
currentOffset = offset;
if (section.DexFile.getSortAllItems()) {
//presort the list, to guarantee a unique ordering
Collections.sort(section.items, new Comparator<ClassDefItem>() {
public int compare(ClassDefItem a, ClassDefItem b) {
return a.getClassType().compareTo(b.getClassType());
}
});
}
//we need to initialize the offset for all the classes to -1, so we can tell which ones
//have been placed
for (ClassDefItem classDefItem: section.items) {
classDefItem.offset = -1;
}
for (ClassDefItem classDefItem: section.items) {
placeClass(classDefItem);
}
for (ClassDefItem classDefItem: unplacedClassDefsByType.values()) {
section.items.set(classDefItem.getIndex(), classDefItem);
}
return currentOffset;
}
private void placeClass(ClassDefItem classDefItem) {
if (classDefItem.getOffset() == -1) {
TypeIdItem superType = classDefItem.superType;
ClassDefItem superClassDefItem = unplacedClassDefsByType.get(superType);
if (superClassDefItem != null) {
placeClass(superClassDefItem);
}
TypeListItem interfaces = classDefItem.implementedInterfaces;
if (interfaces != null) {
for (TypeIdItem interfaceType: interfaces.getTypes()) {
ClassDefItem interfaceClass = unplacedClassDefsByType.get(interfaceType);
if (interfaceClass != null) {
placeClass(interfaceClass);
}
}
}
currentOffset = classDefItem.placeAt(currentOffset, currentIndex++);
unplacedClassDefsByType.remove(classDefItem.classType);
}
}
}
public static class StaticFieldInitializer implements Comparable<StaticFieldInitializer> {
public final EncodedValue value;
public final ClassDataItem.EncodedField field;
public StaticFieldInitializer(EncodedValue value, ClassDataItem.EncodedField field) {
this.value = value;
this.field = field;
}
public int compareTo(StaticFieldInitializer other) {
return field.compareTo(other.field);
}
}
/**
* A helper method to sort the static field initializers and populate the default values as needed
* @param dexFile the <code>DexFile</code>
* @param staticFieldInitializers the initial values
* @return an interned EncodedArrayItem containing the static field initializers
*/
private static EncodedArrayItem makeStaticFieldInitializersItem(DexFile dexFile,
List<StaticFieldInitializer> staticFieldInitializers) {
if (staticFieldInitializers == null || staticFieldInitializers.size() == 0) {
return null;
}
int len = staticFieldInitializers.size();
Collections.sort(staticFieldInitializers);
int lastIndex = -1;
for (int i=len-1; i>=0; i--) {
StaticFieldInitializer staticFieldInitializer = staticFieldInitializers.get(i);
if (staticFieldInitializer.value != null &&
(staticFieldInitializer.value.compareTo(TypeUtils.makeDefaultValueForType(dexFile,
staticFieldInitializer.field.field.getFieldType().getTypeDescriptor())) != 0)) {
lastIndex = i;
break;
}
}
//we don't have any non-null/non-default values, so we don't need to create an EncodedArrayItem
if (lastIndex == -1) {
return null;
}
EncodedValue[] values = new EncodedValue[lastIndex+1];
for (int i=0; i<=lastIndex; i++) {
StaticFieldInitializer staticFieldInitializer = staticFieldInitializers.get(i);
EncodedValue encodedValue = staticFieldInitializer.value;
if (encodedValue == null) {
encodedValue = TypeUtils.makeDefaultValueForType(dexFile,
staticFieldInitializer.field.field.getFieldType().getTypeDescriptor());
}
values[i] = encodedValue;
}
ArrayEncodedSubValue encodedArrayValue = new ArrayEncodedSubValue(values);
return EncodedArrayItem.getInternedEncodedArrayItem(dexFile, encodedArrayValue);
}
}

View File

@ -1,138 +1,138 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
import org.jf.dexlib.DexFile;
import java.util.Iterator;
public class ArrayDataPseudoInstruction extends Instruction {
public static final Instruction.InstructionFactory Factory = new Factory();
@Override
public int getSize() {
int size = getElementWidth() * getElementCount();
return size + (size & 0x01) + 8;
}
public static void emit(Output out, int elementWidth, byte[] encodedValues) {
if (encodedValues.length % elementWidth != 0) {
throw new RuntimeException("There are not a whole number of " + elementWidth + " byte elements");
}
//write out padding, if necessary
if (out.getCursor() % 4 != 0) {
out.writeShort(0);
}
int elementCount = encodedValues.length / elementWidth;
out.writeByte(0x00);
out.writeByte(0x03);
out.writeShort(elementWidth);
out.writeInt(elementCount);
out.write(encodedValues);
if ((encodedValues.length % 2) != 0) {
//must write out an even number of bytes
out.writeByte(0);
}
}
public ArrayDataPseudoInstruction(byte[] buffer, int bufferIndex) {
super(Opcode.NOP, buffer, bufferIndex);
byte opcodeByte = buffer[bufferIndex++];
if (opcodeByte != 0x00) {
throw new RuntimeException("Invalid opcode byte for an ArrayData pseudo-instruction");
}
byte subopcodeByte = buffer[bufferIndex];
if (subopcodeByte != 0x03) {
throw new RuntimeException("Invalid sub-opcode byte for an ArrayData pseudo-instruction");
}
}
public Format getFormat() {
return Format.ArrayData;
}
public int getElementWidth() {
return NumberUtils.decodeUnsignedShort(buffer[bufferIndex+2], buffer[bufferIndex+3]);
}
public int getElementCount() {
return NumberUtils.decodeInt(buffer, bufferIndex+4);
}
public static class ArrayElement {
public final byte[] buffer;
public int bufferIndex;
public final int elementWidth;
public ArrayElement(byte[] buffer, int elementWidth) {
this.buffer = buffer;
this.elementWidth = elementWidth;
}
}
public Iterator<ArrayElement> getElements() {
return new Iterator<ArrayElement>() {
final int elementCount = getElementCount();
int i=0;
int position = bufferIndex + 8;
final ArrayElement arrayElement = new ArrayElement(buffer, getElementWidth());
public boolean hasNext() {
return i<elementCount;
}
public ArrayElement next() {
arrayElement.bufferIndex = position;
position += arrayElement.elementWidth;
i++;
return arrayElement;
}
public void remove() {
}
};
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
if (opcode != Opcode.NOP) {
throw new RuntimeException("The opcode for an ArrayDataPseudoInstruction must by NOP");
}
return new ArrayDataPseudoInstruction(buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
import org.jf.dexlib.DexFile;
import java.util.Iterator;
public class ArrayDataPseudoInstruction extends Instruction {
public static final Instruction.InstructionFactory Factory = new Factory();
@Override
public int getSize() {
int size = getElementWidth() * getElementCount();
return size + (size & 0x01) + 8;
}
public static void emit(Output out, int elementWidth, byte[] encodedValues) {
if (encodedValues.length % elementWidth != 0) {
throw new RuntimeException("There are not a whole number of " + elementWidth + " byte elements");
}
//write out padding, if necessary
if (out.getCursor() % 4 != 0) {
out.writeShort(0);
}
int elementCount = encodedValues.length / elementWidth;
out.writeByte(0x00);
out.writeByte(0x03);
out.writeShort(elementWidth);
out.writeInt(elementCount);
out.write(encodedValues);
if ((encodedValues.length % 2) != 0) {
//must write out an even number of bytes
out.writeByte(0);
}
}
public ArrayDataPseudoInstruction(byte[] buffer, int bufferIndex) {
super(Opcode.NOP, buffer, bufferIndex);
byte opcodeByte = buffer[bufferIndex++];
if (opcodeByte != 0x00) {
throw new RuntimeException("Invalid opcode byte for an ArrayData pseudo-instruction");
}
byte subopcodeByte = buffer[bufferIndex];
if (subopcodeByte != 0x03) {
throw new RuntimeException("Invalid sub-opcode byte for an ArrayData pseudo-instruction");
}
}
public Format getFormat() {
return Format.ArrayData;
}
public int getElementWidth() {
return NumberUtils.decodeUnsignedShort(buffer[bufferIndex+2], buffer[bufferIndex+3]);
}
public int getElementCount() {
return NumberUtils.decodeInt(buffer, bufferIndex+4);
}
public static class ArrayElement {
public final byte[] buffer;
public int bufferIndex;
public final int elementWidth;
public ArrayElement(byte[] buffer, int elementWidth) {
this.buffer = buffer;
this.elementWidth = elementWidth;
}
}
public Iterator<ArrayElement> getElements() {
return new Iterator<ArrayElement>() {
final int elementCount = getElementCount();
int i=0;
int position = bufferIndex + 8;
final ArrayElement arrayElement = new ArrayElement(buffer, getElementWidth());
public boolean hasNext() {
return i<elementCount;
}
public ArrayElement next() {
arrayElement.bufferIndex = position;
position += arrayElement.elementWidth;
i++;
return arrayElement;
}
public void remove() {
}
};
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
if (opcode != Opcode.NOP) {
throw new RuntimeException("The opcode for an ArrayDataPseudoInstruction must by NOP");
}
return new ArrayDataPseudoInstruction(buffer, bufferIndex);
}
}
}

View File

@ -1,86 +1,86 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
public enum Format {
Format10t(Instruction10t.Factory, 2),
Format10x(Instruction10x.Factory, 2),
Format11n(Instruction11n.Factory, 2),
Format11x(Instruction11x.Factory, 2),
Format12x(Instruction12x.Factory, 2),
Format20t(Instruction20t.Factory, 4),
Format21c(Instruction21c.Factory, 4),
Format21h(Instruction21h.Factory, 4),
Format21s(Instruction21s.Factory, 4),
Format21t(Instruction21t.Factory, 4),
Format22b(Instruction22b.Factory, 4),
Format22c(Instruction22c.Factory, 4),
Format22cs(Instruction22cs.Factory, 4),
Format22csf(null, 4),
Format22s(Instruction22s.Factory, 4),
Format22t(Instruction22t.Factory, 4),
Format22x(Instruction22x.Factory, 4),
Format23x(Instruction23x.Factory, 4),
Format30t(Instruction30t.Factory, 6),
Format31c(Instruction31c.Factory, 6),
Format31i(Instruction31i.Factory, 6),
Format31t(Instruction31t.Factory, 6),
Format32x(Instruction32x.Factory, 6),
Format35c(Instruction35c.Factory, 6),
Format35s(Instruction35s.Factory, 6),
Format35sf(null, 6),
Format35ms(Instruction35ms.Factory, 6),
Format35msf(null, 6),
Format3rc(Instruction3rc.Factory, 6),
Format3rms(Instruction3rms.Factory, 6),
Format3rmsf(null, 6),
Format51l(Instruction51l.Factory, 10),
ArrayData(null, -1, true),
PackedSwitchData(null, -1, true),
SparseSwitchData(null, -1, true),
UnresolvedNullReference(null, -1, false),
DeadInstruction(null, -1, false)
;
public final Instruction.InstructionFactory Factory;
public final int size;
public final boolean variableSizeFormat;
private Format(Instruction.InstructionFactory factory, int size) {
this(factory, size, false);
}
private Format(Instruction.InstructionFactory factory, int size, boolean variableSizeFormat) {
this.Factory = factory;
this.size = size;
this.variableSizeFormat = variableSizeFormat;
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
public enum Format {
Format10t(Instruction10t.Factory, 2),
Format10x(Instruction10x.Factory, 2),
Format11n(Instruction11n.Factory, 2),
Format11x(Instruction11x.Factory, 2),
Format12x(Instruction12x.Factory, 2),
Format20t(Instruction20t.Factory, 4),
Format21c(Instruction21c.Factory, 4),
Format21h(Instruction21h.Factory, 4),
Format21s(Instruction21s.Factory, 4),
Format21t(Instruction21t.Factory, 4),
Format22b(Instruction22b.Factory, 4),
Format22c(Instruction22c.Factory, 4),
Format22cs(Instruction22cs.Factory, 4),
Format22csf(null, 4),
Format22s(Instruction22s.Factory, 4),
Format22t(Instruction22t.Factory, 4),
Format22x(Instruction22x.Factory, 4),
Format23x(Instruction23x.Factory, 4),
Format30t(Instruction30t.Factory, 6),
Format31c(Instruction31c.Factory, 6),
Format31i(Instruction31i.Factory, 6),
Format31t(Instruction31t.Factory, 6),
Format32x(Instruction32x.Factory, 6),
Format35c(Instruction35c.Factory, 6),
Format35s(Instruction35s.Factory, 6),
Format35sf(null, 6),
Format35ms(Instruction35ms.Factory, 6),
Format35msf(null, 6),
Format3rc(Instruction3rc.Factory, 6),
Format3rms(Instruction3rms.Factory, 6),
Format3rmsf(null, 6),
Format51l(Instruction51l.Factory, 10),
ArrayData(null, -1, true),
PackedSwitchData(null, -1, true),
SparseSwitchData(null, -1, true),
UnresolvedNullReference(null, -1, false),
DeadInstruction(null, -1, false)
;
public final Instruction.InstructionFactory Factory;
public final int size;
public final boolean variableSizeFormat;
private Format(Instruction.InstructionFactory factory, int size) {
this(factory, size, false);
}
private Format(Instruction.InstructionFactory factory, int size, boolean variableSizeFormat) {
this.Factory = factory;
this.size = size;
this.variableSizeFormat = variableSizeFormat;
}
}

View File

@ -1,70 +1,70 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.Output;
public class Instruction10t extends Instruction implements OffsetInstruction {
public static final InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte offA) {
if (offA == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
}
out.writeByte(opcode.value);
out.writeByte(offA);
}
private Instruction10t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
}
}
public Format getFormat() {
return Format.Format10t;
}
public int getOffset() {
return buffer[bufferIndex + 1];
}
private static class Factory implements InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction10t(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.Output;
public class Instruction10t extends Instruction implements OffsetInstruction {
public static final InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte offA) {
if (offA == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
}
out.writeByte(opcode.value);
out.writeByte(offA);
}
private Instruction10t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
}
}
public Format getFormat() {
return Format.Format10t;
}
public int getOffset() {
return buffer[bufferIndex + 1];
}
private static class Factory implements InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction10t(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,61 +1,61 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.Output;
public class Instruction10x extends Instruction {
public static final InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode) {
out.writeByte(opcode.value);
out.writeByte(0);
}
public Instruction10x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
if (buffer[bufferIndex + 1] != 0x00) {
throw new RuntimeException("The second byte of the instruction must be 0");
}
}
public Format getFormat() {
return Format.Format10x;
}
private static class Factory implements InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction10x(opcode, buffer, bufferIndex);
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.Output;
public class Instruction10x extends Instruction {
public static final InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode) {
out.writeByte(opcode.value);
out.writeByte(0);
}
public Instruction10x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
if (buffer[bufferIndex + 1] != 0x00) {
throw new RuntimeException("The second byte of the instruction must be 0");
}
}
public Format getFormat() {
return Format.Format10x;
}
private static class Factory implements InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction10x(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,77 +1,77 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction11n extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte litB) {
if (regA >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16");
}
if (litB < -(1 << 3) ||
litB >= 1 << 3) {
throw new RuntimeException("The literal value must be between -8 and 7 inclusive");
}
out.writeByte(opcode.value);
out.writeByte((litB << 4) | regA);
}
private Instruction11n(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format11n;
}
public int getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
}
public long getLiteral() {
return NumberUtils.decodeHighSignedNibble(buffer[bufferIndex + 1]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction11n(opcode, buffer, bufferIndex);
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction11n extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte litB) {
if (regA >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16");
}
if (litB < -(1 << 3) ||
litB >= 1 << 3) {
throw new RuntimeException("The literal value must be between -8 and 7 inclusive");
}
out.writeByte(opcode.value);
out.writeByte((litB << 4) | regA);
}
private Instruction11n(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format11n;
}
public int getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
}
public long getLiteral() {
return NumberUtils.decodeHighSignedNibble(buffer[bufferIndex + 1]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction11n(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,67 +1,67 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction11x extends Instruction implements SingleRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
}
private Instruction11x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format11x;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction11x(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction11x extends Instruction implements SingleRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
}
private Instruction11x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format11x;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction11x(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,72 +1,72 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction12x extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte regB) {
if (regA >= 1 << 4 ||
regB >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16");
}
out.writeByte(opcode.value);
out.writeByte((regB << 4) | regA);
}
private Instruction12x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format12x;
}
public int getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
}
public int getRegisterB() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction12x(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction12x extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte regB) {
if (regA >= 1 << 4 ||
regB >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16");
}
out.writeByte(opcode.value);
out.writeByte((regB << 4) | regA);
}
private Instruction12x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format12x;
}
public int getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
}
public int getRegisterB() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction12x(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,72 +1,72 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction20t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short offA) {
if (offA == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
}
out.writeByte(opcode.value);
out.writeByte(0);
out.writeShort(offA);
}
private Instruction20t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
}
}
public Format getFormat() {
return Format.Format20t;
}
public int getOffset() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction20t(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction20t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short offA) {
if (offA == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
}
out.writeByte(opcode.value);
out.writeByte(0);
out.writeShort(offA);
}
private Instruction20t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
}
}
public Format getFormat() {
return Format.Format20t;
}
public int getOffset() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction20t(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,82 +1,82 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Item;
import org.jf.dexlib.TypeIdItem;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction21c extends InstructionWithReference implements SingleRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, Item referencedItem) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
if (opcode == Opcode.NEW_INSTANCE) {
assert referencedItem instanceof TypeIdItem;
if (((TypeIdItem)referencedItem).getTypeDescriptor().charAt(0) != 'L') {
throw new RuntimeException("Only class references can be used with the new-instance opcode");
}
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeShort(0);
}
private Instruction21c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex);
if (opcode == Opcode.NEW_INSTANCE && ((TypeIdItem) this.getReferencedItem()).getTypeDescriptor().charAt(0) != 'L') {
throw new RuntimeException("Only class references can be used with the new-instance opcode");
}
}
public Format getFormat() {
return Format.Format21c;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction21c(dexFile, opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Item;
import org.jf.dexlib.TypeIdItem;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction21c extends InstructionWithReference implements SingleRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, Item referencedItem) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
if (opcode == Opcode.NEW_INSTANCE) {
assert referencedItem instanceof TypeIdItem;
if (((TypeIdItem)referencedItem).getTypeDescriptor().charAt(0) != 'L') {
throw new RuntimeException("Only class references can be used with the new-instance opcode");
}
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeShort(0);
}
private Instruction21c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex);
if (opcode == Opcode.NEW_INSTANCE && ((TypeIdItem) this.getReferencedItem()).getTypeDescriptor().charAt(0) != 'L') {
throw new RuntimeException("Only class references can be used with the new-instance opcode");
}
}
public Format getFormat() {
return Format.Format21c;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction21c(dexFile, opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,73 +1,73 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction21h extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short litB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeShort(litB);
}
private Instruction21h(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format21h;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public long getLiteral() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction21h(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction21h extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short litB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeShort(litB);
}
private Instruction21h(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format21h;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public long getLiteral() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction21h(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,73 +1,73 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction21s extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short litB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeShort(litB);
}
private Instruction21s(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format21s;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public long getLiteral() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction21s(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction21s extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short litB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeShort(litB);
}
private Instruction21s(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format21s;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public long getLiteral() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction21s(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,80 +1,80 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction21t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short offB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
if (offB == 0) {
throw new RuntimeException("The offset cannot be 0.");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeShort(offB);
}
private Instruction21t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0.");
}
}
public Format getFormat() {
return Format.Format21t;
}
public short getRegister() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public int getOffset() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction21t(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction21t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short offB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
if (offB == 0) {
throw new RuntimeException("The offset cannot be 0.");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeShort(offB);
}
private Instruction21t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0.");
}
}
public Format getFormat() {
return Format.Format21t;
}
public short getRegister() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public int getOffset() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction21t(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,78 +1,78 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction22b extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short regB, byte litC) {
if (regA >= 1 << 8 ||
regB >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeByte(regB);
out.writeByte(litC);
}
private Instruction22b(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format22b;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public int getRegisterB() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 2]);
}
public byte getLiteral() {
return buffer[bufferIndex + 3];
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22b(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction22b extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short regB, byte litC) {
if (regA >= 1 << 8 ||
regB >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeByte(regB);
out.writeByte(litC);
}
private Instruction22b(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format22b;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public int getRegisterB() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 2]);
}
public byte getLiteral() {
return buffer[bufferIndex + 3];
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22b(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,74 +1,74 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction22c extends InstructionWithReference implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte regB) {
if (regA >= 1 << 4 ||
regB >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16");
}
out.writeByte(opcode.value);
out.writeByte((regB << 4) | regA);
out.writeShort(0);
}
private Instruction22c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format22c;
}
public int getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
}
public int getRegisterB() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22c(dexFile, opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction22c extends InstructionWithReference implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte regB) {
if (regA >= 1 << 4 ||
regB >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16");
}
out.writeByte(opcode.value);
out.writeByte((regB << 4) | regA);
out.writeShort(0);
}
private Instruction22c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format22c;
}
public int getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
}
public int getRegisterB() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22c(dexFile, opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,77 +1,77 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction22s extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte regB, short litC) {
if (regA >= 1 << 4 ||
regB >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16");
}
out.writeByte(opcode.value);
out.writeByte((regB << 4) | regA);
out.writeShort(litC);
}
private Instruction22s(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format22s;
}
public int getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
}
public int getRegisterB() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
}
public short getLiteral() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22s(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction22s extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte regB, short litC) {
if (regA >= 1 << 4 ||
regB >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16");
}
out.writeByte(opcode.value);
out.writeByte((regB << 4) | regA);
out.writeShort(litC);
}
private Instruction22s(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format22s;
}
public int getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
}
public int getRegisterB() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
}
public short getLiteral() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22s(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,85 +1,85 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction22t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte regB, short offC) {
if (regA >= 1 << 4 ||
regB >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16");
}
if (offC == 0) {
throw new RuntimeException("The offset cannot be 0.");
}
out.writeByte(opcode.value);
out.writeByte((regB << 4) | regA);
out.writeShort(offC);
}
private Instruction22t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0.");
}
}
public Format getFormat() {
return Format.Format22t;
}
public byte getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
}
public byte getRegisterB() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
}
public int getOffset() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22t(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction22t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte regB, short offC) {
if (regA >= 1 << 4 ||
regB >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16");
}
if (offC == 0) {
throw new RuntimeException("The offset cannot be 0.");
}
out.writeByte(opcode.value);
out.writeByte((regB << 4) | regA);
out.writeShort(offC);
}
private Instruction22t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0.");
}
}
public Format getFormat() {
return Format.Format22t;
}
public byte getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
}
public byte getRegisterB() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
}
public int getOffset() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22t(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,76 +1,76 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction22x extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, int regB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v16");
}
if (regB >= 1 << 16) {
throw new RuntimeException("The register number must be less than v65536");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeShort(regB);
}
private Instruction22x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format22x;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public int getRegisterB() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22x(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction22x extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, int regB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v16");
}
if (regB >= 1 << 16) {
throw new RuntimeException("The register number must be less than v65536");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeShort(regB);
}
private Instruction22x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format22x;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public int getRegisterB() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22x(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,79 +1,79 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.ThreeRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction23x extends Instruction implements ThreeRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short regB, short regC) {
if (regA >= 1 << 8 ||
regB >= 1 << 8 ||
regC >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeByte(regB);
out.writeByte(regC);
}
private Instruction23x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format23x;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public int getRegisterB() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 2]);
}
public int getRegisterC() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 3]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction23x(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.ThreeRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction23x extends Instruction implements ThreeRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short regB, short regC) {
if (regA >= 1 << 8 ||
regB >= 1 << 8 ||
regC >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeByte(regB);
out.writeByte(regC);
}
private Instruction23x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format23x;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public int getRegisterB() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 2]);
}
public int getRegisterC() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 3]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction23x(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,64 +1,64 @@
/*
* [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.Code.Format;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction30t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, int offA) {
out.writeByte(opcode.value);
out.writeByte(0);
out.writeInt(offA);
}
private Instruction30t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format30t;
}
public int getOffset() {
return NumberUtils.decodeInt(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction30t(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction30t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, int offA) {
out.writeByte(opcode.value);
out.writeByte(0);
out.writeInt(offA);
}
private Instruction30t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format30t;
}
public int getOffset() {
return NumberUtils.decodeInt(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction30t(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,74 +1,74 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Item;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction31c extends InstructionWithReference implements SingleRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeInt(0);
}
private Instruction31c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex);
}
protected int getReferencedItemIndex() {
return NumberUtils.decodeInt(buffer, bufferIndex + 2);
}
public Format getFormat() {
return Format.Format31c;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction31c(dexFile, opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Item;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction31c extends InstructionWithReference implements SingleRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeInt(0);
}
private Instruction31c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex);
}
protected int getReferencedItemIndex() {
return NumberUtils.decodeInt(buffer, bufferIndex + 2);
}
public Format getFormat() {
return Format.Format31c;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction31c(dexFile, opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,73 +1,73 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction31i extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, int litB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeInt(litB);
}
private Instruction31i(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format31i;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public long getLiteral() {
return NumberUtils.decodeInt(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction31i(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction31i extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, int litB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeInt(litB);
}
private Instruction31i(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format31i;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public long getLiteral() {
return NumberUtils.decodeInt(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction31i(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,72 +1,72 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction31t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, int offB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeInt(offB);
}
private Instruction31t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format31t;
}
public short getRegister() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public int getOffset() {
return NumberUtils.decodeInt(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction31t(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction31t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, int offB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeInt(offB);
}
private Instruction31t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format31t;
}
public short getRegister() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public int getOffset() {
return NumberUtils.decodeInt(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction31t(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,74 +1,74 @@
/*
* [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.Code.Format;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction32x extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, int regA, int regB) {
if (regA >= 1<<16 ||
regB >= 1<<16) {
throw new RuntimeException("The register number must be less than v65536");
}
out.writeByte(opcode.value);
out.writeByte(0);
out.writeShort(regA);
out.writeShort(regB);
}
private Instruction32x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format32x;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
}
public int getRegisterB() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction32x(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction32x extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, int regA, int regB) {
if (regA >= 1<<16 ||
regB >= 1<<16) {
throw new RuntimeException("The register number must be less than v65536");
}
out.writeByte(opcode.value);
out.writeByte(0);
out.writeShort(regA);
out.writeShort(regB);
}
private Instruction32x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format32x;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
}
public int getRegisterB() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction32x(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,134 +1,134 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode;
import static org.jf.dexlib.Code.Opcode.*;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Item;
import org.jf.dexlib.MethodIdItem;
import org.jf.dexlib.TypeIdItem;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction35c extends InstructionWithReference {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, int regCount, byte regD, byte regE, byte regF, byte regG,
byte regA, Item referencedItem) {
if (regCount > 5) {
throw new RuntimeException("regCount cannot be greater than 5");
}
if (regD >= 1 << 4 ||
regE >= 1 << 4 ||
regF >= 1 << 4 ||
regG >= 1 << 4 ||
regA >= 1 << 4) {
throw new RuntimeException("All register args must fit in 4 bits");
}
out.writeByte(opcode.value);
out.writeByte((regCount << 4) | regA);
out.writeShort(0);
out.writeByte((regE << 4) | regD);
out.writeByte((regG << 4) | regF);
checkItem(opcode, referencedItem, regCount);
}
protected Instruction35c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex);
if (getRegCount() > 5) {
throw new RuntimeException("regCount cannot be greater than 5");
}
checkItem(opcode, getReferencedItem(), getRegCount());
}
public Format getFormat() {
return Format.Format35c;
}
public byte getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
}
public byte getRegCount() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
}
public byte getRegisterD() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 4]);
}
public byte getRegisterE() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 4]);
}
public byte getRegisterF() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 5]);
}
public byte getRegisterG() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 5]);
}
private static void checkItem(Opcode opcode, Item item, int regCount) {
if (opcode == FILLED_NEW_ARRAY) {
//check data for filled-new-array opcode
String type = ((TypeIdItem) item).getTypeDescriptor();
if (type.charAt(0) != '[') {
throw new RuntimeException("The type must be an array type");
}
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
throw new RuntimeException("The type cannot be an array of longs or doubles");
}
} else if (opcode.value >= INVOKE_VIRTUAL.value && opcode.value <= INVOKE_INTERFACE.value) {
//check data for invoke-* opcodes
MethodIdItem methodIdItem = (MethodIdItem) item;
int parameterRegisterCount = methodIdItem.getPrototype().getParameterRegisterCount();
if (opcode != INVOKE_STATIC) {
parameterRegisterCount++;
}
if (parameterRegisterCount != regCount) {
throw new RuntimeException("regCount does not match the number of arguments of the method");
}
}
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction35c(dexFile, opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode;
import static org.jf.dexlib.Code.Opcode.*;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Item;
import org.jf.dexlib.MethodIdItem;
import org.jf.dexlib.TypeIdItem;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction35c extends InstructionWithReference {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, int regCount, byte regD, byte regE, byte regF, byte regG,
byte regA, Item referencedItem) {
if (regCount > 5) {
throw new RuntimeException("regCount cannot be greater than 5");
}
if (regD >= 1 << 4 ||
regE >= 1 << 4 ||
regF >= 1 << 4 ||
regG >= 1 << 4 ||
regA >= 1 << 4) {
throw new RuntimeException("All register args must fit in 4 bits");
}
out.writeByte(opcode.value);
out.writeByte((regCount << 4) | regA);
out.writeShort(0);
out.writeByte((regE << 4) | regD);
out.writeByte((regG << 4) | regF);
checkItem(opcode, referencedItem, regCount);
}
protected Instruction35c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex);
if (getRegCount() > 5) {
throw new RuntimeException("regCount cannot be greater than 5");
}
checkItem(opcode, getReferencedItem(), getRegCount());
}
public Format getFormat() {
return Format.Format35c;
}
public byte getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
}
public byte getRegCount() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
}
public byte getRegisterD() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 4]);
}
public byte getRegisterE() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 4]);
}
public byte getRegisterF() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 5]);
}
public byte getRegisterG() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 5]);
}
private static void checkItem(Opcode opcode, Item item, int regCount) {
if (opcode == FILLED_NEW_ARRAY) {
//check data for filled-new-array opcode
String type = ((TypeIdItem) item).getTypeDescriptor();
if (type.charAt(0) != '[') {
throw new RuntimeException("The type must be an array type");
}
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
throw new RuntimeException("The type cannot be an array of longs or doubles");
}
} else if (opcode.value >= INVOKE_VIRTUAL.value && opcode.value <= INVOKE_INTERFACE.value) {
//check data for invoke-* opcodes
MethodIdItem methodIdItem = (MethodIdItem) item;
int parameterRegisterCount = methodIdItem.getPrototype().getParameterRegisterCount();
if (opcode != INVOKE_STATIC) {
parameterRegisterCount++;
}
if (parameterRegisterCount != regCount) {
throw new RuntimeException("regCount does not match the number of arguments of the method");
}
}
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction35c(dexFile, opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,114 +1,114 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode;
import static org.jf.dexlib.Code.Opcode.*;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Item;
import org.jf.dexlib.MethodIdItem;
import org.jf.dexlib.TypeIdItem;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction3rc extends InstructionWithReference {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regCount, int startReg, Item referencedItem) {
if (regCount >= 1 << 8) {
throw new RuntimeException("regCount must be less than 256");
}
if (regCount < 0) {
throw new RuntimeException("regCount cannot be negative");
}
if (startReg >= 1 << 16) {
throw new RuntimeException("The beginning register of the range must be less than 65536");
}
if (startReg < 0) {
throw new RuntimeException("The beginning register of the range cannot be negative");
}
out.writeByte(opcode.value);
out.writeByte(regCount);
out.writeShort(0);
out.writeShort(startReg);
checkItem(opcode, referencedItem, regCount);
}
private Instruction3rc(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex);
checkItem(opcode, getReferencedItem(), getRegCount());
}
public Format getFormat() {
return Format.Format3rc;
}
public short getRegCount() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public int getStartRegister() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4);
}
private static void checkItem(Opcode opcode, Item item, int regCount) {
if (opcode == FILLED_NEW_ARRAY_RANGE) {
//check data for filled-new-array/range opcode
String type = ((TypeIdItem) item).getTypeDescriptor();
if (type.charAt(0) != '[') {
throw new RuntimeException("The type must be an array type");
}
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
throw new RuntimeException("The type cannot be an array of longs or doubles");
}
} else if (opcode.value >= INVOKE_VIRTUAL_RANGE.value && opcode.value <= INVOKE_INTERFACE_RANGE.value) {
//check data for invoke-*/range opcodes
MethodIdItem methodIdItem = (MethodIdItem) item;
int parameterRegisterCount = methodIdItem.getPrototype().getParameterRegisterCount();
if (opcode != INVOKE_STATIC_RANGE) {
parameterRegisterCount++;
}
if (parameterRegisterCount != regCount) {
throw new RuntimeException("regCount does not match the number of arguments of the method");
}
}
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction3rc(dexFile, opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode;
import static org.jf.dexlib.Code.Opcode.*;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Item;
import org.jf.dexlib.MethodIdItem;
import org.jf.dexlib.TypeIdItem;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction3rc extends InstructionWithReference {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regCount, int startReg, Item referencedItem) {
if (regCount >= 1 << 8) {
throw new RuntimeException("regCount must be less than 256");
}
if (regCount < 0) {
throw new RuntimeException("regCount cannot be negative");
}
if (startReg >= 1 << 16) {
throw new RuntimeException("The beginning register of the range must be less than 65536");
}
if (startReg < 0) {
throw new RuntimeException("The beginning register of the range cannot be negative");
}
out.writeByte(opcode.value);
out.writeByte(regCount);
out.writeShort(0);
out.writeShort(startReg);
checkItem(opcode, referencedItem, regCount);
}
private Instruction3rc(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex);
checkItem(opcode, getReferencedItem(), getRegCount());
}
public Format getFormat() {
return Format.Format3rc;
}
public short getRegCount() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public int getStartRegister() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4);
}
private static void checkItem(Opcode opcode, Item item, int regCount) {
if (opcode == FILLED_NEW_ARRAY_RANGE) {
//check data for filled-new-array/range opcode
String type = ((TypeIdItem) item).getTypeDescriptor();
if (type.charAt(0) != '[') {
throw new RuntimeException("The type must be an array type");
}
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
throw new RuntimeException("The type cannot be an array of longs or doubles");
}
} else if (opcode.value >= INVOKE_VIRTUAL_RANGE.value && opcode.value <= INVOKE_INTERFACE_RANGE.value) {
//check data for invoke-*/range opcodes
MethodIdItem methodIdItem = (MethodIdItem) item;
int parameterRegisterCount = methodIdItem.getPrototype().getParameterRegisterCount();
if (opcode != INVOKE_STATIC_RANGE) {
parameterRegisterCount++;
}
if (parameterRegisterCount != regCount) {
throw new RuntimeException("regCount does not match the number of arguments of the method");
}
}
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction3rc(dexFile, opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,73 +1,73 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction51l extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, long litB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeLong(litB);
}
private Instruction51l(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format51l;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public long getLiteral() {
return NumberUtils.decodeLong(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction51l(opcode, buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
public class Instruction51l extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, long litB) {
if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256");
}
out.writeByte(opcode.value);
out.writeByte(regA);
out.writeLong(litB);
}
private Instruction51l(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex);
}
public Format getFormat() {
return Format.Format51l;
}
public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
}
public long getLiteral() {
return NumberUtils.decodeLong(buffer, bufferIndex + 2);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction51l(opcode, buffer, bufferIndex);
}
}
}

View File

@ -1,136 +1,136 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
import org.jf.dexlib.DexFile;
import java.util.Iterator;
public class PackedSwitchDataPseudoInstruction extends Instruction {
public static final Instruction.InstructionFactory Factory = new Factory();
@Override
public int getSize() {
return getTargetCount() * 4 + 8;
}
public static void emit(Output out, int firstKey, int[] targets) {
if (targets.length > 0xFFFF) {
throw new RuntimeException("The packed-switch data contains too many elements. " +
"The maximum number of switch elements is 65535");
}
//write out padding, if necessary
if (out.getCursor() % 4 != 0) {
out.writeShort(0);
}
out.writeByte(0x00);
out.writeByte(0x01);
out.writeShort(targets.length);
out.writeInt(firstKey);
for (int target : targets) {
out.writeInt(target);
}
}
public PackedSwitchDataPseudoInstruction(byte[] buffer, int bufferIndex) {
super(Opcode.NOP, buffer, bufferIndex);
byte opcodeByte = buffer[bufferIndex++];
if (opcodeByte != 0x00) {
throw new RuntimeException("Invalid opcode byte for a PackedSwitchData pseudo-instruction");
}
byte subopcodeByte = buffer[bufferIndex];
if (subopcodeByte != 0x01) {
throw new RuntimeException("Invalid sub-opcode byte for a PackedSwitchData pseudo-instruction");
}
}
public Format getFormat() {
return Format.PackedSwitchData;
}
public int getTargetCount() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
}
public int getFirstKey() {
return NumberUtils.decodeInt(buffer, bufferIndex + 4);
}
public static class PackedSwitchTarget {
public int value;
public int target;
}
public Iterator<PackedSwitchTarget> getTargets() {
return new Iterator<PackedSwitchTarget>() {
final int targetCount = getTargetCount();
int i = 0;
int position = bufferIndex + 8;
int value = getFirstKey();
PackedSwitchTarget packedSwitchTarget = new PackedSwitchTarget();
public boolean hasNext() {
return i<targetCount;
}
public PackedSwitchTarget next() {
packedSwitchTarget.value = value++;
packedSwitchTarget.target = NumberUtils.decodeInt(buffer, position);
position+=4;
i++;
return packedSwitchTarget;
}
public void remove() {
}
};
}
public static interface PackedSwitchTargetIteratorDelegate {
void ProcessPackedSwitchTarget(int value, int target);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
if (opcode != Opcode.NOP) {
throw new RuntimeException("The opcode for a PackedSwitchDataPseudoInstruction must by NOP");
}
return new PackedSwitchDataPseudoInstruction(buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
import org.jf.dexlib.DexFile;
import java.util.Iterator;
public class PackedSwitchDataPseudoInstruction extends Instruction {
public static final Instruction.InstructionFactory Factory = new Factory();
@Override
public int getSize() {
return getTargetCount() * 4 + 8;
}
public static void emit(Output out, int firstKey, int[] targets) {
if (targets.length > 0xFFFF) {
throw new RuntimeException("The packed-switch data contains too many elements. " +
"The maximum number of switch elements is 65535");
}
//write out padding, if necessary
if (out.getCursor() % 4 != 0) {
out.writeShort(0);
}
out.writeByte(0x00);
out.writeByte(0x01);
out.writeShort(targets.length);
out.writeInt(firstKey);
for (int target : targets) {
out.writeInt(target);
}
}
public PackedSwitchDataPseudoInstruction(byte[] buffer, int bufferIndex) {
super(Opcode.NOP, buffer, bufferIndex);
byte opcodeByte = buffer[bufferIndex++];
if (opcodeByte != 0x00) {
throw new RuntimeException("Invalid opcode byte for a PackedSwitchData pseudo-instruction");
}
byte subopcodeByte = buffer[bufferIndex];
if (subopcodeByte != 0x01) {
throw new RuntimeException("Invalid sub-opcode byte for a PackedSwitchData pseudo-instruction");
}
}
public Format getFormat() {
return Format.PackedSwitchData;
}
public int getTargetCount() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
}
public int getFirstKey() {
return NumberUtils.decodeInt(buffer, bufferIndex + 4);
}
public static class PackedSwitchTarget {
public int value;
public int target;
}
public Iterator<PackedSwitchTarget> getTargets() {
return new Iterator<PackedSwitchTarget>() {
final int targetCount = getTargetCount();
int i = 0;
int position = bufferIndex + 8;
int value = getFirstKey();
PackedSwitchTarget packedSwitchTarget = new PackedSwitchTarget();
public boolean hasNext() {
return i<targetCount;
}
public PackedSwitchTarget next() {
packedSwitchTarget.value = value++;
packedSwitchTarget.target = NumberUtils.decodeInt(buffer, position);
position+=4;
i++;
return packedSwitchTarget;
}
public void remove() {
}
};
}
public static interface PackedSwitchTargetIteratorDelegate {
void ProcessPackedSwitchTarget(int value, int target);
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
if (opcode != Opcode.NOP) {
throw new RuntimeException("The opcode for a PackedSwitchDataPseudoInstruction must by NOP");
}
return new PackedSwitchDataPseudoInstruction(buffer, bufferIndex);
}
}
}

View File

@ -1,152 +1,151 @@
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
import org.jf.dexlib.DexFile;
import java.util.Iterator;
public class SparseSwitchDataPseudoInstruction extends Instruction {
public static final Instruction.InstructionFactory Factory = new Factory();
@Override
public int getSize() {
return getTargetCount() * 8 + 4;
}
public static void emit(Output out, int[] keys, int[] targets) {
if (keys.length != targets.length) {
throw new RuntimeException("The number of keys and offsets don't match");
}
if (targets.length == 0) {
throw new RuntimeException("The sparse-switch data must contain at least 1 key/target");
}
if (targets.length > 0xFFFF) {
throw new RuntimeException("The sparse-switch data contains too many elements. " +
"The maximum number of switch elements is 65535");
}
//write out padding, if necessary
if (out.getCursor() % 4 != 0) {
out.writeShort(0);
}
out.writeByte(0x00);
out.writeByte(0x02);
out.writeShort(targets.length);
if (targets.length > 0) {
int key = keys[0];
out.writeInt(key);
for (int i = 1; i < keys.length; i++) {
key = keys[i];
if (key <= keys[i - 1]) {
throw new RuntimeException("The targets in a sparse switch block must be sorted in ascending" +
"order, by key");
}
out.writeInt(key);
}
for (int target : targets) {
out.writeInt(target);
}
}
}
public SparseSwitchDataPseudoInstruction(byte[] buffer, int bufferIndex) {
super(Opcode.NOP, buffer, bufferIndex);
byte opcodeByte = buffer[bufferIndex++];
if (opcodeByte != 0x00) {
throw new RuntimeException("Invalid opcode byte for a SparseSwitchData pseudo-instruction");
}
byte subopcodeByte = buffer[bufferIndex];
if (subopcodeByte != 0x02) {
throw new RuntimeException("Invalid sub-opcode byte for a SparseSwitchData pseudo-instruction");
}
}
public Format getFormat() {
return Format.SparseSwitchData;
}
public int getTargetCount() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
}
public static class SparseSwitchTarget {
public int value;
public int target;
}
public Iterator<SparseSwitchTarget> getTargets() {
return new Iterator<SparseSwitchTarget>() {
final int targetCount = getTargetCount();
int i = 0;
int valuePosition = bufferIndex + 4;
int targetPosition = bufferIndex + 4 + targetCount * 4;
SparseSwitchTarget sparseSwitchTarget = new SparseSwitchTarget();
public boolean hasNext() {
return i<targetCount;
}
public SparseSwitchTarget next() {
sparseSwitchTarget.value = NumberUtils.decodeInt(buffer, valuePosition);
sparseSwitchTarget.target = NumberUtils.decodeInt(buffer, targetPosition);
valuePosition+=4;
targetPosition+=4;
i++;
return sparseSwitchTarget;
}
public void remove() {
}
};
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
if (opcode != Opcode.NOP) {
throw new RuntimeException("The opcode for a SparseSwitchDataPseudoInstruction must by NOP");
}
return new SparseSwitchDataPseudoInstruction(buffer, bufferIndex);
}
}
}
/*
* [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.Code.Format;
import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output;
import org.jf.dexlib.DexFile;
import java.util.Iterator;
public class SparseSwitchDataPseudoInstruction extends Instruction {
public static final Instruction.InstructionFactory Factory = new Factory();
@Override
public int getSize() {
return getTargetCount() * 8 + 4;
}
public static void emit(Output out, int[] keys, int[] targets) {
if (keys.length != targets.length) {
throw new RuntimeException("The number of keys and offsets don't match");
}
if (targets.length == 0) {
throw new RuntimeException("The sparse-switch data must contain at least 1 key/target");
}
if (targets.length > 0xFFFF) {
throw new RuntimeException("The sparse-switch data contains too many elements. " +
"The maximum number of switch elements is 65535");
}
//write out padding, if necessary
if (out.getCursor() % 4 != 0) {
out.writeShort(0);
}
out.writeByte(0x00);
out.writeByte(0x02);
out.writeShort(targets.length);
if (targets.length > 0) {
int key = keys[0];
out.writeInt(key);
for (int i = 1; i < keys.length; i++) {
key = keys[i];
if (key <= keys[i - 1]) {
throw new RuntimeException("The targets in a sparse switch block must be sorted in ascending" +
"order, by key");
}
out.writeInt(key);
}
for (int target : targets) {
out.writeInt(target);
}
}
}
public SparseSwitchDataPseudoInstruction(byte[] buffer, int bufferIndex) {
super(Opcode.NOP, buffer, bufferIndex);
byte opcodeByte = buffer[bufferIndex++];
if (opcodeByte != 0x00) {
throw new RuntimeException("Invalid opcode byte for a SparseSwitchData pseudo-instruction");
}
byte subopcodeByte = buffer[bufferIndex];
if (subopcodeByte != 0x02) {
throw new RuntimeException("Invalid sub-opcode byte for a SparseSwitchData pseudo-instruction");
}
}
public Format getFormat() {
return Format.SparseSwitchData;
}
public int getTargetCount() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
}
public static class SparseSwitchTarget {
public int value;
public int target;
}
public Iterator<SparseSwitchTarget> getTargets() {
return new Iterator<SparseSwitchTarget>() {
final int targetCount = getTargetCount();
int i = 0;
int valuePosition = bufferIndex + 4;
int targetPosition = bufferIndex + 4 + targetCount * 4;
SparseSwitchTarget sparseSwitchTarget = new SparseSwitchTarget();
public boolean hasNext() {
return i<targetCount;
}
public SparseSwitchTarget next() {
sparseSwitchTarget.value = NumberUtils.decodeInt(buffer, valuePosition);
sparseSwitchTarget.target = NumberUtils.decodeInt(buffer, targetPosition);
valuePosition+=4;
targetPosition+=4;
i++;
return sparseSwitchTarget;
}
public void remove() {
}
};
}
private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
if (opcode != Opcode.NOP) {
throw new RuntimeException("The opcode for a SparseSwitchDataPseudoInstruction must by NOP");
}
return new SparseSwitchDataPseudoInstruction(buffer, bufferIndex);
}
}
}

View File

@ -1,73 +1,73 @@
/*
* [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.Code;
import org.jf.dexlib.*;
import org.jf.dexlib.Code.Format.Format;
public abstract class Instruction {
public final Opcode opcode;
protected final byte[] buffer;
protected final int bufferIndex;
public int getSize() {
return opcode.format.size;
}
protected Instruction(Opcode opcode) {
this.opcode = opcode;
this.bufferIndex = 0;
this.buffer = new byte[opcode.format.size];
}
protected Instruction(Opcode opcode, int bufferSize) {
this.opcode = opcode;
this.bufferIndex = 0;
this.buffer = new byte[bufferSize];
}
protected Instruction(Opcode opcode, byte[] buffer, int bufferIndex) {
this.opcode = opcode;
this.buffer = buffer;
this.bufferIndex = bufferIndex;
if (buffer[bufferIndex] != opcode.value) {
throw new RuntimeException("The given opcode doesn't match the opcode byte");
}
}
public abstract Format getFormat();
public static interface InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex);
}
}
/*
* [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.Code;
import org.jf.dexlib.*;
import org.jf.dexlib.Code.Format.Format;
public abstract class Instruction {
public final Opcode opcode;
protected final byte[] buffer;
protected final int bufferIndex;
public int getSize() {
return opcode.format.size;
}
protected Instruction(Opcode opcode) {
this.opcode = opcode;
this.bufferIndex = 0;
this.buffer = new byte[opcode.format.size];
}
protected Instruction(Opcode opcode, int bufferSize) {
this.opcode = opcode;
this.bufferIndex = 0;
this.buffer = new byte[bufferSize];
}
protected Instruction(Opcode opcode, byte[] buffer, int bufferIndex) {
this.opcode = opcode;
this.buffer = buffer;
this.bufferIndex = bufferIndex;
if (buffer[bufferIndex] != opcode.value) {
throw new RuntimeException("The given opcode doesn't match the opcode byte");
}
}
public abstract Format getFormat();
public static interface InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex);
}
}

View File

@ -1,310 +1,310 @@
/*
* [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.Code;
import org.jf.dexlib.Code.Format.Format;
import java.util.HashMap;
public enum Opcode
{
NOP((byte)0x00, "nop", ReferenceType.none, Format.Format10x),
MOVE((byte)0x01, "move", ReferenceType.none, Format.Format12x),
MOVE_FROM16((byte)0x02, "move/from16", ReferenceType.none, Format.Format22x),
MOVE_16((byte)0x03, "move/16", ReferenceType.none, Format.Format32x),
MOVE_WIDE((byte)0x04, "move-wide", ReferenceType.none, Format.Format12x),
MOVE_WIDE_FROM16((byte)0x05, "move-wide/from16", ReferenceType.none, Format.Format22x),
MOVE_WIDE_16((byte)0x06, "move-wide/16", ReferenceType.none, Format.Format32x),
MOVE_OBJECT((byte)0x07, "move-object", ReferenceType.none, Format.Format12x),
MOVE_OBJECT_FROM16((byte)0x08, "move-object/from16", ReferenceType.none, Format.Format22x),
MOVE_OBJECT_16((byte)0x09, "move-object/16", ReferenceType.none, Format.Format32x),
MOVE_RESULT((byte)0x0a, "move-result", ReferenceType.none, Format.Format11x),
MOVE_RESULT_WIDE((byte)0x0b, "move-result-wide", ReferenceType.none, Format.Format11x),
MOVE_RESULT_OBJECT((byte)0x0c, "move-result-object", ReferenceType.none, Format.Format11x),
MOVE_EXCEPTION((byte)0x0d, "move-exception", ReferenceType.none, Format.Format11x),
RETURN_VOID((byte)0x0e, "return-void", ReferenceType.none, Format.Format10x),
RETURN((byte)0x0f, "return", ReferenceType.none, Format.Format11x),
RETURN_WIDE((byte)0x10, "return-wide", ReferenceType.none, Format.Format11x),
RETURN_OBJECT((byte)0x11, "return-object", ReferenceType.none, Format.Format11x),
CONST_4((byte)0x12, "const/4", ReferenceType.none, Format.Format11n),
CONST_16((byte)0x13, "const/16", ReferenceType.none, Format.Format21s),
CONST((byte)0x14, "const", ReferenceType.none, Format.Format31i),
CONST_HIGH16((byte)0x15, "const/high16", ReferenceType.none, Format.Format21h),
CONST_WIDE_16((byte)0x16, "const-wide/16", ReferenceType.none, Format.Format21s),
CONST_WIDE_32((byte)0x17, "const-wide/32", ReferenceType.none, Format.Format31i),
CONST_WIDE((byte)0x18, "const-wide", ReferenceType.none, Format.Format51l),
CONST_WIDE_HIGH16((byte)0x19, "const-wide/high16", ReferenceType.none, Format.Format21h),
CONST_STRING((byte)0x1a, "const-string", ReferenceType.string, Format.Format21c),
CONST_STRING_JUMBO((byte)0x1b, "const-string/jumbo", ReferenceType.string, Format.Format31c),
CONST_CLASS((byte)0x1c, "const-class", ReferenceType.type, Format.Format21c),
MONITOR_ENTER((byte)0x1d, "monitor-enter", ReferenceType.none, Format.Format11x),
MONITOR_EXIT((byte)0x1e, "monitor-exit", ReferenceType.none, Format.Format11x),
CHECK_CAST((byte)0x1f, "check-cast", ReferenceType.type, Format.Format21c),
INSTANCE_OF((byte)0x20, "instance-of", ReferenceType.type, Format.Format22c),
ARRAY_LENGTH((byte)0x21, "array-length", ReferenceType.none, Format.Format12x),
NEW_INSTANCE((byte)0x22, "new-instance", ReferenceType.type, Format.Format21c),
NEW_ARRAY((byte)0x23, "new-array", ReferenceType.type, Format.Format22c),
FILLED_NEW_ARRAY((byte)0x24, "filled-new-array", ReferenceType.type, Format.Format35c),
FILLED_NEW_ARRAY_RANGE((byte)0x25, "filled-new-array/range", ReferenceType.type, Format.Format3rc),
FILL_ARRAY_DATA((byte)0x26, "fill-array-data", ReferenceType.none, Format.Format31t),
THROW((byte)0x27, "throw", ReferenceType.none, Format.Format11x),
GOTO((byte)0x28, "goto", ReferenceType.none, Format.Format10t),
GOTO_16((byte)0x29, "goto/16", ReferenceType.none, Format.Format20t),
GOTO_32((byte)0x2a, "goto/32", ReferenceType.none, Format.Format30t),
PACKED_SWITCH((byte)0x2b, "packed-switch", ReferenceType.none, Format.Format31t),
SPARSE_SWITCH((byte)0x2c, "sparse-switch", ReferenceType.none, Format.Format31t),
CMPL_FLOAT((byte)0x2d, "cmpl-float", ReferenceType.none, Format.Format23x),
CMPG_FLOAT((byte)0x2e, "cmpg-float", ReferenceType.none, Format.Format23x),
CMPL_DOUBLE((byte)0x2f, "cmpl-double", ReferenceType.none, Format.Format23x),
CMPG_DOUBLE((byte)0x30, "cmpg-double", ReferenceType.none, Format.Format23x),
CMP_LONG((byte)0x31, "cmp-long", ReferenceType.none, Format.Format23x),
IF_EQ((byte)0x32, "if-eq", ReferenceType.none, Format.Format22t),
IF_NE((byte)0x33, "if-ne", ReferenceType.none, Format.Format22t),
IF_LT((byte)0x34, "if-lt", ReferenceType.none, Format.Format22t),
IF_GE((byte)0x35, "if-ge", ReferenceType.none, Format.Format22t),
IF_GT((byte)0x36, "if-gt", ReferenceType.none, Format.Format22t),
IF_LE((byte)0x37, "if-le", ReferenceType.none, Format.Format22t),
IF_EQZ((byte)0x38, "if-eqz", ReferenceType.none, Format.Format21t),
IF_NEZ((byte)0x39, "if-nez", ReferenceType.none, Format.Format21t),
IF_LTZ((byte)0x3a, "if-ltz", ReferenceType.none, Format.Format21t),
IF_GEZ((byte)0x3b, "if-gez", ReferenceType.none, Format.Format21t),
IF_GTZ((byte)0x3c, "if-gtz", ReferenceType.none, Format.Format21t),
IF_LEZ((byte)0x3d, "if-lez", ReferenceType.none, Format.Format21t),
AGET((byte)0x44, "aget", ReferenceType.none, Format.Format23x),
AGET_WIDE((byte)0x45, "aget-wide", ReferenceType.none, Format.Format23x),
AGET_OBJECT((byte)0x46, "aget-object", ReferenceType.none, Format.Format23x),
AGET_BOOLEAN((byte)0x47, "aget-boolean", ReferenceType.none, Format.Format23x),
AGET_BYTE((byte)0x48, "aget-byte", ReferenceType.none, Format.Format23x),
AGET_CHAR((byte)0x49, "aget-char", ReferenceType.none, Format.Format23x),
AGET_SHORT((byte)0x4a, "aget-short", ReferenceType.none, Format.Format23x),
APUT((byte)0x4b, "aput", ReferenceType.none, Format.Format23x),
APUT_WIDE((byte)0x4c, "aput-wide", ReferenceType.none, Format.Format23x),
APUT_OBJECT((byte)0x4d, "aput-object", ReferenceType.none, Format.Format23x),
APUT_BOOLEAN((byte)0x4e, "aput-boolean", ReferenceType.none, Format.Format23x),
APUT_BYTE((byte)0x4f, "aput-byte", ReferenceType.none, Format.Format23x),
APUT_CHAR((byte)0x50, "aput-char", ReferenceType.none, Format.Format23x),
APUT_SHORT((byte)0x51, "aput-short", ReferenceType.none, Format.Format23x),
IGET((byte)0x52, "iget", ReferenceType.field, Format.Format22c),
IGET_WIDE((byte)0x53, "iget-wide", ReferenceType.field, Format.Format22c),
IGET_OBJECT((byte)0x54, "iget-object", ReferenceType.field, Format.Format22c),
IGET_BOOLEAN((byte)0x55, "iget-boolean", ReferenceType.field, Format.Format22c),
IGET_BYTE((byte)0x56, "iget-byte", ReferenceType.field, Format.Format22c),
IGET_CHAR((byte)0x57, "iget-char", ReferenceType.field, Format.Format22c),
IGET_SHORT((byte)0x58, "iget-short", ReferenceType.field, Format.Format22c),
IPUT((byte)0x59, "iput", ReferenceType.field, Format.Format22c),
IPUT_WIDE((byte)0x5a, "iput-wide", ReferenceType.field, Format.Format22c),
IPUT_OBJECT((byte)0x5b, "iput-object", ReferenceType.field, Format.Format22c),
IPUT_BOOLEAN((byte)0x5c, "iput-boolean", ReferenceType.field, Format.Format22c),
IPUT_BYTE((byte)0x5d, "iput-byte", ReferenceType.field, Format.Format22c),
IPUT_CHAR((byte)0x5e, "iput-char", ReferenceType.field, Format.Format22c),
IPUT_SHORT((byte)0x5f, "iput-short", ReferenceType.field, Format.Format22c),
SGET((byte)0x60, "sget", ReferenceType.field, Format.Format21c),
SGET_WIDE((byte)0x61, "sget-wide", ReferenceType.field, Format.Format21c),
SGET_OBJECT((byte)0x62, "sget-object", ReferenceType.field, Format.Format21c),
SGET_BOOLEAN((byte)0x63, "sget-boolean", ReferenceType.field, Format.Format21c),
SGET_BYTE((byte)0x64, "sget-byte", ReferenceType.field, Format.Format21c),
SGET_CHAR((byte)0x65, "sget-char", ReferenceType.field, Format.Format21c),
SGET_SHORT((byte)0x66, "sget-short", ReferenceType.field, Format.Format21c),
SPUT((byte)0x67, "sput", ReferenceType.field, Format.Format21c),
SPUT_WIDE((byte)0x68, "sput-wide", ReferenceType.field, Format.Format21c),
SPUT_OBJECT((byte)0x69, "sput-object", ReferenceType.field, Format.Format21c),
SPUT_BOOLEAN((byte)0x6a, "sput-boolean", ReferenceType.field, Format.Format21c),
SPUT_BYTE((byte)0x6b, "sput-byte", ReferenceType.field, Format.Format21c),
SPUT_CHAR((byte)0x6c, "sput-char", ReferenceType.field, Format.Format21c),
SPUT_SHORT((byte)0x6d, "sput-short", ReferenceType.field, Format.Format21c),
INVOKE_VIRTUAL((byte)0x6e, "invoke-virtual", ReferenceType.method, Format.Format35c),
INVOKE_SUPER((byte)0x6f, "invoke-super", ReferenceType.method, Format.Format35c),
INVOKE_DIRECT((byte)0x70, "invoke-direct", ReferenceType.method, Format.Format35c),
INVOKE_STATIC((byte)0x71, "invoke-static", ReferenceType.method, Format.Format35c),
INVOKE_INTERFACE((byte)0x72, "invoke-interface", ReferenceType.method, Format.Format35c),
INVOKE_VIRTUAL_RANGE((byte)0x74, "invoke-virtual/range", ReferenceType.method, Format.Format3rc),
INVOKE_SUPER_RANGE((byte)0x75, "invoke-super/range", ReferenceType.method, Format.Format3rc),
INVOKE_DIRECT_RANGE((byte)0x76, "invoke-direct/range", ReferenceType.method, Format.Format3rc),
INVOKE_STATIC_RANGE((byte)0x77, "invoke-static/range", ReferenceType.method, Format.Format3rc),
INVOKE_INTERFACE_RANGE((byte)0x78, "invoke-interface/range", ReferenceType.method, Format.Format3rc),
NEG_INT((byte)0x7b, "neg-int", ReferenceType.none, Format.Format12x),
NOT_INT((byte)0x7c, "not-int", ReferenceType.none, Format.Format12x),
NEG_LONG((byte)0x7d, "neg-long", ReferenceType.none, Format.Format12x),
NOT_LONG((byte)0x7e, "not-long", ReferenceType.none, Format.Format12x),
NEG_FLOAT((byte)0x7f, "neg-float", ReferenceType.none, Format.Format12x),
NEG_DOUBLE((byte)0x80, "neg-double", ReferenceType.none, Format.Format12x),
INT_TO_LONG((byte)0x81, "int-to-long", ReferenceType.none, Format.Format12x),
INT_TO_FLOAT((byte)0x82, "int-to-float", ReferenceType.none, Format.Format12x),
INT_TO_DOUBLE((byte)0x83, "int-to-double", ReferenceType.none, Format.Format12x),
LONG_TO_INT((byte)0x84, "long-to-int", ReferenceType.none, Format.Format12x),
LONG_TO_FLOAT((byte)0x85, "long-to-float", ReferenceType.none, Format.Format12x),
LONG_TO_DOUBLE((byte)0x86, "long-to-double", ReferenceType.none, Format.Format12x),
FLOAT_TO_INT((byte)0x87, "float-to-int", ReferenceType.none, Format.Format12x),
FLOAT_TO_LONG((byte)0x88, "float-to-long", ReferenceType.none, Format.Format12x),
FLOAT_TO_DOUBLE((byte)0x89, "float-to-double", ReferenceType.none, Format.Format12x),
DOUBLE_TO_INT((byte)0x8a, "double-to-int", ReferenceType.none, Format.Format12x),
DOUBLE_TO_LONG((byte)0x8b, "double-to-long", ReferenceType.none, Format.Format12x),
DOUBLE_TO_FLOAT((byte)0x8c, "double-to-float", ReferenceType.none, Format.Format12x),
INT_TO_BYTE((byte)0x8d, "int-to-byte", ReferenceType.none, Format.Format12x),
INT_TO_CHAR((byte)0x8e, "int-to-char", ReferenceType.none, Format.Format12x),
INT_TO_SHORT((byte)0x8f, "int-to-short", ReferenceType.none, Format.Format12x),
ADD_INT((byte)0x90, "add-int", ReferenceType.none, Format.Format23x),
SUB_INT((byte)0x91, "sub-int", ReferenceType.none, Format.Format23x),
MUL_INT((byte)0x92, "mul-int", ReferenceType.none, Format.Format23x),
DIV_INT((byte)0x93, "div-int", ReferenceType.none, Format.Format23x),
REM_INT((byte)0x94, "rem-int", ReferenceType.none, Format.Format23x),
AND_INT((byte)0x95, "and-int", ReferenceType.none, Format.Format23x),
OR_INT((byte)0x96, "or-int", ReferenceType.none, Format.Format23x),
XOR_INT((byte)0x97, "xor-int", ReferenceType.none, Format.Format23x),
SHL_INT((byte)0x98, "shl-int", ReferenceType.none, Format.Format23x),
SHR_INT((byte)0x99, "shr-int", ReferenceType.none, Format.Format23x),
USHR_INT((byte)0x9a, "ushr-int", ReferenceType.none, Format.Format23x),
ADD_LONG((byte)0x9b, "add-long", ReferenceType.none, Format.Format23x),
SUB_LONG((byte)0x9c, "sub-long", ReferenceType.none, Format.Format23x),
MUL_LONG((byte)0x9d, "mul-long", ReferenceType.none, Format.Format23x),
DIV_LONG((byte)0x9e, "div-long", ReferenceType.none, Format.Format23x),
REM_LONG((byte)0x9f, "rem-long", ReferenceType.none, Format.Format23x),
AND_LONG((byte)0xa0, "and-long", ReferenceType.none, Format.Format23x),
OR_LONG((byte)0xa1, "or-long", ReferenceType.none, Format.Format23x),
XOR_LONG((byte)0xa2, "xor-long", ReferenceType.none, Format.Format23x),
SHL_LONG((byte)0xa3, "shl-long", ReferenceType.none, Format.Format23x),
SHR_LONG((byte)0xa4, "shr-long", ReferenceType.none, Format.Format23x),
USHR_LONG((byte)0xa5, "ushr-long", ReferenceType.none, Format.Format23x),
ADD_FLOAT((byte)0xa6, "add-float", ReferenceType.none, Format.Format23x),
SUB_FLOAT((byte)0xa7, "sub-float", ReferenceType.none, Format.Format23x),
MUL_FLOAT((byte)0xa8, "mul-float", ReferenceType.none, Format.Format23x),
DIV_FLOAT((byte)0xa9, "div-float", ReferenceType.none, Format.Format23x),
REM_FLOAT((byte)0xaa, "rem-float", ReferenceType.none, Format.Format23x),
ADD_DOUBLE((byte)0xab, "add-double", ReferenceType.none, Format.Format23x),
SUB_DOUBLE((byte)0xac, "sub-double", ReferenceType.none, Format.Format23x),
MUL_DOUBLE((byte)0xad, "mul-double", ReferenceType.none, Format.Format23x),
DIV_DOUBLE((byte)0xae, "div-double", ReferenceType.none, Format.Format23x),
REM_DOUBLE((byte)0xaf, "rem-double", ReferenceType.none, Format.Format23x),
ADD_INT_2ADDR((byte)0xb0, "add-int/2addr", ReferenceType.none, Format.Format12x),
SUB_INT_2ADDR((byte)0xb1, "sub-int/2addr", ReferenceType.none, Format.Format12x),
MUL_INT_2ADDR((byte)0xb2, "mul-int/2addr", ReferenceType.none, Format.Format12x),
DIV_INT_2ADDR((byte)0xb3, "div-int/2addr", ReferenceType.none, Format.Format12x),
REM_INT_2ADDR((byte)0xb4, "rem-int/2addr", ReferenceType.none, Format.Format12x),
AND_INT_2ADDR((byte)0xb5, "and-int/2addr", ReferenceType.none, Format.Format12x),
OR_INT_2ADDR((byte)0xb6, "or-int/2addr", ReferenceType.none, Format.Format12x),
XOR_INT_2ADDR((byte)0xb7, "xor-int/2addr", ReferenceType.none, Format.Format12x),
SHL_INT_2ADDR((byte)0xb8, "shl-int/2addr", ReferenceType.none, Format.Format12x),
SHR_INT_2ADDR((byte)0xb9, "shr-int/2addr", ReferenceType.none, Format.Format12x),
USHR_INT_2ADDR((byte)0xba, "ushr-int/2addr", ReferenceType.none, Format.Format12x),
ADD_LONG_2ADDR((byte)0xbb, "add-long/2addr", ReferenceType.none, Format.Format12x),
SUB_LONG_2ADDR((byte)0xbc, "sub-long/2addr", ReferenceType.none, Format.Format12x),
MUL_LONG_2ADDR((byte)0xbd, "mul-long/2addr", ReferenceType.none, Format.Format12x),
DIV_LONG_2ADDR((byte)0xbe, "div-long/2addr", ReferenceType.none, Format.Format12x),
REM_LONG_2ADDR((byte)0xbf, "rem-long/2addr", ReferenceType.none, Format.Format12x),
AND_LONG_2ADDR((byte)0xc0, "and-long/2addr", ReferenceType.none, Format.Format12x),
OR_LONG_2ADDR((byte)0xc1, "or-long/2addr", ReferenceType.none, Format.Format12x),
XOR_LONG_2ADDR((byte)0xc2, "xor-long/2addr", ReferenceType.none, Format.Format12x),
SHL_LONG_2ADDR((byte)0xc3, "shl-long/2addr", ReferenceType.none, Format.Format12x),
SHR_LONG_2ADDR((byte)0xc4, "shr-long/2addr", ReferenceType.none, Format.Format12x),
USHR_LONG_2ADDR((byte)0xc5, "ushr-long/2addr", ReferenceType.none, Format.Format12x),
ADD_FLOAT_2ADDR((byte)0xc6, "add-float/2addr", ReferenceType.none, Format.Format12x),
SUB_FLOAT_2ADDR((byte)0xc7, "sub-float/2addr", ReferenceType.none, Format.Format12x),
MUL_FLOAT_2ADDR((byte)0xc8, "mul-float/2addr", ReferenceType.none, Format.Format12x),
DIV_FLOAT_2ADDR((byte)0xc9, "div-float/2addr", ReferenceType.none, Format.Format12x),
REM_FLOAT_2ADDR((byte)0xca, "rem-float/2addr", ReferenceType.none, Format.Format12x),
ADD_DOUBLE_2ADDR((byte)0xcb, "add-double/2addr", ReferenceType.none, Format.Format12x),
SUB_DOUBLE_2ADDR((byte)0xcc, "sub-double/2addr", ReferenceType.none, Format.Format12x),
MUL_DOUBLE_2ADDR((byte)0xcd, "mul-double/2addr", ReferenceType.none, Format.Format12x),
DIV_DOUBLE_2ADDR((byte)0xce, "div-double/2addr", ReferenceType.none, Format.Format12x),
REM_DOUBLE_2ADDR((byte)0xcf, "rem-double/2addr", ReferenceType.none, Format.Format12x),
ADD_INT_LIT16((byte)0xd0, "add-int/lit16", ReferenceType.none, Format.Format22s),
RSUB_INT((byte)0xd1, "rsub-int", ReferenceType.none, Format.Format22s),
MUL_INT_LIT16((byte)0xd2, "mul-int/lit16", ReferenceType.none, Format.Format22s),
DIV_INT_LIT16((byte)0xd3, "div-int/lit16", ReferenceType.none, Format.Format22s),
REM_INT_LIT16((byte)0xd4, "rem-int/lit16", ReferenceType.none, Format.Format22s),
AND_INT_LIT16((byte)0xd5, "and-int/lit16", ReferenceType.none, Format.Format22s),
OR_INT_LIT16((byte)0xd6, "or-int/lit16", ReferenceType.none, Format.Format22s),
XOR_INT_LIT16((byte)0xd7, "xor-int/lit16", ReferenceType.none, Format.Format22s),
ADD_INT_LIT8((byte)0xd8, "add-int/lit8", ReferenceType.none, Format.Format22b),
RSUB_INT_LIT8((byte)0xd9, "rsub-int/lit8", ReferenceType.none, Format.Format22b),
MUL_INT_LIT8((byte)0xda, "mul-int/lit8", ReferenceType.none, Format.Format22b),
DIV_INT_LIT8((byte)0xdb, "div-int/lit8", ReferenceType.none, Format.Format22b),
REM_INT_LIT8((byte)0xdc, "rem-int/lit8", ReferenceType.none, Format.Format22b),
AND_INT_LIT8((byte)0xdd, "and-int/lit8", ReferenceType.none, Format.Format22b),
OR_INT_LIT8((byte)0xde, "or-int/lit8", ReferenceType.none, Format.Format22b),
XOR_INT_LIT8((byte)0xdf, "xor-int/lit8", ReferenceType.none, Format.Format22b),
SHL_INT_LIT8((byte)0xe0, "shl-int/lit8", ReferenceType.none, Format.Format22b),
SHR_INT_LIT8((byte)0xe1, "shr-int/lit8", ReferenceType.none, Format.Format22b),
USHR_INT_LIT8((byte)0xe2, "ushr-int/lit8", ReferenceType.none, Format.Format22b),
INVOKE_EXECUTE_INLINE((byte)0xee, "execute_inline", ReferenceType.none, Format.Format35ms, true),
INVOKE_DIRECT_EMPTY((byte)0xf0, "invoke-direct-empty", ReferenceType.method, Format.Format35s, true),
IGET_QUICK((byte)0xf2, "iget-quick", ReferenceType.none, Format.Format22cs, true),
IGET_WIDE_QUICK((byte)0xf3, "iget-wide-quick", ReferenceType.none, Format.Format22cs, true),
IGET_OBJECT_QUICK((byte)0xf4, "iget-object-quick", ReferenceType.none, Format.Format22cs, true),
IPUT_QUICK((byte)0xf5, "iput-quick", ReferenceType.none, Format.Format22cs, true),
IPUT_WIDE_QUICK((byte)0xf6, "iput-wide-quick", ReferenceType.none, Format.Format22cs, true),
IPUT_OBJECT_QUICK((byte)0xf7, "iput-object-quick", ReferenceType.none, Format.Format22cs, true),
INVOKE_VIRTUAL_QUICK((byte)0xf8, "invoke-virtual-quick", ReferenceType.none, Format.Format35ms, true),
INVOKE_VIRTUAL_RANGE_QUICK((byte)0xf9, "invoke-virtual-range-quick", ReferenceType.none, Format.Format3rms, true),
INVOKE_SUPER_QUICK((byte)0xfa, "invoke-super-quick", ReferenceType.none, Format.Format35ms, true),
INVOKE_SUPER_RANGE_QUICK((byte)0xfb, "invoke-super-range-quick", ReferenceType.none, Format.Format3rms, true);
private static Opcode[] opcodesByValue;
private static HashMap<Integer, Opcode> opcodesByName;
static {
opcodesByValue = new Opcode[256];
opcodesByName = new HashMap<Integer, Opcode>();
for (Opcode opcode: Opcode.values()) {
opcodesByValue[opcode.value & 0xFF] = opcode;
opcodesByName.put(opcode.name.hashCode(), opcode);
}
}
public static Opcode getOpcodeByName(String opcodeName) {
return opcodesByName.get(opcodeName.toLowerCase().hashCode());
}
public static Opcode getOpcodeByValue(byte opcodeValue) {
return opcodesByValue[opcodeValue & 0xFF];
}
public final byte value;
public final String name;
public final ReferenceType referenceType;
public final Format format;
public final boolean odexOnly;
Opcode(byte opcodeValue, String opcodeName, ReferenceType referenceType, Format format) {
this(opcodeValue, opcodeName, referenceType, format, false);
}
Opcode(byte opcodeValue, String opcodeName, ReferenceType referenceType, Format format, boolean odexOnly) {
this.value = opcodeValue;
this.name = opcodeName;
this.referenceType = referenceType;
this.format = format;
this.odexOnly = odexOnly;
}
}
/*
* [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.Code;
import org.jf.dexlib.Code.Format.Format;
import java.util.HashMap;
public enum Opcode
{
NOP((byte)0x00, "nop", ReferenceType.none, Format.Format10x),
MOVE((byte)0x01, "move", ReferenceType.none, Format.Format12x),
MOVE_FROM16((byte)0x02, "move/from16", ReferenceType.none, Format.Format22x),
MOVE_16((byte)0x03, "move/16", ReferenceType.none, Format.Format32x),
MOVE_WIDE((byte)0x04, "move-wide", ReferenceType.none, Format.Format12x),
MOVE_WIDE_FROM16((byte)0x05, "move-wide/from16", ReferenceType.none, Format.Format22x),
MOVE_WIDE_16((byte)0x06, "move-wide/16", ReferenceType.none, Format.Format32x),
MOVE_OBJECT((byte)0x07, "move-object", ReferenceType.none, Format.Format12x),
MOVE_OBJECT_FROM16((byte)0x08, "move-object/from16", ReferenceType.none, Format.Format22x),
MOVE_OBJECT_16((byte)0x09, "move-object/16", ReferenceType.none, Format.Format32x),
MOVE_RESULT((byte)0x0a, "move-result", ReferenceType.none, Format.Format11x),
MOVE_RESULT_WIDE((byte)0x0b, "move-result-wide", ReferenceType.none, Format.Format11x),
MOVE_RESULT_OBJECT((byte)0x0c, "move-result-object", ReferenceType.none, Format.Format11x),
MOVE_EXCEPTION((byte)0x0d, "move-exception", ReferenceType.none, Format.Format11x),
RETURN_VOID((byte)0x0e, "return-void", ReferenceType.none, Format.Format10x),
RETURN((byte)0x0f, "return", ReferenceType.none, Format.Format11x),
RETURN_WIDE((byte)0x10, "return-wide", ReferenceType.none, Format.Format11x),
RETURN_OBJECT((byte)0x11, "return-object", ReferenceType.none, Format.Format11x),
CONST_4((byte)0x12, "const/4", ReferenceType.none, Format.Format11n),
CONST_16((byte)0x13, "const/16", ReferenceType.none, Format.Format21s),
CONST((byte)0x14, "const", ReferenceType.none, Format.Format31i),
CONST_HIGH16((byte)0x15, "const/high16", ReferenceType.none, Format.Format21h),
CONST_WIDE_16((byte)0x16, "const-wide/16", ReferenceType.none, Format.Format21s),
CONST_WIDE_32((byte)0x17, "const-wide/32", ReferenceType.none, Format.Format31i),
CONST_WIDE((byte)0x18, "const-wide", ReferenceType.none, Format.Format51l),
CONST_WIDE_HIGH16((byte)0x19, "const-wide/high16", ReferenceType.none, Format.Format21h),
CONST_STRING((byte)0x1a, "const-string", ReferenceType.string, Format.Format21c),
CONST_STRING_JUMBO((byte)0x1b, "const-string/jumbo", ReferenceType.string, Format.Format31c),
CONST_CLASS((byte)0x1c, "const-class", ReferenceType.type, Format.Format21c),
MONITOR_ENTER((byte)0x1d, "monitor-enter", ReferenceType.none, Format.Format11x),
MONITOR_EXIT((byte)0x1e, "monitor-exit", ReferenceType.none, Format.Format11x),
CHECK_CAST((byte)0x1f, "check-cast", ReferenceType.type, Format.Format21c),
INSTANCE_OF((byte)0x20, "instance-of", ReferenceType.type, Format.Format22c),
ARRAY_LENGTH((byte)0x21, "array-length", ReferenceType.none, Format.Format12x),
NEW_INSTANCE((byte)0x22, "new-instance", ReferenceType.type, Format.Format21c),
NEW_ARRAY((byte)0x23, "new-array", ReferenceType.type, Format.Format22c),
FILLED_NEW_ARRAY((byte)0x24, "filled-new-array", ReferenceType.type, Format.Format35c),
FILLED_NEW_ARRAY_RANGE((byte)0x25, "filled-new-array/range", ReferenceType.type, Format.Format3rc),
FILL_ARRAY_DATA((byte)0x26, "fill-array-data", ReferenceType.none, Format.Format31t),
THROW((byte)0x27, "throw", ReferenceType.none, Format.Format11x),
GOTO((byte)0x28, "goto", ReferenceType.none, Format.Format10t),
GOTO_16((byte)0x29, "goto/16", ReferenceType.none, Format.Format20t),
GOTO_32((byte)0x2a, "goto/32", ReferenceType.none, Format.Format30t),
PACKED_SWITCH((byte)0x2b, "packed-switch", ReferenceType.none, Format.Format31t),
SPARSE_SWITCH((byte)0x2c, "sparse-switch", ReferenceType.none, Format.Format31t),
CMPL_FLOAT((byte)0x2d, "cmpl-float", ReferenceType.none, Format.Format23x),
CMPG_FLOAT((byte)0x2e, "cmpg-float", ReferenceType.none, Format.Format23x),
CMPL_DOUBLE((byte)0x2f, "cmpl-double", ReferenceType.none, Format.Format23x),
CMPG_DOUBLE((byte)0x30, "cmpg-double", ReferenceType.none, Format.Format23x),
CMP_LONG((byte)0x31, "cmp-long", ReferenceType.none, Format.Format23x),
IF_EQ((byte)0x32, "if-eq", ReferenceType.none, Format.Format22t),
IF_NE((byte)0x33, "if-ne", ReferenceType.none, Format.Format22t),
IF_LT((byte)0x34, "if-lt", ReferenceType.none, Format.Format22t),
IF_GE((byte)0x35, "if-ge", ReferenceType.none, Format.Format22t),
IF_GT((byte)0x36, "if-gt", ReferenceType.none, Format.Format22t),
IF_LE((byte)0x37, "if-le", ReferenceType.none, Format.Format22t),
IF_EQZ((byte)0x38, "if-eqz", ReferenceType.none, Format.Format21t),
IF_NEZ((byte)0x39, "if-nez", ReferenceType.none, Format.Format21t),
IF_LTZ((byte)0x3a, "if-ltz", ReferenceType.none, Format.Format21t),
IF_GEZ((byte)0x3b, "if-gez", ReferenceType.none, Format.Format21t),
IF_GTZ((byte)0x3c, "if-gtz", ReferenceType.none, Format.Format21t),
IF_LEZ((byte)0x3d, "if-lez", ReferenceType.none, Format.Format21t),
AGET((byte)0x44, "aget", ReferenceType.none, Format.Format23x),
AGET_WIDE((byte)0x45, "aget-wide", ReferenceType.none, Format.Format23x),
AGET_OBJECT((byte)0x46, "aget-object", ReferenceType.none, Format.Format23x),
AGET_BOOLEAN((byte)0x47, "aget-boolean", ReferenceType.none, Format.Format23x),
AGET_BYTE((byte)0x48, "aget-byte", ReferenceType.none, Format.Format23x),
AGET_CHAR((byte)0x49, "aget-char", ReferenceType.none, Format.Format23x),
AGET_SHORT((byte)0x4a, "aget-short", ReferenceType.none, Format.Format23x),
APUT((byte)0x4b, "aput", ReferenceType.none, Format.Format23x),
APUT_WIDE((byte)0x4c, "aput-wide", ReferenceType.none, Format.Format23x),
APUT_OBJECT((byte)0x4d, "aput-object", ReferenceType.none, Format.Format23x),
APUT_BOOLEAN((byte)0x4e, "aput-boolean", ReferenceType.none, Format.Format23x),
APUT_BYTE((byte)0x4f, "aput-byte", ReferenceType.none, Format.Format23x),
APUT_CHAR((byte)0x50, "aput-char", ReferenceType.none, Format.Format23x),
APUT_SHORT((byte)0x51, "aput-short", ReferenceType.none, Format.Format23x),
IGET((byte)0x52, "iget", ReferenceType.field, Format.Format22c),
IGET_WIDE((byte)0x53, "iget-wide", ReferenceType.field, Format.Format22c),
IGET_OBJECT((byte)0x54, "iget-object", ReferenceType.field, Format.Format22c),
IGET_BOOLEAN((byte)0x55, "iget-boolean", ReferenceType.field, Format.Format22c),
IGET_BYTE((byte)0x56, "iget-byte", ReferenceType.field, Format.Format22c),
IGET_CHAR((byte)0x57, "iget-char", ReferenceType.field, Format.Format22c),
IGET_SHORT((byte)0x58, "iget-short", ReferenceType.field, Format.Format22c),
IPUT((byte)0x59, "iput", ReferenceType.field, Format.Format22c),
IPUT_WIDE((byte)0x5a, "iput-wide", ReferenceType.field, Format.Format22c),
IPUT_OBJECT((byte)0x5b, "iput-object", ReferenceType.field, Format.Format22c),
IPUT_BOOLEAN((byte)0x5c, "iput-boolean", ReferenceType.field, Format.Format22c),
IPUT_BYTE((byte)0x5d, "iput-byte", ReferenceType.field, Format.Format22c),
IPUT_CHAR((byte)0x5e, "iput-char", ReferenceType.field, Format.Format22c),
IPUT_SHORT((byte)0x5f, "iput-short", ReferenceType.field, Format.Format22c),
SGET((byte)0x60, "sget", ReferenceType.field, Format.Format21c),
SGET_WIDE((byte)0x61, "sget-wide", ReferenceType.field, Format.Format21c),
SGET_OBJECT((byte)0x62, "sget-object", ReferenceType.field, Format.Format21c),
SGET_BOOLEAN((byte)0x63, "sget-boolean", ReferenceType.field, Format.Format21c),
SGET_BYTE((byte)0x64, "sget-byte", ReferenceType.field, Format.Format21c),
SGET_CHAR((byte)0x65, "sget-char", ReferenceType.field, Format.Format21c),
SGET_SHORT((byte)0x66, "sget-short", ReferenceType.field, Format.Format21c),
SPUT((byte)0x67, "sput", ReferenceType.field, Format.Format21c),
SPUT_WIDE((byte)0x68, "sput-wide", ReferenceType.field, Format.Format21c),
SPUT_OBJECT((byte)0x69, "sput-object", ReferenceType.field, Format.Format21c),
SPUT_BOOLEAN((byte)0x6a, "sput-boolean", ReferenceType.field, Format.Format21c),
SPUT_BYTE((byte)0x6b, "sput-byte", ReferenceType.field, Format.Format21c),
SPUT_CHAR((byte)0x6c, "sput-char", ReferenceType.field, Format.Format21c),
SPUT_SHORT((byte)0x6d, "sput-short", ReferenceType.field, Format.Format21c),
INVOKE_VIRTUAL((byte)0x6e, "invoke-virtual", ReferenceType.method, Format.Format35c),
INVOKE_SUPER((byte)0x6f, "invoke-super", ReferenceType.method, Format.Format35c),
INVOKE_DIRECT((byte)0x70, "invoke-direct", ReferenceType.method, Format.Format35c),
INVOKE_STATIC((byte)0x71, "invoke-static", ReferenceType.method, Format.Format35c),
INVOKE_INTERFACE((byte)0x72, "invoke-interface", ReferenceType.method, Format.Format35c),
INVOKE_VIRTUAL_RANGE((byte)0x74, "invoke-virtual/range", ReferenceType.method, Format.Format3rc),
INVOKE_SUPER_RANGE((byte)0x75, "invoke-super/range", ReferenceType.method, Format.Format3rc),
INVOKE_DIRECT_RANGE((byte)0x76, "invoke-direct/range", ReferenceType.method, Format.Format3rc),
INVOKE_STATIC_RANGE((byte)0x77, "invoke-static/range", ReferenceType.method, Format.Format3rc),
INVOKE_INTERFACE_RANGE((byte)0x78, "invoke-interface/range", ReferenceType.method, Format.Format3rc),
NEG_INT((byte)0x7b, "neg-int", ReferenceType.none, Format.Format12x),
NOT_INT((byte)0x7c, "not-int", ReferenceType.none, Format.Format12x),
NEG_LONG((byte)0x7d, "neg-long", ReferenceType.none, Format.Format12x),
NOT_LONG((byte)0x7e, "not-long", ReferenceType.none, Format.Format12x),
NEG_FLOAT((byte)0x7f, "neg-float", ReferenceType.none, Format.Format12x),
NEG_DOUBLE((byte)0x80, "neg-double", ReferenceType.none, Format.Format12x),
INT_TO_LONG((byte)0x81, "int-to-long", ReferenceType.none, Format.Format12x),
INT_TO_FLOAT((byte)0x82, "int-to-float", ReferenceType.none, Format.Format12x),
INT_TO_DOUBLE((byte)0x83, "int-to-double", ReferenceType.none, Format.Format12x),
LONG_TO_INT((byte)0x84, "long-to-int", ReferenceType.none, Format.Format12x),
LONG_TO_FLOAT((byte)0x85, "long-to-float", ReferenceType.none, Format.Format12x),
LONG_TO_DOUBLE((byte)0x86, "long-to-double", ReferenceType.none, Format.Format12x),
FLOAT_TO_INT((byte)0x87, "float-to-int", ReferenceType.none, Format.Format12x),
FLOAT_TO_LONG((byte)0x88, "float-to-long", ReferenceType.none, Format.Format12x),
FLOAT_TO_DOUBLE((byte)0x89, "float-to-double", ReferenceType.none, Format.Format12x),
DOUBLE_TO_INT((byte)0x8a, "double-to-int", ReferenceType.none, Format.Format12x),
DOUBLE_TO_LONG((byte)0x8b, "double-to-long", ReferenceType.none, Format.Format12x),
DOUBLE_TO_FLOAT((byte)0x8c, "double-to-float", ReferenceType.none, Format.Format12x),
INT_TO_BYTE((byte)0x8d, "int-to-byte", ReferenceType.none, Format.Format12x),
INT_TO_CHAR((byte)0x8e, "int-to-char", ReferenceType.none, Format.Format12x),
INT_TO_SHORT((byte)0x8f, "int-to-short", ReferenceType.none, Format.Format12x),
ADD_INT((byte)0x90, "add-int", ReferenceType.none, Format.Format23x),
SUB_INT((byte)0x91, "sub-int", ReferenceType.none, Format.Format23x),
MUL_INT((byte)0x92, "mul-int", ReferenceType.none, Format.Format23x),
DIV_INT((byte)0x93, "div-int", ReferenceType.none, Format.Format23x),
REM_INT((byte)0x94, "rem-int", ReferenceType.none, Format.Format23x),
AND_INT((byte)0x95, "and-int", ReferenceType.none, Format.Format23x),
OR_INT((byte)0x96, "or-int", ReferenceType.none, Format.Format23x),
XOR_INT((byte)0x97, "xor-int", ReferenceType.none, Format.Format23x),
SHL_INT((byte)0x98, "shl-int", ReferenceType.none, Format.Format23x),
SHR_INT((byte)0x99, "shr-int", ReferenceType.none, Format.Format23x),
USHR_INT((byte)0x9a, "ushr-int", ReferenceType.none, Format.Format23x),
ADD_LONG((byte)0x9b, "add-long", ReferenceType.none, Format.Format23x),
SUB_LONG((byte)0x9c, "sub-long", ReferenceType.none, Format.Format23x),
MUL_LONG((byte)0x9d, "mul-long", ReferenceType.none, Format.Format23x),
DIV_LONG((byte)0x9e, "div-long", ReferenceType.none, Format.Format23x),
REM_LONG((byte)0x9f, "rem-long", ReferenceType.none, Format.Format23x),
AND_LONG((byte)0xa0, "and-long", ReferenceType.none, Format.Format23x),
OR_LONG((byte)0xa1, "or-long", ReferenceType.none, Format.Format23x),
XOR_LONG((byte)0xa2, "xor-long", ReferenceType.none, Format.Format23x),
SHL_LONG((byte)0xa3, "shl-long", ReferenceType.none, Format.Format23x),
SHR_LONG((byte)0xa4, "shr-long", ReferenceType.none, Format.Format23x),
USHR_LONG((byte)0xa5, "ushr-long", ReferenceType.none, Format.Format23x),
ADD_FLOAT((byte)0xa6, "add-float", ReferenceType.none, Format.Format23x),
SUB_FLOAT((byte)0xa7, "sub-float", ReferenceType.none, Format.Format23x),
MUL_FLOAT((byte)0xa8, "mul-float", ReferenceType.none, Format.Format23x),
DIV_FLOAT((byte)0xa9, "div-float", ReferenceType.none, Format.Format23x),
REM_FLOAT((byte)0xaa, "rem-float", ReferenceType.none, Format.Format23x),
ADD_DOUBLE((byte)0xab, "add-double", ReferenceType.none, Format.Format23x),
SUB_DOUBLE((byte)0xac, "sub-double", ReferenceType.none, Format.Format23x),
MUL_DOUBLE((byte)0xad, "mul-double", ReferenceType.none, Format.Format23x),
DIV_DOUBLE((byte)0xae, "div-double", ReferenceType.none, Format.Format23x),
REM_DOUBLE((byte)0xaf, "rem-double", ReferenceType.none, Format.Format23x),
ADD_INT_2ADDR((byte)0xb0, "add-int/2addr", ReferenceType.none, Format.Format12x),
SUB_INT_2ADDR((byte)0xb1, "sub-int/2addr", ReferenceType.none, Format.Format12x),
MUL_INT_2ADDR((byte)0xb2, "mul-int/2addr", ReferenceType.none, Format.Format12x),
DIV_INT_2ADDR((byte)0xb3, "div-int/2addr", ReferenceType.none, Format.Format12x),
REM_INT_2ADDR((byte)0xb4, "rem-int/2addr", ReferenceType.none, Format.Format12x),
AND_INT_2ADDR((byte)0xb5, "and-int/2addr", ReferenceType.none, Format.Format12x),
OR_INT_2ADDR((byte)0xb6, "or-int/2addr", ReferenceType.none, Format.Format12x),
XOR_INT_2ADDR((byte)0xb7, "xor-int/2addr", ReferenceType.none, Format.Format12x),
SHL_INT_2ADDR((byte)0xb8, "shl-int/2addr", ReferenceType.none, Format.Format12x),
SHR_INT_2ADDR((byte)0xb9, "shr-int/2addr", ReferenceType.none, Format.Format12x),
USHR_INT_2ADDR((byte)0xba, "ushr-int/2addr", ReferenceType.none, Format.Format12x),
ADD_LONG_2ADDR((byte)0xbb, "add-long/2addr", ReferenceType.none, Format.Format12x),
SUB_LONG_2ADDR((byte)0xbc, "sub-long/2addr", ReferenceType.none, Format.Format12x),
MUL_LONG_2ADDR((byte)0xbd, "mul-long/2addr", ReferenceType.none, Format.Format12x),
DIV_LONG_2ADDR((byte)0xbe, "div-long/2addr", ReferenceType.none, Format.Format12x),
REM_LONG_2ADDR((byte)0xbf, "rem-long/2addr", ReferenceType.none, Format.Format12x),
AND_LONG_2ADDR((byte)0xc0, "and-long/2addr", ReferenceType.none, Format.Format12x),
OR_LONG_2ADDR((byte)0xc1, "or-long/2addr", ReferenceType.none, Format.Format12x),
XOR_LONG_2ADDR((byte)0xc2, "xor-long/2addr", ReferenceType.none, Format.Format12x),
SHL_LONG_2ADDR((byte)0xc3, "shl-long/2addr", ReferenceType.none, Format.Format12x),
SHR_LONG_2ADDR((byte)0xc4, "shr-long/2addr", ReferenceType.none, Format.Format12x),
USHR_LONG_2ADDR((byte)0xc5, "ushr-long/2addr", ReferenceType.none, Format.Format12x),
ADD_FLOAT_2ADDR((byte)0xc6, "add-float/2addr", ReferenceType.none, Format.Format12x),
SUB_FLOAT_2ADDR((byte)0xc7, "sub-float/2addr", ReferenceType.none, Format.Format12x),
MUL_FLOAT_2ADDR((byte)0xc8, "mul-float/2addr", ReferenceType.none, Format.Format12x),
DIV_FLOAT_2ADDR((byte)0xc9, "div-float/2addr", ReferenceType.none, Format.Format12x),
REM_FLOAT_2ADDR((byte)0xca, "rem-float/2addr", ReferenceType.none, Format.Format12x),
ADD_DOUBLE_2ADDR((byte)0xcb, "add-double/2addr", ReferenceType.none, Format.Format12x),
SUB_DOUBLE_2ADDR((byte)0xcc, "sub-double/2addr", ReferenceType.none, Format.Format12x),
MUL_DOUBLE_2ADDR((byte)0xcd, "mul-double/2addr", ReferenceType.none, Format.Format12x),
DIV_DOUBLE_2ADDR((byte)0xce, "div-double/2addr", ReferenceType.none, Format.Format12x),
REM_DOUBLE_2ADDR((byte)0xcf, "rem-double/2addr", ReferenceType.none, Format.Format12x),
ADD_INT_LIT16((byte)0xd0, "add-int/lit16", ReferenceType.none, Format.Format22s),
RSUB_INT((byte)0xd1, "rsub-int", ReferenceType.none, Format.Format22s),
MUL_INT_LIT16((byte)0xd2, "mul-int/lit16", ReferenceType.none, Format.Format22s),
DIV_INT_LIT16((byte)0xd3, "div-int/lit16", ReferenceType.none, Format.Format22s),
REM_INT_LIT16((byte)0xd4, "rem-int/lit16", ReferenceType.none, Format.Format22s),
AND_INT_LIT16((byte)0xd5, "and-int/lit16", ReferenceType.none, Format.Format22s),
OR_INT_LIT16((byte)0xd6, "or-int/lit16", ReferenceType.none, Format.Format22s),
XOR_INT_LIT16((byte)0xd7, "xor-int/lit16", ReferenceType.none, Format.Format22s),
ADD_INT_LIT8((byte)0xd8, "add-int/lit8", ReferenceType.none, Format.Format22b),
RSUB_INT_LIT8((byte)0xd9, "rsub-int/lit8", ReferenceType.none, Format.Format22b),
MUL_INT_LIT8((byte)0xda, "mul-int/lit8", ReferenceType.none, Format.Format22b),
DIV_INT_LIT8((byte)0xdb, "div-int/lit8", ReferenceType.none, Format.Format22b),
REM_INT_LIT8((byte)0xdc, "rem-int/lit8", ReferenceType.none, Format.Format22b),
AND_INT_LIT8((byte)0xdd, "and-int/lit8", ReferenceType.none, Format.Format22b),
OR_INT_LIT8((byte)0xde, "or-int/lit8", ReferenceType.none, Format.Format22b),
XOR_INT_LIT8((byte)0xdf, "xor-int/lit8", ReferenceType.none, Format.Format22b),
SHL_INT_LIT8((byte)0xe0, "shl-int/lit8", ReferenceType.none, Format.Format22b),
SHR_INT_LIT8((byte)0xe1, "shr-int/lit8", ReferenceType.none, Format.Format22b),
USHR_INT_LIT8((byte)0xe2, "ushr-int/lit8", ReferenceType.none, Format.Format22b),
INVOKE_EXECUTE_INLINE((byte)0xee, "execute_inline", ReferenceType.none, Format.Format35ms, true),
INVOKE_DIRECT_EMPTY((byte)0xf0, "invoke-direct-empty", ReferenceType.method, Format.Format35s, true),
IGET_QUICK((byte)0xf2, "iget-quick", ReferenceType.none, Format.Format22cs, true),
IGET_WIDE_QUICK((byte)0xf3, "iget-wide-quick", ReferenceType.none, Format.Format22cs, true),
IGET_OBJECT_QUICK((byte)0xf4, "iget-object-quick", ReferenceType.none, Format.Format22cs, true),
IPUT_QUICK((byte)0xf5, "iput-quick", ReferenceType.none, Format.Format22cs, true),
IPUT_WIDE_QUICK((byte)0xf6, "iput-wide-quick", ReferenceType.none, Format.Format22cs, true),
IPUT_OBJECT_QUICK((byte)0xf7, "iput-object-quick", ReferenceType.none, Format.Format22cs, true),
INVOKE_VIRTUAL_QUICK((byte)0xf8, "invoke-virtual-quick", ReferenceType.none, Format.Format35ms, true),
INVOKE_VIRTUAL_RANGE_QUICK((byte)0xf9, "invoke-virtual-range-quick", ReferenceType.none, Format.Format3rms, true),
INVOKE_SUPER_QUICK((byte)0xfa, "invoke-super-quick", ReferenceType.none, Format.Format35ms, true),
INVOKE_SUPER_RANGE_QUICK((byte)0xfb, "invoke-super-range-quick", ReferenceType.none, Format.Format3rms, true);
private static Opcode[] opcodesByValue;
private static HashMap<Integer, Opcode> opcodesByName;
static {
opcodesByValue = new Opcode[256];
opcodesByName = new HashMap<Integer, Opcode>();
for (Opcode opcode: Opcode.values()) {
opcodesByValue[opcode.value & 0xFF] = opcode;
opcodesByName.put(opcode.name.hashCode(), opcode);
}
}
public static Opcode getOpcodeByName(String opcodeName) {
return opcodesByName.get(opcodeName.toLowerCase().hashCode());
}
public static Opcode getOpcodeByValue(byte opcodeValue) {
return opcodesByValue[opcodeValue & 0xFF];
}
public final byte value;
public final String name;
public final ReferenceType referenceType;
public final Format format;
public final boolean odexOnly;
Opcode(byte opcodeValue, String opcodeName, ReferenceType referenceType, Format format) {
this(opcodeValue, opcodeName, referenceType, format, false);
}
Opcode(byte opcodeValue, String opcodeName, ReferenceType referenceType, Format format, boolean odexOnly) {
this.value = opcodeValue;
this.name = opcodeName;
this.referenceType = referenceType;
this.format = format;
this.odexOnly = odexOnly;
}
}

View File

@ -1,56 +1,56 @@
/*
* [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.Code;
import org.jf.dexlib.*;
public enum ReferenceType
{
string,
type,
field,
method,
none;
public boolean checkItem(Item item) {
switch (this) {
case string:
return item instanceof StringIdItem;
case type:
return item instanceof TypeIdItem;
case field:
return item instanceof FieldIdItem;
case method:
return item instanceof MethodIdItem;
case none:
return item == null;
}
return false;
}
/*
* [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.Code;
import org.jf.dexlib.*;
public enum ReferenceType
{
string,
type,
field,
method,
none;
public boolean checkItem(Item item) {
switch (this) {
case string:
return item instanceof StringIdItem;
case type:
return item instanceof TypeIdItem;
case field:
return item instanceof FieldIdItem;
case method:
return item instanceof MethodIdItem;
case none:
return item == null;
}
return false;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,135 +1,135 @@
/*
* [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;
import org.jf.dexlib.EncodedValue.ArrayEncodedSubValue;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class EncodedArrayItem extends Item<EncodedArrayItem> {
private int hashCode = 0;
private ArrayEncodedSubValue encodedArray;
/**
* Creates a new uninitialized <code>EncodedArrayItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected EncodedArrayItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>EncodedArrayItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param encodedArray The encoded array value
*/
private EncodedArrayItem(DexFile dexFile, ArrayEncodedSubValue encodedArray) {
super(dexFile);
this.encodedArray = encodedArray;
}
/**
* Returns an <code>EncodedArrayItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param encodedArray The encoded array value
* @return an <code>EncodedArrayItem</code> for the given values, and that has been interned into the given
*/
public static EncodedArrayItem getInternedEncodedArrayItem(DexFile dexFile, ArrayEncodedSubValue encodedArray) {
EncodedArrayItem encodedArrayItem = new EncodedArrayItem(dexFile, encodedArray);
return dexFile.EncodedArraysSection.intern(encodedArrayItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
encodedArray = new ArrayEncodedSubValue(dexFile, in);
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return encodedArray.placeValue(offset);
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
encodedArray.writeValue(out);
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_ENCODED_ARRAY_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "encoded_array @0x" + Integer.toHexString(getOffset());
}
/** {@inheritDoc} */
public int compareTo(EncodedArrayItem encodedArrayItem) {
return encodedArray.compareTo(encodedArrayItem.encodedArray);
}
/**
* @return The encoded array value
*/
public ArrayEncodedSubValue getEncodedArray() {
return encodedArray;
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = encodedArray.hashCode();
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
EncodedArrayItem other = (EncodedArrayItem)o;
return (encodedArray.compareTo(other.encodedArray) == 0);
}
}
/*
* [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;
import org.jf.dexlib.EncodedValue.ArrayEncodedSubValue;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class EncodedArrayItem extends Item<EncodedArrayItem> {
private int hashCode = 0;
private ArrayEncodedSubValue encodedArray;
/**
* Creates a new uninitialized <code>EncodedArrayItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected EncodedArrayItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>EncodedArrayItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param encodedArray The encoded array value
*/
private EncodedArrayItem(DexFile dexFile, ArrayEncodedSubValue encodedArray) {
super(dexFile);
this.encodedArray = encodedArray;
}
/**
* Returns an <code>EncodedArrayItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param encodedArray The encoded array value
* @return an <code>EncodedArrayItem</code> for the given values, and that has been interned into the given
*/
public static EncodedArrayItem getInternedEncodedArrayItem(DexFile dexFile, ArrayEncodedSubValue encodedArray) {
EncodedArrayItem encodedArrayItem = new EncodedArrayItem(dexFile, encodedArray);
return dexFile.EncodedArraysSection.intern(encodedArrayItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
encodedArray = new ArrayEncodedSubValue(dexFile, in);
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return encodedArray.placeValue(offset);
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
encodedArray.writeValue(out);
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_ENCODED_ARRAY_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "encoded_array @0x" + Integer.toHexString(getOffset());
}
/** {@inheritDoc} */
public int compareTo(EncodedArrayItem encodedArrayItem) {
return encodedArray.compareTo(encodedArrayItem.encodedArray);
}
/**
* @return The encoded array value
*/
public ArrayEncodedSubValue getEncodedArray() {
return encodedArray;
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = encodedArray.hashCode();
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
EncodedArrayItem other = (EncodedArrayItem)o;
return (encodedArray.compareTo(other.encodedArray) == 0);
}
}

View File

@ -1,86 +1,86 @@
/*
* [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.EncodedValue;
import org.jf.dexlib.Util.SparseArray;
public enum ValueType {
VALUE_BYTE((byte) 0x00),
VALUE_SHORT((byte) 0x02),
VALUE_CHAR((byte) 0x03),
VALUE_INT((byte) 0x04),
VALUE_LONG((byte) 0x06),
VALUE_FLOAT((byte) 0x10),
VALUE_DOUBLE((byte) 0x11),
VALUE_STRING((byte) 0x17),
VALUE_TYPE((byte) 0x18),
VALUE_FIELD((byte) 0x19),
VALUE_METHOD((byte) 0x1a),
VALUE_ENUM((byte) 0x1b),
VALUE_ARRAY((byte) 0x1c),
VALUE_ANNOTATION((byte) 0x1d),
VALUE_NULL((byte) 0x1e),
VALUE_BOOLEAN((byte) 0x1f);
/**
* A map to facilitate looking up a <code>ValueType</code> by byte value
*/
private final static SparseArray<ValueType> valueTypeIntegerMap;
static {
/** build the <code>valueTypeIntegerMap</code> object */
valueTypeIntegerMap = new SparseArray<ValueType>(16);
for (ValueType valueType : ValueType.values()) {
valueTypeIntegerMap.put(valueType.value, valueType);
}
}
/**
* The byte value for this ValueType
*/
public final byte value;
private ValueType(byte value) {
this.value = value;
}
/**
* Converts a byte value to the corresponding ValueType enum value,
* or null if the value isn't a valid ValueType value
*
* @param valueType the byte value to convert to a ValueType
* @return the ValueType enum value corresponding to valueType, or null
* if not a valid ValueType value
*/
public static ValueType fromByte(byte valueType) {
return valueTypeIntegerMap.get(valueType);
}
/*
* [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.EncodedValue;
import org.jf.dexlib.Util.SparseArray;
public enum ValueType {
VALUE_BYTE((byte) 0x00),
VALUE_SHORT((byte) 0x02),
VALUE_CHAR((byte) 0x03),
VALUE_INT((byte) 0x04),
VALUE_LONG((byte) 0x06),
VALUE_FLOAT((byte) 0x10),
VALUE_DOUBLE((byte) 0x11),
VALUE_STRING((byte) 0x17),
VALUE_TYPE((byte) 0x18),
VALUE_FIELD((byte) 0x19),
VALUE_METHOD((byte) 0x1a),
VALUE_ENUM((byte) 0x1b),
VALUE_ARRAY((byte) 0x1c),
VALUE_ANNOTATION((byte) 0x1d),
VALUE_NULL((byte) 0x1e),
VALUE_BOOLEAN((byte) 0x1f);
/**
* A map to facilitate looking up a <code>ValueType</code> by byte value
*/
private final static SparseArray<ValueType> valueTypeIntegerMap;
static {
/** build the <code>valueTypeIntegerMap</code> object */
valueTypeIntegerMap = new SparseArray<ValueType>(16);
for (ValueType valueType : ValueType.values()) {
valueTypeIntegerMap.put(valueType.value, valueType);
}
}
/**
* The byte value for this ValueType
*/
public final byte value;
private ValueType(byte value) {
this.value = value;
}
/**
* Converts a byte value to the corresponding ValueType enum value,
* or null if the value isn't a valid ValueType value
*
* @param valueType the byte value to convert to a ValueType
* @return the ValueType enum value corresponding to valueType, or null
* if not a valid ValueType value
*/
public static ValueType fromByte(byte valueType) {
return valueTypeIntegerMap.get(valueType);
}
}

View File

@ -1,217 +1,217 @@
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class FieldIdItem extends Item<FieldIdItem> {
private int hashCode = 0;
private TypeIdItem classType;
private TypeIdItem fieldType;
private StringIdItem fieldName;
/**
* Creates a new uninitialized <code>FieldIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected FieldIdItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>FieldIdItem</code> for the given class, type and name
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType the class that the field is a member of
* @param fieldType the type of the field
* @param fieldName the name of the field
*/
private FieldIdItem(DexFile dexFile, TypeIdItem classType, TypeIdItem fieldType, StringIdItem fieldName) {
this(dexFile);
assert classType.dexFile == dexFile;
assert fieldType.dexFile == dexFile;
assert fieldName.dexFile == dexFile;
this.classType = classType;
this.fieldType = fieldType;
this.fieldName = fieldName;
}
/**
* Returns a <code>FieldIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType the class that the field is a member of
* @param fieldType the type of the field
* @param fieldName the name of the field
* @return a <code>FieldIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static FieldIdItem getInternedFieldIdItem(DexFile dexFile, TypeIdItem classType, TypeIdItem fieldType,
StringIdItem fieldName) {
FieldIdItem fieldIdItem = new FieldIdItem(dexFile, classType, fieldType, fieldName);
return dexFile.FieldIdsSection.intern(fieldIdItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
classType = dexFile.TypeIdsSection.getItemByIndex(in.readShort());
fieldType = dexFile.TypeIdsSection.getItemByIndex(in.readShort());
fieldName = dexFile.StringIdsSection.getItemByIndex(in.readInt());
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 8;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
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());
out.writeShort(fieldType.getIndex());
out.writeInt(fieldName.getIndex());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_FIELD_ID_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
String parentClass = classType.getTypeDescriptor();
//strip off the leading L and trailing ;
parentClass = parentClass.substring(1, parentClass.length() - 1);
return parentClass + "/" + fieldName.getStringValue() +
":" + fieldType.getTypeDescriptor();
}
/** {@inheritDoc} */
public int compareTo(FieldIdItem o) {
int result = classType.compareTo(o.classType);
if (result != 0) {
return result;
}
result = fieldName.compareTo(o.fieldName);
if (result != 0) {
return result;
}
return fieldType.compareTo(o.fieldType);
}
/**
* @return the class that this field is a member of
*/
public TypeIdItem getContainingClass() {
return classType;
}
/**
* @return the type of this field
*/
public TypeIdItem getFieldType() {
return fieldType;
}
/**
* @return the field name
*/
public StringIdItem getFieldName() {
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
*/
private void calcHashCode() {
hashCode = classType.hashCode();
hashCode = 31 * hashCode + fieldType.hashCode();
hashCode = 31 * hashCode + fieldName.hashCode();
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
FieldIdItem other = (FieldIdItem)o;
return (classType == other.classType &&
fieldType == other.fieldType &&
fieldName == other.fieldName);
}
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class FieldIdItem extends Item<FieldIdItem> {
private int hashCode = 0;
private TypeIdItem classType;
private TypeIdItem fieldType;
private StringIdItem fieldName;
/**
* Creates a new uninitialized <code>FieldIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected FieldIdItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>FieldIdItem</code> for the given class, type and name
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType the class that the field is a member of
* @param fieldType the type of the field
* @param fieldName the name of the field
*/
private FieldIdItem(DexFile dexFile, TypeIdItem classType, TypeIdItem fieldType, StringIdItem fieldName) {
this(dexFile);
assert classType.dexFile == dexFile;
assert fieldType.dexFile == dexFile;
assert fieldName.dexFile == dexFile;
this.classType = classType;
this.fieldType = fieldType;
this.fieldName = fieldName;
}
/**
* Returns a <code>FieldIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType the class that the field is a member of
* @param fieldType the type of the field
* @param fieldName the name of the field
* @return a <code>FieldIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static FieldIdItem getInternedFieldIdItem(DexFile dexFile, TypeIdItem classType, TypeIdItem fieldType,
StringIdItem fieldName) {
FieldIdItem fieldIdItem = new FieldIdItem(dexFile, classType, fieldType, fieldName);
return dexFile.FieldIdsSection.intern(fieldIdItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
classType = dexFile.TypeIdsSection.getItemByIndex(in.readShort());
fieldType = dexFile.TypeIdsSection.getItemByIndex(in.readShort());
fieldName = dexFile.StringIdsSection.getItemByIndex(in.readInt());
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 8;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
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());
out.writeShort(fieldType.getIndex());
out.writeInt(fieldName.getIndex());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_FIELD_ID_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
String parentClass = classType.getTypeDescriptor();
//strip off the leading L and trailing ;
parentClass = parentClass.substring(1, parentClass.length() - 1);
return parentClass + "/" + fieldName.getStringValue() +
":" + fieldType.getTypeDescriptor();
}
/** {@inheritDoc} */
public int compareTo(FieldIdItem o) {
int result = classType.compareTo(o.classType);
if (result != 0) {
return result;
}
result = fieldName.compareTo(o.fieldName);
if (result != 0) {
return result;
}
return fieldType.compareTo(o.fieldType);
}
/**
* @return the class that this field is a member of
*/
public TypeIdItem getContainingClass() {
return classType;
}
/**
* @return the type of this field
*/
public TypeIdItem getFieldType() {
return fieldType;
}
/**
* @return the field name
*/
public StringIdItem getFieldName() {
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
*/
private void calcHashCode() {
hashCode = classType.hashCode();
hashCode = 31 * hashCode + fieldType.hashCode();
hashCode = 31 * hashCode + fieldName.hashCode();
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
FieldIdItem other = (FieldIdItem)o;
return (classType == other.classType &&
fieldType == other.fieldType &&
fieldName == other.fieldName);
}
}

View File

@ -1,234 +1,234 @@
/*
* [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;
import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.Utf8Utils;
import java.io.UnsupportedEncodingException;
public class HeaderItem extends Item<HeaderItem> {
/**
* the file format magic number, represented as the
* low-order bytes of a string
*/
public static final byte[] MAGIC = new byte[] {0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x35, 0x00};//"dex\n035" + '\0';
/** size of this section, in bytes */
private static final int HEADER_SIZE = 0x70;
/** the endianness constants */
private static final int LITTLE_ENDIAN = 0x12345678;
private static final int BIG_ENDIAN = 0x78562312;
/**
* Create a new uninitialized <code>HeaderItem</code>
* @param dexFile The <code>DexFile</code> containing this <code>HeaderItem</code>
*/
protected HeaderItem(final DexFile dexFile) {
super(dexFile);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
byte[] readMagic = in.readBytes(8);
for (int i=0; i<8; i++) {
if (MAGIC[i] != readMagic[i]) {
throw new RuntimeException("The magic value is not the expected value");
}
}
in.readBytes(20); //checksum
in.readInt(); //signature
in.readInt(); //filesize
if (in.readInt() != HEADER_SIZE) {
throw new RuntimeException("The header size is not the expected value (0x70)");
}
int endianTag = in.readInt();
if (endianTag == BIG_ENDIAN) {
throw new RuntimeException("This dex file is big endian. Only little endian is currently supported.");
} else if (endianTag != LITTLE_ENDIAN) {
throw new RuntimeException("The endian tag is not 0x12345678 or 0x78563412");
}
//link_size
if (in.readInt() != 0) {
throw new RuntimeException("This dex file has a link section, which is not supported");
}
//link_off
if (in.readInt() != 0) {
throw new RuntimeException("This dex file has a link section, which is not supported");
}
int sectionSize;
int sectionOffset;
//map_offset
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_MAP_LIST, 1, sectionOffset);
//string_id_item
sectionSize = in.readInt();
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_STRING_ID_ITEM, sectionSize, sectionOffset);
//type_id_item
sectionSize = in.readInt();
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_TYPE_ID_ITEM, sectionSize, sectionOffset);
//proto_id_item
sectionSize = in.readInt();
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_PROTO_ID_ITEM, sectionSize, sectionOffset);
//field_id_item
sectionSize = in.readInt();
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_FIELD_ID_ITEM, sectionSize, sectionOffset);
//method_id_item
sectionSize = in.readInt();
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_METHOD_ID_ITEM, sectionSize, sectionOffset);
//class_data_item
sectionSize = in.readInt();
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_CLASS_DEF_ITEM, sectionSize, sectionOffset);
in.readInt(); //data_size
in.readInt(); //data_off
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return HEADER_SIZE;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
StringBuilder magicBuilder = new StringBuilder();
for (int i=0; i<8; i++) {
magicBuilder.append((char)MAGIC[i]);
}
out.annotate("magic: " + Utf8Utils.escapeString(magicBuilder.toString()));
out.write(MAGIC);
out.annotate("checksum");
out.writeInt(0);
out.annotate("signature");
out.write(new byte[20]);
out.annotate("file_size: 0x" + Integer.toHexString(dexFile.getFileSize()) + " (" + dexFile.getFileSize() +
" bytes)");
out.writeInt(dexFile.getFileSize());
out.annotate("header_size: 0x" + Integer.toHexString(HEADER_SIZE));
out.writeInt(HEADER_SIZE);
out.annotate("endian_tag: 0x" + Integer.toHexString(LITTLE_ENDIAN));
out.writeInt(LITTLE_ENDIAN);
out.annotate("link_size: 0");
out.writeInt(0);
out.annotate("link_off: 0");
out.writeInt(0);
out.annotate("map_off: 0x" + Integer.toHexString(dexFile.MapItem.getOffset()));
out.writeInt(dexFile.MapItem.getOffset());
out.annotate("string_ids_size: " + dexFile.StringIdsSection.getItems().size());
out.writeInt(dexFile.StringIdsSection.getItems().size());
out.annotate("string_ids_off: 0x" + Integer.toHexString(dexFile.StringIdsSection.getOffset()));
out.writeInt(dexFile.StringIdsSection.getOffset());
out.annotate("type_ids_size: " + dexFile.TypeIdsSection.getItems().size());
out.writeInt(dexFile.TypeIdsSection.getItems().size());
out.annotate("type_ids_off: 0x" + Integer.toHexString(dexFile.TypeIdsSection.getOffset()));
out.writeInt(dexFile.TypeIdsSection.getOffset());
out.annotate("proto_ids_size: " + dexFile.ProtoIdsSection.getItems().size());
out.writeInt(dexFile.ProtoIdsSection.getItems().size());
out.annotate("proto_ids_off: 0x" + Integer.toHexString(dexFile.ProtoIdsSection.getOffset()));
out.writeInt(dexFile.ProtoIdsSection.getOffset());
out.annotate("field_ids_size: " + dexFile.FieldIdsSection.getItems().size());
out.writeInt(dexFile.FieldIdsSection.getItems().size());
out.annotate("field_ids_off: 0x" + Integer.toHexString(dexFile.FieldIdsSection.getOffset()));
out.writeInt(dexFile.FieldIdsSection.getOffset());
out.annotate("method_ids_size: " + dexFile.MethodIdsSection.getItems().size());
out.writeInt(dexFile.MethodIdsSection.getItems().size());
out.annotate("method_ids_off: 0x" + Integer.toHexString(dexFile.MethodIdsSection.getOffset()));
out.writeInt(dexFile.MethodIdsSection.getOffset());
out.annotate("class_defs_size: " + dexFile.ClassDefsSection.getItems().size());
out.writeInt(dexFile.ClassDefsSection.getItems().size());
out.annotate("class_defs_off: 0x" + Integer.toHexString(dexFile.ClassDefsSection.getOffset()));
out.writeInt(dexFile.ClassDefsSection.getOffset());
out.annotate("data_size: 0x" + Integer.toHexString(dexFile.getDataSize()) + " (" + dexFile.getDataSize() +
" bytes)");
out.writeInt(dexFile.getDataSize());
out.annotate("data_off: 0x" + Integer.toHexString(dexFile.getDataOffset()));
out.writeInt(dexFile.getDataOffset());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_HEADER_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "header_item";
}
/** {@inheritDoc} */
public int compareTo(HeaderItem o) {
//there is only 1 header item
return 0;
}
}
/*
* [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;
import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.Utf8Utils;
import java.io.UnsupportedEncodingException;
public class HeaderItem extends Item<HeaderItem> {
/**
* the file format magic number, represented as the
* low-order bytes of a string
*/
public static final byte[] MAGIC = new byte[] {0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x35, 0x00};//"dex\n035" + '\0';
/** size of this section, in bytes */
private static final int HEADER_SIZE = 0x70;
/** the endianness constants */
private static final int LITTLE_ENDIAN = 0x12345678;
private static final int BIG_ENDIAN = 0x78562312;
/**
* Create a new uninitialized <code>HeaderItem</code>
* @param dexFile The <code>DexFile</code> containing this <code>HeaderItem</code>
*/
protected HeaderItem(final DexFile dexFile) {
super(dexFile);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
byte[] readMagic = in.readBytes(8);
for (int i=0; i<8; i++) {
if (MAGIC[i] != readMagic[i]) {
throw new RuntimeException("The magic value is not the expected value");
}
}
in.readBytes(20); //checksum
in.readInt(); //signature
in.readInt(); //filesize
if (in.readInt() != HEADER_SIZE) {
throw new RuntimeException("The header size is not the expected value (0x70)");
}
int endianTag = in.readInt();
if (endianTag == BIG_ENDIAN) {
throw new RuntimeException("This dex file is big endian. Only little endian is currently supported.");
} else if (endianTag != LITTLE_ENDIAN) {
throw new RuntimeException("The endian tag is not 0x12345678 or 0x78563412");
}
//link_size
if (in.readInt() != 0) {
throw new RuntimeException("This dex file has a link section, which is not supported");
}
//link_off
if (in.readInt() != 0) {
throw new RuntimeException("This dex file has a link section, which is not supported");
}
int sectionSize;
int sectionOffset;
//map_offset
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_MAP_LIST, 1, sectionOffset);
//string_id_item
sectionSize = in.readInt();
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_STRING_ID_ITEM, sectionSize, sectionOffset);
//type_id_item
sectionSize = in.readInt();
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_TYPE_ID_ITEM, sectionSize, sectionOffset);
//proto_id_item
sectionSize = in.readInt();
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_PROTO_ID_ITEM, sectionSize, sectionOffset);
//field_id_item
sectionSize = in.readInt();
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_FIELD_ID_ITEM, sectionSize, sectionOffset);
//method_id_item
sectionSize = in.readInt();
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_METHOD_ID_ITEM, sectionSize, sectionOffset);
//class_data_item
sectionSize = in.readInt();
sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_CLASS_DEF_ITEM, sectionSize, sectionOffset);
in.readInt(); //data_size
in.readInt(); //data_off
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return HEADER_SIZE;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
StringBuilder magicBuilder = new StringBuilder();
for (int i=0; i<8; i++) {
magicBuilder.append((char)MAGIC[i]);
}
out.annotate("magic: " + Utf8Utils.escapeString(magicBuilder.toString()));
out.write(MAGIC);
out.annotate("checksum");
out.writeInt(0);
out.annotate("signature");
out.write(new byte[20]);
out.annotate("file_size: 0x" + Integer.toHexString(dexFile.getFileSize()) + " (" + dexFile.getFileSize() +
" bytes)");
out.writeInt(dexFile.getFileSize());
out.annotate("header_size: 0x" + Integer.toHexString(HEADER_SIZE));
out.writeInt(HEADER_SIZE);
out.annotate("endian_tag: 0x" + Integer.toHexString(LITTLE_ENDIAN));
out.writeInt(LITTLE_ENDIAN);
out.annotate("link_size: 0");
out.writeInt(0);
out.annotate("link_off: 0");
out.writeInt(0);
out.annotate("map_off: 0x" + Integer.toHexString(dexFile.MapItem.getOffset()));
out.writeInt(dexFile.MapItem.getOffset());
out.annotate("string_ids_size: " + dexFile.StringIdsSection.getItems().size());
out.writeInt(dexFile.StringIdsSection.getItems().size());
out.annotate("string_ids_off: 0x" + Integer.toHexString(dexFile.StringIdsSection.getOffset()));
out.writeInt(dexFile.StringIdsSection.getOffset());
out.annotate("type_ids_size: " + dexFile.TypeIdsSection.getItems().size());
out.writeInt(dexFile.TypeIdsSection.getItems().size());
out.annotate("type_ids_off: 0x" + Integer.toHexString(dexFile.TypeIdsSection.getOffset()));
out.writeInt(dexFile.TypeIdsSection.getOffset());
out.annotate("proto_ids_size: " + dexFile.ProtoIdsSection.getItems().size());
out.writeInt(dexFile.ProtoIdsSection.getItems().size());
out.annotate("proto_ids_off: 0x" + Integer.toHexString(dexFile.ProtoIdsSection.getOffset()));
out.writeInt(dexFile.ProtoIdsSection.getOffset());
out.annotate("field_ids_size: " + dexFile.FieldIdsSection.getItems().size());
out.writeInt(dexFile.FieldIdsSection.getItems().size());
out.annotate("field_ids_off: 0x" + Integer.toHexString(dexFile.FieldIdsSection.getOffset()));
out.writeInt(dexFile.FieldIdsSection.getOffset());
out.annotate("method_ids_size: " + dexFile.MethodIdsSection.getItems().size());
out.writeInt(dexFile.MethodIdsSection.getItems().size());
out.annotate("method_ids_off: 0x" + Integer.toHexString(dexFile.MethodIdsSection.getOffset()));
out.writeInt(dexFile.MethodIdsSection.getOffset());
out.annotate("class_defs_size: " + dexFile.ClassDefsSection.getItems().size());
out.writeInt(dexFile.ClassDefsSection.getItems().size());
out.annotate("class_defs_off: 0x" + Integer.toHexString(dexFile.ClassDefsSection.getOffset()));
out.writeInt(dexFile.ClassDefsSection.getOffset());
out.annotate("data_size: 0x" + Integer.toHexString(dexFile.getDataSize()) + " (" + dexFile.getDataSize() +
" bytes)");
out.writeInt(dexFile.getDataSize());
out.annotate("data_off: 0x" + Integer.toHexString(dexFile.getDataOffset()));
out.writeInt(dexFile.getDataOffset());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_HEADER_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "header_item";
}
/** {@inheritDoc} */
public int compareTo(HeaderItem o) {
//there is only 1 header item
return 0;
}
}

View File

@ -1,67 +1,67 @@
/*
* [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;
import org.jf.dexlib.Util.Input;
public class IndexedSection<T extends Item> extends Section<T> {
/**
* Create a new indexed section
* @param dexFile The <code>DexFile</code> that this section belongs to
* @param itemType The itemType that this section will hold
*/
public IndexedSection(DexFile dexFile, ItemType itemType) {
super(dexFile, itemType);
}
/** {@inheritDoc} */
protected void readItems(Input in, ReadContext readContext) {
for (int i = 0; i < items.size(); i++) {
T item = (T)ItemFactory.makeItem(ItemType, DexFile);
items.set(i, item);
item.readFrom(in, i, readContext);
}
}
/**
* Gets the item at the specified index in this section
* @param index the index of the item to get
* @return the item at the specified index in this section
* @throws IndexOutOfBoundsException if index is outside the bounds of this section
*/
public T getItemByIndex(int index) {
if (index == -1) {
return null;
}
//if index is out of bounds, just let it throw an exception
return items.get(index);
}
/*
* [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;
import org.jf.dexlib.Util.Input;
public class IndexedSection<T extends Item> extends Section<T> {
/**
* Create a new indexed section
* @param dexFile The <code>DexFile</code> that this section belongs to
* @param itemType The itemType that this section will hold
*/
public IndexedSection(DexFile dexFile, ItemType itemType) {
super(dexFile, itemType);
}
/** {@inheritDoc} */
protected void readItems(Input in, ReadContext readContext) {
for (int i = 0; i < items.size(); i++) {
T item = (T)ItemFactory.makeItem(ItemType, DexFile);
items.set(i, item);
item.readFrom(in, i, readContext);
}
}
/**
* Gets the item at the specified index in this section
* @param index the index of the item to get
* @return the item at the specified index in this section
* @throws IndexOutOfBoundsException if index is outside the bounds of this section
*/
public T getItemByIndex(int index) {
if (index == -1) {
return null;
}
//if index is out of bounds, just let it throw an exception
return items.get(index);
}
}

View File

@ -1,182 +1,182 @@
/*
* [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;
import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AlignmentUtils;
public abstract class Item<T extends Item> implements Comparable<T> {
/**
* The offset of this item in the dex file, or -1 if not known
*/
protected int offset = -1;
/**
* The index of this item in the containing section, or -1 if not known
*/
protected int index = -1;
/**
* The DexFile that this item is associatedr with
*/
protected final DexFile dexFile;
/**
* The constructor that is used when reading in a <code>DexFile</code>
* @param dexFile the <code>DexFile</code> that this item is associated with
*/
protected Item(DexFile dexFile) {
this.dexFile = dexFile;
}
/**
* Read in the item from the given input stream, and initialize the index
* @param in the <code>Input</code> object to read from
* @param index the index within the containing section of the item being read in
* @param readContext a <code>ReadContext</code> object to hold information that is
* only needed while reading in a file
*/
protected void readFrom(Input in, int index, ReadContext readContext) {
assert in.getCursor() % getItemType().ItemAlignment == 0;
this.offset = in.getCursor();
this.index = index;
this.readItem(in, readContext);
}
/**
* Place the item at the given offset and index, and return the offset of the byte following this item
* @param offset The offset to place the item at
* @param index The index of the item within the containing section
* @return The offset of the byte following this item
*/
protected int placeAt(int offset, int index) {
assert offset % getItemType().ItemAlignment == 0;
assert !dexFile.getInplace() || (offset == this.offset && this.index == index);
this.offset = offset;
this.index = index;
return this.placeItem(offset);
}
/**
* Write and annotate this item to the output stream
* @param out The output stream to write and annotate to
*/
protected void writeTo(AnnotatedOutput out) {
assert out.getCursor() % getItemType().ItemAlignment == 0;
assert out.getCursor() == offset;
if (out.annotates()) {
out.annotate(0, "[" + index + "] " + this.getItemType().TypeName);
}
out.indent();
writeItem(out);
out.deindent();
}
/**
* Returns a human readable form of this item
* @return a human readable form of this item
*/
public String toString() {
return getConciseIdentity();
}
/**
* The method in the concrete item subclass that actually reads in the data for the item
*
* The logic in this method can assume that the given Input object is valid and is
* aligned as neccessary.
*
* This method is for internal use only
* @param in the <code>Input</code> object to read from
* @param readContext a <code>ReadContext</code> object to hold information that is
* only needed while reading in a file
*/
protected abstract void readItem(Input in, ReadContext readContext);
/**
* The method should finalize the layout of the item and return the offset of the byte
* immediately following the item.
*
* The implementation of this method can assume that the offset argument has already been
* aligned based on the item's alignment requirements
*
* This method is for internal use only
* @param offset the (pre-aligned) offset to place the item at
* @return the size of the item, in bytes
*/
protected abstract int placeItem(int offset);
/**
* The method in the concrete item subclass that actually writes and annotates the data
* for the item.
*
* The logic in this method can assume that the given Output object is valid and is
* aligned as neccessary
*
* @param out The <code>AnnotatedOutput</code> object to write/annotate to
*/
protected abstract void writeItem(AnnotatedOutput out);
/**
* @return An ItemType enum that represents the item type of this item
*/
public abstract ItemType getItemType();
/**
* @return A concise (human-readable) string value that conveys the identity of this item
*/
public abstract String getConciseIdentity();
/**
* @return the offset in the dex file where this item is located
*/
public int getOffset() {
return offset;
}
/**
* @return the index of this item within the item's containing section
*/
public int getIndex() {
return index;
}
/**
* @return the <code>DexFile</code> that contains this item
*/
public DexFile getDexFile() {
return dexFile;
}
}
/*
* [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;
import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AlignmentUtils;
public abstract class Item<T extends Item> implements Comparable<T> {
/**
* The offset of this item in the dex file, or -1 if not known
*/
protected int offset = -1;
/**
* The index of this item in the containing section, or -1 if not known
*/
protected int index = -1;
/**
* The DexFile that this item is associatedr with
*/
protected final DexFile dexFile;
/**
* The constructor that is used when reading in a <code>DexFile</code>
* @param dexFile the <code>DexFile</code> that this item is associated with
*/
protected Item(DexFile dexFile) {
this.dexFile = dexFile;
}
/**
* Read in the item from the given input stream, and initialize the index
* @param in the <code>Input</code> object to read from
* @param index the index within the containing section of the item being read in
* @param readContext a <code>ReadContext</code> object to hold information that is
* only needed while reading in a file
*/
protected void readFrom(Input in, int index, ReadContext readContext) {
assert in.getCursor() % getItemType().ItemAlignment == 0;
this.offset = in.getCursor();
this.index = index;
this.readItem(in, readContext);
}
/**
* Place the item at the given offset and index, and return the offset of the byte following this item
* @param offset The offset to place the item at
* @param index The index of the item within the containing section
* @return The offset of the byte following this item
*/
protected int placeAt(int offset, int index) {
assert offset % getItemType().ItemAlignment == 0;
assert !dexFile.getInplace() || (offset == this.offset && this.index == index);
this.offset = offset;
this.index = index;
return this.placeItem(offset);
}
/**
* Write and annotate this item to the output stream
* @param out The output stream to write and annotate to
*/
protected void writeTo(AnnotatedOutput out) {
assert out.getCursor() % getItemType().ItemAlignment == 0;
assert out.getCursor() == offset;
if (out.annotates()) {
out.annotate(0, "[" + index + "] " + this.getItemType().TypeName);
}
out.indent();
writeItem(out);
out.deindent();
}
/**
* Returns a human readable form of this item
* @return a human readable form of this item
*/
public String toString() {
return getConciseIdentity();
}
/**
* The method in the concrete item subclass that actually reads in the data for the item
*
* The logic in this method can assume that the given Input object is valid and is
* aligned as neccessary.
*
* This method is for internal use only
* @param in the <code>Input</code> object to read from
* @param readContext a <code>ReadContext</code> object to hold information that is
* only needed while reading in a file
*/
protected abstract void readItem(Input in, ReadContext readContext);
/**
* The method should finalize the layout of the item and return the offset of the byte
* immediately following the item.
*
* The implementation of this method can assume that the offset argument has already been
* aligned based on the item's alignment requirements
*
* This method is for internal use only
* @param offset the (pre-aligned) offset to place the item at
* @return the size of the item, in bytes
*/
protected abstract int placeItem(int offset);
/**
* The method in the concrete item subclass that actually writes and annotates the data
* for the item.
*
* The logic in this method can assume that the given Output object is valid and is
* aligned as neccessary
*
* @param out The <code>AnnotatedOutput</code> object to write/annotate to
*/
protected abstract void writeItem(AnnotatedOutput out);
/**
* @return An ItemType enum that represents the item type of this item
*/
public abstract ItemType getItemType();
/**
* @return A concise (human-readable) string value that conveys the identity of this item
*/
public abstract String getConciseIdentity();
/**
* @return the offset in the dex file where this item is located
*/
public int getOffset() {
return offset;
}
/**
* @return the index of this item within the item's containing section
*/
public int getIndex() {
return index;
}
/**
* @return the <code>DexFile</code> that contains this item
*/
public DexFile getDexFile() {
return dexFile;
}
}

View File

@ -1,138 +1,138 @@
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
/**
* This item represents a map_list item from the dex specification. It contains a
* SectionInfo instance for every section in the DexFile, with the number of items
* in and offset of that section.
*/
public class MapItem extends Item<MapItem> {
/**
* This item is read in immediately after the HeaderItem, and the section info contained
* by this item is added to the ReadContext object, which is used when reading in the other
* sections in the dex file.
*
* This item should be placed last. It depends on the fact that the other sections
* in the file have been placed.
*/
/**
* Create a new uninitialized <code>MapItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected MapItem(final DexFile dexFile) {
super(dexFile);
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
Section[] sections = dexFile.getOrderedSections();
//the list returned by getOrderedSections doesn't contain the header
//or map section, so add 2 to the length
return offset + 4 + (sections.length + 2) * 12;
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
int size = in.readInt();
for (int i=0; i<size; i++) {
ItemType itemType = ItemType.fromInt(in.readShort());
//unused
in.readShort();
int sectionSize = in.readInt();
int sectionOffset = in.readInt();
readContext.addSection(itemType, sectionSize, sectionOffset);
}
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
assert getOffset() > 0;
Section[] sections = dexFile.getOrderedSections();
out.annotate("map_size: 0x" + Integer.toHexString(sections.length + 2) + " (" +
Integer.toString(sections.length + 2) + ")");
out.writeInt(sections.length + 2);
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, "item_type: " + itemType);
out.annotate(2, "unused");
out.annotate(4, "section_size: 0x" + Integer.toHexString(sectionSize) + " (" + sectionSize + ")");
out.annotate(4, "section_off: 0x" + Integer.toHexString(sectionOffset));
}
out.writeShort(itemType.MapValue);
out.writeShort(0);
out.writeInt(sectionSize);
out.writeInt(sectionOffset);
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_MAP_LIST;
}
/** {@inheritDoc} */
public int compareTo(MapItem o) {
return 0;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "map_item";
}
}
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
/**
* This item represents a map_list item from the dex specification. It contains a
* SectionInfo instance for every section in the DexFile, with the number of items
* in and offset of that section.
*/
public class MapItem extends Item<MapItem> {
/**
* This item is read in immediately after the HeaderItem, and the section info contained
* by this item is added to the ReadContext object, which is used when reading in the other
* sections in the dex file.
*
* This item should be placed last. It depends on the fact that the other sections
* in the file have been placed.
*/
/**
* Create a new uninitialized <code>MapItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected MapItem(final DexFile dexFile) {
super(dexFile);
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
Section[] sections = dexFile.getOrderedSections();
//the list returned by getOrderedSections doesn't contain the header
//or map section, so add 2 to the length
return offset + 4 + (sections.length + 2) * 12;
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
int size = in.readInt();
for (int i=0; i<size; i++) {
ItemType itemType = ItemType.fromInt(in.readShort());
//unused
in.readShort();
int sectionSize = in.readInt();
int sectionOffset = in.readInt();
readContext.addSection(itemType, sectionSize, sectionOffset);
}
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
assert getOffset() > 0;
Section[] sections = dexFile.getOrderedSections();
out.annotate("map_size: 0x" + Integer.toHexString(sections.length + 2) + " (" +
Integer.toString(sections.length + 2) + ")");
out.writeInt(sections.length + 2);
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, "item_type: " + itemType);
out.annotate(2, "unused");
out.annotate(4, "section_size: 0x" + Integer.toHexString(sectionSize) + " (" + sectionSize + ")");
out.annotate(4, "section_off: 0x" + Integer.toHexString(sectionOffset));
}
out.writeShort(itemType.MapValue);
out.writeShort(0);
out.writeInt(sectionSize);
out.writeInt(sectionOffset);
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_MAP_LIST;
}
/** {@inheritDoc} */
public int compareTo(MapItem o) {
return 0;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "map_item";
}
}

View File

@ -1,207 +1,207 @@
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class MethodIdItem extends Item<MethodIdItem> {
private int hashCode = 0;
private TypeIdItem classType;
private ProtoIdItem methodPrototype;
private StringIdItem methodName;
/**
* Creates a new uninitialized <code>MethodIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected MethodIdItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>MethodIdItem</code> for the given class, type and name
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType the class that the method is a member of
* @param methodPrototype the type of the method
* @param methodName the name of the method
*/
private MethodIdItem(DexFile dexFile, TypeIdItem classType, ProtoIdItem methodPrototype, StringIdItem methodName) {
this(dexFile);
this.classType = classType;
this.methodPrototype = methodPrototype;
this.methodName = methodName;
}
/**
* Returns a <code>MethodIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType the class that the method is a member of
* @param methodPrototype the type of the method
* @param methodName the name of the method
* @return a <code>MethodIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static MethodIdItem getInternedMethodIdItem(DexFile dexFile, TypeIdItem classType,
ProtoIdItem methodPrototype, StringIdItem methodName) {
MethodIdItem methodIdItem = new MethodIdItem(dexFile, classType, methodPrototype, methodName);
return dexFile.MethodIdsSection.intern(methodIdItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
classType = dexFile.TypeIdsSection.getItemByIndex(in.readShort());
methodPrototype = dexFile.ProtoIdsSection.getItemByIndex(in.readShort());
methodName = dexFile.StringIdsSection.getItemByIndex(in.readInt());
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 8;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
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());
out.writeShort(methodPrototype.getIndex());
out.writeInt(methodName.getIndex());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_METHOD_ID_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "method_id_item: " + getMethodString();
}
/** {@inheritDoc} */
public int compareTo(MethodIdItem o) {
int result = classType.compareTo(o.classType);
if (result != 0) {
return result;
}
result = methodName.compareTo(o.methodName);
if (result != 0) {
return result;
}
return methodPrototype.compareTo(o.methodPrototype);
}
private String cachedMethodString = null;
/**
* @return a string formatted like LclassName;->methodName(TTTT..)R
*/
public String getMethodString() {
if (cachedMethodString == null) {
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;
}
/**
* @return the method prototype
*/
public ProtoIdItem getPrototype() {
return methodPrototype;
}
/**
* @return the name of the method
*/
public StringIdItem getMethodName() {
return methodName;
}
/**
* @return the class this method is a member of
*/
public TypeIdItem getContainingClass() {
return classType;
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = classType.hashCode();
hashCode = 31 * hashCode + methodPrototype.hashCode();
hashCode = 31 * hashCode + methodName.hashCode();
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
MethodIdItem other = (MethodIdItem)o;
return (classType == other.classType &&
methodPrototype == other.methodPrototype &&
methodName == other.methodName);
}
}
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class MethodIdItem extends Item<MethodIdItem> {
private int hashCode = 0;
private TypeIdItem classType;
private ProtoIdItem methodPrototype;
private StringIdItem methodName;
/**
* Creates a new uninitialized <code>MethodIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected MethodIdItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>MethodIdItem</code> for the given class, type and name
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType the class that the method is a member of
* @param methodPrototype the type of the method
* @param methodName the name of the method
*/
private MethodIdItem(DexFile dexFile, TypeIdItem classType, ProtoIdItem methodPrototype, StringIdItem methodName) {
this(dexFile);
this.classType = classType;
this.methodPrototype = methodPrototype;
this.methodName = methodName;
}
/**
* Returns a <code>MethodIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType the class that the method is a member of
* @param methodPrototype the type of the method
* @param methodName the name of the method
* @return a <code>MethodIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static MethodIdItem getInternedMethodIdItem(DexFile dexFile, TypeIdItem classType,
ProtoIdItem methodPrototype, StringIdItem methodName) {
MethodIdItem methodIdItem = new MethodIdItem(dexFile, classType, methodPrototype, methodName);
return dexFile.MethodIdsSection.intern(methodIdItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
classType = dexFile.TypeIdsSection.getItemByIndex(in.readShort());
methodPrototype = dexFile.ProtoIdsSection.getItemByIndex(in.readShort());
methodName = dexFile.StringIdsSection.getItemByIndex(in.readInt());
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 8;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
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());
out.writeShort(methodPrototype.getIndex());
out.writeInt(methodName.getIndex());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_METHOD_ID_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "method_id_item: " + getMethodString();
}
/** {@inheritDoc} */
public int compareTo(MethodIdItem o) {
int result = classType.compareTo(o.classType);
if (result != 0) {
return result;
}
result = methodName.compareTo(o.methodName);
if (result != 0) {
return result;
}
return methodPrototype.compareTo(o.methodPrototype);
}
private String cachedMethodString = null;
/**
* @return a string formatted like LclassName;->methodName(TTTT..)R
*/
public String getMethodString() {
if (cachedMethodString == null) {
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;
}
/**
* @return the method prototype
*/
public ProtoIdItem getPrototype() {
return methodPrototype;
}
/**
* @return the name of the method
*/
public StringIdItem getMethodName() {
return methodName;
}
/**
* @return the class this method is a member of
*/
public TypeIdItem getContainingClass() {
return classType;
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = classType.hashCode();
hashCode = 31 * hashCode + methodPrototype.hashCode();
hashCode = 31 * hashCode + methodName.hashCode();
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
MethodIdItem other = (MethodIdItem)o;
return (classType == other.classType &&
methodPrototype == other.methodPrototype &&
methodName == other.methodName);
}
}

View File

@ -1,83 +1,83 @@
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.SparseArray;
import org.jf.dexlib.Util.Hex;
import junit.framework.Assert;
public class OffsettedSection<T extends Item> extends Section<T> {
public OffsettedSection(DexFile dexFile, ItemType itemType) {
super(dexFile, itemType);
}
public void readItems(Input in, ReadContext readContext) {
SparseArray<T> precreatedItems = (SparseArray<T>)readContext.getItemsByType(ItemType);
assert precreatedItems.size() <= items.size(): "Trying to read " + items.size() + " items, but this section " +
"already contains " + precreatedItems.size() + " items.";
int precreatedIndex = 0;
int nextPrecreatedOffset = Integer.MAX_VALUE;
if (precreatedItems.size() > 0) {
nextPrecreatedOffset = precreatedItems.keyAt(0);
}
for (int i = 0; i < items.size(); i++) {
assert items.get(i) == null;
T item = null;
in.alignTo(ItemType.ItemAlignment);
int currentOffset = in.getCursor();
if (currentOffset == nextPrecreatedOffset) {
item = precreatedItems.valueAt(precreatedIndex++);
if (precreatedIndex < precreatedItems.size()) {
nextPrecreatedOffset = precreatedItems.keyAt(precreatedIndex);
} else {
nextPrecreatedOffset = Integer.MAX_VALUE;
}
} else if (currentOffset > nextPrecreatedOffset) {
//we passed by the next precreated item, something is wrong
throw new RuntimeException("The pre-created item at offset 0x" + Hex.u4(nextPrecreatedOffset)
+ " was not read");
} else {
item = (T)ItemFactory.makeItem(ItemType, DexFile);
}
items.set(i, item);
item.readFrom(in, i, readContext);
}
readContext.setItemsForSection(ItemType, items);
}
}
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.SparseArray;
import org.jf.dexlib.Util.Hex;
import junit.framework.Assert;
public class OffsettedSection<T extends Item> extends Section<T> {
public OffsettedSection(DexFile dexFile, ItemType itemType) {
super(dexFile, itemType);
}
public void readItems(Input in, ReadContext readContext) {
SparseArray<T> precreatedItems = (SparseArray<T>)readContext.getItemsByType(ItemType);
assert precreatedItems.size() <= items.size(): "Trying to read " + items.size() + " items, but this section " +
"already contains " + precreatedItems.size() + " items.";
int precreatedIndex = 0;
int nextPrecreatedOffset = Integer.MAX_VALUE;
if (precreatedItems.size() > 0) {
nextPrecreatedOffset = precreatedItems.keyAt(0);
}
for (int i = 0; i < items.size(); i++) {
assert items.get(i) == null;
T item = null;
in.alignTo(ItemType.ItemAlignment);
int currentOffset = in.getCursor();
if (currentOffset == nextPrecreatedOffset) {
item = precreatedItems.valueAt(precreatedIndex++);
if (precreatedIndex < precreatedItems.size()) {
nextPrecreatedOffset = precreatedItems.keyAt(precreatedIndex);
} else {
nextPrecreatedOffset = Integer.MAX_VALUE;
}
} else if (currentOffset > nextPrecreatedOffset) {
//we passed by the next precreated item, something is wrong
throw new RuntimeException("The pre-created item at offset 0x" + Hex.u4(nextPrecreatedOffset)
+ " was not read");
} else {
item = (T)ItemFactory.makeItem(ItemType, DexFile);
}
items.set(i, item);
item.readFrom(in, i, readContext);
}
readContext.setItemsForSection(ItemType, items);
}
}

View File

@ -1,217 +1,217 @@
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class ProtoIdItem extends Item<ProtoIdItem> {
private int hashCode = 0;
private StringIdItem shortyDescriptor;
private TypeIdItem returnType;
private TypeListItem parameters;
/**
* Creates a new uninitialized <code>ProtoIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected ProtoIdItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>ProtoIdItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param returnType the return type
* @param parameters a <code>TypeListItem</code> containing a list of the parameter types
*/
private ProtoIdItem(DexFile dexFile, TypeIdItem returnType, TypeListItem parameters) {
this(dexFile);
String shortyString = returnType.toShorty();
if (parameters != null) {
shortyString += parameters.getShortyString();
}
this.shortyDescriptor = StringIdItem.getInternedStringIdItem(dexFile, shortyString);
this.returnType = returnType;
this.parameters = parameters;
}
/**
* Returns a <code>ProtoIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param returnType the return type
* @param parameters a <code>TypeListItem</code> containing a list of the parameter types
* @return a <code>ProtoIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static ProtoIdItem getInternedProtoIdItem(DexFile dexFile, TypeIdItem returnType, TypeListItem parameters) {
ProtoIdItem protoIdItem = new ProtoIdItem(dexFile, returnType, parameters);
return dexFile.ProtoIdsSection.intern(protoIdItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
shortyDescriptor = dexFile.StringIdsSection.getItemByIndex(in.readInt());
returnType = dexFile.TypeIdsSection.getItemByIndex(in.readInt());
parameters = (TypeListItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_TYPE_LIST, in.readInt());
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 12;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(4, "shorty_descriptor: " + shortyDescriptor.getStringValue());
out.annotate(4, "return_type: " + returnType.getTypeDescriptor());
if (parameters == null) {
out.annotate(4, "parameters:");
} else {
out.annotate(4, "parameters: " + parameters.getTypeListString(""));
}
}
out.writeInt(shortyDescriptor.getIndex());
out.writeInt(returnType.getIndex());
out.writeInt(parameters == null?0:parameters.getOffset());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_PROTO_ID_ITEM;
}
/** {@inheritDoc} */
public int compareTo(ProtoIdItem o) {
int result = returnType.compareTo(o.returnType);
if (result != 0) {
return result;
}
if (parameters == null) {
if (o.parameters == null) {
return 0;
}
return -1;
} else if (o.parameters == null) {
return 1;
}
return parameters.compareTo(o.parameters);
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "proto_id_item: " + getPrototypeString();
}
private String cachedPrototypeString = null;
/**
* @return a string in the format (TTTT..)R where TTTT.. are the parameter types and R is the return type
*/
public String getPrototypeString() {
if (cachedPrototypeString == null) {
StringBuilder sb = new StringBuilder("(");
if (parameters != null) {
sb.append(parameters.getTypeListString(""));
}
sb.append(")");
sb.append(returnType.getTypeDescriptor());
cachedPrototypeString = sb.toString();
}
return cachedPrototypeString;
}
/**
* @return the return type of the method
*/
public TypeIdItem getReturnType() {
return returnType;
}
/**
* @return a <code>TypeListItem</code> containing the method parameter types
*/
public TypeListItem getParameters() {
return parameters;
}
/**
* @return the number of registers required for the parameters of this <code>ProtoIdItem</code>
*/
public int getParameterRegisterCount() {
if (parameters == null) {
return 0;
} else {
return parameters.getRegisterCount();
}
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = returnType.hashCode();
hashCode = 31 * hashCode + (parameters==null?0:parameters.hashCode());
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
ProtoIdItem other = (ProtoIdItem)o;
return (returnType == other.returnType &&
parameters == other.parameters);
}
}
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class ProtoIdItem extends Item<ProtoIdItem> {
private int hashCode = 0;
private StringIdItem shortyDescriptor;
private TypeIdItem returnType;
private TypeListItem parameters;
/**
* Creates a new uninitialized <code>ProtoIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected ProtoIdItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>ProtoIdItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param returnType the return type
* @param parameters a <code>TypeListItem</code> containing a list of the parameter types
*/
private ProtoIdItem(DexFile dexFile, TypeIdItem returnType, TypeListItem parameters) {
this(dexFile);
String shortyString = returnType.toShorty();
if (parameters != null) {
shortyString += parameters.getShortyString();
}
this.shortyDescriptor = StringIdItem.getInternedStringIdItem(dexFile, shortyString);
this.returnType = returnType;
this.parameters = parameters;
}
/**
* Returns a <code>ProtoIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param returnType the return type
* @param parameters a <code>TypeListItem</code> containing a list of the parameter types
* @return a <code>ProtoIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static ProtoIdItem getInternedProtoIdItem(DexFile dexFile, TypeIdItem returnType, TypeListItem parameters) {
ProtoIdItem protoIdItem = new ProtoIdItem(dexFile, returnType, parameters);
return dexFile.ProtoIdsSection.intern(protoIdItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
shortyDescriptor = dexFile.StringIdsSection.getItemByIndex(in.readInt());
returnType = dexFile.TypeIdsSection.getItemByIndex(in.readInt());
parameters = (TypeListItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_TYPE_LIST, in.readInt());
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 12;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(4, "shorty_descriptor: " + shortyDescriptor.getStringValue());
out.annotate(4, "return_type: " + returnType.getTypeDescriptor());
if (parameters == null) {
out.annotate(4, "parameters:");
} else {
out.annotate(4, "parameters: " + parameters.getTypeListString(""));
}
}
out.writeInt(shortyDescriptor.getIndex());
out.writeInt(returnType.getIndex());
out.writeInt(parameters == null?0:parameters.getOffset());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_PROTO_ID_ITEM;
}
/** {@inheritDoc} */
public int compareTo(ProtoIdItem o) {
int result = returnType.compareTo(o.returnType);
if (result != 0) {
return result;
}
if (parameters == null) {
if (o.parameters == null) {
return 0;
}
return -1;
} else if (o.parameters == null) {
return 1;
}
return parameters.compareTo(o.parameters);
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "proto_id_item: " + getPrototypeString();
}
private String cachedPrototypeString = null;
/**
* @return a string in the format (TTTT..)R where TTTT.. are the parameter types and R is the return type
*/
public String getPrototypeString() {
if (cachedPrototypeString == null) {
StringBuilder sb = new StringBuilder("(");
if (parameters != null) {
sb.append(parameters.getTypeListString(""));
}
sb.append(")");
sb.append(returnType.getTypeDescriptor());
cachedPrototypeString = sb.toString();
}
return cachedPrototypeString;
}
/**
* @return the return type of the method
*/
public TypeIdItem getReturnType() {
return returnType;
}
/**
* @return a <code>TypeListItem</code> containing the method parameter types
*/
public TypeListItem getParameters() {
return parameters;
}
/**
* @return the number of registers required for the parameters of this <code>ProtoIdItem</code>
*/
public int getParameterRegisterCount() {
if (parameters == null) {
return 0;
} else {
return parameters.getRegisterCount();
}
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = returnType.hashCode();
hashCode = 31 * hashCode + (parameters==null?0:parameters.hashCode());
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
ProtoIdItem other = (ProtoIdItem)o;
return (returnType == other.returnType &&
parameters == other.parameters);
}
}

View File

@ -1,218 +1,218 @@
/*
* [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;
import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AlignmentUtils;
import java.util.*;
public abstract class Section<T extends Item> {
/**
* A list of the items that this section contains.
* If the section has been placed, this list should be in the order that the items
* will written to the dex file
*/
protected final ArrayList<T> items;
/**
* A HashMap of the items in this section. This is used when interning items, to determine
* if this section already has an item equivalent to the one that is being interned.
* Both the key and the value should be the same object
*/
protected HashMap<T,T> uniqueItems = null;
/**
* The offset of this section within the <code>DexFile</code>
*/
protected int offset = 0;
/**
* The type of item that this section holds
*/
public final ItemType ItemType;
/**
* The <code>DexFile</code> that this section belongs to
*/
public final DexFile DexFile;
/**
* Create a new section
* @param dexFile The <code>DexFile</code> that this section belongs to
* @param itemType The itemType that this section will hold
*/
protected Section(DexFile dexFile, ItemType itemType) {
this.DexFile = dexFile;
items = new ArrayList<T>();
this.ItemType = itemType;
}
/**
* Finalize the location of all items, and place them starting at the given offset
* @param offset The offset where this section should be placed
* @return the offset of the byte immediate after the last item in this section
*/
protected int placeAt(int offset) {
if (items.size() > 0) {
offset = AlignmentUtils.alignOffset(offset, ItemType.ItemAlignment);
assert !DexFile.getInplace() || offset == this.offset;
this.offset = offset;
for (int i=0; i < items.size(); i++) {
T item = items.get(i);
assert item != null;
offset = AlignmentUtils.alignOffset(offset, ItemType.ItemAlignment);
offset = item.placeAt(offset, i);
}
} else {
this.offset = 0;
}
return offset;
}
/**
* Write the items to the given <code>AnnotatedOutput</code>
* @param out the <code>AnnotatedOutput</code> object to write to
*/
protected void writeTo(AnnotatedOutput out) {
out.annotate(0, " ");
out.annotate(0, "-----------------------------");
out.annotate(0, this.ItemType.TypeName + " section");
out.annotate(0, "-----------------------------");
out.annotate(0, " ");
for (Item item: items) {
assert item!=null;
out.alignTo(ItemType.ItemAlignment);
item.writeTo(out);
out.annotate(0, " ");
}
}
/**
* Read the specified number of items from the given <code>Input</code> object
* @param size The number of items to read
* @param in The <code>Input</code> object to read from
* @param readContext a <code>ReadContext</code> object to hold information that is
* only needed while reading in a file
*/
protected void readFrom(int size, Input in, ReadContext readContext) {
//readItems() expects that the list will already be the correct size, so add null items
//until we reach the specified size
items.ensureCapacity(size);
for (int i = items.size(); i < size; i++) {
items.add(null);
}
in.alignTo(ItemType.ItemAlignment);
offset = in.getCursor();
//call the subclass's method that actually reads in the items
readItems(in, readContext);
}
/**
* This method in the concrete item subclass should read in all the items from the given <code>Input</code>
* object, using any pre-created items as applicable (i.e. items that were created prior to reading in the
* section, by other items requesting items from this section that they reference by index/offset)
* @param in the <code>Input</code>
* @param readContext a <code>ReadContext</code> object to hold information that is
* only needed while reading in a file
*/
protected abstract void readItems(Input in, ReadContext readContext);
/**
* Gets the offset where the first item in this section is placed
* @return the ofset where the first item in this section is placed
*/
public int getOffset() {
return offset;
}
/**
* Gets a the items contained in this section as a read-only list
* @return A read-only <code>List</code> object containing the items in this section
*/
public List<T> getItems() {
return Collections.unmodifiableList(items);
}
/**
* This method checks if an item that is equivalent to the given item has already been added. If found,
* it returns that item. If not found, it adds the given item to this section and returns it.
* @param item the item to intern
* @return An item from this section that is equivalent to the given item. It may or may not be the same
* as the item passed to this method.
*/
protected T intern(T item) {
if (item == null) {
return null;
}
T internedItem = getInternedItem(item);
if (internedItem == null && !item.dexFile.getInterningDisabled()) {
uniqueItems.put(item, item);
items.add(item);
return item;
}
return internedItem;
}
/**
* Returns the interned item that is equivalent to the given item, or null
* @param item the item to check
* @return the interned item that is equivalent to the given item, or null
*/
protected T getInternedItem(T item) {
if (uniqueItems == null) {
buildInternedItemMap();
}
return uniqueItems.get(item);
}
/**
* Builds the interned item map from the items that are in this section
*/
private void buildInternedItemMap() {
uniqueItems = new HashMap<T,T>();
for (T item: items) {
assert item != null;
uniqueItems.put(item, item);
}
}
/**
* Sorts the items in the section
*/
protected void sortSection() {
Collections.sort(items);
}
/*
* [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;
import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AlignmentUtils;
import java.util.*;
public abstract class Section<T extends Item> {
/**
* A list of the items that this section contains.
* If the section has been placed, this list should be in the order that the items
* will written to the dex file
*/
protected final ArrayList<T> items;
/**
* A HashMap of the items in this section. This is used when interning items, to determine
* if this section already has an item equivalent to the one that is being interned.
* Both the key and the value should be the same object
*/
protected HashMap<T,T> uniqueItems = null;
/**
* The offset of this section within the <code>DexFile</code>
*/
protected int offset = 0;
/**
* The type of item that this section holds
*/
public final ItemType ItemType;
/**
* The <code>DexFile</code> that this section belongs to
*/
public final DexFile DexFile;
/**
* Create a new section
* @param dexFile The <code>DexFile</code> that this section belongs to
* @param itemType The itemType that this section will hold
*/
protected Section(DexFile dexFile, ItemType itemType) {
this.DexFile = dexFile;
items = new ArrayList<T>();
this.ItemType = itemType;
}
/**
* Finalize the location of all items, and place them starting at the given offset
* @param offset The offset where this section should be placed
* @return the offset of the byte immediate after the last item in this section
*/
protected int placeAt(int offset) {
if (items.size() > 0) {
offset = AlignmentUtils.alignOffset(offset, ItemType.ItemAlignment);
assert !DexFile.getInplace() || offset == this.offset;
this.offset = offset;
for (int i=0; i < items.size(); i++) {
T item = items.get(i);
assert item != null;
offset = AlignmentUtils.alignOffset(offset, ItemType.ItemAlignment);
offset = item.placeAt(offset, i);
}
} else {
this.offset = 0;
}
return offset;
}
/**
* Write the items to the given <code>AnnotatedOutput</code>
* @param out the <code>AnnotatedOutput</code> object to write to
*/
protected void writeTo(AnnotatedOutput out) {
out.annotate(0, " ");
out.annotate(0, "-----------------------------");
out.annotate(0, this.ItemType.TypeName + " section");
out.annotate(0, "-----------------------------");
out.annotate(0, " ");
for (Item item: items) {
assert item!=null;
out.alignTo(ItemType.ItemAlignment);
item.writeTo(out);
out.annotate(0, " ");
}
}
/**
* Read the specified number of items from the given <code>Input</code> object
* @param size The number of items to read
* @param in The <code>Input</code> object to read from
* @param readContext a <code>ReadContext</code> object to hold information that is
* only needed while reading in a file
*/
protected void readFrom(int size, Input in, ReadContext readContext) {
//readItems() expects that the list will already be the correct size, so add null items
//until we reach the specified size
items.ensureCapacity(size);
for (int i = items.size(); i < size; i++) {
items.add(null);
}
in.alignTo(ItemType.ItemAlignment);
offset = in.getCursor();
//call the subclass's method that actually reads in the items
readItems(in, readContext);
}
/**
* This method in the concrete item subclass should read in all the items from the given <code>Input</code>
* object, using any pre-created items as applicable (i.e. items that were created prior to reading in the
* section, by other items requesting items from this section that they reference by index/offset)
* @param in the <code>Input</code>
* @param readContext a <code>ReadContext</code> object to hold information that is
* only needed while reading in a file
*/
protected abstract void readItems(Input in, ReadContext readContext);
/**
* Gets the offset where the first item in this section is placed
* @return the ofset where the first item in this section is placed
*/
public int getOffset() {
return offset;
}
/**
* Gets a the items contained in this section as a read-only list
* @return A read-only <code>List</code> object containing the items in this section
*/
public List<T> getItems() {
return Collections.unmodifiableList(items);
}
/**
* This method checks if an item that is equivalent to the given item has already been added. If found,
* it returns that item. If not found, it adds the given item to this section and returns it.
* @param item the item to intern
* @return An item from this section that is equivalent to the given item. It may or may not be the same
* as the item passed to this method.
*/
protected T intern(T item) {
if (item == null) {
return null;
}
T internedItem = getInternedItem(item);
if (internedItem == null && !item.dexFile.getInterningDisabled()) {
uniqueItems.put(item, item);
items.add(item);
return item;
}
return internedItem;
}
/**
* Returns the interned item that is equivalent to the given item, or null
* @param item the item to check
* @return the interned item that is equivalent to the given item, or null
*/
protected T getInternedItem(T item) {
if (uniqueItems == null) {
buildInternedItemMap();
}
return uniqueItems.get(item);
}
/**
* Builds the interned item map from the items that are in this section
*/
private void buildInternedItemMap() {
uniqueItems = new HashMap<T,T>();
for (T item: items) {
assert item != null;
uniqueItems.put(item, item);
}
}
/**
* Sorts the items in the section
*/
protected void sortSection() {
Collections.sort(items);
}
}

View File

@ -1,153 +1,153 @@
/*
* [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;
import org.jf.dexlib.Util.*;
public class StringDataItem extends Item<StringDataItem> {
private int hashCode = 0;
private String stringValue;
/**
* Creates a new uninitialized <code>StringDataItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected StringDataItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>StringDataItem</code> for the given string
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param stringValue The string value that this item represents
*/
private StringDataItem(DexFile dexFile, String stringValue) {
super(dexFile);
this.stringValue = stringValue;
}
/**
* Returns a <code>StringDataItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param value The string value that this item represents
* @return a <code>StringDataItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static StringDataItem getInternedStringDataItem(DexFile dexFile, String value) {
StringDataItem StringDataItem = new StringDataItem(dexFile, value);
return dexFile.StringDataSection.intern(StringDataItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
in.readUnsignedLeb128(); //string length
stringValue = Utf8Utils.utf8BytesToString(in.readNullTerminatedBytes());
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + Leb128Utils.unsignedLeb128Size(stringValue.length()) +
Utf8Utils.stringToUtf8Bytes(stringValue).length + 1;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
byte[] encodedValue = Utf8Utils.stringToUtf8Bytes(stringValue);
if (out.annotates()) {
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);
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_STRING_DATA_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "string_data_item: \"" + Utf8Utils.escapeString(getStringValue()) + "\"";
}
/** {@inheritDoc} */
public int compareTo(StringDataItem o) {
return getStringValue().compareTo(o.getStringValue());
}
/**
* Get the string value of this item as a <code>String</code>
* @return the string value of this item as a String
*/
public String getStringValue() {
return stringValue;
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = getStringValue().hashCode();
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
StringDataItem other = (StringDataItem)o;
return getStringValue().equals(other.getStringValue());
}
}
/*
* [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;
import org.jf.dexlib.Util.*;
public class StringDataItem extends Item<StringDataItem> {
private int hashCode = 0;
private String stringValue;
/**
* Creates a new uninitialized <code>StringDataItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected StringDataItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>StringDataItem</code> for the given string
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param stringValue The string value that this item represents
*/
private StringDataItem(DexFile dexFile, String stringValue) {
super(dexFile);
this.stringValue = stringValue;
}
/**
* Returns a <code>StringDataItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param value The string value that this item represents
* @return a <code>StringDataItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static StringDataItem getInternedStringDataItem(DexFile dexFile, String value) {
StringDataItem StringDataItem = new StringDataItem(dexFile, value);
return dexFile.StringDataSection.intern(StringDataItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
in.readUnsignedLeb128(); //string length
stringValue = Utf8Utils.utf8BytesToString(in.readNullTerminatedBytes());
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + Leb128Utils.unsignedLeb128Size(stringValue.length()) +
Utf8Utils.stringToUtf8Bytes(stringValue).length + 1;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
byte[] encodedValue = Utf8Utils.stringToUtf8Bytes(stringValue);
if (out.annotates()) {
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);
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_STRING_DATA_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "string_data_item: \"" + Utf8Utils.escapeString(getStringValue()) + "\"";
}
/** {@inheritDoc} */
public int compareTo(StringDataItem o) {
return getStringValue().compareTo(o.getStringValue());
}
/**
* Get the string value of this item as a <code>String</code>
* @return the string value of this item as a String
*/
public String getStringValue() {
return stringValue;
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
hashCode = getStringValue().hashCode();
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
StringDataItem other = (StringDataItem)o;
return getStringValue().equals(other.getStringValue());
}
}

View File

@ -1,148 +1,148 @@
/*
* [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;
import org.jf.dexlib.Util.Utf8Utils;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class StringIdItem extends Item<StringIdItem> {
private StringDataItem stringDataItem;
/**
* Creates a new uninitialized <code>StringIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected StringIdItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>StringIdItem</code> for the given <code>StringDataItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param stringDataItem The <code>StringDataItem</code> that this <code>StringIdItem</code> represents
*/
protected StringIdItem(DexFile dexFile, StringDataItem stringDataItem) {
super(dexFile);
this.stringDataItem = stringDataItem;
}
/**
* Returns a <code>StringIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item will belong to
* @param stringValue The string value that this item represents
* @return a <code>StringIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static StringIdItem getInternedStringIdItem(DexFile dexFile, String stringValue) {
StringDataItem stringDataItem = StringDataItem.getInternedStringDataItem(dexFile, stringValue);
if (stringDataItem == null) {
return null;
}
StringIdItem stringIdItem = new StringIdItem(dexFile, stringDataItem);
return dexFile.StringIdsSection.intern(stringIdItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
int stringDataOffset = in.readInt();
stringDataItem = (StringDataItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_STRING_DATA_ITEM,
stringDataOffset);
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 4;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(4, stringDataItem.getConciseIdentity());
}
out.writeInt(stringDataItem.getOffset());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_STRING_ID_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "string_id_item: " + Utf8Utils.escapeString(getStringValue());
}
/** {@inheritDoc} */
public int compareTo(StringIdItem o) {
//sort by the string value
return getStringValue().compareTo(o.getStringValue());
}
/**
* Get the <code>String</code> value that this <code>StringIdItem</code> represents
* @return the <code>String</code> value that this <code>StringIdItem</code> represents
*/
public String getStringValue() {
return stringDataItem.getStringValue();
}
/**
* Get the <code>StringDataItem</code> that this <code>StringIdItem</code> references
* @return the <code>StringDataItem</code> that this <code>StringIdItem</code> references
*/
public StringDataItem getStringDataItem() {
return stringDataItem;
}
@Override
public int hashCode() {
return stringDataItem.hashCode();
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
StringIdItem other = (StringIdItem)o;
return stringDataItem == other.stringDataItem;
}
}
/*
* [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;
import org.jf.dexlib.Util.Utf8Utils;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class StringIdItem extends Item<StringIdItem> {
private StringDataItem stringDataItem;
/**
* Creates a new uninitialized <code>StringIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected StringIdItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>StringIdItem</code> for the given <code>StringDataItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param stringDataItem The <code>StringDataItem</code> that this <code>StringIdItem</code> represents
*/
protected StringIdItem(DexFile dexFile, StringDataItem stringDataItem) {
super(dexFile);
this.stringDataItem = stringDataItem;
}
/**
* Returns a <code>StringIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item will belong to
* @param stringValue The string value that this item represents
* @return a <code>StringIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static StringIdItem getInternedStringIdItem(DexFile dexFile, String stringValue) {
StringDataItem stringDataItem = StringDataItem.getInternedStringDataItem(dexFile, stringValue);
if (stringDataItem == null) {
return null;
}
StringIdItem stringIdItem = new StringIdItem(dexFile, stringDataItem);
return dexFile.StringIdsSection.intern(stringIdItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
int stringDataOffset = in.readInt();
stringDataItem = (StringDataItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_STRING_DATA_ITEM,
stringDataOffset);
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 4;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(4, stringDataItem.getConciseIdentity());
}
out.writeInt(stringDataItem.getOffset());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_STRING_ID_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "string_id_item: " + Utf8Utils.escapeString(getStringValue());
}
/** {@inheritDoc} */
public int compareTo(StringIdItem o) {
//sort by the string value
return getStringValue().compareTo(o.getStringValue());
}
/**
* Get the <code>String</code> value that this <code>StringIdItem</code> represents
* @return the <code>String</code> value that this <code>StringIdItem</code> represents
*/
public String getStringValue() {
return stringDataItem.getStringValue();
}
/**
* Get the <code>StringDataItem</code> that this <code>StringIdItem</code> references
* @return the <code>StringDataItem</code> that this <code>StringIdItem</code> references
*/
public StringDataItem getStringDataItem() {
return stringDataItem;
}
@Override
public int hashCode() {
return stringDataItem.hashCode();
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
StringIdItem other = (StringIdItem)o;
return stringDataItem == other.stringDataItem;
}
}

View File

@ -1,182 +1,182 @@
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class TypeIdItem extends Item<TypeIdItem> {
private StringIdItem typeDescriptor;
/**
* Creates a new uninitialized <code>TypeIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected TypeIdItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>TypeIdItem</code> for the given <code>StringIdItem</code>
* @param dexFile The <code>DexFile</code> that this item will belong to
* @param typeDescriptor The <code>StringIdItem</code> containing the type descriptor that
* this <code>TypeIdItem</code> represents
*/
private TypeIdItem(DexFile dexFile, StringIdItem typeDescriptor) {
super(dexFile);
this.typeDescriptor = typeDescriptor;
}
/**
* Returns a <code>TypeIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item will belong to
* @param typeDescriptor The <code>StringIdItem</code> containing the type descriptor that
* this <code>TypeIdItem</code> represents
* @return a <code>TypeIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static TypeIdItem getInternedTypeIdItem(DexFile dexFile, StringIdItem typeDescriptor) {
TypeIdItem typeIdItem = new TypeIdItem(dexFile, typeDescriptor);
return dexFile.TypeIdsSection.intern(typeIdItem);
}
/**
* Returns a <code>TypeIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item will belong to
* @param typeDescriptor The string containing the type descriptor that this
* <code>TypeIdItem</code> represents
* @return a <code>TypeIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static TypeIdItem getInternedTypeIdItem(DexFile dexFile, String typeDescriptor) {
StringIdItem stringIdItem = StringIdItem.getInternedStringIdItem(dexFile, typeDescriptor);
if (stringIdItem == null) {
return null;
}
TypeIdItem typeIdItem = new TypeIdItem(dexFile, stringIdItem);
return dexFile.TypeIdsSection.intern(typeIdItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
int stringIdIndex = in.readInt();
this.typeDescriptor = dexFile.StringIdsSection.getItemByIndex(stringIdIndex);
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 4;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(4, typeDescriptor.getConciseIdentity());
}
out.writeInt(typeDescriptor.getIndex());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_TYPE_ID_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "type_id_item: " + getTypeDescriptor();
}
/** {@inheritDoc} */
public int compareTo(TypeIdItem o) {
//sort by the index of the StringIdItem
return typeDescriptor.compareTo(o.typeDescriptor);
}
/**
* Returns the type descriptor as a <code>String</code> for this type
* @return the type descriptor as a <code>String</code> for this type
*/
public String getTypeDescriptor() {
return typeDescriptor.getStringValue();
}
/**
* Returns the "shorty" representation of this type, used to create the shorty prototype string for a method
* @return the "shorty" representation of this type, used to create the shorty prototype string for a method
*/
public String toShorty() {
String type = getTypeDescriptor();
if (type.length() > 1) {
return "L";
} else {
return type;
}
}
/**
* Calculates the number of 2-byte registers that an instance of this type requires
* @return The number of 2-byte registers that an instance of this type requires
*/
public int getRegisterCount() {
String type = this.getTypeDescriptor();
/** Only the long and double primitive types are 2 words,
* everything else is a single word
*/
if (type.equals("J") || type.equals("D")) {
return 2;
} else {
return 1;
}
}
@Override
public int hashCode() {
return typeDescriptor.hashCode();
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
TypeIdItem other = (TypeIdItem)o;
return typeDescriptor == other.typeDescriptor;
}
}
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
public class TypeIdItem extends Item<TypeIdItem> {
private StringIdItem typeDescriptor;
/**
* Creates a new uninitialized <code>TypeIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected TypeIdItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>TypeIdItem</code> for the given <code>StringIdItem</code>
* @param dexFile The <code>DexFile</code> that this item will belong to
* @param typeDescriptor The <code>StringIdItem</code> containing the type descriptor that
* this <code>TypeIdItem</code> represents
*/
private TypeIdItem(DexFile dexFile, StringIdItem typeDescriptor) {
super(dexFile);
this.typeDescriptor = typeDescriptor;
}
/**
* Returns a <code>TypeIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item will belong to
* @param typeDescriptor The <code>StringIdItem</code> containing the type descriptor that
* this <code>TypeIdItem</code> represents
* @return a <code>TypeIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static TypeIdItem getInternedTypeIdItem(DexFile dexFile, StringIdItem typeDescriptor) {
TypeIdItem typeIdItem = new TypeIdItem(dexFile, typeDescriptor);
return dexFile.TypeIdsSection.intern(typeIdItem);
}
/**
* Returns a <code>TypeIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item will belong to
* @param typeDescriptor The string containing the type descriptor that this
* <code>TypeIdItem</code> represents
* @return a <code>TypeIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static TypeIdItem getInternedTypeIdItem(DexFile dexFile, String typeDescriptor) {
StringIdItem stringIdItem = StringIdItem.getInternedStringIdItem(dexFile, typeDescriptor);
if (stringIdItem == null) {
return null;
}
TypeIdItem typeIdItem = new TypeIdItem(dexFile, stringIdItem);
return dexFile.TypeIdsSection.intern(typeIdItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
int stringIdIndex = in.readInt();
this.typeDescriptor = dexFile.StringIdsSection.getItemByIndex(stringIdIndex);
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 4;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) {
out.annotate(4, typeDescriptor.getConciseIdentity());
}
out.writeInt(typeDescriptor.getIndex());
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_TYPE_ID_ITEM;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "type_id_item: " + getTypeDescriptor();
}
/** {@inheritDoc} */
public int compareTo(TypeIdItem o) {
//sort by the index of the StringIdItem
return typeDescriptor.compareTo(o.typeDescriptor);
}
/**
* Returns the type descriptor as a <code>String</code> for this type
* @return the type descriptor as a <code>String</code> for this type
*/
public String getTypeDescriptor() {
return typeDescriptor.getStringValue();
}
/**
* Returns the "shorty" representation of this type, used to create the shorty prototype string for a method
* @return the "shorty" representation of this type, used to create the shorty prototype string for a method
*/
public String toShorty() {
String type = getTypeDescriptor();
if (type.length() > 1) {
return "L";
} else {
return type;
}
}
/**
* Calculates the number of 2-byte registers that an instance of this type requires
* @return The number of 2-byte registers that an instance of this type requires
*/
public int getRegisterCount() {
String type = this.getTypeDescriptor();
/** Only the long and double primitive types are 2 words,
* everything else is a single word
*/
if (type.equals("J") || type.equals("D")) {
return 2;
} else {
return 1;
}
}
@Override
public int hashCode() {
return typeDescriptor.hashCode();
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
TypeIdItem other = (TypeIdItem)o;
return typeDescriptor == other.typeDescriptor;
}
}

View File

@ -1,258 +1,258 @@
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.ReadOnlyArrayList;
import java.util.List;
public class TypeListItem extends Item<TypeListItem> {
private int hashCode = 0;
private TypeIdItem[] typeList;
/**
* Creates a new uninitialized <code>TypeListItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected TypeListItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>TypeListItem</code> for the given string
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param typeList A list of the types that this <code>TypeListItem</code> represents
*/
private TypeListItem(DexFile dexFile, TypeIdItem[] typeList) {
super(dexFile);
this.typeList = typeList;
}
/**
* Returns a <code>TypeListItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param typeList A list of the types that this <code>TypeListItem</code> represents
* @return a <code>TypeListItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static TypeListItem getInternedTypeListItem(DexFile dexFile, List<TypeIdItem> typeList) {
TypeIdItem[] typeArray = new TypeIdItem[typeList.size()];
typeList.toArray(typeArray);
TypeListItem typeListItem = new TypeListItem(dexFile, typeArray);
return dexFile.TypeListsSection.intern(typeListItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
int size = in.readInt();
typeList = new TypeIdItem[size];
for (int i=0; i<size; i++) {
int typeIndex = in.readShort();
typeList[i] = dexFile.TypeIdsSection.getItemByIndex(typeIndex);
}
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 4 + typeList.length * 2;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
//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: 0x" + Integer.toHexString(typeList.length) + " (" + typeList.length +")");
for (TypeIdItem typeIdItem: typeList) {
out.annotate(2, "type_id_item: " + typeIdItem.getTypeDescriptor());
}
}
out.writeInt(typeList.length);
for (TypeIdItem typeIdItem: typeList) {
out.writeShort(typeIdItem.getIndex());
}
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_TYPE_LIST;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "type_list: " + getTypeListString("");
}
/** {@inheritDoc} */
public int compareTo(TypeListItem o) {
if (o == null) {
return 1;
}
int thisSize = typeList.length;
int otherSize = o.typeList.length;
int size = Math.min(thisSize, otherSize);
for (int i = 0; i < size; i++) {
int result = typeList[i].compareTo(o.typeList[i]);
if (result != 0) {
return result;
}
}
if (thisSize < otherSize) {
return -1;
} else if (thisSize > otherSize) {
return 1;
} else {
return 0;
}
}
/**
* @return the number of registers required for this <code>TypeListItem</code>
*/
public int getRegisterCount() {
int wordCount = 0;
for (TypeIdItem typeIdItem: typeList) {
wordCount += typeIdItem.getRegisterCount();
}
return wordCount;
}
/**
* @return a string consisting of the type descriptors in this <code>TypeListItem</code>
* that are separated by the given separator
* @param separator the separator between each type
*/
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);
}
if (typeList.length > 0) {
sb.delete(sb.length() - separator.length(), sb.length());
}
return sb.toString();
}
/**
* @return a string consisting of the shorty form of the type descriptors in this
* <code>TypeListItem</code> that are directly concatenated together
*/
public String getShortyString() {
StringBuilder sb = new StringBuilder();
for (TypeIdItem typeIdItem: typeList) {
sb.append(typeIdItem.toShorty());
}
return sb.toString();
}
/**
* @param index the index of the <code>TypeIdItem</code> to get
* @return the <code>TypeIdItem</code> at the given index
*/
public TypeIdItem getTypeIdItem(int index) {
return typeList[index];
}
/**
* @return the number of types in this <code>TypeListItem</code>
*/
public int getTypeCount() {
return typeList.length;
}
/**
* @return an array of the <code>TypeIdItems</code> in this <code>TypeListItem</code>
*/
public List<TypeIdItem> getTypes() {
return new ReadOnlyArrayList<TypeIdItem>(typeList);
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
int hashCode = 1;
for (TypeIdItem typeIdItem: typeList) {
hashCode = 31 * hashCode + typeIdItem.hashCode();
}
this.hashCode = hashCode;
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
TypeListItem other = (TypeListItem)o;
if (typeList.length != other.typeList.length) {
return false;
}
for (int i=0; i<typeList.length; i++) {
if (typeList[i] != other.typeList[i]) {
return false;
}
}
return true;
}
}
/*
* [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;
import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.ReadOnlyArrayList;
import java.util.List;
public class TypeListItem extends Item<TypeListItem> {
private int hashCode = 0;
private TypeIdItem[] typeList;
/**
* Creates a new uninitialized <code>TypeListItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
*/
protected TypeListItem(DexFile dexFile) {
super(dexFile);
}
/**
* Creates a new <code>TypeListItem</code> for the given string
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param typeList A list of the types that this <code>TypeListItem</code> represents
*/
private TypeListItem(DexFile dexFile, TypeIdItem[] typeList) {
super(dexFile);
this.typeList = typeList;
}
/**
* Returns a <code>TypeListItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to
* @param typeList A list of the types that this <code>TypeListItem</code> represents
* @return a <code>TypeListItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code>
*/
public static TypeListItem getInternedTypeListItem(DexFile dexFile, List<TypeIdItem> typeList) {
TypeIdItem[] typeArray = new TypeIdItem[typeList.size()];
typeList.toArray(typeArray);
TypeListItem typeListItem = new TypeListItem(dexFile, typeArray);
return dexFile.TypeListsSection.intern(typeListItem);
}
/** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) {
int size = in.readInt();
typeList = new TypeIdItem[size];
for (int i=0; i<size; i++) {
int typeIndex = in.readShort();
typeList[i] = dexFile.TypeIdsSection.getItemByIndex(typeIndex);
}
}
/** {@inheritDoc} */
protected int placeItem(int offset) {
return offset + 4 + typeList.length * 2;
}
/** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) {
//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: 0x" + Integer.toHexString(typeList.length) + " (" + typeList.length +")");
for (TypeIdItem typeIdItem: typeList) {
out.annotate(2, "type_id_item: " + typeIdItem.getTypeDescriptor());
}
}
out.writeInt(typeList.length);
for (TypeIdItem typeIdItem: typeList) {
out.writeShort(typeIdItem.getIndex());
}
}
/** {@inheritDoc} */
public ItemType getItemType() {
return ItemType.TYPE_TYPE_LIST;
}
/** {@inheritDoc} */
public String getConciseIdentity() {
return "type_list: " + getTypeListString("");
}
/** {@inheritDoc} */
public int compareTo(TypeListItem o) {
if (o == null) {
return 1;
}
int thisSize = typeList.length;
int otherSize = o.typeList.length;
int size = Math.min(thisSize, otherSize);
for (int i = 0; i < size; i++) {
int result = typeList[i].compareTo(o.typeList[i]);
if (result != 0) {
return result;
}
}
if (thisSize < otherSize) {
return -1;
} else if (thisSize > otherSize) {
return 1;
} else {
return 0;
}
}
/**
* @return the number of registers required for this <code>TypeListItem</code>
*/
public int getRegisterCount() {
int wordCount = 0;
for (TypeIdItem typeIdItem: typeList) {
wordCount += typeIdItem.getRegisterCount();
}
return wordCount;
}
/**
* @return a string consisting of the type descriptors in this <code>TypeListItem</code>
* that are separated by the given separator
* @param separator the separator between each type
*/
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);
}
if (typeList.length > 0) {
sb.delete(sb.length() - separator.length(), sb.length());
}
return sb.toString();
}
/**
* @return a string consisting of the shorty form of the type descriptors in this
* <code>TypeListItem</code> that are directly concatenated together
*/
public String getShortyString() {
StringBuilder sb = new StringBuilder();
for (TypeIdItem typeIdItem: typeList) {
sb.append(typeIdItem.toShorty());
}
return sb.toString();
}
/**
* @param index the index of the <code>TypeIdItem</code> to get
* @return the <code>TypeIdItem</code> at the given index
*/
public TypeIdItem getTypeIdItem(int index) {
return typeList[index];
}
/**
* @return the number of types in this <code>TypeListItem</code>
*/
public int getTypeCount() {
return typeList.length;
}
/**
* @return an array of the <code>TypeIdItems</code> in this <code>TypeListItem</code>
*/
public List<TypeIdItem> getTypes() {
return new ReadOnlyArrayList<TypeIdItem>(typeList);
}
/**
* calculate and cache the hashcode
*/
private void calcHashCode() {
int hashCode = 1;
for (TypeIdItem typeIdItem: typeList) {
hashCode = 31 * hashCode + typeIdItem.hashCode();
}
this.hashCode = hashCode;
}
@Override
public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time
if (hashCode == 0)
calcHashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (this==o) {
return true;
}
if (o==null || !this.getClass().equals(o.getClass())) {
return false;
}
//This assumes that the referenced items have been interned in both objects.
//This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned
TypeListItem other = (TypeListItem)o;
if (typeList.length != other.typeList.length) {
return false;
}
for (int i=0; i<typeList.length; i++) {
if (typeList[i] != other.typeList[i]) {
return false;
}
}
return true;
}
}

View File

@ -1,175 +1,175 @@
/*
* [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.ArrayList;
import java.util.HashMap;
import java.util.List;
public enum AccessFlags
{
PUBLIC(0x1, "public", true, true, true),
PRIVATE(0x2, "private", true, true, true),
PROTECTED(0x4, "protected", true, true, true),
STATIC(0x8, "static", true, true, true),
FINAL(0x10, "final", true, true, true),
SYNCHRONIZED(0x20, "synchronized", false, true, false),
VOLATILE(0x40, "volatile", false, false, true),
BRIDGE(0x40, "bridge", false, true, false),
TRANSIENT(0x80, "transient", false, false, true),
VARARGS(0x80, "varargs", false, true, false),
NATIVE(0x100, "native", false, true, false),
INTERFACE(0x200, "interface", true, false, false),
ABSTRACT(0x400, "abstract", true, true, false),
STRICTFP(0x800, "strictfp", false, true, false),
SYNTHETIC(0x1000, "synthetic", true, true, true),
ANNOTATION(0x2000, "annotation", true, false, false),
ENUM(0x4000, "enum", true, false, true),
CONSTRUCTOR(0x10000, "constructor", false, true, false),
DECLARED_SYNCHRONIZED(0x20000, "declared-synchronized", false, true, false);
private int value;
private String accessFlagName;
private boolean validForClass;
private boolean validForMethod;
private boolean validForField;
private static HashMap<String, AccessFlags> accessFlagsByName;
static {
accessFlagsByName = new HashMap<String, AccessFlags>();
for (AccessFlags accessFlag: AccessFlags.values()) {
accessFlagsByName.put(accessFlag.accessFlagName, accessFlag);
}
}
private AccessFlags(int value, String accessFlagName, boolean validForClass, boolean validForMethod,
boolean validForField) {
this.value = value;
this.accessFlagName = accessFlagName;
this.validForClass = validForClass;
this.validForMethod = validForMethod;
this.validForField = validForField;
}
public static AccessFlags[] getAccessFlagsForClass(int accessFlagValue) {
int size = 0;
for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
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;
}
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) {
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 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) {
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);
}
public int getValue() {
return value;
}
public String toString() {
return accessFlagName;
}
}
/*
* [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.ArrayList;
import java.util.HashMap;
import java.util.List;
public enum AccessFlags
{
PUBLIC(0x1, "public", true, true, true),
PRIVATE(0x2, "private", true, true, true),
PROTECTED(0x4, "protected", true, true, true),
STATIC(0x8, "static", true, true, true),
FINAL(0x10, "final", true, true, true),
SYNCHRONIZED(0x20, "synchronized", false, true, false),
VOLATILE(0x40, "volatile", false, false, true),
BRIDGE(0x40, "bridge", false, true, false),
TRANSIENT(0x80, "transient", false, false, true),
VARARGS(0x80, "varargs", false, true, false),
NATIVE(0x100, "native", false, true, false),
INTERFACE(0x200, "interface", true, false, false),
ABSTRACT(0x400, "abstract", true, true, false),
STRICTFP(0x800, "strictfp", false, true, false),
SYNTHETIC(0x1000, "synthetic", true, true, true),
ANNOTATION(0x2000, "annotation", true, false, false),
ENUM(0x4000, "enum", true, false, true),
CONSTRUCTOR(0x10000, "constructor", false, true, false),
DECLARED_SYNCHRONIZED(0x20000, "declared-synchronized", false, true, false);
private int value;
private String accessFlagName;
private boolean validForClass;
private boolean validForMethod;
private boolean validForField;
private static HashMap<String, AccessFlags> accessFlagsByName;
static {
accessFlagsByName = new HashMap<String, AccessFlags>();
for (AccessFlags accessFlag: AccessFlags.values()) {
accessFlagsByName.put(accessFlag.accessFlagName, accessFlag);
}
}
private AccessFlags(int value, String accessFlagName, boolean validForClass, boolean validForMethod,
boolean validForField) {
this.value = value;
this.accessFlagName = accessFlagName;
this.validForClass = validForClass;
this.validForMethod = validForMethod;
this.validForField = validForField;
}
public static AccessFlags[] getAccessFlagsForClass(int accessFlagValue) {
int size = 0;
for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
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;
}
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) {
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 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) {
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);
}
public int getValue() {
return value;
}
public String toString() {
return accessFlagName;
}
}

View File

@ -1,364 +1,364 @@
/*
* [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;
/**
* Implementation of {@link Input} which reads the data from a
* <code>byte[]</code> instance.
*
* <p><b>Note:</b> As per the {@link Input } interface, multi-byte
* reads all use little-endian order.</p>
*/
public class ByteArrayInput
implements Input {
/** non-null; the data itself */
private byte[] data;
/** &gt;= 0; current read cursor */
private int cursor;
/**
* Constructs an instance with the given data
*
* @param data non-null; data array to use for input
*/
public ByteArrayInput(byte[] data) {
if (data == null) {
throw new NullPointerException("data == null");
}
this.data = data;
this.cursor = 0;
}
/**
* Gets the underlying <code>byte[]</code> of this instance
*
* @return non-null; the <code>byte[]</code>
*/
public byte[] getArray() {
return data;
}
/** {@inheritDoc} */
public int getCursor() {
return cursor;
}
/** {@inheritDoc} */
public void setCursor(int cursor) {
if (cursor < 0 || cursor >= data.length)
throw new IndexOutOfBoundsException("The provided cursor value " +
"is not within the bounds of this instance's data array");
this.cursor = cursor;
}
/** {@inheritDoc} */
public void assertCursor(int expectedCursor) {
if (cursor != expectedCursor) {
throw new ExceptionWithContext("expected cursor " +
expectedCursor + "; actual value: " + cursor);
}
}
/** {@inheritDoc} */
public byte readByte() {
int readAt = cursor;
int end = readAt + 1;
if (end > data.length) {
throwBounds();
}
cursor = end;
return data[readAt];
}
/** {@inheritDoc} */
public int readShort() {
int readAt = cursor;
int end = readAt + 2;
if (end > data.length) {
throwBounds();
}
cursor = end;
return (int)((data[readAt] & 0xff) +
((data[readAt + 1] & 0xff) << 8));
}
/** {@inheritDoc} */
public int readInt() {
int readAt = cursor;
int end = readAt + 4;
if (end > data.length) {
throwBounds();
}
cursor = end;
return (data[readAt] & 0xff) +
((data[readAt + 1] & 0xff) << 8) +
((data[readAt + 2] & 0xff) << 16) +
((data[readAt + 3] & 0xff) << 24);
}
/** {@inheritDoc} */
public long readLong() {
int readAt = cursor;
int end = readAt + 8;
if (end > data.length) {
throwBounds();
}
cursor = end;
return (data[readAt] & 0xffL) |
((data[readAt + 1] & 0xffL) << 8) |
((data[readAt + 2] & 0xffL) << 16) |
((data[readAt + 3] & 0xffL) << 24) |
((data[readAt + 4] & 0xffL) << 32) |
((data[readAt + 5] & 0xffL) << 40) |
((data[readAt + 6] & 0xffL) << 48) |
((data[readAt + 7] & 0xffL) << 58);
}
/** {@inheritDoc} */
public int readUnsignedOrSignedLeb128() {
int end = cursor;
int currentByteValue;
int result;
result = data[end++] & 0xff;
if (result > 0x7f) {
currentByteValue = data[end++] & 0xff;
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 14;
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 21;
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
if (currentByteValue > 0x0f) {
throwInvalidLeb();
}
result |= currentByteValue << 28;
}
}
}
} else {
cursor = end;
return result;
}
cursor = end;
//If the last byte is 0, then this was an unsigned value (incorrectly) written in a signed format
//The caller wants to know if this is the case, so we'll return the negated value instead
//If there was only a single byte that had a value of 0, then we would have returned in the above
//"else"
if (data[end-1] == 0) {
return ~result;
}
return result;
}
/** {@inheritDoc} */
public int readUnsignedLeb128() {
int end = cursor;
int currentByteValue;
int result;
result = data[end++] & 0xff;
if (result > 0x7f) {
currentByteValue = data[end++] & 0xff;
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 14;
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 21;
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
if (currentByteValue > 0x0f) {
throwInvalidLeb();
}
result |= currentByteValue << 28;
}
}
}
}
cursor = end;
return result;
}
/** {@inheritDoc} */
public int readSignedLeb128() {
int end = cursor;
int currentByteValue;
int result;
result = data[end++] & 0xff;
if (result <= 0x7f) {
result = (result << 25) >> 25;
} else {
currentByteValue = data[end++] & 0xff;
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
if (currentByteValue <= 0x7f) {
result = (result << 18) >> 18;
} else {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 14;
if (currentByteValue <= 0x7f) {
result = (result << 11) >> 11;
} else {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 21;
if (currentByteValue <= 0x7f) {
result = (result << 4) >> 4;
} else {
currentByteValue = data[end++] & 0xff;
if (currentByteValue > 0x0f) {
throwInvalidLeb();
}
result |= currentByteValue << 28;
}
}
}
}
cursor = end;
return result;
}
/** {@inheritDoc} */
public void read(byte[] bytes, int offset, int length) {
int end = cursor + length;
if (end > data.length) {
throwBounds();
}
System.arraycopy(data, cursor, bytes, offset, length);
cursor = end;
}
/** {@inheritDoc} */
public void read(byte[] bytes) {
int length = bytes.length;
int end = cursor + length;
if (end > data.length) {
throwBounds();
}
System.arraycopy(data, cursor, bytes, 0, length);
cursor = end;
}
/** {@inheritDoc} */
public byte[] readBytes(int length) {
int end = cursor + length;
if (end > data.length) {
throwBounds();
}
byte[] result = new byte[length];
System.arraycopy(data, cursor, result, 0, length);
cursor = end;
return result;
}
/** {@inheritDoc} */
public byte[] readNullTerminatedBytes() {
int startPosition = cursor;
while (data[cursor] != 0) {
cursor++;
if (cursor >= data.length) {
throwBounds();
}
}
int byteCount = cursor - startPosition;
//skip the terminating null
cursor++;
byte[] result = new byte[byteCount];
System.arraycopy(data, startPosition, result, 0, byteCount);
return result;
}
/** {@inheritDoc} */
public void skipBytes(int count) {
int end = cursor + count;
if (end > data.length) {
throwBounds();
}
cursor = end;
}
/** {@inheritDoc} */
public void alignTo(int alignment) {
int end = AlignmentUtils.alignOffset(cursor, alignment);
if (end > data.length) {
throwBounds();
}
cursor = end;
}
/**
* Throws the excpetion for when an attempt is made to read past the
* end of the instance.
*/
private static void throwBounds() {
throw new IndexOutOfBoundsException("attempt to read past the end");
}
/**
* Throws the exception for when an invalid LEB128 value is encountered
*/
private static void throwInvalidLeb() {
throw new RuntimeException("invalid LEB128 integer encountered");
}
}
/*
* [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;
/**
* Implementation of {@link Input} which reads the data from a
* <code>byte[]</code> instance.
*
* <p><b>Note:</b> As per the {@link Input } interface, multi-byte
* reads all use little-endian order.</p>
*/
public class ByteArrayInput
implements Input {
/** non-null; the data itself */
private byte[] data;
/** &gt;= 0; current read cursor */
private int cursor;
/**
* Constructs an instance with the given data
*
* @param data non-null; data array to use for input
*/
public ByteArrayInput(byte[] data) {
if (data == null) {
throw new NullPointerException("data == null");
}
this.data = data;
this.cursor = 0;
}
/**
* Gets the underlying <code>byte[]</code> of this instance
*
* @return non-null; the <code>byte[]</code>
*/
public byte[] getArray() {
return data;
}
/** {@inheritDoc} */
public int getCursor() {
return cursor;
}
/** {@inheritDoc} */
public void setCursor(int cursor) {
if (cursor < 0 || cursor >= data.length)
throw new IndexOutOfBoundsException("The provided cursor value " +
"is not within the bounds of this instance's data array");
this.cursor = cursor;
}
/** {@inheritDoc} */
public void assertCursor(int expectedCursor) {
if (cursor != expectedCursor) {
throw new ExceptionWithContext("expected cursor " +
expectedCursor + "; actual value: " + cursor);
}
}
/** {@inheritDoc} */
public byte readByte() {
int readAt = cursor;
int end = readAt + 1;
if (end > data.length) {
throwBounds();
}
cursor = end;
return data[readAt];
}
/** {@inheritDoc} */
public int readShort() {
int readAt = cursor;
int end = readAt + 2;
if (end > data.length) {
throwBounds();
}
cursor = end;
return (int)((data[readAt] & 0xff) +
((data[readAt + 1] & 0xff) << 8));
}
/** {@inheritDoc} */
public int readInt() {
int readAt = cursor;
int end = readAt + 4;
if (end > data.length) {
throwBounds();
}
cursor = end;
return (data[readAt] & 0xff) +
((data[readAt + 1] & 0xff) << 8) +
((data[readAt + 2] & 0xff) << 16) +
((data[readAt + 3] & 0xff) << 24);
}
/** {@inheritDoc} */
public long readLong() {
int readAt = cursor;
int end = readAt + 8;
if (end > data.length) {
throwBounds();
}
cursor = end;
return (data[readAt] & 0xffL) |
((data[readAt + 1] & 0xffL) << 8) |
((data[readAt + 2] & 0xffL) << 16) |
((data[readAt + 3] & 0xffL) << 24) |
((data[readAt + 4] & 0xffL) << 32) |
((data[readAt + 5] & 0xffL) << 40) |
((data[readAt + 6] & 0xffL) << 48) |
((data[readAt + 7] & 0xffL) << 58);
}
/** {@inheritDoc} */
public int readUnsignedOrSignedLeb128() {
int end = cursor;
int currentByteValue;
int result;
result = data[end++] & 0xff;
if (result > 0x7f) {
currentByteValue = data[end++] & 0xff;
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 14;
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 21;
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
if (currentByteValue > 0x0f) {
throwInvalidLeb();
}
result |= currentByteValue << 28;
}
}
}
} else {
cursor = end;
return result;
}
cursor = end;
//If the last byte is 0, then this was an unsigned value (incorrectly) written in a signed format
//The caller wants to know if this is the case, so we'll return the negated value instead
//If there was only a single byte that had a value of 0, then we would have returned in the above
//"else"
if (data[end-1] == 0) {
return ~result;
}
return result;
}
/** {@inheritDoc} */
public int readUnsignedLeb128() {
int end = cursor;
int currentByteValue;
int result;
result = data[end++] & 0xff;
if (result > 0x7f) {
currentByteValue = data[end++] & 0xff;
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 14;
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 21;
if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff;
if (currentByteValue > 0x0f) {
throwInvalidLeb();
}
result |= currentByteValue << 28;
}
}
}
}
cursor = end;
return result;
}
/** {@inheritDoc} */
public int readSignedLeb128() {
int end = cursor;
int currentByteValue;
int result;
result = data[end++] & 0xff;
if (result <= 0x7f) {
result = (result << 25) >> 25;
} else {
currentByteValue = data[end++] & 0xff;
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
if (currentByteValue <= 0x7f) {
result = (result << 18) >> 18;
} else {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 14;
if (currentByteValue <= 0x7f) {
result = (result << 11) >> 11;
} else {
currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 21;
if (currentByteValue <= 0x7f) {
result = (result << 4) >> 4;
} else {
currentByteValue = data[end++] & 0xff;
if (currentByteValue > 0x0f) {
throwInvalidLeb();
}
result |= currentByteValue << 28;
}
}
}
}
cursor = end;
return result;
}
/** {@inheritDoc} */
public void read(byte[] bytes, int offset, int length) {
int end = cursor + length;
if (end > data.length) {
throwBounds();
}
System.arraycopy(data, cursor, bytes, offset, length);
cursor = end;
}
/** {@inheritDoc} */
public void read(byte[] bytes) {
int length = bytes.length;
int end = cursor + length;
if (end > data.length) {
throwBounds();
}
System.arraycopy(data, cursor, bytes, 0, length);
cursor = end;
}
/** {@inheritDoc} */
public byte[] readBytes(int length) {
int end = cursor + length;
if (end > data.length) {
throwBounds();
}
byte[] result = new byte[length];
System.arraycopy(data, cursor, result, 0, length);
cursor = end;
return result;
}
/** {@inheritDoc} */
public byte[] readNullTerminatedBytes() {
int startPosition = cursor;
while (data[cursor] != 0) {
cursor++;
if (cursor >= data.length) {
throwBounds();
}
}
int byteCount = cursor - startPosition;
//skip the terminating null
cursor++;
byte[] result = new byte[byteCount];
System.arraycopy(data, startPosition, result, 0, byteCount);
return result;
}
/** {@inheritDoc} */
public void skipBytes(int count) {
int end = cursor + count;
if (end > data.length) {
throwBounds();
}
cursor = end;
}
/** {@inheritDoc} */
public void alignTo(int alignment) {
int end = AlignmentUtils.alignOffset(cursor, alignment);
if (end > data.length) {
throwBounds();
}
cursor = end;
}
/**
* Throws the excpetion for when an attempt is made to read past the
* end of the instance.
*/
private static void throwBounds() {
throw new IndexOutOfBoundsException("attempt to read past the end");
}
/**
* Throws the exception for when an invalid LEB128 value is encountered
*/
private static void throwInvalidLeb() {
throw new RuntimeException("invalid LEB128 integer encountered");
}
}

View File

@ -1,451 +1,451 @@
/*
* [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 org.jf.dexlib.*;
import java.util.ArrayList;
import java.util.List;
/**
* This class is intended to provide an easy to use container to build up a method's debug info. You can easily add
* an "event" at a specific address, where an event is something like a line number, start/end local, etc.
* The events must be added such that the code addresses increase monotonically. This matches how a parser would
* generally behave, and is intended to increase performance.
*/
public class DebugInfoBuilder
{
private static final int LINE_BASE = -4;
private static final int LINE_RANGE = 15;
private static final int FIRST_SPECIAL = 0x0a;
private int lineStart = 0;
private ArrayList<String> parameterNames = new ArrayList<String>();
private ArrayList<Event> events = new ArrayList<Event>();
private int lastAddress = 0;
private boolean hasData;
private int currentAddress;
private int currentLine;
public DebugInfoBuilder() {
}
private void checkAddress(int address) {
if (lastAddress > address) {
throw new RuntimeException("Cannot add an event with an address before the address of the prior event");
}
}
public void addParameterName(String parameterName) {
if (parameterName != null) {
hasData = true;
}
parameterNames.add(parameterName);
}
public void addLine(int address, int line) {
hasData = true;
checkAddress(address);
if (lineStart == 0) {
lineStart = line;
}
events.add(new LineEvent(address, line));
}
public void addLocal(int address, int registerNumber, String localName, String localType) {
hasData = true;
checkAddress(address);
events.add(new StartLocalEvent(address, registerNumber, localName, localType));
}
public void addLocalExtended(int address, int registerNumber, String localName, String localType,
String signature) {
hasData = true;
checkAddress(address);
events.add(new StartLocalExtendedEvent(address, registerNumber, localName, localType, signature));
}
public void addEndLocal(int address, int registerNumber) {
hasData = true;
checkAddress(address);
events.add(new EndLocalEvent(address, registerNumber));
}
public void addRestartLocal(int address, int registerNumber) {
hasData = true;
checkAddress(address);
events.add(new RestartLocalEvent(address, registerNumber));
}
public void addPrologue(int address) {
hasData = true;
checkAddress(address);
events.add(new PrologueEvent(address));
}
public void addEpilogue(int address) {
hasData = true;
checkAddress(address);
events.add(new EpilogueEvent(address));
}
public void addSetFile(int address, String fileName) {
hasData = true;
checkAddress(address);
events.add(new SetFileEvent(address, fileName));
}
public int getParameterNameCount() {
return parameterNames.size();
}
public DebugInfoItem encodeDebugInfo(DexFile dexFile) {
if (!hasData) {
return null;
}
ByteArrayOutput out = new ByteArrayOutput();
StringIdItem[] parameterNamesArray = new StringIdItem[parameterNames.size()];
ArrayList<Item> referencedItems = new ArrayList<Item>();
if (lineStart == 0) {
lineStart = 1;
}
currentLine = lineStart;
for (Event event: events) {
event.emit(dexFile, out, referencedItems);
}
emitEndSequence(out);
int index = 0;
for (String parameterName: parameterNames) {
if (parameterName == null) {
parameterNamesArray[index++] = null;
} else {
parameterNamesArray[index++] = StringIdItem.getInternedStringIdItem(dexFile, parameterName);
}
}
Item[] referencedItemsArray = new Item[referencedItems.size()];
referencedItems.toArray(referencedItemsArray);
return DebugInfoItem.getInternedDebugInfoItem(dexFile, lineStart, parameterNamesArray, out.getArray(),
referencedItemsArray);
}
private interface Event
{
int getAddress();
void emit(DexFile dexFile, Output out, List<Item> referencedItems);
}
private void emitEndSequence(Output out) {
out.writeByte(0);
}
private void emitAdvancePC(Output out, int address) {
int addressDelta = address-currentAddress;
if (addressDelta > 0) {
out.writeByte(1);
out.writeUnsignedLeb128(addressDelta);
currentAddress = address;
}
}
private void emitAdvanceLine(Output out, int lineDelta) {
out.writeByte(2);
out.writeSignedLeb128(lineDelta);
}
private void emitStartLocal(Output out, int registerNum) {
out.writeByte(3);
out.writeUnsignedLeb128(registerNum);
out.writeByte(1);
out.writeByte(1);
}
private void emitStartLocalExtended(Output out, int registerNum) {
out.writeByte(4);
out.writeUnsignedLeb128(registerNum);
out.writeByte(1);
out.writeByte(1);
out.writeByte(1);
}
private void emitEndLocal(Output out, int registerNum) {
out.writeByte(5);
out.writeUnsignedLeb128(registerNum);
}
private void emitRestartLocal(Output out, int registerNum) {
out.writeByte(6);
out.writeUnsignedLeb128(registerNum);
}
private void emitSetPrologueEnd(Output out) {
out.writeByte(7);
}
private void emitSetEpilogueBegin(Output out) {
out.writeByte(8);
}
private void emitSetFile(Output out) {
out.writeByte(9);
out.writeByte(1);
}
private void emitSpecialOpcode(Output out, byte opcode) {
out.writeByte(opcode);
}
private class LineEvent implements Event
{
private final int address;
private final int line;
public LineEvent(int address, int line) {
this.address = address;
this.line = line;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
int lineDelta = line - currentLine;
int addressDelta = address - currentAddress;
if (lineDelta < -4 || lineDelta > 10) {
emitAdvanceLine(out, lineDelta);
lineDelta = 0;
}
if (lineDelta < 2 && addressDelta > 16 || lineDelta > 1 && addressDelta > 15) {
emitAdvancePC(out, address);
addressDelta = 0;
}
//TODO: need to handle the case when the line delta is larger than a signed int
emitSpecialOpcode(out, calculateSpecialOpcode(lineDelta, addressDelta));
currentAddress = address;
currentLine = line;
}
private byte calculateSpecialOpcode(int lineDelta, int addressDelta) {
return (byte)(FIRST_SPECIAL + (addressDelta * LINE_RANGE) + (lineDelta - LINE_BASE));
}
}
private class StartLocalEvent implements Event
{
private final int address;
private final int registerNum;
private final String localName;
private final String localType;
public StartLocalEvent(int address, int registerNum, String localName, String localType) {
this.address = address;
this.registerNum = registerNum;
this.localName = localName;
this.localType = localType;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitStartLocal(out, registerNum);
referencedItems.add(localName==null?null:StringIdItem.getInternedStringIdItem(dexFile, localName));
referencedItems.add(localType==null?null:TypeIdItem.getInternedTypeIdItem(dexFile,
StringIdItem.getInternedStringIdItem(dexFile, localType)));
}
}
private class StartLocalExtendedEvent implements Event
{
private final int address;
private final int registerNum;
private final String localName;
private final String localType;
private final String signature;
public StartLocalExtendedEvent(int address, int registerNum, String localName, String localType,
String signature) {
this.address = address;
this.registerNum = registerNum;
this.localName = localName;
this.localType = localType;
this.signature = signature;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitStartLocalExtended(out, registerNum);
if (localName != null) {
referencedItems.add(StringIdItem.getInternedStringIdItem(dexFile, localName));
}
if (localType != null) {
referencedItems.add(TypeIdItem.getInternedTypeIdItem(dexFile,
StringIdItem.getInternedStringIdItem(dexFile, localType)));
}
if (signature != null) {
referencedItems.add(StringIdItem.getInternedStringIdItem(dexFile, signature));
}
}
}
private class EndLocalEvent implements Event
{
private final int address;
private final int registerNum;
public EndLocalEvent(int address, int registerNum) {
this.address = address;
this.registerNum = registerNum;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitEndLocal(out, registerNum);
}
}
private class RestartLocalEvent implements Event
{
private final int address;
private final int registerNum;
public RestartLocalEvent(int address, int registerNum) {
this.address = address;
this.registerNum = registerNum;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitRestartLocal(out, registerNum);
}
}
private class PrologueEvent implements Event
{
private final int address;
public PrologueEvent(int address) {
this.address = address;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitSetPrologueEnd(out);
}
}
private class EpilogueEvent implements Event
{
private final int address;
public EpilogueEvent(int address) {
this.address = address;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitSetEpilogueBegin(out);
}
}
private class SetFileEvent implements Event
{
private final int address;
private final String fileName;
public SetFileEvent(int address, String fileName) {
this.address = address;
this.fileName = fileName;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitSetFile(out);
if (fileName != null) {
referencedItems.add(StringIdItem.getInternedStringIdItem(dexFile, fileName));
}
}
}
}
/*
* [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 org.jf.dexlib.*;
import java.util.ArrayList;
import java.util.List;
/**
* This class is intended to provide an easy to use container to build up a method's debug info. You can easily add
* an "event" at a specific address, where an event is something like a line number, start/end local, etc.
* The events must be added such that the code addresses increase monotonically. This matches how a parser would
* generally behave, and is intended to increase performance.
*/
public class DebugInfoBuilder
{
private static final int LINE_BASE = -4;
private static final int LINE_RANGE = 15;
private static final int FIRST_SPECIAL = 0x0a;
private int lineStart = 0;
private ArrayList<String> parameterNames = new ArrayList<String>();
private ArrayList<Event> events = new ArrayList<Event>();
private int lastAddress = 0;
private boolean hasData;
private int currentAddress;
private int currentLine;
public DebugInfoBuilder() {
}
private void checkAddress(int address) {
if (lastAddress > address) {
throw new RuntimeException("Cannot add an event with an address before the address of the prior event");
}
}
public void addParameterName(String parameterName) {
if (parameterName != null) {
hasData = true;
}
parameterNames.add(parameterName);
}
public void addLine(int address, int line) {
hasData = true;
checkAddress(address);
if (lineStart == 0) {
lineStart = line;
}
events.add(new LineEvent(address, line));
}
public void addLocal(int address, int registerNumber, String localName, String localType) {
hasData = true;
checkAddress(address);
events.add(new StartLocalEvent(address, registerNumber, localName, localType));
}
public void addLocalExtended(int address, int registerNumber, String localName, String localType,
String signature) {
hasData = true;
checkAddress(address);
events.add(new StartLocalExtendedEvent(address, registerNumber, localName, localType, signature));
}
public void addEndLocal(int address, int registerNumber) {
hasData = true;
checkAddress(address);
events.add(new EndLocalEvent(address, registerNumber));
}
public void addRestartLocal(int address, int registerNumber) {
hasData = true;
checkAddress(address);
events.add(new RestartLocalEvent(address, registerNumber));
}
public void addPrologue(int address) {
hasData = true;
checkAddress(address);
events.add(new PrologueEvent(address));
}
public void addEpilogue(int address) {
hasData = true;
checkAddress(address);
events.add(new EpilogueEvent(address));
}
public void addSetFile(int address, String fileName) {
hasData = true;
checkAddress(address);
events.add(new SetFileEvent(address, fileName));
}
public int getParameterNameCount() {
return parameterNames.size();
}
public DebugInfoItem encodeDebugInfo(DexFile dexFile) {
if (!hasData) {
return null;
}
ByteArrayOutput out = new ByteArrayOutput();
StringIdItem[] parameterNamesArray = new StringIdItem[parameterNames.size()];
ArrayList<Item> referencedItems = new ArrayList<Item>();
if (lineStart == 0) {
lineStart = 1;
}
currentLine = lineStart;
for (Event event: events) {
event.emit(dexFile, out, referencedItems);
}
emitEndSequence(out);
int index = 0;
for (String parameterName: parameterNames) {
if (parameterName == null) {
parameterNamesArray[index++] = null;
} else {
parameterNamesArray[index++] = StringIdItem.getInternedStringIdItem(dexFile, parameterName);
}
}
Item[] referencedItemsArray = new Item[referencedItems.size()];
referencedItems.toArray(referencedItemsArray);
return DebugInfoItem.getInternedDebugInfoItem(dexFile, lineStart, parameterNamesArray, out.getArray(),
referencedItemsArray);
}
private interface Event
{
int getAddress();
void emit(DexFile dexFile, Output out, List<Item> referencedItems);
}
private void emitEndSequence(Output out) {
out.writeByte(0);
}
private void emitAdvancePC(Output out, int address) {
int addressDelta = address-currentAddress;
if (addressDelta > 0) {
out.writeByte(1);
out.writeUnsignedLeb128(addressDelta);
currentAddress = address;
}
}
private void emitAdvanceLine(Output out, int lineDelta) {
out.writeByte(2);
out.writeSignedLeb128(lineDelta);
}
private void emitStartLocal(Output out, int registerNum) {
out.writeByte(3);
out.writeUnsignedLeb128(registerNum);
out.writeByte(1);
out.writeByte(1);
}
private void emitStartLocalExtended(Output out, int registerNum) {
out.writeByte(4);
out.writeUnsignedLeb128(registerNum);
out.writeByte(1);
out.writeByte(1);
out.writeByte(1);
}
private void emitEndLocal(Output out, int registerNum) {
out.writeByte(5);
out.writeUnsignedLeb128(registerNum);
}
private void emitRestartLocal(Output out, int registerNum) {
out.writeByte(6);
out.writeUnsignedLeb128(registerNum);
}
private void emitSetPrologueEnd(Output out) {
out.writeByte(7);
}
private void emitSetEpilogueBegin(Output out) {
out.writeByte(8);
}
private void emitSetFile(Output out) {
out.writeByte(9);
out.writeByte(1);
}
private void emitSpecialOpcode(Output out, byte opcode) {
out.writeByte(opcode);
}
private class LineEvent implements Event
{
private final int address;
private final int line;
public LineEvent(int address, int line) {
this.address = address;
this.line = line;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
int lineDelta = line - currentLine;
int addressDelta = address - currentAddress;
if (lineDelta < -4 || lineDelta > 10) {
emitAdvanceLine(out, lineDelta);
lineDelta = 0;
}
if (lineDelta < 2 && addressDelta > 16 || lineDelta > 1 && addressDelta > 15) {
emitAdvancePC(out, address);
addressDelta = 0;
}
//TODO: need to handle the case when the line delta is larger than a signed int
emitSpecialOpcode(out, calculateSpecialOpcode(lineDelta, addressDelta));
currentAddress = address;
currentLine = line;
}
private byte calculateSpecialOpcode(int lineDelta, int addressDelta) {
return (byte)(FIRST_SPECIAL + (addressDelta * LINE_RANGE) + (lineDelta - LINE_BASE));
}
}
private class StartLocalEvent implements Event
{
private final int address;
private final int registerNum;
private final String localName;
private final String localType;
public StartLocalEvent(int address, int registerNum, String localName, String localType) {
this.address = address;
this.registerNum = registerNum;
this.localName = localName;
this.localType = localType;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitStartLocal(out, registerNum);
referencedItems.add(localName==null?null:StringIdItem.getInternedStringIdItem(dexFile, localName));
referencedItems.add(localType==null?null:TypeIdItem.getInternedTypeIdItem(dexFile,
StringIdItem.getInternedStringIdItem(dexFile, localType)));
}
}
private class StartLocalExtendedEvent implements Event
{
private final int address;
private final int registerNum;
private final String localName;
private final String localType;
private final String signature;
public StartLocalExtendedEvent(int address, int registerNum, String localName, String localType,
String signature) {
this.address = address;
this.registerNum = registerNum;
this.localName = localName;
this.localType = localType;
this.signature = signature;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitStartLocalExtended(out, registerNum);
if (localName != null) {
referencedItems.add(StringIdItem.getInternedStringIdItem(dexFile, localName));
}
if (localType != null) {
referencedItems.add(TypeIdItem.getInternedTypeIdItem(dexFile,
StringIdItem.getInternedStringIdItem(dexFile, localType)));
}
if (signature != null) {
referencedItems.add(StringIdItem.getInternedStringIdItem(dexFile, signature));
}
}
}
private class EndLocalEvent implements Event
{
private final int address;
private final int registerNum;
public EndLocalEvent(int address, int registerNum) {
this.address = address;
this.registerNum = registerNum;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitEndLocal(out, registerNum);
}
}
private class RestartLocalEvent implements Event
{
private final int address;
private final int registerNum;
public RestartLocalEvent(int address, int registerNum) {
this.address = address;
this.registerNum = registerNum;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitRestartLocal(out, registerNum);
}
}
private class PrologueEvent implements Event
{
private final int address;
public PrologueEvent(int address) {
this.address = address;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitSetPrologueEnd(out);
}
}
private class EpilogueEvent implements Event
{
private final int address;
public EpilogueEvent(int address) {
this.address = address;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitSetEpilogueBegin(out);
}
}
private class SetFileEvent implements Event
{
private final int address;
private final String fileName;
public SetFileEvent(int address, String fileName) {
this.address = address;
this.fileName = fileName;
}
public int getAddress() {
return address;
}
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address);
emitSetFile(out);
if (fileName != null) {
referencedItems.add(StringIdItem.getInternedStringIdItem(dexFile, fileName));
}
}
}
}

View File

@ -1,143 +1,143 @@
/*
* [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;
public class EncodedValueUtils {
public static byte getRequiredBytesForSignedIntegralValue(long value) {
/*
* Figure out how many bits are needed to represent the value,
* including a sign bit: The bit count is subtracted from 65
* and not 64 to account for the sign bit. The xor operation
* has the effect of leaving non-negative values alone and
* unary complementing negative values (so that a leading zero
* count always returns a useful number for our present
* purpose).
*/
int requiredBits =
65 - Long.numberOfLeadingZeros(value ^ (value >> 63));
// Round up the requiredBits to a number of bytes.
return (byte)((requiredBits + 0x07) >> 3);
}
public static long decodeSignedIntegralValue(byte[] bytes) {
long value = 0;
for (int i = 0; i < bytes.length; i++) {
value |= (((long)(bytes[i] & 0xFF)) << (i * 8));
}
int shift = (8 - bytes.length) * 8;
return value << shift >> shift;
}
public static byte[] encodeSignedIntegralValue(long value) {
int requiredBytes = getRequiredBytesForSignedIntegralValue(value);
byte[] bytes = new byte[requiredBytes];
for (int i = 0; i < requiredBytes; i++) {
bytes[i] = (byte) value;
value >>= 8;
}
return bytes;
}
public static byte getRequiredBytesForUnsignedIntegralValue(long value) {
// Figure out how many bits are needed to represent the value.
int requiredBits = 64 - Long.numberOfLeadingZeros(value);
if (requiredBits == 0) {
requiredBits = 1;
}
// Round up the requiredBits to a number of bytes.
return (byte)((requiredBits + 0x07) >> 3);
}
public static long decodeUnsignedIntegralValue(byte[] bytes) {
long value = 0;
for (int i = 0; i < bytes.length; i++) {
value |= (((long)(bytes[i] & 0xFF)) << i * 8);
}
return value;
}
public static byte[] encodeUnsignedIntegralValue(long value) {
int requiredBytes = getRequiredBytesForUnsignedIntegralValue(value);
byte[] bytes = new byte[requiredBytes];
for (int i = 0; i < requiredBytes; i++) {
bytes[i] = (byte) value;
value >>= 8;
}
return bytes;
}
public static int getRequiredBytesForRightZeroExtendedValue(long value) {
// Figure out how many bits are needed to represent the value.
int requiredBits = 64 - Long.numberOfTrailingZeros(value);
if (requiredBits == 0) {
requiredBits = 1;
}
// Round up the requiredBits to a number of bytes.
return (requiredBits + 0x07) >> 3;
}
public static long decodeRightZeroExtendedValue(byte[] bytes) {
long value = 0;
for (int i = 0; i < bytes.length; i++) {
value |= (((long)(bytes[i] & 0xFF)) << (i * 8));
}
return value << (8 - bytes.length) * 8;
}
public static byte[] encodeRightZeroExtendedValue(long value) {
int requiredBytes = getRequiredBytesForRightZeroExtendedValue(value);
// Scootch the first bits to be written down to the low-order bits.
value >>= 64 - (requiredBytes * 8);
byte[] bytes = new byte[requiredBytes];
for(int i = 0; i < requiredBytes; i++) {
bytes[i] = (byte)value;
value >>= 8;
}
return bytes;
}
}
/*
* [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;
public class EncodedValueUtils {
public static byte getRequiredBytesForSignedIntegralValue(long value) {
/*
* Figure out how many bits are needed to represent the value,
* including a sign bit: The bit count is subtracted from 65
* and not 64 to account for the sign bit. The xor operation
* has the effect of leaving non-negative values alone and
* unary complementing negative values (so that a leading zero
* count always returns a useful number for our present
* purpose).
*/
int requiredBits =
65 - Long.numberOfLeadingZeros(value ^ (value >> 63));
// Round up the requiredBits to a number of bytes.
return (byte)((requiredBits + 0x07) >> 3);
}
public static long decodeSignedIntegralValue(byte[] bytes) {
long value = 0;
for (int i = 0; i < bytes.length; i++) {
value |= (((long)(bytes[i] & 0xFF)) << (i * 8));
}
int shift = (8 - bytes.length) * 8;
return value << shift >> shift;
}
public static byte[] encodeSignedIntegralValue(long value) {
int requiredBytes = getRequiredBytesForSignedIntegralValue(value);
byte[] bytes = new byte[requiredBytes];
for (int i = 0; i < requiredBytes; i++) {
bytes[i] = (byte) value;
value >>= 8;
}
return bytes;
}
public static byte getRequiredBytesForUnsignedIntegralValue(long value) {
// Figure out how many bits are needed to represent the value.
int requiredBits = 64 - Long.numberOfLeadingZeros(value);
if (requiredBits == 0) {
requiredBits = 1;
}
// Round up the requiredBits to a number of bytes.
return (byte)((requiredBits + 0x07) >> 3);
}
public static long decodeUnsignedIntegralValue(byte[] bytes) {
long value = 0;
for (int i = 0; i < bytes.length; i++) {
value |= (((long)(bytes[i] & 0xFF)) << i * 8);
}
return value;
}
public static byte[] encodeUnsignedIntegralValue(long value) {
int requiredBytes = getRequiredBytesForUnsignedIntegralValue(value);
byte[] bytes = new byte[requiredBytes];
for (int i = 0; i < requiredBytes; i++) {
bytes[i] = (byte) value;
value >>= 8;
}
return bytes;
}
public static int getRequiredBytesForRightZeroExtendedValue(long value) {
// Figure out how many bits are needed to represent the value.
int requiredBits = 64 - Long.numberOfTrailingZeros(value);
if (requiredBits == 0) {
requiredBits = 1;
}
// Round up the requiredBits to a number of bytes.
return (requiredBits + 0x07) >> 3;
}
public static long decodeRightZeroExtendedValue(byte[] bytes) {
long value = 0;
for (int i = 0; i < bytes.length; i++) {
value |= (((long)(bytes[i] & 0xFF)) << (i * 8));
}
return value << (8 - bytes.length) * 8;
}
public static byte[] encodeRightZeroExtendedValue(long value) {
int requiredBytes = getRequiredBytesForRightZeroExtendedValue(value);
// Scootch the first bits to be written down to the low-order bits.
value >>= 64 - (requiredBytes * 8);
byte[] bytes = new byte[requiredBytes];
for(int i = 0; i < requiredBytes; i++) {
bytes[i] = (byte)value;
value >>= 8;
}
return bytes;
}
}

View File

@ -1,167 +1,167 @@
/*
* [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;
/**
* Interface for a source for binary input. This is similar to
* <code>java.util.DataInput</code>, but no <code>IOExceptions</code>
* are declared, and multibyte input is defined to be little-endian.
*/
public interface Input {
/**
* Gets the current cursor position. This is the same as the number of
* bytes read from this instance.
*
* @return &gt;= 0; the cursor position
*/
public int getCursor();
/**
* Sets the current cursor position.
*
* @return &gt;= 0; the cursor position
*/
public void setCursor(int cursor);
/**
* Asserts that the cursor is the given value.
*
* @param expectedCursor the expected cursor value
* @throws RuntimeException thrown if <code>getCursor() !=
* expectedCursor</code>
*/
public void assertCursor(int expectedCursor);
/**
* Reads a <code>byte</code> from this instance.
*
* @return the byte value that was read
*/
public byte readByte();
/**
* Reads a <code>short</code> from this instance.
*
* @return the short value that was read, as an int
*/
public int readShort();
/**
* Reads an <code>int</code> from this instance.
*
* @return the unsigned int value that was read
*/
public int readInt();
/**
* Reads a <code>long</code> from this instance.
*
* @return the long value that was read
*/
public long readLong();
/**
* Reads a DWARFv3-style signed LEB128 integer. For details,
* see the "Dalvik Executable Format" document or DWARF v3 section
* 7.6.
*
* @return the integer value that was read
*/
public int readSignedLeb128();
/**
* Reads a DWARFv3-style unsigned LEB128 integer. For details,
* see the "Dalvik Executable Format" document or DWARF v3 section
* 7.6.
*
* @return the integer value that was read
*/
public int readUnsignedLeb128();
/**
* Reads a unsigned value as a DWARFv3-style LEB128 integer. It specifically
* checks for the case when the value was incorrectly formatted as a signed
* LEB128, and returns the appropriate unsigned value, but negated
* @return If the value was formatted as a ULEB128, it returns the actual unsigned
* value. Otherwise, if the value was formatted as a signed LEB128, it negates the
* "correct" unsigned value and returns that
*/
public int readUnsignedOrSignedLeb128();
/**
* reads a <code>byte[]</code> from this instance.
*
* @param bytes non-null; the buffer to read the data into
* @param offset &gt;= 0; offset into <code>bytes</code> for the first
* byte to write
* @param length &gt;= 0; number of bytes to read
*/
public void read(byte[] bytes, int offset, int length);
/**
* reads a <code>byte[]</code> from this instance. This is just
* a convenient shorthand for <code>read(bytes, 0, bytes.length)</code>.
*
* @param bytes non-null; the buffer to read the data into
*/
public void read(byte[] bytes);
/**
* reads a <code>byte[]</code> from this instance
*
* @param length &gt;= 0; number of bytes to read
* @return a byte array containing <code>length</code> bytes
*/
public byte[] readBytes(int length);
/**
* reads a <code>byte[]</code> from this instance, from the current cursor up to but not including
* the next null (0) byte. The terminating null byte is read and discarded, so that after the read,
* the cursor is positioned at the byte immediately after the terminating null
*/
public byte[] readNullTerminatedBytes();
/**
* Skips the given number of bytes.
*
* @param count &gt;= 0; the number of bytes to skip
*/
public void skipBytes(int count);
/**
* Skip extra bytes if necessary to force alignment of the output
* cursor as given.
*
* @param alignment &gt; 0; the alignment; must be a power of two
*/
public void alignTo(int alignment);
}
/*
* [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;
/**
* Interface for a source for binary input. This is similar to
* <code>java.util.DataInput</code>, but no <code>IOExceptions</code>
* are declared, and multibyte input is defined to be little-endian.
*/
public interface Input {
/**
* Gets the current cursor position. This is the same as the number of
* bytes read from this instance.
*
* @return &gt;= 0; the cursor position
*/
public int getCursor();
/**
* Sets the current cursor position.
*
* @return &gt;= 0; the cursor position
*/
public void setCursor(int cursor);
/**
* Asserts that the cursor is the given value.
*
* @param expectedCursor the expected cursor value
* @throws RuntimeException thrown if <code>getCursor() !=
* expectedCursor</code>
*/
public void assertCursor(int expectedCursor);
/**
* Reads a <code>byte</code> from this instance.
*
* @return the byte value that was read
*/
public byte readByte();
/**
* Reads a <code>short</code> from this instance.
*
* @return the short value that was read, as an int
*/
public int readShort();
/**
* Reads an <code>int</code> from this instance.
*
* @return the unsigned int value that was read
*/
public int readInt();
/**
* Reads a <code>long</code> from this instance.
*
* @return the long value that was read
*/
public long readLong();
/**
* Reads a DWARFv3-style signed LEB128 integer. For details,
* see the "Dalvik Executable Format" document or DWARF v3 section
* 7.6.
*
* @return the integer value that was read
*/
public int readSignedLeb128();
/**
* Reads a DWARFv3-style unsigned LEB128 integer. For details,
* see the "Dalvik Executable Format" document or DWARF v3 section
* 7.6.
*
* @return the integer value that was read
*/
public int readUnsignedLeb128();
/**
* Reads a unsigned value as a DWARFv3-style LEB128 integer. It specifically
* checks for the case when the value was incorrectly formatted as a signed
* LEB128, and returns the appropriate unsigned value, but negated
* @return If the value was formatted as a ULEB128, it returns the actual unsigned
* value. Otherwise, if the value was formatted as a signed LEB128, it negates the
* "correct" unsigned value and returns that
*/
public int readUnsignedOrSignedLeb128();
/**
* reads a <code>byte[]</code> from this instance.
*
* @param bytes non-null; the buffer to read the data into
* @param offset &gt;= 0; offset into <code>bytes</code> for the first
* byte to write
* @param length &gt;= 0; number of bytes to read
*/
public void read(byte[] bytes, int offset, int length);
/**
* reads a <code>byte[]</code> from this instance. This is just
* a convenient shorthand for <code>read(bytes, 0, bytes.length)</code>.
*
* @param bytes non-null; the buffer to read the data into
*/
public void read(byte[] bytes);
/**
* reads a <code>byte[]</code> from this instance
*
* @param length &gt;= 0; number of bytes to read
* @return a byte array containing <code>length</code> bytes
*/
public byte[] readBytes(int length);
/**
* reads a <code>byte[]</code> from this instance, from the current cursor up to but not including
* the next null (0) byte. The terminating null byte is read and discarded, so that after the read,
* the cursor is positioned at the byte immediately after the terminating null
*/
public byte[] readNullTerminatedBytes();
/**
* Skips the given number of bytes.
*
* @param count &gt;= 0; the number of bytes to skip
*/
public void skipBytes(int count);
/**
* Skip extra bytes if necessary to force alignment of the output
* cursor as given.
*
* @param alignment &gt; 0; the alignment; must be a power of two
*/
public void alignTo(int alignment);
}

View File

@ -1,40 +1,40 @@
/*
* [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;
public class Pair<A, B> {
public final A first;
public final B second;
public Pair(A first, B second) {
this.first = first;
this.second = second;
}
}
/*
* [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;
public class Pair<A, B> {
public final A first;
public final B second;
public Pair(A first, B second) {
this.first = first;
this.second = second;
}
}

View File

@ -1,347 +1,347 @@
/*
* [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 org.jf.dexlib.CodeItem;
import org.jf.dexlib.TypeIdItem;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
public class TryListBuilder
{
/*TODO: add logic to merge adjacent, identical try blocks, and remove superflous handlers
Also provide a "strict" mode, where the above isn't performed, which will be useful to be able to
exactly reproduce the original .dex file (for testing/verification purposes)*/
private TryRange firstTryRange = new TryRange(0,0);
private TryRange lastTryRange = new TryRange(0,0);
public TryListBuilder() {
firstTryRange.next = lastTryRange;
lastTryRange.previous = firstTryRange;
}
private class TryRange
{
public TryRange previous = null;
public TryRange next = null;
public int startAddress;
public int endAddress;
public LinkedList<Handler> handlers;
public int catchAllHandlerAddress;
public TryRange(int startAddress, int endAddress) {
this.startAddress = startAddress;
this.endAddress = endAddress;
this.handlers = new LinkedList<Handler>();
this.previous = null;
this.next = null;
catchAllHandlerAddress = -1;
}
public void append(TryRange tryRange) {
/*we use a dummy last item, so this.next will always
have a value*/
this.next.previous = tryRange;
tryRange.next = this.next;
this.next = tryRange;
tryRange.previous = this;
}
public void prepend(TryRange tryRange){
/*we use a dummy first item, so this.previous will always
have a value*/
this.previous.next = tryRange;
tryRange.previous = this.previous;
this.previous = tryRange;
tryRange.next = this;
}
/**
* This splits the current range into two ranges at the given
* address. The existing range will be shortened to the first
* half, and a new range will be created and returned for the
* 2nd half.
* @param address The address to split at
* @return The 2nd half of the
*/
public TryRange split(int address) {
//this is a private class, so address is assumed
//to be valid
TryRange tryRange = new TryRange(address, endAddress);
tryRange.catchAllHandlerAddress = this.catchAllHandlerAddress;
tryRange.handlers.addAll(this.handlers);
append(tryRange);
this.endAddress = address;
return tryRange;
}
public void appendHandler(Handler handler) {
handlers.addLast(handler);
}
public void prependHandler(Handler handler) {
handlers.addFirst(handler);
}
}
private class Handler
{
public final TypeIdItem type;
public final int handlerAddress;
public Handler(TypeIdItem type, int handlerAddress) {
this.type = type;
this.handlerAddress = handlerAddress;
}
}
public Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>> encodeTries() {
if (firstTryRange.next == lastTryRange) {
return new Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>>(null, null);
}
ArrayList<CodeItem.TryItem> tries = new ArrayList<CodeItem.TryItem>();
ArrayList<CodeItem.EncodedCatchHandler> handlers = new ArrayList<CodeItem.EncodedCatchHandler>();
HashMap<CodeItem.EncodedCatchHandler, CodeItem.EncodedCatchHandler> handlerDict =
new HashMap<CodeItem.EncodedCatchHandler, CodeItem.EncodedCatchHandler>();
TryRange tryRange = firstTryRange.next;
while (tryRange != lastTryRange) {
CodeItem.EncodedTypeAddrPair[] encodedTypeAddrPairs =
new CodeItem.EncodedTypeAddrPair[tryRange.handlers.size()];
int index = 0;
for (Handler handler: tryRange.handlers) {
CodeItem.EncodedTypeAddrPair encodedTypeAddrPair = new CodeItem.EncodedTypeAddrPair(
handler.type,
handler.handlerAddress);
encodedTypeAddrPairs[index++] = encodedTypeAddrPair;
}
CodeItem.EncodedCatchHandler encodedCatchHandler = new CodeItem.EncodedCatchHandler(
encodedTypeAddrPairs,
tryRange.catchAllHandlerAddress);
CodeItem.EncodedCatchHandler internedEncodedCatchHandler = handlerDict.get(encodedCatchHandler);
if (internedEncodedCatchHandler == null) {
handlerDict.put(encodedCatchHandler, encodedCatchHandler);
handlers.add(encodedCatchHandler);
} else {
encodedCatchHandler = internedEncodedCatchHandler;
}
CodeItem.TryItem tryItem = new CodeItem.TryItem(
tryRange.startAddress,
tryRange.endAddress - tryRange.startAddress,
encodedCatchHandler);
tries.add(tryItem);
tryRange = tryRange.next;
}
return new Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>>(tries, handlers);
}
public void addCatchAllHandler(int startAddress, int endAddress, int handlerAddress) {
TryRange startRange;
TryRange endRange;
Pair<TryRange, TryRange> ranges = getBoundingRanges(startAddress, endAddress);
startRange = ranges.first;
endRange = ranges.second;
int previousEnd = startAddress;
TryRange tryRange = startRange;
/*Now we have the start and end ranges that exactly match the start and end
of the range being added. We need to iterate over all the ranges from the start
to end range inclusively, and append the handler to the end of each range's handler
list. We also need to create a new range for any "holes" in the existing ranges*/
do
{
//is there a hole? If so, add a new range to fill the hole
if (tryRange.startAddress > previousEnd) {
TryRange newRange = new TryRange(previousEnd, tryRange.startAddress);
tryRange.prepend(newRange);
tryRange = newRange;
}
if (tryRange.catchAllHandlerAddress == -1) {
tryRange.catchAllHandlerAddress = handlerAddress;
}
previousEnd = tryRange.endAddress;
tryRange = tryRange.next;
} while (tryRange.previous != endRange);
}
public Pair<TryRange, TryRange> getBoundingRanges(int startAddress, int endAddress) {
TryRange startRange = null;
TryRange endRange = null;
TryRange tryRange = firstTryRange.next;
while (tryRange != lastTryRange) {
if (startAddress == tryRange.startAddress) {
//|-----|
//^------
/*Bam. We hit the start of the range right on the head*/
startRange = tryRange;
break;
} else if (startAddress > tryRange.startAddress && startAddress < tryRange.endAddress) {
//|-----|
// ^----
/*Almost. The start of the range being added is in the middle
of an existing try range. We need to split the existing range
at the start address of the range being added*/
startRange = tryRange.split(startAddress);
break;
}else if (startAddress < tryRange.startAddress) {
if (endAddress <= tryRange.startAddress) {
// |-----|
//^--^
/*Oops, totally too far! The new range doesn't overlap any existing
ones, so we just add it and return*/
startRange = new TryRange(startAddress, endAddress);
tryRange.prepend(startRange);
return new Pair<TryRange, TryRange>(startRange, startRange);
} else {
// |-----|
//^---------
/*Oops, too far! We've passed the start of the range being added, but
the new range does overlap this one. We need to add a new range just
before this one*/
startRange = new TryRange(startAddress, tryRange.startAddress);
tryRange.prepend(startRange);
break;
}
}
tryRange = tryRange.next;
}
//|-----|
// ^-----
/*Either the list of tries is blank, or all the tries in the list
end before the range being added starts. In either case, we just need
to add a new range at the end of the list*/
if (startRange == null) {
startRange = new TryRange(startAddress, endAddress);
lastTryRange.prepend(startRange);
return new Pair<TryRange, TryRange>(startRange, startRange);
}
tryRange = startRange;
while (tryRange != lastTryRange) {
if (tryRange.endAddress == endAddress) {
//|-----|
//------^
/*Bam! We hit the end right on the head.*/
endRange = tryRange;
break;
} else if (tryRange.startAddress < endAddress && tryRange.endAddress > endAddress) {
//|-----|
//--^
/*Almost. The range being added ends in the middle of an
existing range. We need to split the existing range
at the end of the range being added.*/
tryRange.split(endAddress);
endRange = tryRange;
break;
} else if (tryRange.startAddress >= endAddress) {
//|-----| |-----|
//-----------^
/*Oops, too far! The current range starts after the range being added
ends. We need to create a new range that starts at the end of the
previous range, and ends at the end of the range being added*/
endRange = new TryRange(tryRange.previous.endAddress, endAddress);
tryRange.prepend(endRange);
break;
}
tryRange = tryRange.next;
}
//|-----|
//--------^
/*The last range in the list ended before the end of the range being added.
We need to add a new range that starts at the end of the last range in the
list, and ends at the end of the range being added.*/
if (endRange == null) {
endRange = new TryRange(lastTryRange.previous.endAddress, endAddress);
lastTryRange.prepend(endRange);
}
return new Pair<TryRange, TryRange>(startRange, endRange);
}
public void addHandler(TypeIdItem type, int startAddress, int endAddress, int handlerAddress) {
TryRange startRange;
TryRange endRange;
//TODO: need to check for pre-existing exception types in the handler list?
Pair<TryRange, TryRange> ranges = getBoundingRanges(startAddress, endAddress);
startRange = ranges.first;
endRange = ranges.second;
Handler handler = new Handler(type, handlerAddress);
int previousEnd = startAddress;
TryRange tryRange = startRange;
/*Now we have the start and end ranges that exactly match the start and end
of the range being added. We need to iterate over all the ranges from the start
to end range inclusively, and append the handler to the end of each range's handler
list. We also need to create a new range for any "holes" in the existing ranges*/
do
{
//is there a hole? If so, add a new range to fill the hole
if (tryRange.startAddress > previousEnd) {
TryRange newRange = new TryRange(previousEnd, tryRange.startAddress);
tryRange.prepend(newRange);
tryRange = newRange;
}
tryRange.appendHandler(handler);
previousEnd = tryRange.endAddress;
tryRange = tryRange.next;
} while (tryRange.previous != endRange);
}
}
/*
* [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 org.jf.dexlib.CodeItem;
import org.jf.dexlib.TypeIdItem;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
public class TryListBuilder
{
/*TODO: add logic to merge adjacent, identical try blocks, and remove superflous handlers
Also provide a "strict" mode, where the above isn't performed, which will be useful to be able to
exactly reproduce the original .dex file (for testing/verification purposes)*/
private TryRange firstTryRange = new TryRange(0,0);
private TryRange lastTryRange = new TryRange(0,0);
public TryListBuilder() {
firstTryRange.next = lastTryRange;
lastTryRange.previous = firstTryRange;
}
private class TryRange
{
public TryRange previous = null;
public TryRange next = null;
public int startAddress;
public int endAddress;
public LinkedList<Handler> handlers;
public int catchAllHandlerAddress;
public TryRange(int startAddress, int endAddress) {
this.startAddress = startAddress;
this.endAddress = endAddress;
this.handlers = new LinkedList<Handler>();
this.previous = null;
this.next = null;
catchAllHandlerAddress = -1;
}
public void append(TryRange tryRange) {
/*we use a dummy last item, so this.next will always
have a value*/
this.next.previous = tryRange;
tryRange.next = this.next;
this.next = tryRange;
tryRange.previous = this;
}
public void prepend(TryRange tryRange){
/*we use a dummy first item, so this.previous will always
have a value*/
this.previous.next = tryRange;
tryRange.previous = this.previous;
this.previous = tryRange;
tryRange.next = this;
}
/**
* This splits the current range into two ranges at the given
* address. The existing range will be shortened to the first
* half, and a new range will be created and returned for the
* 2nd half.
* @param address The address to split at
* @return The 2nd half of the
*/
public TryRange split(int address) {
//this is a private class, so address is assumed
//to be valid
TryRange tryRange = new TryRange(address, endAddress);
tryRange.catchAllHandlerAddress = this.catchAllHandlerAddress;
tryRange.handlers.addAll(this.handlers);
append(tryRange);
this.endAddress = address;
return tryRange;
}
public void appendHandler(Handler handler) {
handlers.addLast(handler);
}
public void prependHandler(Handler handler) {
handlers.addFirst(handler);
}
}
private class Handler
{
public final TypeIdItem type;
public final int handlerAddress;
public Handler(TypeIdItem type, int handlerAddress) {
this.type = type;
this.handlerAddress = handlerAddress;
}
}
public Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>> encodeTries() {
if (firstTryRange.next == lastTryRange) {
return new Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>>(null, null);
}
ArrayList<CodeItem.TryItem> tries = new ArrayList<CodeItem.TryItem>();
ArrayList<CodeItem.EncodedCatchHandler> handlers = new ArrayList<CodeItem.EncodedCatchHandler>();
HashMap<CodeItem.EncodedCatchHandler, CodeItem.EncodedCatchHandler> handlerDict =
new HashMap<CodeItem.EncodedCatchHandler, CodeItem.EncodedCatchHandler>();
TryRange tryRange = firstTryRange.next;
while (tryRange != lastTryRange) {
CodeItem.EncodedTypeAddrPair[] encodedTypeAddrPairs =
new CodeItem.EncodedTypeAddrPair[tryRange.handlers.size()];
int index = 0;
for (Handler handler: tryRange.handlers) {
CodeItem.EncodedTypeAddrPair encodedTypeAddrPair = new CodeItem.EncodedTypeAddrPair(
handler.type,
handler.handlerAddress);
encodedTypeAddrPairs[index++] = encodedTypeAddrPair;
}
CodeItem.EncodedCatchHandler encodedCatchHandler = new CodeItem.EncodedCatchHandler(
encodedTypeAddrPairs,
tryRange.catchAllHandlerAddress);
CodeItem.EncodedCatchHandler internedEncodedCatchHandler = handlerDict.get(encodedCatchHandler);
if (internedEncodedCatchHandler == null) {
handlerDict.put(encodedCatchHandler, encodedCatchHandler);
handlers.add(encodedCatchHandler);
} else {
encodedCatchHandler = internedEncodedCatchHandler;
}
CodeItem.TryItem tryItem = new CodeItem.TryItem(
tryRange.startAddress,
tryRange.endAddress - tryRange.startAddress,
encodedCatchHandler);
tries.add(tryItem);
tryRange = tryRange.next;
}
return new Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>>(tries, handlers);
}
public void addCatchAllHandler(int startAddress, int endAddress, int handlerAddress) {
TryRange startRange;
TryRange endRange;
Pair<TryRange, TryRange> ranges = getBoundingRanges(startAddress, endAddress);
startRange = ranges.first;
endRange = ranges.second;
int previousEnd = startAddress;
TryRange tryRange = startRange;
/*Now we have the start and end ranges that exactly match the start and end
of the range being added. We need to iterate over all the ranges from the start
to end range inclusively, and append the handler to the end of each range's handler
list. We also need to create a new range for any "holes" in the existing ranges*/
do
{
//is there a hole? If so, add a new range to fill the hole
if (tryRange.startAddress > previousEnd) {
TryRange newRange = new TryRange(previousEnd, tryRange.startAddress);
tryRange.prepend(newRange);
tryRange = newRange;
}
if (tryRange.catchAllHandlerAddress == -1) {
tryRange.catchAllHandlerAddress = handlerAddress;
}
previousEnd = tryRange.endAddress;
tryRange = tryRange.next;
} while (tryRange.previous != endRange);
}
public Pair<TryRange, TryRange> getBoundingRanges(int startAddress, int endAddress) {
TryRange startRange = null;
TryRange endRange = null;
TryRange tryRange = firstTryRange.next;
while (tryRange != lastTryRange) {
if (startAddress == tryRange.startAddress) {
//|-----|
//^------
/*Bam. We hit the start of the range right on the head*/
startRange = tryRange;
break;
} else if (startAddress > tryRange.startAddress && startAddress < tryRange.endAddress) {
//|-----|
// ^----
/*Almost. The start of the range being added is in the middle
of an existing try range. We need to split the existing range
at the start address of the range being added*/
startRange = tryRange.split(startAddress);
break;
}else if (startAddress < tryRange.startAddress) {
if (endAddress <= tryRange.startAddress) {
// |-----|
//^--^
/*Oops, totally too far! The new range doesn't overlap any existing
ones, so we just add it and return*/
startRange = new TryRange(startAddress, endAddress);
tryRange.prepend(startRange);
return new Pair<TryRange, TryRange>(startRange, startRange);
} else {
// |-----|
//^---------
/*Oops, too far! We've passed the start of the range being added, but
the new range does overlap this one. We need to add a new range just
before this one*/
startRange = new TryRange(startAddress, tryRange.startAddress);
tryRange.prepend(startRange);
break;
}
}
tryRange = tryRange.next;
}
//|-----|
// ^-----
/*Either the list of tries is blank, or all the tries in the list
end before the range being added starts. In either case, we just need
to add a new range at the end of the list*/
if (startRange == null) {
startRange = new TryRange(startAddress, endAddress);
lastTryRange.prepend(startRange);
return new Pair<TryRange, TryRange>(startRange, startRange);
}
tryRange = startRange;
while (tryRange != lastTryRange) {
if (tryRange.endAddress == endAddress) {
//|-----|
//------^
/*Bam! We hit the end right on the head.*/
endRange = tryRange;
break;
} else if (tryRange.startAddress < endAddress && tryRange.endAddress > endAddress) {
//|-----|
//--^
/*Almost. The range being added ends in the middle of an
existing range. We need to split the existing range
at the end of the range being added.*/
tryRange.split(endAddress);
endRange = tryRange;
break;
} else if (tryRange.startAddress >= endAddress) {
//|-----| |-----|
//-----------^
/*Oops, too far! The current range starts after the range being added
ends. We need to create a new range that starts at the end of the
previous range, and ends at the end of the range being added*/
endRange = new TryRange(tryRange.previous.endAddress, endAddress);
tryRange.prepend(endRange);
break;
}
tryRange = tryRange.next;
}
//|-----|
//--------^
/*The last range in the list ended before the end of the range being added.
We need to add a new range that starts at the end of the last range in the
list, and ends at the end of the range being added.*/
if (endRange == null) {
endRange = new TryRange(lastTryRange.previous.endAddress, endAddress);
lastTryRange.prepend(endRange);
}
return new Pair<TryRange, TryRange>(startRange, endRange);
}
public void addHandler(TypeIdItem type, int startAddress, int endAddress, int handlerAddress) {
TryRange startRange;
TryRange endRange;
//TODO: need to check for pre-existing exception types in the handler list?
Pair<TryRange, TryRange> ranges = getBoundingRanges(startAddress, endAddress);
startRange = ranges.first;
endRange = ranges.second;
Handler handler = new Handler(type, handlerAddress);
int previousEnd = startAddress;
TryRange tryRange = startRange;
/*Now we have the start and end ranges that exactly match the start and end
of the range being added. We need to iterate over all the ranges from the start
to end range inclusively, and append the handler to the end of each range's handler
list. We also need to create a new range for any "holes" in the existing ranges*/
do
{
//is there a hole? If so, add a new range to fill the hole
if (tryRange.startAddress > previousEnd) {
TryRange newRange = new TryRange(previousEnd, tryRange.startAddress);
tryRange.prepend(newRange);
tryRange = newRange;
}
tryRange.appendHandler(handler);
previousEnd = tryRange.endAddress;
tryRange = tryRange.next;
} while (tryRange.previous != endRange);
}
}

View File

@ -1,61 +1,61 @@
/*
* [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 org.jf.dexlib.DexFile;
import org.jf.dexlib.EncodedValue.*;
public class TypeUtils
{
public static EncodedValue makeDefaultValueForType(DexFile dexFile, String type) {
EncodedValue subField;
switch (type.charAt(0)) {
case 'Z':
return BooleanEncodedValue.FalseValue;
case 'B':
return new ByteEncodedValue((byte)0);
case 'S':
return new ShortEncodedValue((short)0);
case 'C':
return new CharEncodedValue((char)0);
case 'I':
return new IntEncodedValue(0);
case 'J':
return new LongEncodedValue(0);
case 'F':
return new FloatEncodedValue(0);
case 'D':
return new DoubleEncodedValue(0);
case 'L':
case '[':
return NullEncodedValue.NullValue;
}
return null;
}
}
/*
* [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 org.jf.dexlib.DexFile;
import org.jf.dexlib.EncodedValue.*;
public class TypeUtils
{
public static EncodedValue makeDefaultValueForType(DexFile dexFile, String type) {
EncodedValue subField;
switch (type.charAt(0)) {
case 'Z':
return BooleanEncodedValue.FalseValue;
case 'B':
return new ByteEncodedValue((byte)0);
case 'S':
return new ShortEncodedValue((short)0);
case 'C':
return new CharEncodedValue((char)0);
case 'I':
return new IntEncodedValue(0);
case 'J':
return new LongEncodedValue(0);
case 'F':
return new FloatEncodedValue(0);
case 'D':
return new DoubleEncodedValue(0);
case 'L':
case '[':
return NullEncodedValue.NullValue;
}
return null;
}
}

View File

@ -1,378 +1,378 @@
/*
* [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.smali;
public class literalTools
{
public static byte parseByte(String byteLiteral)
throws NumberFormatException {
if (byteLiteral == null) {
throw new NumberFormatException("string is null");
}
if (byteLiteral.length() == 0) {
throw new NumberFormatException("string is blank");
}
char[] byteChars;
if (byteLiteral.toUpperCase().endsWith("T")) {
byteChars = byteLiteral.substring(0, byteLiteral.length()-1).toCharArray();
} else {
byteChars = byteLiteral.toCharArray();
}
int position = 0;
int radix = 10;
boolean negative = false;
if (byteChars[position] == '-') {
position++;
negative = true;
}
if (byteChars[position] == '0') {
position++;
if (position == byteChars.length) {
return 0;
} else if (byteChars[position] == 'x' || byteChars[position] == 'X') {
radix = 16;
position++;
} else if (Character.digit(byteChars[position], 8) >= 0) {
radix = 8;
}
}
byte result = 0;
byte shiftedResult;
int digit;
byte maxValue = (byte)(Byte.MAX_VALUE / (radix / 2));
while (position < byteChars.length) {
digit = Character.digit(byteChars[position], radix);
if (digit < 0) {
throw new NumberFormatException("The string contains invalid an digit - '" + byteChars[position] + "'");
}
shiftedResult = (byte)(result * radix);
if (result > maxValue) {
throw new NumberFormatException(byteLiteral + " cannot fit into a byte");
}
if (shiftedResult < 0 && shiftedResult >= -digit) {
throw new NumberFormatException(byteLiteral + " cannot fit into a byte");
}
result = (byte)(shiftedResult + digit);
position++;
}
if (negative) {
//allow -0x80, which is = 0x80
if (result == Byte.MIN_VALUE) {
return result;
} else if (result < 0) {
throw new NumberFormatException(byteLiteral + " cannot fit into a byte");
}
return (byte)(result * -1);
} else {
return result;
}
}
public static short parseShort(String shortLiteral)
throws NumberFormatException {
if (shortLiteral == null) {
throw new NumberFormatException("string is null");
}
if (shortLiteral.length() == 0) {
throw new NumberFormatException("string is blank");
}
char[] shortChars;
if (shortLiteral.toUpperCase().endsWith("S")) {
shortChars = shortLiteral.substring(0, shortLiteral.length()-1).toCharArray();
} else {
shortChars = shortLiteral.toCharArray();
}
int position = 0;
int radix = 10;
boolean negative = false;
if (shortChars[position] == '-') {
position++;
negative = true;
}
if (shortChars[position] == '0') {
position++;
if (position == shortChars.length) {
return 0;
} else if (shortChars[position] == 'x' || shortChars[position] == 'X') {
radix = 16;
position++;
} else if (Character.digit(shortChars[position], 8) >= 0) {
radix = 8;
}
}
short result = 0;
short shiftedResult;
int digit;
short maxValue = (short)(Short.MAX_VALUE / (radix / 2));
while (position < shortChars.length) {
digit = Character.digit(shortChars[position], radix);
if (digit < 0) {
throw new NumberFormatException("The string contains invalid an digit - '" + shortChars[position] + "'");
}
shiftedResult = (short)(result * radix);
if (result > maxValue) {
throw new NumberFormatException(shortLiteral + " cannot fit into a short");
}
if (shiftedResult < 0 && shiftedResult >= -digit) {
throw new NumberFormatException(shortLiteral + " cannot fit into a short");
}
result = (short)(shiftedResult + digit);
position++;
}
if (negative) {
//allow -0x8000, which is = 0x8000
if (result == Short.MIN_VALUE) {
return result;
} else if (result < 0) {
throw new NumberFormatException(shortLiteral + " cannot fit into a short");
}
return (short)(result * -1);
} else {
return result;
}
}
public static int parseInt(String intLiteral)
throws NumberFormatException {
if (intLiteral == null) {
throw new NumberFormatException("string is null");
}
if (intLiteral.length() == 0) {
throw new NumberFormatException("string is blank");
}
char[] intChars = intLiteral.toCharArray();
int position = 0;
int radix = 10;
boolean negative = false;
if (intChars[position] == '-') {
position++;
negative = true;
}
if (intChars[position] == '0') {
position++;
if (position == intChars.length) {
return 0;
} else if (intChars[position] == 'x' || intChars[position] == 'X') {
radix = 16;
position++;
} else if (Character.digit(intChars[position], 8) >= 0) {
radix = 8;
}
}
int result = 0;
int shiftedResult;
int digit;
int maxValue = Integer.MAX_VALUE / (radix / 2);
while (position < intChars.length) {
digit = Character.digit(intChars[position], radix);
if (digit < 0) {
throw new NumberFormatException("The string contains an invalid digit - '" + intChars[position] + "'");
}
shiftedResult = result * radix;
if (result > maxValue) {
throw new NumberFormatException(intLiteral + " cannot fit into an int");
}
if (shiftedResult < 0 && shiftedResult >= -digit) {
throw new NumberFormatException(intLiteral + " cannot fit into an int");
}
result = shiftedResult + digit;
position++;
}
if (negative) {
//allow -0x80000000, which is = 0x80000000
if (result == Integer.MIN_VALUE) {
return result;
} else if (result < 0) {
throw new NumberFormatException(intLiteral + " cannot fit into an int");
}
return result * -1;
} else {
return result;
}
}
public static long parseLong(String longLiteral)
throws NumberFormatException {
if (longLiteral == null) {
throw new NumberFormatException("string is null");
}
if (longLiteral.length() == 0) {
throw new NumberFormatException("string is blank");
}
char[] longChars;
if (longLiteral.toUpperCase().endsWith("L")) {
longChars = longLiteral.substring(0, longLiteral.length()-1).toCharArray();
} else {
longChars = longLiteral.toCharArray();
}
int position = 0;
int radix = 10;
boolean negative = false;
if (longChars[position] == '-') {
position++;
negative = true;
}
if (longChars[position] == '0') {
position++;
if (position == longChars.length) {
return 0;
} else if (longChars[position] == 'x' || longChars[position] == 'X') {
radix = 16;
position++;
} else if (Character.digit(longChars[position], 8) >= 0) {
radix = 8;
}
}
long result = 0;
long shiftedResult;
int digit;
long maxValue = Long.MAX_VALUE / (radix / 2);
while (position < longChars.length) {
digit = Character.digit(longChars[position], radix);
if (digit < 0) {
throw new NumberFormatException("The string contains an invalid digit - '" + longChars[position] + "'");
}
shiftedResult = result * radix;
if (result > maxValue) {
throw new NumberFormatException(longLiteral + " cannot fit into a long");
}
if (shiftedResult < 0 && shiftedResult >= -digit) {
throw new NumberFormatException(longLiteral + " cannot fit into a long");
}
result = shiftedResult + digit;
position++;
}
if (negative) {
//allow -0x8000000000000000, which is = 0x8000000000000000
if (result == Long.MIN_VALUE) {
return result;
} else if (result < 0) {
throw new NumberFormatException(longLiteral + " cannot fit into a long");
}
return result * -1;
} else {
return result;
}
}
public static byte[] longToBytes(long value) {
byte[] bytes = new byte[8];
for (int i=0; value != 0; i++) {
bytes[i] = (byte)value;
value = value >>> 8;
}
return bytes;
}
public static byte[] intToBytes(int value) {
byte[] bytes = new byte[4];
for (int i=0; value != 0; i++) {
bytes[i] = (byte)value;
value = value >>> 8;
}
return bytes;
}
public static byte[] shortToBytes(short value) {
byte[] bytes = new byte[2];
bytes[0] = (byte)value;
bytes[1] = (byte)(value >>> 8);
return bytes;
}
public static byte[] floatToBytes(float value) {
return intToBytes(Float.floatToRawIntBits(value));
}
public static byte[] doubleToBytes(double value) {
return longToBytes(Double.doubleToRawLongBits(value));
}
public static byte[] charToBytes(char value) {
return shortToBytes((short)value);
}
public static byte[] boolToBytes(boolean value) {
if (value) {
return new byte[] { 0x01 };
} else {
return new byte[] { 0x00 };
}
}
public static void checkInt(long value) {
if (value > 0xFFFFFFFF || value < -0x80000000) {
throw new NumberFormatException(Long.toString(value) + " cannot fit into an int");
}
}
public static void checkShort(long value) {
if (value > 0xFFFF | value < -0x8000) {
throw new NumberFormatException(Long.toString(value) + " cannot fit into a short");
}
}
public static void checkByte(long value) {
if (value > 0xFF | value < -0x80) {
throw new NumberFormatException(Long.toString(value) + " cannot fit into a byte");
}
}
public static void checkNibble(long value) {
if (value > 0x0F | value < -0x08) {
throw new NumberFormatException(Long.toString(value) + " cannot fit into a nibble");
}
}
}
/*
* [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.smali;
public class literalTools
{
public static byte parseByte(String byteLiteral)
throws NumberFormatException {
if (byteLiteral == null) {
throw new NumberFormatException("string is null");
}
if (byteLiteral.length() == 0) {
throw new NumberFormatException("string is blank");
}
char[] byteChars;
if (byteLiteral.toUpperCase().endsWith("T")) {
byteChars = byteLiteral.substring(0, byteLiteral.length()-1).toCharArray();
} else {
byteChars = byteLiteral.toCharArray();
}
int position = 0;
int radix = 10;
boolean negative = false;
if (byteChars[position] == '-') {
position++;
negative = true;
}
if (byteChars[position] == '0') {
position++;
if (position == byteChars.length) {
return 0;
} else if (byteChars[position] == 'x' || byteChars[position] == 'X') {
radix = 16;
position++;
} else if (Character.digit(byteChars[position], 8) >= 0) {
radix = 8;
}
}
byte result = 0;
byte shiftedResult;
int digit;
byte maxValue = (byte)(Byte.MAX_VALUE / (radix / 2));
while (position < byteChars.length) {
digit = Character.digit(byteChars[position], radix);
if (digit < 0) {
throw new NumberFormatException("The string contains invalid an digit - '" + byteChars[position] + "'");
}
shiftedResult = (byte)(result * radix);
if (result > maxValue) {
throw new NumberFormatException(byteLiteral + " cannot fit into a byte");
}
if (shiftedResult < 0 && shiftedResult >= -digit) {
throw new NumberFormatException(byteLiteral + " cannot fit into a byte");
}
result = (byte)(shiftedResult + digit);
position++;
}
if (negative) {
//allow -0x80, which is = 0x80
if (result == Byte.MIN_VALUE) {
return result;
} else if (result < 0) {
throw new NumberFormatException(byteLiteral + " cannot fit into a byte");
}
return (byte)(result * -1);
} else {
return result;
}
}
public static short parseShort(String shortLiteral)
throws NumberFormatException {
if (shortLiteral == null) {
throw new NumberFormatException("string is null");
}
if (shortLiteral.length() == 0) {
throw new NumberFormatException("string is blank");
}
char[] shortChars;
if (shortLiteral.toUpperCase().endsWith("S")) {
shortChars = shortLiteral.substring(0, shortLiteral.length()-1).toCharArray();
} else {
shortChars = shortLiteral.toCharArray();
}
int position = 0;
int radix = 10;
boolean negative = false;
if (shortChars[position] == '-') {
position++;
negative = true;
}
if (shortChars[position] == '0') {
position++;
if (position == shortChars.length) {
return 0;
} else if (shortChars[position] == 'x' || shortChars[position] == 'X') {
radix = 16;
position++;
} else if (Character.digit(shortChars[position], 8) >= 0) {
radix = 8;
}
}
short result = 0;
short shiftedResult;
int digit;
short maxValue = (short)(Short.MAX_VALUE / (radix / 2));
while (position < shortChars.length) {
digit = Character.digit(shortChars[position], radix);
if (digit < 0) {
throw new NumberFormatException("The string contains invalid an digit - '" + shortChars[position] + "'");
}
shiftedResult = (short)(result * radix);
if (result > maxValue) {
throw new NumberFormatException(shortLiteral + " cannot fit into a short");
}
if (shiftedResult < 0 && shiftedResult >= -digit) {
throw new NumberFormatException(shortLiteral + " cannot fit into a short");
}
result = (short)(shiftedResult + digit);
position++;
}
if (negative) {
//allow -0x8000, which is = 0x8000
if (result == Short.MIN_VALUE) {
return result;
} else if (result < 0) {
throw new NumberFormatException(shortLiteral + " cannot fit into a short");
}
return (short)(result * -1);
} else {
return result;
}
}
public static int parseInt(String intLiteral)
throws NumberFormatException {
if (intLiteral == null) {
throw new NumberFormatException("string is null");
}
if (intLiteral.length() == 0) {
throw new NumberFormatException("string is blank");
}
char[] intChars = intLiteral.toCharArray();
int position = 0;
int radix = 10;
boolean negative = false;
if (intChars[position] == '-') {
position++;
negative = true;
}
if (intChars[position] == '0') {
position++;
if (position == intChars.length) {
return 0;
} else if (intChars[position] == 'x' || intChars[position] == 'X') {
radix = 16;
position++;
} else if (Character.digit(intChars[position], 8) >= 0) {
radix = 8;
}
}
int result = 0;
int shiftedResult;
int digit;
int maxValue = Integer.MAX_VALUE / (radix / 2);
while (position < intChars.length) {
digit = Character.digit(intChars[position], radix);
if (digit < 0) {
throw new NumberFormatException("The string contains an invalid digit - '" + intChars[position] + "'");
}
shiftedResult = result * radix;
if (result > maxValue) {
throw new NumberFormatException(intLiteral + " cannot fit into an int");
}
if (shiftedResult < 0 && shiftedResult >= -digit) {
throw new NumberFormatException(intLiteral + " cannot fit into an int");
}
result = shiftedResult + digit;
position++;
}
if (negative) {
//allow -0x80000000, which is = 0x80000000
if (result == Integer.MIN_VALUE) {
return result;
} else if (result < 0) {
throw new NumberFormatException(intLiteral + " cannot fit into an int");
}
return result * -1;
} else {
return result;
}
}
public static long parseLong(String longLiteral)
throws NumberFormatException {
if (longLiteral == null) {
throw new NumberFormatException("string is null");
}
if (longLiteral.length() == 0) {
throw new NumberFormatException("string is blank");
}
char[] longChars;
if (longLiteral.toUpperCase().endsWith("L")) {
longChars = longLiteral.substring(0, longLiteral.length()-1).toCharArray();
} else {
longChars = longLiteral.toCharArray();
}
int position = 0;
int radix = 10;
boolean negative = false;
if (longChars[position] == '-') {
position++;
negative = true;
}
if (longChars[position] == '0') {
position++;
if (position == longChars.length) {
return 0;
} else if (longChars[position] == 'x' || longChars[position] == 'X') {
radix = 16;
position++;
} else if (Character.digit(longChars[position], 8) >= 0) {
radix = 8;
}
}
long result = 0;
long shiftedResult;
int digit;
long maxValue = Long.MAX_VALUE / (radix / 2);
while (position < longChars.length) {
digit = Character.digit(longChars[position], radix);
if (digit < 0) {
throw new NumberFormatException("The string contains an invalid digit - '" + longChars[position] + "'");
}
shiftedResult = result * radix;
if (result > maxValue) {
throw new NumberFormatException(longLiteral + " cannot fit into a long");
}
if (shiftedResult < 0 && shiftedResult >= -digit) {
throw new NumberFormatException(longLiteral + " cannot fit into a long");
}
result = shiftedResult + digit;
position++;
}
if (negative) {
//allow -0x8000000000000000, which is = 0x8000000000000000
if (result == Long.MIN_VALUE) {
return result;
} else if (result < 0) {
throw new NumberFormatException(longLiteral + " cannot fit into a long");
}
return result * -1;
} else {
return result;
}
}
public static byte[] longToBytes(long value) {
byte[] bytes = new byte[8];
for (int i=0; value != 0; i++) {
bytes[i] = (byte)value;
value = value >>> 8;
}
return bytes;
}
public static byte[] intToBytes(int value) {
byte[] bytes = new byte[4];
for (int i=0; value != 0; i++) {
bytes[i] = (byte)value;
value = value >>> 8;
}
return bytes;
}
public static byte[] shortToBytes(short value) {
byte[] bytes = new byte[2];
bytes[0] = (byte)value;
bytes[1] = (byte)(value >>> 8);
return bytes;
}
public static byte[] floatToBytes(float value) {
return intToBytes(Float.floatToRawIntBits(value));
}
public static byte[] doubleToBytes(double value) {
return longToBytes(Double.doubleToRawLongBits(value));
}
public static byte[] charToBytes(char value) {
return shortToBytes((short)value);
}
public static byte[] boolToBytes(boolean value) {
if (value) {
return new byte[] { 0x01 };
} else {
return new byte[] { 0x00 };
}
}
public static void checkInt(long value) {
if (value > 0xFFFFFFFF || value < -0x80000000) {
throw new NumberFormatException(Long.toString(value) + " cannot fit into an int");
}
}
public static void checkShort(long value) {
if (value > 0xFFFF | value < -0x8000) {
throw new NumberFormatException(Long.toString(value) + " cannot fit into a short");
}
}
public static void checkByte(long value) {
if (value > 0xFF | value < -0x80) {
throw new NumberFormatException(Long.toString(value) + " cannot fit into a byte");
}
}
public static void checkNibble(long value) {
if (value > 0x0F | value < -0x08) {
throw new NumberFormatException(Long.toString(value) + " cannot fit into a nibble");
}
}
}

View File

@ -57,7 +57,7 @@ public class main {
VERSION = version;
}
/**
* This class is uninstantiable.
*/
@ -290,7 +290,7 @@ public class main {
if (dexGen.getNumberOfSyntaxErrors() > 0) {
return false;
}
return true;
}
@ -314,7 +314,7 @@ public class main {
System.exit(0);
}
private static void buildOptions() {
Option versionOption = OptionBuilder.withLongOpt("version")

View File

@ -1,139 +1,139 @@
/*
* [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.
*/
import org.jf.smali.literalTools;
import org.junit.Assert;
import org.junit.Test;
public class ByteLiteralTest
{
@Test
public void SuccessHexTests() {
Assert.assertTrue(literalTools.parseByte("0x0T") == 0x0);
Assert.assertTrue(literalTools.parseByte("0x00") == 0x0);
Assert.assertTrue(literalTools.parseByte("0x1T") == 0x1);
Assert.assertTrue(literalTools.parseByte("0x12") == 0x12);
Assert.assertTrue(literalTools.parseByte("0x7fT") == 0x7f);
Assert.assertTrue(literalTools.parseByte("0x80t") == Byte.MIN_VALUE);
Assert.assertTrue(literalTools.parseByte("0xFFt") == -1);
Assert.assertTrue(literalTools.parseByte("-0x00") == 0);
Assert.assertTrue(literalTools.parseByte("-0x01") == -1);
Assert.assertTrue(literalTools.parseByte("-0x12") == -0x12);
Assert.assertTrue(literalTools.parseByte("-0x80") == Byte.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileHexTest1() {
literalTools.parseByte("-0x81");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest2() {
literalTools.parseByte("-0xFF");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest3() {
literalTools.parseByte("0x100");
}
@Test
public void SuccessDecTests() {
Assert.assertTrue(literalTools.parseByte("0") == 0);
Assert.assertTrue(literalTools.parseByte("1t") == 1);
Assert.assertTrue(literalTools.parseByte("123") == 123);
Assert.assertTrue(literalTools.parseByte("127T") == 127);
Assert.assertTrue(literalTools.parseByte("128") == Byte.MIN_VALUE);
Assert.assertTrue(literalTools.parseByte("255") == -1);
Assert.assertTrue(literalTools.parseByte("-0") == 0);
Assert.assertTrue(literalTools.parseByte("-1") == -1);
Assert.assertTrue(literalTools.parseByte("-123") == -123);
Assert.assertTrue(literalTools.parseByte("-127") == -127);
Assert.assertTrue(literalTools.parseByte("-128") == Byte.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileDecTest1() {
literalTools.parseByte("-129");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest2() {
literalTools.parseByte("-255");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest3() {
literalTools.parseByte("256");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest4() {
literalTools.parseByte("260");
}
@Test
public void SuccessOctTests() {
Assert.assertTrue(literalTools.parseByte("00") == 00);
Assert.assertTrue(literalTools.parseByte("01") == 01);
Assert.assertTrue(literalTools.parseByte("0123t") == 0123);
Assert.assertTrue(literalTools.parseByte("0177") == Byte.MAX_VALUE);
Assert.assertTrue(literalTools.parseByte("0200T") == Byte.MIN_VALUE);
Assert.assertTrue(literalTools.parseByte("0377") == -1);
Assert.assertTrue(literalTools.parseByte("-00") == 0);
Assert.assertTrue(literalTools.parseByte("-01") == -1);
Assert.assertTrue(literalTools.parseByte("-0123") == -0123);
Assert.assertTrue(literalTools.parseByte("-0177") == -0177);
Assert.assertTrue(literalTools.parseByte("-0200") == Byte.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileOctTest1() {
literalTools.parseByte("-0201");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest2() {
literalTools.parseByte("-0377");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest3() {
literalTools.parseByte("0400");
}
}
/*
* [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.
*/
import org.jf.smali.literalTools;
import org.junit.Assert;
import org.junit.Test;
public class ByteLiteralTest
{
@Test
public void SuccessHexTests() {
Assert.assertTrue(literalTools.parseByte("0x0T") == 0x0);
Assert.assertTrue(literalTools.parseByte("0x00") == 0x0);
Assert.assertTrue(literalTools.parseByte("0x1T") == 0x1);
Assert.assertTrue(literalTools.parseByte("0x12") == 0x12);
Assert.assertTrue(literalTools.parseByte("0x7fT") == 0x7f);
Assert.assertTrue(literalTools.parseByte("0x80t") == Byte.MIN_VALUE);
Assert.assertTrue(literalTools.parseByte("0xFFt") == -1);
Assert.assertTrue(literalTools.parseByte("-0x00") == 0);
Assert.assertTrue(literalTools.parseByte("-0x01") == -1);
Assert.assertTrue(literalTools.parseByte("-0x12") == -0x12);
Assert.assertTrue(literalTools.parseByte("-0x80") == Byte.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileHexTest1() {
literalTools.parseByte("-0x81");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest2() {
literalTools.parseByte("-0xFF");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest3() {
literalTools.parseByte("0x100");
}
@Test
public void SuccessDecTests() {
Assert.assertTrue(literalTools.parseByte("0") == 0);
Assert.assertTrue(literalTools.parseByte("1t") == 1);
Assert.assertTrue(literalTools.parseByte("123") == 123);
Assert.assertTrue(literalTools.parseByte("127T") == 127);
Assert.assertTrue(literalTools.parseByte("128") == Byte.MIN_VALUE);
Assert.assertTrue(literalTools.parseByte("255") == -1);
Assert.assertTrue(literalTools.parseByte("-0") == 0);
Assert.assertTrue(literalTools.parseByte("-1") == -1);
Assert.assertTrue(literalTools.parseByte("-123") == -123);
Assert.assertTrue(literalTools.parseByte("-127") == -127);
Assert.assertTrue(literalTools.parseByte("-128") == Byte.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileDecTest1() {
literalTools.parseByte("-129");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest2() {
literalTools.parseByte("-255");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest3() {
literalTools.parseByte("256");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest4() {
literalTools.parseByte("260");
}
@Test
public void SuccessOctTests() {
Assert.assertTrue(literalTools.parseByte("00") == 00);
Assert.assertTrue(literalTools.parseByte("01") == 01);
Assert.assertTrue(literalTools.parseByte("0123t") == 0123);
Assert.assertTrue(literalTools.parseByte("0177") == Byte.MAX_VALUE);
Assert.assertTrue(literalTools.parseByte("0200T") == Byte.MIN_VALUE);
Assert.assertTrue(literalTools.parseByte("0377") == -1);
Assert.assertTrue(literalTools.parseByte("-00") == 0);
Assert.assertTrue(literalTools.parseByte("-01") == -1);
Assert.assertTrue(literalTools.parseByte("-0123") == -0123);
Assert.assertTrue(literalTools.parseByte("-0177") == -0177);
Assert.assertTrue(literalTools.parseByte("-0200") == Byte.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileOctTest1() {
literalTools.parseByte("-0201");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest2() {
literalTools.parseByte("-0377");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest3() {
literalTools.parseByte("0400");
}
}

View File

@ -1,144 +1,144 @@
/*
* [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.
*/
import org.jf.smali.literalTools;
import org.junit.Assert;
import org.junit.Test;
public class IntLiteralTest
{
@Test
public void SuccessHexTests() {
Assert.assertTrue(literalTools.parseInt("0x0") == 0x0);
Assert.assertTrue(literalTools.parseInt("0x00") == 0x0);
Assert.assertTrue(literalTools.parseInt("0x1") == 0x1);
Assert.assertTrue(literalTools.parseInt("0x12345678") == 0x12345678);
Assert.assertTrue(literalTools.parseInt("0x7fffffff") == 0x7fffffff);
Assert.assertTrue(literalTools.parseInt("0x80000000") == Integer.MIN_VALUE);
Assert.assertTrue(literalTools.parseInt("0xFFFFFFFF") == -1);
Assert.assertTrue(literalTools.parseInt("-0x00") == 0);
Assert.assertTrue(literalTools.parseInt("-0x01") == -1);
Assert.assertTrue(literalTools.parseInt("-0x12345678") == -0x12345678);
Assert.assertTrue(literalTools.parseInt("-0x80000000") == Integer.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileHexTest1() {
literalTools.parseInt("-0x80000001");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest2() {
literalTools.parseInt("-0xFFFFFFFF");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest3() {
literalTools.parseInt("0x100000000");
}
@Test
public void SuccessDecTests() {
Assert.assertTrue(literalTools.parseInt("0") == 0);
Assert.assertTrue(literalTools.parseInt("1") == 1);
Assert.assertTrue(literalTools.parseInt("1234567890") == 1234567890);
Assert.assertTrue(literalTools.parseInt("2147483647") == 2147483647);
Assert.assertTrue(literalTools.parseInt("2147483648") == Integer.MIN_VALUE);
Assert.assertTrue(literalTools.parseInt("4294967295") == -1);
Assert.assertTrue(literalTools.parseInt("-0") == 0);
Assert.assertTrue(literalTools.parseInt("-1") == -1);
Assert.assertTrue(literalTools.parseInt("-1234567890") == -1234567890);
Assert.assertTrue(literalTools.parseInt("-2147483647") == -2147483647);
Assert.assertTrue(literalTools.parseInt("-2147483648") == Integer.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileDecTest1() {
literalTools.parseInt("-2147483649");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest2() {
literalTools.parseInt("-4294967295");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest3() {
literalTools.parseInt("4294967296");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest4() {
literalTools.parseInt("4294967300");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest5() {
literalTools.parseInt("8589934592");
}
@Test
public void SuccessOctTests() {
Assert.assertTrue(literalTools.parseInt("00") == 00);
Assert.assertTrue(literalTools.parseInt("01") == 01);
Assert.assertTrue(literalTools.parseInt("012345670123") == 012345670123);
Assert.assertTrue(literalTools.parseInt("017777777777") == Integer.MAX_VALUE);
Assert.assertTrue(literalTools.parseInt("020000000000") == Integer.MIN_VALUE);
Assert.assertTrue(literalTools.parseInt("037777777777") == -1);
Assert.assertTrue(literalTools.parseInt("-00") == 0);
Assert.assertTrue(literalTools.parseInt("-01") == -1);
Assert.assertTrue(literalTools.parseInt("-012345670123") == -012345670123);
Assert.assertTrue(literalTools.parseInt("-017777777777") == -017777777777);
Assert.assertTrue(literalTools.parseInt("-020000000000") == Integer.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileOctTest1() {
literalTools.parseInt("-020000000001");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest2() {
literalTools.parseInt("-037777777777");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest3() {
literalTools.parseInt("040000000000");
}
}
/*
* [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.
*/
import org.jf.smali.literalTools;
import org.junit.Assert;
import org.junit.Test;
public class IntLiteralTest
{
@Test
public void SuccessHexTests() {
Assert.assertTrue(literalTools.parseInt("0x0") == 0x0);
Assert.assertTrue(literalTools.parseInt("0x00") == 0x0);
Assert.assertTrue(literalTools.parseInt("0x1") == 0x1);
Assert.assertTrue(literalTools.parseInt("0x12345678") == 0x12345678);
Assert.assertTrue(literalTools.parseInt("0x7fffffff") == 0x7fffffff);
Assert.assertTrue(literalTools.parseInt("0x80000000") == Integer.MIN_VALUE);
Assert.assertTrue(literalTools.parseInt("0xFFFFFFFF") == -1);
Assert.assertTrue(literalTools.parseInt("-0x00") == 0);
Assert.assertTrue(literalTools.parseInt("-0x01") == -1);
Assert.assertTrue(literalTools.parseInt("-0x12345678") == -0x12345678);
Assert.assertTrue(literalTools.parseInt("-0x80000000") == Integer.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileHexTest1() {
literalTools.parseInt("-0x80000001");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest2() {
literalTools.parseInt("-0xFFFFFFFF");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest3() {
literalTools.parseInt("0x100000000");
}
@Test
public void SuccessDecTests() {
Assert.assertTrue(literalTools.parseInt("0") == 0);
Assert.assertTrue(literalTools.parseInt("1") == 1);
Assert.assertTrue(literalTools.parseInt("1234567890") == 1234567890);
Assert.assertTrue(literalTools.parseInt("2147483647") == 2147483647);
Assert.assertTrue(literalTools.parseInt("2147483648") == Integer.MIN_VALUE);
Assert.assertTrue(literalTools.parseInt("4294967295") == -1);
Assert.assertTrue(literalTools.parseInt("-0") == 0);
Assert.assertTrue(literalTools.parseInt("-1") == -1);
Assert.assertTrue(literalTools.parseInt("-1234567890") == -1234567890);
Assert.assertTrue(literalTools.parseInt("-2147483647") == -2147483647);
Assert.assertTrue(literalTools.parseInt("-2147483648") == Integer.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileDecTest1() {
literalTools.parseInt("-2147483649");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest2() {
literalTools.parseInt("-4294967295");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest3() {
literalTools.parseInt("4294967296");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest4() {
literalTools.parseInt("4294967300");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest5() {
literalTools.parseInt("8589934592");
}
@Test
public void SuccessOctTests() {
Assert.assertTrue(literalTools.parseInt("00") == 00);
Assert.assertTrue(literalTools.parseInt("01") == 01);
Assert.assertTrue(literalTools.parseInt("012345670123") == 012345670123);
Assert.assertTrue(literalTools.parseInt("017777777777") == Integer.MAX_VALUE);
Assert.assertTrue(literalTools.parseInt("020000000000") == Integer.MIN_VALUE);
Assert.assertTrue(literalTools.parseInt("037777777777") == -1);
Assert.assertTrue(literalTools.parseInt("-00") == 0);
Assert.assertTrue(literalTools.parseInt("-01") == -1);
Assert.assertTrue(literalTools.parseInt("-012345670123") == -012345670123);
Assert.assertTrue(literalTools.parseInt("-017777777777") == -017777777777);
Assert.assertTrue(literalTools.parseInt("-020000000000") == Integer.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileOctTest1() {
literalTools.parseInt("-020000000001");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest2() {
literalTools.parseInt("-037777777777");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest3() {
literalTools.parseInt("040000000000");
}
}

View File

@ -1,139 +1,139 @@
/*
* [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.
*/
import org.jf.smali.literalTools;
import org.junit.Assert;
import org.junit.Test;
public class LongLiteralTest
{
@Test
public void SuccessHexTests() {
Assert.assertTrue(literalTools.parseLong("0x0L") == 0x0);
Assert.assertTrue(literalTools.parseLong("0x00") == 0x0);
Assert.assertTrue(literalTools.parseLong("0x1L") == 0x1);
Assert.assertTrue(literalTools.parseLong("0x1234567890123456L") == 0x1234567890123456L);
Assert.assertTrue(literalTools.parseLong("0x7fffffffffffffffL") == 0x7fffffffffffffffL);
Assert.assertTrue(literalTools.parseLong("0x8000000000000000L") == Long.MIN_VALUE);
Assert.assertTrue(literalTools.parseLong("0xFFFFFFFFFFFFFFFFL") == -1);
Assert.assertTrue(literalTools.parseLong("-0x00L") == 0);
Assert.assertTrue(literalTools.parseLong("-0x01L") == -1);
Assert.assertTrue(literalTools.parseLong("-0x1234567890123456L") == -0x1234567890123456L);
Assert.assertTrue(literalTools.parseLong("-0x8000000000000000") == Long.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileHexTest1() {
literalTools.parseLong("-0x8000000000000001");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest2() {
literalTools.parseLong("-0xFFFFFFFFFFFFFFFF");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest3() {
literalTools.parseLong("0x10000000000000000");
}
@Test
public void SuccessDecTests() {
Assert.assertTrue(literalTools.parseLong("0L") == 0);
Assert.assertTrue(literalTools.parseLong("1") == 1);
Assert.assertTrue(literalTools.parseLong("1234567890123456789") == 1234567890123456789L);
Assert.assertTrue(literalTools.parseLong("9223372036854775807") == 9223372036854775807L);
Assert.assertTrue(literalTools.parseLong("9223372036854775808") == Long.MIN_VALUE);
Assert.assertTrue(literalTools.parseLong("18446744073709551615L") == -1);
Assert.assertTrue(literalTools.parseLong("-0") == 0);
Assert.assertTrue(literalTools.parseLong("-1") == -1);
Assert.assertTrue(literalTools.parseLong("-1234567890123456789") == -1234567890123456789L);
Assert.assertTrue(literalTools.parseLong("-9223372036854775807") == -9223372036854775807L);
Assert.assertTrue(literalTools.parseLong("-9223372036854775808") == Long.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileDecTest1() {
literalTools.parseLong("-9223372036854775809");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest2() {
literalTools.parseLong("-18446744073709551616");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest3() {
literalTools.parseLong("18446744073709551617");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest4() {
literalTools.parseLong("18446744073709551700");
}
@Test
public void SuccessOctTests() {
Assert.assertTrue(literalTools.parseLong("00") == 00);
Assert.assertTrue(literalTools.parseLong("01") == 01);
Assert.assertTrue(literalTools.parseLong("0123456701234567012345") == 0123456701234567012345L);
Assert.assertTrue(literalTools.parseLong("0777777777777777777777") == Long.MAX_VALUE);
Assert.assertTrue(literalTools.parseLong("01000000000000000000000") == Long.MIN_VALUE);
Assert.assertTrue(literalTools.parseLong("01777777777777777777777") == -1);
Assert.assertTrue(literalTools.parseLong("-00") == 0);
Assert.assertTrue(literalTools.parseLong("-01") == -1);
Assert.assertTrue(literalTools.parseLong("-0123456701234567012345") == -0123456701234567012345L);
Assert.assertTrue(literalTools.parseLong("-0777777777777777777777") == -0777777777777777777777L);
Assert.assertTrue(literalTools.parseLong("-01000000000000000000000") == Long.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileOctTest1() {
literalTools.parseLong("-01000000000000000000001");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest2() {
literalTools.parseLong("-01777777777777777777777");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest3() {
literalTools.parseLong("02000000000000000000000");
}
}
/*
* [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.
*/
import org.jf.smali.literalTools;
import org.junit.Assert;
import org.junit.Test;
public class LongLiteralTest
{
@Test
public void SuccessHexTests() {
Assert.assertTrue(literalTools.parseLong("0x0L") == 0x0);
Assert.assertTrue(literalTools.parseLong("0x00") == 0x0);
Assert.assertTrue(literalTools.parseLong("0x1L") == 0x1);
Assert.assertTrue(literalTools.parseLong("0x1234567890123456L") == 0x1234567890123456L);
Assert.assertTrue(literalTools.parseLong("0x7fffffffffffffffL") == 0x7fffffffffffffffL);
Assert.assertTrue(literalTools.parseLong("0x8000000000000000L") == Long.MIN_VALUE);
Assert.assertTrue(literalTools.parseLong("0xFFFFFFFFFFFFFFFFL") == -1);
Assert.assertTrue(literalTools.parseLong("-0x00L") == 0);
Assert.assertTrue(literalTools.parseLong("-0x01L") == -1);
Assert.assertTrue(literalTools.parseLong("-0x1234567890123456L") == -0x1234567890123456L);
Assert.assertTrue(literalTools.parseLong("-0x8000000000000000") == Long.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileHexTest1() {
literalTools.parseLong("-0x8000000000000001");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest2() {
literalTools.parseLong("-0xFFFFFFFFFFFFFFFF");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest3() {
literalTools.parseLong("0x10000000000000000");
}
@Test
public void SuccessDecTests() {
Assert.assertTrue(literalTools.parseLong("0L") == 0);
Assert.assertTrue(literalTools.parseLong("1") == 1);
Assert.assertTrue(literalTools.parseLong("1234567890123456789") == 1234567890123456789L);
Assert.assertTrue(literalTools.parseLong("9223372036854775807") == 9223372036854775807L);
Assert.assertTrue(literalTools.parseLong("9223372036854775808") == Long.MIN_VALUE);
Assert.assertTrue(literalTools.parseLong("18446744073709551615L") == -1);
Assert.assertTrue(literalTools.parseLong("-0") == 0);
Assert.assertTrue(literalTools.parseLong("-1") == -1);
Assert.assertTrue(literalTools.parseLong("-1234567890123456789") == -1234567890123456789L);
Assert.assertTrue(literalTools.parseLong("-9223372036854775807") == -9223372036854775807L);
Assert.assertTrue(literalTools.parseLong("-9223372036854775808") == Long.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileDecTest1() {
literalTools.parseLong("-9223372036854775809");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest2() {
literalTools.parseLong("-18446744073709551616");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest3() {
literalTools.parseLong("18446744073709551617");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest4() {
literalTools.parseLong("18446744073709551700");
}
@Test
public void SuccessOctTests() {
Assert.assertTrue(literalTools.parseLong("00") == 00);
Assert.assertTrue(literalTools.parseLong("01") == 01);
Assert.assertTrue(literalTools.parseLong("0123456701234567012345") == 0123456701234567012345L);
Assert.assertTrue(literalTools.parseLong("0777777777777777777777") == Long.MAX_VALUE);
Assert.assertTrue(literalTools.parseLong("01000000000000000000000") == Long.MIN_VALUE);
Assert.assertTrue(literalTools.parseLong("01777777777777777777777") == -1);
Assert.assertTrue(literalTools.parseLong("-00") == 0);
Assert.assertTrue(literalTools.parseLong("-01") == -1);
Assert.assertTrue(literalTools.parseLong("-0123456701234567012345") == -0123456701234567012345L);
Assert.assertTrue(literalTools.parseLong("-0777777777777777777777") == -0777777777777777777777L);
Assert.assertTrue(literalTools.parseLong("-01000000000000000000000") == Long.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileOctTest1() {
literalTools.parseLong("-01000000000000000000001");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest2() {
literalTools.parseLong("-01777777777777777777777");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest3() {
literalTools.parseLong("02000000000000000000000");
}
}

View File

@ -1,139 +1,139 @@
/*
* [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.
*/
import org.jf.smali.literalTools;
import org.junit.Assert;
import org.junit.Test;
public class ShortLiteralTest
{
@Test
public void SuccessHexTests() {
Assert.assertTrue(literalTools.parseShort("0x0") == 0x0);
Assert.assertTrue(literalTools.parseShort("0x00") == 0x0);
Assert.assertTrue(literalTools.parseShort("0x1") == 0x1);
Assert.assertTrue(literalTools.parseShort("0x1234") == 0x1234);
Assert.assertTrue(literalTools.parseShort("0x7fff") == 0x7fff);
Assert.assertTrue(literalTools.parseShort("0x8000") == Short.MIN_VALUE);
Assert.assertTrue(literalTools.parseShort("0xFFFF") == -1);
Assert.assertTrue(literalTools.parseShort("-0x00") == 0);
Assert.assertTrue(literalTools.parseShort("-0x01") == -1);
Assert.assertTrue(literalTools.parseShort("-0x1234") == -0x1234);
Assert.assertTrue(literalTools.parseShort("-0x8000") == Short.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileHexTest1() {
literalTools.parseShort("-0x8001");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest2() {
literalTools.parseShort("-0xFFFF");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest3() {
literalTools.parseShort("0x100000");
}
@Test
public void SuccessDecTests() {
Assert.assertTrue(literalTools.parseShort("0") == 0);
Assert.assertTrue(literalTools.parseShort("1") == 1);
Assert.assertTrue(literalTools.parseShort("12345") == 12345);
Assert.assertTrue(literalTools.parseShort("32767") == 32767);
Assert.assertTrue(literalTools.parseShort("32768") == Short.MIN_VALUE);
Assert.assertTrue(literalTools.parseShort("65535") == -1);
Assert.assertTrue(literalTools.parseShort("-0") == 0);
Assert.assertTrue(literalTools.parseShort("-1") == -1);
Assert.assertTrue(literalTools.parseShort("-12345") == -12345);
Assert.assertTrue(literalTools.parseShort("-32767") == -32767);
Assert.assertTrue(literalTools.parseShort("-32768") == Short.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileDecTest1() {
literalTools.parseShort("-32769");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest2() {
literalTools.parseShort("-65535");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest3() {
literalTools.parseShort("65536");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest4() {
literalTools.parseShort("65600");
}
@Test
public void SuccessOctTests() {
Assert.assertTrue(literalTools.parseShort("00") == 00);
Assert.assertTrue(literalTools.parseShort("01") == 01);
Assert.assertTrue(literalTools.parseShort("012345") == 012345);
Assert.assertTrue(literalTools.parseShort("077777") == Short.MAX_VALUE);
Assert.assertTrue(literalTools.parseShort("0100000") == Short.MIN_VALUE);
Assert.assertTrue(literalTools.parseShort("0177777") == -1);
Assert.assertTrue(literalTools.parseShort("-00") == 0);
Assert.assertTrue(literalTools.parseShort("-01") == -1);
Assert.assertTrue(literalTools.parseShort("-012345") == -012345);
Assert.assertTrue(literalTools.parseShort("-077777") == -077777);
Assert.assertTrue(literalTools.parseShort("-0100000") == Short.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileOctTest1() {
literalTools.parseShort("-0100001");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest2() {
literalTools.parseShort("-0177777");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest3() {
literalTools.parseShort("0200000");
}
}
/*
* [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.
*/
import org.jf.smali.literalTools;
import org.junit.Assert;
import org.junit.Test;
public class ShortLiteralTest
{
@Test
public void SuccessHexTests() {
Assert.assertTrue(literalTools.parseShort("0x0") == 0x0);
Assert.assertTrue(literalTools.parseShort("0x00") == 0x0);
Assert.assertTrue(literalTools.parseShort("0x1") == 0x1);
Assert.assertTrue(literalTools.parseShort("0x1234") == 0x1234);
Assert.assertTrue(literalTools.parseShort("0x7fff") == 0x7fff);
Assert.assertTrue(literalTools.parseShort("0x8000") == Short.MIN_VALUE);
Assert.assertTrue(literalTools.parseShort("0xFFFF") == -1);
Assert.assertTrue(literalTools.parseShort("-0x00") == 0);
Assert.assertTrue(literalTools.parseShort("-0x01") == -1);
Assert.assertTrue(literalTools.parseShort("-0x1234") == -0x1234);
Assert.assertTrue(literalTools.parseShort("-0x8000") == Short.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileHexTest1() {
literalTools.parseShort("-0x8001");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest2() {
literalTools.parseShort("-0xFFFF");
}
@Test(expected=NumberFormatException.class)
public void FailHexTest3() {
literalTools.parseShort("0x100000");
}
@Test
public void SuccessDecTests() {
Assert.assertTrue(literalTools.parseShort("0") == 0);
Assert.assertTrue(literalTools.parseShort("1") == 1);
Assert.assertTrue(literalTools.parseShort("12345") == 12345);
Assert.assertTrue(literalTools.parseShort("32767") == 32767);
Assert.assertTrue(literalTools.parseShort("32768") == Short.MIN_VALUE);
Assert.assertTrue(literalTools.parseShort("65535") == -1);
Assert.assertTrue(literalTools.parseShort("-0") == 0);
Assert.assertTrue(literalTools.parseShort("-1") == -1);
Assert.assertTrue(literalTools.parseShort("-12345") == -12345);
Assert.assertTrue(literalTools.parseShort("-32767") == -32767);
Assert.assertTrue(literalTools.parseShort("-32768") == Short.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileDecTest1() {
literalTools.parseShort("-32769");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest2() {
literalTools.parseShort("-65535");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest3() {
literalTools.parseShort("65536");
}
@Test(expected=NumberFormatException.class)
public void FailDecTest4() {
literalTools.parseShort("65600");
}
@Test
public void SuccessOctTests() {
Assert.assertTrue(literalTools.parseShort("00") == 00);
Assert.assertTrue(literalTools.parseShort("01") == 01);
Assert.assertTrue(literalTools.parseShort("012345") == 012345);
Assert.assertTrue(literalTools.parseShort("077777") == Short.MAX_VALUE);
Assert.assertTrue(literalTools.parseShort("0100000") == Short.MIN_VALUE);
Assert.assertTrue(literalTools.parseShort("0177777") == -1);
Assert.assertTrue(literalTools.parseShort("-00") == 0);
Assert.assertTrue(literalTools.parseShort("-01") == -1);
Assert.assertTrue(literalTools.parseShort("-012345") == -012345);
Assert.assertTrue(literalTools.parseShort("-077777") == -077777);
Assert.assertTrue(literalTools.parseShort("-0100000") == Short.MIN_VALUE);
}
@Test(expected=NumberFormatException.class)
public void FaileOctTest1() {
literalTools.parseShort("-0100001");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest2() {
literalTools.parseShort("-0177777");
}
@Test(expected=NumberFormatException.class)
public void FailOctTest3() {
literalTools.parseShort("0200000");
}
}