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; import java.util.ArrayList;
public abstract class AnnotationEncodedValueAdaptor { public abstract class AnnotationEncodedValueAdaptor {
public static StringTemplate makeTemplate(StringTemplateGroup stg, AnnotationEncodedSubValue encodedAnnotation) { public static StringTemplate makeTemplate(StringTemplateGroup stg, AnnotationEncodedSubValue encodedAnnotation) {
StringTemplate template = stg.getInstanceOf("AnnotationEncodedValue"); StringTemplate template = stg.getInstanceOf("AnnotationEncodedValue");
template.setAttribute("AnnotationType", TypeReference.makeTemplate(stg, encodedAnnotation.annotationType)); 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); return SimpleEncodedValueAdaptor.makeTemplate(stg, ((FloatEncodedValue)encodedValue).value);
case VALUE_INT: case VALUE_INT:
return SimpleEncodedValueAdaptor.makeTemplate(stg, ((IntEncodedValue)encodedValue).value); return SimpleEncodedValueAdaptor.makeTemplate(stg, ((IntEncodedValue)encodedValue).value);
case VALUE_LONG: case VALUE_LONG:
return SimpleEncodedValueAdaptor.makeTemplate(stg, ((LongEncodedValue)encodedValue).value); return SimpleEncodedValueAdaptor.makeTemplate(stg, ((LongEncodedValue)encodedValue).value);
case VALUE_METHOD: case VALUE_METHOD:
return EncodedIndexedItemAdaptor.makeTemplate(stg, MethodReference.makeTemplate(stg, return EncodedIndexedItemAdaptor.makeTemplate(stg, MethodReference.makeTemplate(stg,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,473 +1,473 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> { public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
private AnnotationSetItem classAnnotations; private AnnotationSetItem classAnnotations;
private FieldIdItem[] fieldAnnotationFields; private FieldIdItem[] fieldAnnotationFields;
private AnnotationSetItem[] fieldAnnotations; private AnnotationSetItem[] fieldAnnotations;
private MethodIdItem[] methodAnnotationMethods; private MethodIdItem[] methodAnnotationMethods;
private AnnotationSetItem[] methodAnnotations; private AnnotationSetItem[] methodAnnotations;
private MethodIdItem[] parameterAnnotationMethods; private MethodIdItem[] parameterAnnotationMethods;
private AnnotationSetRefList[] parameterAnnotations; private AnnotationSetRefList[] parameterAnnotations;
/** /**
* typically each AnnotationDirectoryItem will have a distinct parent. The only case that isn't true is when * 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 * the AnnotationDirectoryItem *only* contains class annotations, with no other type of annotation. In that
* case, the same AnnotationDirectoryItem could be referenced from multiple classes. * 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, * 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 * which handles it as a special case
*/ */
private ClassDefItem parent = null; private ClassDefItem parent = null;
/** /**
* Creates a new uninitialized <code>AnnotationDirectoryItem</code> * Creates a new uninitialized <code>AnnotationDirectoryItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected AnnotationDirectoryItem(DexFile dexFile) { protected AnnotationDirectoryItem(DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** /**
* Creates a new <code>AnnotationDirectoryItem</code> with the given values * Creates a new <code>AnnotationDirectoryItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param classAnnotations The annotations associated with the overall class * @param classAnnotations The annotations associated with the overall class
* @param fieldAnnotationFields An array of <code>FieldIdItem</code> objects that the annotations in * @param fieldAnnotationFields An array of <code>FieldIdItem</code> objects that the annotations in
* <code>fieldAnnotations</code> are associated with * <code>fieldAnnotations</code> are associated with
* @param fieldAnnotations An array of <code>AnnotationSetItem</code> objects that contain the annotations for the * @param fieldAnnotations An array of <code>AnnotationSetItem</code> objects that contain the annotations for the
* fields in <code>fieldAnnotationFields</code> * fields in <code>fieldAnnotationFields</code>
* @param methodAnnotationMethods An array of <code>MethodIdItem</code> objects that the annotations in * @param methodAnnotationMethods An array of <code>MethodIdItem</code> objects that the annotations in
* <code>methodAnnotations</code> are associated with * <code>methodAnnotations</code> are associated with
* @param methodAnnotations An array of <code>AnnotationSetItem</code> objects that contain the annotations for the * @param methodAnnotations An array of <code>AnnotationSetItem</code> objects that contain the annotations for the
* methods in <code>methodAnnotationMethods</code> * methods in <code>methodAnnotationMethods</code>
* @param parameterAnnotationMethods An array of <code>MethodIdItem</code> objects that the annotations in * @param parameterAnnotationMethods An array of <code>MethodIdItem</code> objects that the annotations in
* <code>parameterAnnotations</code> are associated with * <code>parameterAnnotations</code> are associated with
* @param parameterAnnotations An array of <code>AnnotationSetRefList</code> objects that contain the parameter * @param parameterAnnotations An array of <code>AnnotationSetRefList</code> objects that contain the parameter
* annotations for the methods in <code>parameterAnnotationMethods</code> * annotations for the methods in <code>parameterAnnotationMethods</code>
*/ */
private AnnotationDirectoryItem(DexFile dexFile, AnnotationSetItem classAnnotations, private AnnotationDirectoryItem(DexFile dexFile, AnnotationSetItem classAnnotations,
FieldIdItem[] fieldAnnotationFields, AnnotationSetItem[] fieldAnnotations, FieldIdItem[] fieldAnnotationFields, AnnotationSetItem[] fieldAnnotations,
MethodIdItem[] methodAnnotationMethods, AnnotationSetItem[] methodAnnotations, MethodIdItem[] methodAnnotationMethods, AnnotationSetItem[] methodAnnotations,
MethodIdItem[] parameterAnnotationMethods, MethodIdItem[] parameterAnnotationMethods,
AnnotationSetRefList[] parameterAnnotations) { AnnotationSetRefList[] parameterAnnotations) {
super(dexFile); super(dexFile);
this.classAnnotations = classAnnotations; this.classAnnotations = classAnnotations;
this.fieldAnnotationFields = fieldAnnotationFields; this.fieldAnnotationFields = fieldAnnotationFields;
this.fieldAnnotations = fieldAnnotations; this.fieldAnnotations = fieldAnnotations;
this.methodAnnotationMethods = methodAnnotationMethods; this.methodAnnotationMethods = methodAnnotationMethods;
this.methodAnnotations = methodAnnotations; this.methodAnnotations = methodAnnotations;
this.parameterAnnotationMethods = parameterAnnotationMethods; this.parameterAnnotationMethods = parameterAnnotationMethods;
this.parameterAnnotations = parameterAnnotations; this.parameterAnnotations = parameterAnnotations;
} }
/** /**
* Returns an <code>AnnotationDirectoryItem</code> for the given values, and that has been interned into the given * Returns an <code>AnnotationDirectoryItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code> * <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param classAnnotations The annotations associated with the class * @param classAnnotations The annotations associated with the class
* @param fieldAnnotations A list of <code>FieldAnnotation</code> objects containing the field annotations * @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 methodAnnotations A list of <code>MethodAnnotation</code> objects containing the method annotations
* @param parameterAnnotations A list of <code>ParameterAnnotation</code> objects containin the parameter * @param parameterAnnotations A list of <code>ParameterAnnotation</code> objects containin the parameter
* annotations * annotations
* @return an <code>AnnotationItem</code> for the given values, and that has been interned into the given * @return an <code>AnnotationItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code> * <code>DexFile</code>
*/ */
public static AnnotationDirectoryItem getInternedAnnotationDirectoryItem(DexFile dexFile, public static AnnotationDirectoryItem getInternedAnnotationDirectoryItem(DexFile dexFile,
AnnotationSetItem classAnnotations, AnnotationSetItem classAnnotations,
List<FieldAnnotation> fieldAnnotations, List<FieldAnnotation> fieldAnnotations,
List<MethodAnnotation> methodAnnotations, List<MethodAnnotation> methodAnnotations,
List<ParameterAnnotation> parameterAnnotations) { List<ParameterAnnotation> parameterAnnotations) {
FieldIdItem[] fieldAnnotationFields = null; FieldIdItem[] fieldAnnotationFields = null;
AnnotationSetItem[] fieldAnnotationsArray = null; AnnotationSetItem[] fieldAnnotationsArray = null;
MethodIdItem[] methodAnnotationMethods = null; MethodIdItem[] methodAnnotationMethods = null;
AnnotationSetItem[] methodAnnotationsArray = null; AnnotationSetItem[] methodAnnotationsArray = null;
MethodIdItem[] parameterAnnotationMethods = null; MethodIdItem[] parameterAnnotationMethods = null;
AnnotationSetRefList[] parameterAnnotationsArray = null; AnnotationSetRefList[] parameterAnnotationsArray = null;
if (fieldAnnotations != null && fieldAnnotations.size() > 0) { if (fieldAnnotations != null && fieldAnnotations.size() > 0) {
fieldAnnotationFields = new FieldIdItem[fieldAnnotations.size()]; fieldAnnotationFields = new FieldIdItem[fieldAnnotations.size()];
fieldAnnotationsArray = new AnnotationSetItem[fieldAnnotations.size()]; fieldAnnotationsArray = new AnnotationSetItem[fieldAnnotations.size()];
Collections.sort(fieldAnnotations); Collections.sort(fieldAnnotations);
int index = 0; int index = 0;
for (FieldAnnotation fieldAnnotation: fieldAnnotations) { for (FieldAnnotation fieldAnnotation: fieldAnnotations) {
fieldAnnotationFields[index] = fieldAnnotation.field; fieldAnnotationFields[index] = fieldAnnotation.field;
fieldAnnotationsArray[index++] = fieldAnnotation.annotationSet; fieldAnnotationsArray[index++] = fieldAnnotation.annotationSet;
} }
} }
if (methodAnnotations != null && methodAnnotations.size() > 0) { if (methodAnnotations != null && methodAnnotations.size() > 0) {
methodAnnotationMethods = new MethodIdItem[methodAnnotations.size()]; methodAnnotationMethods = new MethodIdItem[methodAnnotations.size()];
methodAnnotationsArray = new AnnotationSetItem[methodAnnotations.size()]; methodAnnotationsArray = new AnnotationSetItem[methodAnnotations.size()];
Collections.sort(methodAnnotations); Collections.sort(methodAnnotations);
int index = 0; int index = 0;
for (MethodAnnotation methodAnnotation: methodAnnotations) { for (MethodAnnotation methodAnnotation: methodAnnotations) {
methodAnnotationMethods[index] = methodAnnotation.method; methodAnnotationMethods[index] = methodAnnotation.method;
methodAnnotationsArray[index++] = methodAnnotation.annotationSet; methodAnnotationsArray[index++] = methodAnnotation.annotationSet;
} }
} }
if (parameterAnnotations != null && parameterAnnotations.size() > 0) { if (parameterAnnotations != null && parameterAnnotations.size() > 0) {
parameterAnnotationMethods = new MethodIdItem[parameterAnnotations.size()]; parameterAnnotationMethods = new MethodIdItem[parameterAnnotations.size()];
parameterAnnotationsArray = new AnnotationSetRefList[parameterAnnotations.size()]; parameterAnnotationsArray = new AnnotationSetRefList[parameterAnnotations.size()];
Collections.sort(parameterAnnotations); Collections.sort(parameterAnnotations);
int index = 0; int index = 0;
for (ParameterAnnotation parameterAnnotation: parameterAnnotations) { for (ParameterAnnotation parameterAnnotation: parameterAnnotations) {
parameterAnnotationMethods[index] = parameterAnnotation.method; parameterAnnotationMethods[index] = parameterAnnotation.method;
parameterAnnotationsArray[index++] = parameterAnnotation.annotationSet; parameterAnnotationsArray[index++] = parameterAnnotation.annotationSet;
} }
} }
AnnotationDirectoryItem annotationDirectoryItem = new AnnotationDirectoryItem(dexFile, classAnnotations, AnnotationDirectoryItem annotationDirectoryItem = new AnnotationDirectoryItem(dexFile, classAnnotations,
fieldAnnotationFields, fieldAnnotationsArray, methodAnnotationMethods, methodAnnotationsArray, fieldAnnotationFields, fieldAnnotationsArray, methodAnnotationMethods, methodAnnotationsArray,
parameterAnnotationMethods, parameterAnnotationsArray); parameterAnnotationMethods, parameterAnnotationsArray);
return dexFile.AnnotationDirectoriesSection.intern(annotationDirectoryItem); return dexFile.AnnotationDirectoriesSection.intern(annotationDirectoryItem);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
classAnnotations = (AnnotationSetItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_ANNOTATION_SET_ITEM, classAnnotations = (AnnotationSetItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_ANNOTATION_SET_ITEM,
in.readInt()); in.readInt());
fieldAnnotationFields = new FieldIdItem[in.readInt()]; fieldAnnotationFields = new FieldIdItem[in.readInt()];
fieldAnnotations = new AnnotationSetItem[fieldAnnotationFields.length]; fieldAnnotations = new AnnotationSetItem[fieldAnnotationFields.length];
methodAnnotationMethods = new MethodIdItem[in.readInt()]; methodAnnotationMethods = new MethodIdItem[in.readInt()];
methodAnnotations = new AnnotationSetItem[methodAnnotationMethods.length]; methodAnnotations = new AnnotationSetItem[methodAnnotationMethods.length];
parameterAnnotationMethods = new MethodIdItem[in.readInt()]; parameterAnnotationMethods = new MethodIdItem[in.readInt()];
parameterAnnotations = new AnnotationSetRefList[parameterAnnotationMethods.length]; parameterAnnotations = new AnnotationSetRefList[parameterAnnotationMethods.length];
for (int i=0; i<fieldAnnotations.length; i++) { for (int i=0; i<fieldAnnotations.length; i++) {
fieldAnnotationFields[i] = dexFile.FieldIdsSection.getItemByIndex(in.readInt()); fieldAnnotationFields[i] = dexFile.FieldIdsSection.getItemByIndex(in.readInt());
fieldAnnotations[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset( fieldAnnotations[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt()); ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
} }
for (int i=0; i<methodAnnotations.length; i++) { for (int i=0; i<methodAnnotations.length; i++) {
methodAnnotationMethods[i] = dexFile.MethodIdsSection.getItemByIndex(in.readInt()); methodAnnotationMethods[i] = dexFile.MethodIdsSection.getItemByIndex(in.readInt());
methodAnnotations[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset( methodAnnotations[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt()); ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
} }
for (int i=0; i<parameterAnnotations.length; i++) { for (int i=0; i<parameterAnnotations.length; i++) {
parameterAnnotationMethods[i] = dexFile.MethodIdsSection.getItemByIndex(in.readInt()); parameterAnnotationMethods[i] = dexFile.MethodIdsSection.getItemByIndex(in.readInt());
parameterAnnotations[i] = (AnnotationSetRefList)readContext.getOffsettedItemByOffset( parameterAnnotations[i] = (AnnotationSetRefList)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATION_SET_REF_LIST, in.readInt()); ItemType.TYPE_ANNOTATION_SET_REF_LIST, in.readInt());
} }
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return offset + 16 + ( return offset + 16 + (
(fieldAnnotations==null?0:fieldAnnotations.length) + (fieldAnnotations==null?0:fieldAnnotations.length) +
(methodAnnotations==null?0:methodAnnotations.length) + (methodAnnotations==null?0:methodAnnotations.length) +
(parameterAnnotations==null?0:parameterAnnotations.length)) * 8; (parameterAnnotations==null?0:parameterAnnotations.length)) * 8;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
if (!isInternable() && parent != null) { if (!isInternable() && parent != null) {
out.annotate(0, parent.getClassType().getTypeDescriptor()); out.annotate(0, parent.getClassType().getTypeDescriptor());
} }
if (classAnnotations != null) { if (classAnnotations != null) {
out.annotate(4, "class_annotations_off: 0x" + Integer.toHexString(classAnnotations.getOffset())); out.annotate(4, "class_annotations_off: 0x" + Integer.toHexString(classAnnotations.getOffset()));
} else { } else {
out.annotate(4, "class_annotations_off:"); out.annotate(4, "class_annotations_off:");
} }
int length = fieldAnnotations==null?0:fieldAnnotations.length; int length = fieldAnnotations==null?0:fieldAnnotations.length;
out.annotate(4, "annotated_fields_size: 0x" + Integer.toHexString(length) + " (" + out.annotate(4, "annotated_fields_size: 0x" + Integer.toHexString(length) + " (" +
length + ")"); length + ")");
length = methodAnnotations==null?0:methodAnnotations.length; length = methodAnnotations==null?0:methodAnnotations.length;
out.annotate(4, "annotated_methods_size: 0x" + Integer.toHexString(length) + " (" + out.annotate(4, "annotated_methods_size: 0x" + Integer.toHexString(length) + " (" +
length + ")"); length + ")");
length = parameterAnnotations==null?0:parameterAnnotations.length; length = parameterAnnotations==null?0:parameterAnnotations.length;
out.annotate(4, "annotated_parameters_size: 0x" + Integer.toHexString(length) + " (" + out.annotate(4, "annotated_parameters_size: 0x" + Integer.toHexString(length) + " (" +
length + ")"); length + ")");
int index; int index;
if (fieldAnnotations != null) { if (fieldAnnotations != null) {
index = 0; index = 0;
for (int i=0; i<fieldAnnotations.length; i++) { for (int i=0; i<fieldAnnotations.length; i++) {
out.annotate(0, "[" + index++ + "] field_annotation"); out.annotate(0, "[" + index++ + "] field_annotation");
out.indent(); out.indent();
out.annotate(4, "field: " + fieldAnnotationFields[i].getFieldName().getStringValue() + ":" + out.annotate(4, "field: " + fieldAnnotationFields[i].getFieldName().getStringValue() + ":" +
fieldAnnotationFields[i].getFieldType().getTypeDescriptor()); fieldAnnotationFields[i].getFieldType().getTypeDescriptor());
out.annotate(4, "annotations_off: 0x" + Integer.toHexString(fieldAnnotations[i].getOffset())); out.annotate(4, "annotations_off: 0x" + Integer.toHexString(fieldAnnotations[i].getOffset()));
out.deindent(); out.deindent();
} }
} }
if (methodAnnotations != null) { if (methodAnnotations != null) {
index = 0; index = 0;
for (int i=0; i<methodAnnotations.length; i++) { for (int i=0; i<methodAnnotations.length; i++) {
out.annotate(0, "[" + index++ + "] method_annotation"); out.annotate(0, "[" + index++ + "] method_annotation");
out.indent(); out.indent();
out.annotate(4, "method: " + methodAnnotationMethods[i].getMethodString()); out.annotate(4, "method: " + methodAnnotationMethods[i].getMethodString());
out.annotate(4, "annotations_off: 0x" + Integer.toHexString(methodAnnotations[i].getOffset())); out.annotate(4, "annotations_off: 0x" + Integer.toHexString(methodAnnotations[i].getOffset()));
out.deindent(); out.deindent();
} }
} }
if (parameterAnnotations != null) { if (parameterAnnotations != null) {
index = 0; index = 0;
for (int i=0; i<parameterAnnotations.length; i++) { for (int i=0; i<parameterAnnotations.length; i++) {
out.annotate(0, "[" + index++ + "] parameter_annotation"); out.annotate(0, "[" + index++ + "] parameter_annotation");
out.indent(); out.indent();
out.annotate(4, "method: " + parameterAnnotationMethods[i].getMethodString()); out.annotate(4, "method: " + parameterAnnotationMethods[i].getMethodString());
out.annotate(4, "annotations_off: 0x" + Integer.toHexString(parameterAnnotations[i].getOffset())); out.annotate(4, "annotations_off: 0x" + Integer.toHexString(parameterAnnotations[i].getOffset()));
} }
} }
} }
out.writeInt(classAnnotations==null?0:classAnnotations.getOffset()); out.writeInt(classAnnotations==null?0:classAnnotations.getOffset());
out.writeInt(fieldAnnotations==null?0:fieldAnnotations.length); out.writeInt(fieldAnnotations==null?0:fieldAnnotations.length);
out.writeInt(methodAnnotations==null?0:methodAnnotations.length); out.writeInt(methodAnnotations==null?0:methodAnnotations.length);
out.writeInt(parameterAnnotations==null?0:parameterAnnotations.length); out.writeInt(parameterAnnotations==null?0:parameterAnnotations.length);
if (fieldAnnotations != null) { if (fieldAnnotations != null) {
for (int i=0; i<fieldAnnotations.length; i++) { for (int i=0; i<fieldAnnotations.length; i++) {
out.writeInt(fieldAnnotationFields[i].getIndex()); out.writeInt(fieldAnnotationFields[i].getIndex());
out.writeInt(fieldAnnotations[i].getOffset()); out.writeInt(fieldAnnotations[i].getOffset());
} }
} }
if (methodAnnotations != null) { if (methodAnnotations != null) {
for (int i=0; i<methodAnnotations.length; i++) { for (int i=0; i<methodAnnotations.length; i++) {
out.writeInt(methodAnnotationMethods[i].getIndex()); out.writeInt(methodAnnotationMethods[i].getIndex());
out.writeInt(methodAnnotations[i].getOffset()); out.writeInt(methodAnnotations[i].getOffset());
} }
} }
if (parameterAnnotations != null) { if (parameterAnnotations != null) {
for (int i=0; i<parameterAnnotations.length; i++) { for (int i=0; i<parameterAnnotations.length; i++) {
out.writeInt(parameterAnnotationMethods[i].getIndex()); out.writeInt(parameterAnnotationMethods[i].getIndex());
out.writeInt(parameterAnnotations[i].getOffset()); out.writeInt(parameterAnnotations[i].getOffset());
} }
} }
} }
/** {@inheritDoc} */public ItemType getItemType() { /** {@inheritDoc} */public ItemType getItemType() {
return ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM; return ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "annotation_directory_item @0x" + Integer.toHexString(getOffset()); return "annotation_directory_item @0x" + Integer.toHexString(getOffset());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(AnnotationDirectoryItem o) { public int compareTo(AnnotationDirectoryItem o) {
if (!isInternable()) { if (!isInternable()) {
if (!o.isInternable()) { if (!o.isInternable()) {
return parent.compareTo(o.parent); return parent.compareTo(o.parent);
} }
return -1; return -1;
} }
if (!o.isInternable()) { if (!o.isInternable()) {
return 1; return 1;
} }
return classAnnotations.compareTo(o.classAnnotations); return classAnnotations.compareTo(o.classAnnotations);
} }
/** /**
* @return The annotations associated with the class * @return The annotations associated with the class
*/ */
public AnnotationSetItem getClassAnnotations() { public AnnotationSetItem getClassAnnotations() {
return classAnnotations; return classAnnotations;
} }
/** /**
* Iterates over the field annotations, calling delegate.processFieldAnnotations for each * Iterates over the field annotations, calling delegate.processFieldAnnotations for each
* @param delegate the delegate to call * @param delegate the delegate to call
*/ */
public void iterateFieldAnnotations(FieldAnnotationIteratorDelegate delegate) { public void iterateFieldAnnotations(FieldAnnotationIteratorDelegate delegate) {
for (int i=0; i<fieldAnnotationFields.length; i++) { for (int i=0; i<fieldAnnotationFields.length; i++) {
delegate.processFieldAnnotations(fieldAnnotationFields[i], fieldAnnotations[i]); delegate.processFieldAnnotations(fieldAnnotationFields[i], fieldAnnotations[i]);
} }
} }
public static interface FieldAnnotationIteratorDelegate { public static interface FieldAnnotationIteratorDelegate {
void processFieldAnnotations(FieldIdItem field, AnnotationSetItem fieldAnnotations); void processFieldAnnotations(FieldIdItem field, AnnotationSetItem fieldAnnotations);
} }
/** /**
* @return the number of field annotations in this <code>AnnotationDirectoryItem</code> * @return the number of field annotations in this <code>AnnotationDirectoryItem</code>
*/ */
public int getFieldAnnotationCount() { public int getFieldAnnotationCount() {
return fieldAnnotationFields.length; return fieldAnnotationFields.length;
} }
/** /**
* Iterates over the method annotations, calling delegate.processMethodAnnotations for each * Iterates over the method annotations, calling delegate.processMethodAnnotations for each
* @param delegate the delegate to call * @param delegate the delegate to call
*/ */
public void iterateMethodAnnotations(MethodAnnotationIteratorDelegate delegate) { public void iterateMethodAnnotations(MethodAnnotationIteratorDelegate delegate) {
for (int i=0; i<methodAnnotationMethods.length; i++) { for (int i=0; i<methodAnnotationMethods.length; i++) {
delegate.processMethodAnnotations(methodAnnotationMethods[i], methodAnnotations[i]); delegate.processMethodAnnotations(methodAnnotationMethods[i], methodAnnotations[i]);
} }
} }
public static interface MethodAnnotationIteratorDelegate { public static interface MethodAnnotationIteratorDelegate {
void processMethodAnnotations(MethodIdItem method, AnnotationSetItem methodAnnotations); void processMethodAnnotations(MethodIdItem method, AnnotationSetItem methodAnnotations);
} }
/** /**
* @return the number of method annotations in this <code>AnnotationDirectoryItem</code> * @return the number of method annotations in this <code>AnnotationDirectoryItem</code>
*/ */
public int getMethodAnnotationCount() { public int getMethodAnnotationCount() {
return methodAnnotationMethods.length; return methodAnnotationMethods.length;
} }
/** /**
* Iterates over the parameter annotations, calling delegate.processParameterAnnotations for each * Iterates over the parameter annotations, calling delegate.processParameterAnnotations for each
* @param delegate the delegate to call * @param delegate the delegate to call
*/ */
public void iterateParameterAnnotations(ParameterAnnotationIteratorDelegate delegate) { public void iterateParameterAnnotations(ParameterAnnotationIteratorDelegate delegate) {
for (int i=0; i<parameterAnnotationMethods.length; i++) { for (int i=0; i<parameterAnnotationMethods.length; i++) {
delegate.processParameterAnnotations(parameterAnnotationMethods[i], parameterAnnotations[i]); delegate.processParameterAnnotations(parameterAnnotationMethods[i], parameterAnnotations[i]);
} }
} }
public static interface ParameterAnnotationIteratorDelegate { public static interface ParameterAnnotationIteratorDelegate {
void processParameterAnnotations(MethodIdItem method, AnnotationSetRefList parameterAnnotations); void processParameterAnnotations(MethodIdItem method, AnnotationSetRefList parameterAnnotations);
} }
/** /**
* @return the number of parameter annotations in this <code>AnnotationDirectoryItem</code> * @return the number of parameter annotations in this <code>AnnotationDirectoryItem</code>
*/ */
public int getParameterAnnotationCount() { public int getParameterAnnotationCount() {
return parameterAnnotationMethods.length; return parameterAnnotationMethods.length;
} }
/** /**
* @return true if this <code>AnnotationDirectoryItem</code> is internable. It is only internable if it has * @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 * only class annotations, but no field, method or parameter annotations
*/ */
private boolean isInternable() { private boolean isInternable() {
return classAnnotations != null && return classAnnotations != null &&
(fieldAnnotations == null || fieldAnnotations.length == 0) && (fieldAnnotations == null || fieldAnnotations.length == 0) &&
(methodAnnotations == null || methodAnnotations.length == 0) && (methodAnnotations == null || methodAnnotations.length == 0) &&
(parameterAnnotations == null || parameterAnnotations.length == 0); (parameterAnnotations == null || parameterAnnotations.length == 0);
} }
/** /**
* Sets the <code>ClassDefItem</code> that this <code>AnnotationDirectoryItem</code> is associated with. * 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 * This is only applicable if this AnnotationDirectoryItem contains only class annotations, and no field, method
* or parameter annotations. * or parameter annotations.
* @param classDefItem the <code>ClassDefItem</code> that this <code>AnnotationDirectoryItem</code> is associated * @param classDefItem the <code>ClassDefItem</code> that this <code>AnnotationDirectoryItem</code> is associated
* with * with
*/ */
protected void setParent(ClassDefItem classDefItem) { protected void setParent(ClassDefItem classDefItem) {
this.parent = classDefItem; this.parent = classDefItem;
} }
@Override @Override
public int hashCode() { public int hashCode() {
//an instance is only internable if it has only class annotations, but //an instance is only internable if it has only class annotations, but
//no other type of annotation //no other type of annotation
if (!isInternable()) { if (!isInternable()) {
return super.hashCode(); return super.hashCode();
} }
return classAnnotations.hashCode(); return classAnnotations.hashCode();
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this==o) { if (this==o) {
return true; return true;
} }
if (o==null || !this.getClass().equals(o.getClass())) { if (o==null || !this.getClass().equals(o.getClass())) {
return false; return false;
} }
AnnotationDirectoryItem other = (AnnotationDirectoryItem)o; AnnotationDirectoryItem other = (AnnotationDirectoryItem)o;
return (this.compareTo(other) == 0); return (this.compareTo(other) == 0);
} }
public static class FieldAnnotation implements Comparable<FieldAnnotation> { public static class FieldAnnotation implements Comparable<FieldAnnotation> {
public final FieldIdItem field; public final FieldIdItem field;
public final AnnotationSetItem annotationSet; public final AnnotationSetItem annotationSet;
public FieldAnnotation(FieldIdItem field, AnnotationSetItem annotationSet) { public FieldAnnotation(FieldIdItem field, AnnotationSetItem annotationSet) {
this.field = field; this.field = field;
this.annotationSet = annotationSet; this.annotationSet = annotationSet;
} }
public int compareTo(FieldAnnotation other) { public int compareTo(FieldAnnotation other) {
return field.compareTo(other.field); return field.compareTo(other.field);
} }
} }
public static class MethodAnnotation implements Comparable<MethodAnnotation> { public static class MethodAnnotation implements Comparable<MethodAnnotation> {
public final MethodIdItem method; public final MethodIdItem method;
public final AnnotationSetItem annotationSet; public final AnnotationSetItem annotationSet;
public MethodAnnotation(MethodIdItem method, AnnotationSetItem annotationSet) { public MethodAnnotation(MethodIdItem method, AnnotationSetItem annotationSet) {
this.method = method; this.method = method;
this.annotationSet = annotationSet; this.annotationSet = annotationSet;
} }
public int compareTo(MethodAnnotation other) { public int compareTo(MethodAnnotation other) {
return method.compareTo(other.method); return method.compareTo(other.method);
} }
} }
public static class ParameterAnnotation implements Comparable<ParameterAnnotation> { public static class ParameterAnnotation implements Comparable<ParameterAnnotation> {
public final MethodIdItem method; public final MethodIdItem method;
public final AnnotationSetRefList annotationSet; public final AnnotationSetRefList annotationSet;
public ParameterAnnotation(MethodIdItem method, AnnotationSetRefList annotationSet) { public ParameterAnnotation(MethodIdItem method, AnnotationSetRefList annotationSet) {
this.method = method; this.method = method;
this.annotationSet = annotationSet; this.annotationSet = annotationSet;
} }
public int compareTo(ParameterAnnotation other) { public int compareTo(ParameterAnnotation other) {
return method.compareTo(other.method); return method.compareTo(other.method);
} }
} }
} }

View File

@ -1,162 +1,162 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.EncodedValue.AnnotationEncodedSubValue; import org.jf.dexlib.EncodedValue.AnnotationEncodedSubValue;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
public class AnnotationItem extends Item<AnnotationItem> { public class AnnotationItem extends Item<AnnotationItem> {
private int hashCode = 0; private int hashCode = 0;
private AnnotationVisibility visibility; private AnnotationVisibility visibility;
private AnnotationEncodedSubValue annotationValue; private AnnotationEncodedSubValue annotationValue;
/** /**
* Creates a new uninitialized <code>AnnotationItem</code> * Creates a new uninitialized <code>AnnotationItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected AnnotationItem(DexFile dexFile) { protected AnnotationItem(DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** /**
* Creates a new <code>AnnotationItem</code> with the given values * Creates a new <code>AnnotationItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param visibility The visibility of this annotation * @param visibility The visibility of this annotation
* @param annotationValue The value of this annotation * @param annotationValue The value of this annotation
*/ */
private AnnotationItem(DexFile dexFile, AnnotationVisibility visibility, private AnnotationItem(DexFile dexFile, AnnotationVisibility visibility,
AnnotationEncodedSubValue annotationValue) { AnnotationEncodedSubValue annotationValue) {
super(dexFile); super(dexFile);
this.visibility = visibility; this.visibility = visibility;
this.annotationValue = annotationValue; this.annotationValue = annotationValue;
} }
/** /**
* Returns an <code>AnnotationItem</code> for the given values, and that has been interned into the given * Returns an <code>AnnotationItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code> * <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param visibility The visibility of this annotation * @param visibility The visibility of this annotation
* @param annotationValue The value 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 * @return an <code>AnnotationItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code> * <code>DexFile</code>
*/ */
public static AnnotationItem getInternedAnnotationItem(DexFile dexFile, AnnotationVisibility visibility, public static AnnotationItem getInternedAnnotationItem(DexFile dexFile, AnnotationVisibility visibility,
AnnotationEncodedSubValue annotationValue) { AnnotationEncodedSubValue annotationValue) {
AnnotationItem annotationItem = new AnnotationItem(dexFile, visibility, annotationValue); AnnotationItem annotationItem = new AnnotationItem(dexFile, visibility, annotationValue);
return dexFile.AnnotationsSection.intern(annotationItem); return dexFile.AnnotationsSection.intern(annotationItem);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
visibility = AnnotationVisibility.fromByte(in.readByte()); visibility = AnnotationVisibility.fromByte(in.readByte());
annotationValue = new AnnotationEncodedSubValue(dexFile, in); annotationValue = new AnnotationEncodedSubValue(dexFile, in);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return annotationValue.placeValue(offset + 1); return annotationValue.placeValue(offset + 1);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate("visibility: " + visibility.name()); out.annotate("visibility: " + visibility.name());
out.writeByte(visibility.value); out.writeByte(visibility.value);
annotationValue.writeValue(out); annotationValue.writeValue(out);
}else { }else {
out.writeByte(visibility.value); out.writeByte(visibility.value);
annotationValue.writeValue(out); annotationValue.writeValue(out);
} }
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_ANNOTATION_ITEM; return ItemType.TYPE_ANNOTATION_ITEM;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "annotation_item @0x" + Integer.toHexString(getOffset()); return "annotation_item @0x" + Integer.toHexString(getOffset());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(AnnotationItem o) { public int compareTo(AnnotationItem o) {
int comp = visibility.value - o.visibility.value; int comp = visibility.value - o.visibility.value;
if (comp == 0) { if (comp == 0) {
comp = annotationValue.compareTo(o.annotationValue); comp = annotationValue.compareTo(o.annotationValue);
} }
return comp; return comp;
} }
/** /**
* @return The visibility of this annotation * @return The visibility of this annotation
*/ */
public AnnotationVisibility getVisibility() { public AnnotationVisibility getVisibility() {
return visibility; return visibility;
} }
/** /**
* @return The encoded annotation value of this annotation * @return The encoded annotation value of this annotation
*/ */
public AnnotationEncodedSubValue getEncodedAnnotation() { public AnnotationEncodedSubValue getEncodedAnnotation() {
return annotationValue; return annotationValue;
} }
/** /**
* calculate and cache the hashcode * calculate and cache the hashcode
*/ */
private void calcHashCode() { private void calcHashCode() {
hashCode = visibility.value; hashCode = visibility.value;
hashCode = hashCode * 31 + annotationValue.hashCode(); hashCode = hashCode * 31 + annotationValue.hashCode();
} }
@Override @Override
public int hashCode() { public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll //there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time //just end up recalculating it each time
if (hashCode == 0) if (hashCode == 0)
calcHashCode(); calcHashCode();
return hashCode; return hashCode;
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this==o) { if (this==o) {
return true; return true;
} }
if (o==null || !this.getClass().equals(o.getClass())) { if (o==null || !this.getClass().equals(o.getClass())) {
return false; return false;
} }
AnnotationItem other = (AnnotationItem)o; AnnotationItem other = (AnnotationItem)o;
return visibility == other.visibility && annotationValue.equals(other.annotationValue); return visibility == other.visibility && annotationValue.equals(other.annotationValue);
} }
} }

View File

@ -1,169 +1,169 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
import java.util.List; import java.util.List;
public class AnnotationSetItem extends Item<AnnotationSetItem> { public class AnnotationSetItem extends Item<AnnotationSetItem> {
private int hashCode = 0; private int hashCode = 0;
private AnnotationItem[] annotations; private AnnotationItem[] annotations;
/** /**
* Creates a new uninitialized <code>AnnotationSetItem</code> * Creates a new uninitialized <code>AnnotationSetItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected AnnotationSetItem(DexFile dexFile) { protected AnnotationSetItem(DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** /**
* Creates a new <code>AnnotationSetItem</code> for the given annotations * Creates a new <code>AnnotationSetItem</code> for the given annotations
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param annotations The annotations for this <code>AnnotationSetItem</code> * @param annotations The annotations for this <code>AnnotationSetItem</code>
*/ */
private AnnotationSetItem(DexFile dexFile, AnnotationItem[] annotations) { private AnnotationSetItem(DexFile dexFile, AnnotationItem[] annotations) {
super(dexFile); super(dexFile);
this.annotations = annotations; this.annotations = annotations;
} }
/** /**
* Returns an <code>AnnotationSetItem</code> for the given annotations, and that has been interned into the given * Returns an <code>AnnotationSetItem</code> for the given annotations, and that has been interned into the given
* <code>DexFile</code> * <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param annotations The annotations for this <code>AnnotationSetItem</code> * @param annotations The annotations for this <code>AnnotationSetItem</code>
* @return an <code>AnnotationSetItem</code> for the given annotations * @return an <code>AnnotationSetItem</code> for the given annotations
*/ */
public static AnnotationSetItem getInternedAnnotationSetItem(DexFile dexFile, List<AnnotationItem> annotations) { public static AnnotationSetItem getInternedAnnotationSetItem(DexFile dexFile, List<AnnotationItem> annotations) {
AnnotationItem[] annotationsArray = new AnnotationItem[annotations.size()]; AnnotationItem[] annotationsArray = new AnnotationItem[annotations.size()];
annotations.toArray(annotationsArray); annotations.toArray(annotationsArray);
AnnotationSetItem annotationSetItem = new AnnotationSetItem(dexFile, annotationsArray); AnnotationSetItem annotationSetItem = new AnnotationSetItem(dexFile, annotationsArray);
return dexFile.AnnotationSetsSection.intern(annotationSetItem); return dexFile.AnnotationSetsSection.intern(annotationSetItem);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
annotations = new AnnotationItem[in.readInt()]; annotations = new AnnotationItem[in.readInt()];
for (int i=0; i<annotations.length; i++) { for (int i=0; i<annotations.length; i++) {
annotations[i] = (AnnotationItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_ANNOTATION_ITEM, annotations[i] = (AnnotationItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_ANNOTATION_ITEM,
in.readInt()); in.readInt());
} }
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return offset + 4 + annotations.length * 4; return offset + 4 + annotations.length * 4;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(4, "size: 0x" + Integer.toHexString(annotations.length) + " (" + annotations.length + ")"); out.annotate(4, "size: 0x" + Integer.toHexString(annotations.length) + " (" + annotations.length + ")");
for (AnnotationItem annotationItem: annotations) { for (AnnotationItem annotationItem: annotations) {
out.annotate(4, "annotation_off: 0x" + Integer.toHexString(annotationItem.getOffset()) + " - " + out.annotate(4, "annotation_off: 0x" + Integer.toHexString(annotationItem.getOffset()) + " - " +
annotationItem.getEncodedAnnotation().annotationType.getTypeDescriptor()); annotationItem.getEncodedAnnotation().annotationType.getTypeDescriptor());
} }
} }
out.writeInt(annotations.length); out.writeInt(annotations.length);
for (AnnotationItem annotationItem: annotations) { for (AnnotationItem annotationItem: annotations) {
out.writeInt(annotationItem.getOffset()); out.writeInt(annotationItem.getOffset());
} }
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_ANNOTATION_SET_ITEM; return ItemType.TYPE_ANNOTATION_SET_ITEM;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "annotation_set_item @0x" + Integer.toHexString(getOffset()); return "annotation_set_item @0x" + Integer.toHexString(getOffset());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(AnnotationSetItem o) { public int compareTo(AnnotationSetItem o) {
if (o == null) { if (o == null) {
return 1; return 1;
} }
int comp = annotations.length - o.annotations.length; int comp = annotations.length - o.annotations.length;
if (comp == 0) { if (comp == 0) {
for (int i=0; i<annotations.length; i++) { for (int i=0; i<annotations.length; i++) {
comp = annotations[i].compareTo(o.annotations[i]); comp = annotations[i].compareTo(o.annotations[i]);
if (comp != 0) { if (comp != 0) {
return comp; return comp;
} }
} }
} }
return comp; return comp;
} }
/** /**
* @return An array of the <code>AnnotationItem</code> objects in this <code>AnnotationSetItem</code> * @return An array of the <code>AnnotationItem</code> objects in this <code>AnnotationSetItem</code>
*/ */
public AnnotationItem[] getAnnotations() { public AnnotationItem[] getAnnotations() {
return annotations; return annotations;
} }
/** /**
* calculate and cache the hashcode * calculate and cache the hashcode
*/ */
private void calcHashCode() { private void calcHashCode() {
hashCode = 0; hashCode = 0;
for (AnnotationItem annotationItem: annotations) { for (AnnotationItem annotationItem: annotations) {
hashCode = hashCode * 31 + annotationItem.hashCode(); hashCode = hashCode * 31 + annotationItem.hashCode();
} }
} }
@Override @Override
public int hashCode() { public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll //there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time //just end up recalculating it each time
if (hashCode == 0) if (hashCode == 0)
calcHashCode(); calcHashCode();
return hashCode; return hashCode;
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this==o) { if (this==o) {
return true; return true;
} }
if (o==null || !this.getClass().equals(o.getClass())) { if (o==null || !this.getClass().equals(o.getClass())) {
return false; return false;
} }
AnnotationSetItem other = (AnnotationSetItem)o; AnnotationSetItem other = (AnnotationSetItem)o;
return (this.compareTo(other) == 0); return (this.compareTo(other) == 0);
} }
} }

View File

@ -1,170 +1,170 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
import java.util.List; import java.util.List;
public class AnnotationSetRefList extends Item<AnnotationSetRefList> { public class AnnotationSetRefList extends Item<AnnotationSetRefList> {
private int hashCode = 0; private int hashCode = 0;
private AnnotationSetItem[] annotationSets; private AnnotationSetItem[] annotationSets;
/** /**
* Creates a new uninitialized <code>AnnotationSetRefList</code> * Creates a new uninitialized <code>AnnotationSetRefList</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected AnnotationSetRefList(DexFile dexFile) { protected AnnotationSetRefList(DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** /**
* Creates a new <code>AnnotationSetRefList</code> for the given annotation sets * Creates a new <code>AnnotationSetRefList</code> for the given annotation sets
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param annotationSets The annotationSets for this <code>AnnotationSetRefList</code> * @param annotationSets The annotationSets for this <code>AnnotationSetRefList</code>
*/ */
private AnnotationSetRefList(DexFile dexFile, AnnotationSetItem[] annotationSets) { private AnnotationSetRefList(DexFile dexFile, AnnotationSetItem[] annotationSets) {
super(dexFile); super(dexFile);
this.annotationSets = annotationSets; this.annotationSets = annotationSets;
} }
/** /**
* Returns an <code>AnnotationSetRefList</code> for the given annotation sets, and that has been interned into the * Returns an <code>AnnotationSetRefList</code> for the given annotation sets, and that has been interned into the
* given <code>DexFile</code> * given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param annotationSets The annotation sets for this <code>AnnotationSetRefList</code> * @param annotationSets The annotation sets for this <code>AnnotationSetRefList</code>
* @return an <code>AnnotationSetItem</code> for the given annotations * @return an <code>AnnotationSetItem</code> for the given annotations
*/ */
public static AnnotationSetRefList getInternedAnnotationSetRefList(DexFile dexFile, public static AnnotationSetRefList getInternedAnnotationSetRefList(DexFile dexFile,
List<AnnotationSetItem> annotationSets) { List<AnnotationSetItem> annotationSets) {
AnnotationSetItem[] annotationSetsArray = new AnnotationSetItem[annotationSets.size()]; AnnotationSetItem[] annotationSetsArray = new AnnotationSetItem[annotationSets.size()];
annotationSets.toArray(annotationSetsArray); annotationSets.toArray(annotationSetsArray);
AnnotationSetRefList annotationSetRefList = new AnnotationSetRefList(dexFile, annotationSetsArray); AnnotationSetRefList annotationSetRefList = new AnnotationSetRefList(dexFile, annotationSetsArray);
return dexFile.AnnotationSetRefListsSection.intern(annotationSetRefList); return dexFile.AnnotationSetRefListsSection.intern(annotationSetRefList);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
annotationSets = new AnnotationSetItem[in.readInt()]; annotationSets = new AnnotationSetItem[in.readInt()];
for (int i=0; i<annotationSets.length; i++) { for (int i=0; i<annotationSets.length; i++) {
annotationSets[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset( annotationSets[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt()); ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
} }
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return offset + 4 + annotationSets.length * 4; return offset + 4 + annotationSets.length * 4;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(4, "size: 0x" + Integer.toHexString(annotationSets.length) + " (" + annotationSets.length + out.annotate(4, "size: 0x" + Integer.toHexString(annotationSets.length) + " (" + annotationSets.length +
")"); ")");
for (AnnotationSetItem annotationSetItem: annotationSets) { for (AnnotationSetItem annotationSetItem: annotationSets) {
out.annotate(4, "annotation_set_off: 0x" + Integer.toHexString(annotationSetItem.getOffset())); out.annotate(4, "annotation_set_off: 0x" + Integer.toHexString(annotationSetItem.getOffset()));
} }
} }
out.writeInt(annotationSets.length); out.writeInt(annotationSets.length);
for (AnnotationSetItem annotationSetItem: annotationSets) { for (AnnotationSetItem annotationSetItem: annotationSets) {
out.writeInt(annotationSetItem.getOffset()); out.writeInt(annotationSetItem.getOffset());
} }
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_ANNOTATION_SET_REF_LIST; return ItemType.TYPE_ANNOTATION_SET_REF_LIST;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "annotation_set_item @0x" + Integer.toHexString(getOffset()); return "annotation_set_item @0x" + Integer.toHexString(getOffset());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(AnnotationSetRefList o) { public int compareTo(AnnotationSetRefList o) {
int comp = annotationSets.length - o.annotationSets.length; int comp = annotationSets.length - o.annotationSets.length;
if (comp != 0) { if (comp != 0) {
return comp; return comp;
} }
for (int i=0; i<annotationSets.length; i++) { for (int i=0; i<annotationSets.length; i++) {
comp = annotationSets[i].compareTo(o.annotationSets[i]); comp = annotationSets[i].compareTo(o.annotationSets[i]);
if (comp != 0) { if (comp != 0) {
return comp; return comp;
} }
} }
return comp; return comp;
} }
/** /**
* @return An array of the <code>AnnotationSetItem</code> objects that make up this * @return An array of the <code>AnnotationSetItem</code> objects that make up this
* <code>AnnotationSetRefList</code> * <code>AnnotationSetRefList</code>
*/ */
public AnnotationSetItem[] getAnnotationSets() { public AnnotationSetItem[] getAnnotationSets() {
return annotationSets; return annotationSets;
} }
/** /**
* calculate and cache the hashcode * calculate and cache the hashcode
*/ */
private void calcHashCode() { private void calcHashCode() {
hashCode = 0; hashCode = 0;
for (AnnotationSetItem annotationSetItem: annotationSets) { for (AnnotationSetItem annotationSetItem: annotationSets) {
hashCode = hashCode * 31 + annotationSetItem.hashCode(); hashCode = hashCode * 31 + annotationSetItem.hashCode();
} }
} }
@Override @Override
public int hashCode() { public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll //there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time //just end up recalculating it each time
if (hashCode == 0) if (hashCode == 0)
calcHashCode(); calcHashCode();
return hashCode; return hashCode;
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this==o) { if (this==o) {
return true; return true;
} }
if (o==null || !this.getClass().equals(o.getClass())) { if (o==null || !this.getClass().equals(o.getClass())) {
return false; return false;
} }
AnnotationSetRefList other = (AnnotationSetRefList)o; AnnotationSetRefList other = (AnnotationSetRefList)o;
return (this.compareTo(other) == 0); return (this.compareTo(other) == 0);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,377 +1,377 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.AccessFlags; import org.jf.dexlib.Util.AccessFlags;
import org.jf.dexlib.Util.TypeUtils; import org.jf.dexlib.Util.TypeUtils;
import org.jf.dexlib.EncodedValue.EncodedValue; import org.jf.dexlib.EncodedValue.EncodedValue;
import org.jf.dexlib.EncodedValue.ArrayEncodedSubValue; import org.jf.dexlib.EncodedValue.ArrayEncodedSubValue;
import java.util.*; import java.util.*;
public class ClassDefItem extends Item<ClassDefItem> { public class ClassDefItem extends Item<ClassDefItem> {
private TypeIdItem classType; private TypeIdItem classType;
private int accessFlags; private int accessFlags;
private TypeIdItem superType; private TypeIdItem superType;
private TypeListItem implementedInterfaces; private TypeListItem implementedInterfaces;
private StringIdItem sourceFile; private StringIdItem sourceFile;
private AnnotationDirectoryItem annotations; private AnnotationDirectoryItem annotations;
private ClassDataItem classData; private ClassDataItem classData;
private EncodedArrayItem staticFieldInitializers; private EncodedArrayItem staticFieldInitializers;
/** /**
* Creates a new uninitialized <code>ClassDefItem</code> * Creates a new uninitialized <code>ClassDefItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected ClassDefItem(DexFile dexFile) { protected ClassDefItem(DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** /**
* Creates a new <code>ClassDefItem</code> with the given values * Creates a new <code>ClassDefItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType The type of this class * @param classType The type of this class
* @param accessFlags The access flags 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 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 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 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 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 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 * @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 * 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 * 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 * 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. * type-appropriate null/0 encoded value, or null.
*/ */
private ClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags, TypeIdItem superType, private ClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags, TypeIdItem superType,
TypeListItem implementedInterfaces, StringIdItem sourceFile, TypeListItem implementedInterfaces, StringIdItem sourceFile,
AnnotationDirectoryItem annotations, ClassDataItem classData, AnnotationDirectoryItem annotations, ClassDataItem classData,
EncodedArrayItem staticFieldInitializers) { EncodedArrayItem staticFieldInitializers) {
super(dexFile); super(dexFile);
this.classType = classType; this.classType = classType;
this.accessFlags = accessFlags; this.accessFlags = accessFlags;
this.superType = superType; this.superType = superType;
this.implementedInterfaces = implementedInterfaces; this.implementedInterfaces = implementedInterfaces;
this.sourceFile = sourceFile; this.sourceFile = sourceFile;
this.annotations = annotations; this.annotations = annotations;
this.classData = classData; this.classData = classData;
this.staticFieldInitializers = staticFieldInitializers; this.staticFieldInitializers = staticFieldInitializers;
if (classData != null) { if (classData != null) {
classData.setParent(this); classData.setParent(this);
} }
if (annotations != null) { if (annotations != null) {
annotations.setParent(this); annotations.setParent(this);
} }
} }
/** /**
* Returns a <code>ClassDefItem</code> for the given values, and that has been interned into the given * Returns a <code>ClassDefItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code> * <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType The type of this class * @param classType The type of this class
* @param accessFlags The access flags 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 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 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 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 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 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 * @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 * 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 * <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. * 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 * @return a <code>ClassDefItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code> * <code>DexFile</code>
*/ */
public static ClassDefItem getInternedClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags, public static ClassDefItem getInternedClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags,
TypeIdItem superType, TypeListItem implementedInterfaces, StringIdItem sourceFile, TypeIdItem superType, TypeListItem implementedInterfaces, StringIdItem sourceFile,
AnnotationDirectoryItem annotations, ClassDataItem classData, AnnotationDirectoryItem annotations, ClassDataItem classData,
List<StaticFieldInitializer> staticFieldInitializers) { List<StaticFieldInitializer> staticFieldInitializers) {
EncodedArrayItem encodedArrayItem = null; EncodedArrayItem encodedArrayItem = null;
if(!dexFile.getInplace() && staticFieldInitializers != null && staticFieldInitializers.size() > 0) { if(!dexFile.getInplace() && staticFieldInitializers != null && staticFieldInitializers.size() > 0) {
assert classData != null; assert classData != null;
assert staticFieldInitializers.size() == classData.getStaticFields().length; assert staticFieldInitializers.size() == classData.getStaticFields().length;
encodedArrayItem = makeStaticFieldInitializersItem(dexFile, staticFieldInitializers); encodedArrayItem = makeStaticFieldInitializersItem(dexFile, staticFieldInitializers);
} }
ClassDefItem classDefItem = new ClassDefItem(dexFile, classType, accessFlags, superType, implementedInterfaces, ClassDefItem classDefItem = new ClassDefItem(dexFile, classType, accessFlags, superType, implementedInterfaces,
sourceFile, annotations, classData, encodedArrayItem); sourceFile, annotations, classData, encodedArrayItem);
return dexFile.ClassDefsSection.intern(classDefItem); return dexFile.ClassDefsSection.intern(classDefItem);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
classType = dexFile.TypeIdsSection.getItemByIndex(in.readInt()); classType = dexFile.TypeIdsSection.getItemByIndex(in.readInt());
accessFlags = in.readInt(); accessFlags = in.readInt();
superType = dexFile.TypeIdsSection.getItemByIndex(in.readInt()); superType = dexFile.TypeIdsSection.getItemByIndex(in.readInt());
implementedInterfaces = (TypeListItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_TYPE_LIST, implementedInterfaces = (TypeListItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_TYPE_LIST,
in.readInt()); in.readInt());
sourceFile = dexFile.StringIdsSection.getItemByIndex(in.readInt()); sourceFile = dexFile.StringIdsSection.getItemByIndex(in.readInt());
annotations = (AnnotationDirectoryItem)readContext.getOffsettedItemByOffset( annotations = (AnnotationDirectoryItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM, in.readInt()); ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM, in.readInt());
classData = (ClassDataItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_CLASS_DATA_ITEM, in.readInt()); classData = (ClassDataItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_CLASS_DATA_ITEM, in.readInt());
staticFieldInitializers = (EncodedArrayItem)readContext.getOffsettedItemByOffset( staticFieldInitializers = (EncodedArrayItem)readContext.getOffsettedItemByOffset(
ItemType.TYPE_ENCODED_ARRAY_ITEM, in.readInt()); ItemType.TYPE_ENCODED_ARRAY_ITEM, in.readInt());
if (classData != null) { if (classData != null) {
classData.setParent(this); classData.setParent(this);
} }
if (annotations != null) { if (annotations != null) {
annotations.setParent(this); annotations.setParent(this);
} }
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return offset + 32; return offset + 32;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(4, "class_type: " + classType.getTypeDescriptor()); out.annotate(4, "class_type: " + classType.getTypeDescriptor());
out.annotate(4, "access_flags: " + AccessFlags.formatAccessFlagsForClass(accessFlags)); out.annotate(4, "access_flags: " + AccessFlags.formatAccessFlagsForClass(accessFlags));
out.annotate(4, "superclass_type: " + (superType==null?"":superType.getTypeDescriptor())); out.annotate(4, "superclass_type: " + (superType==null?"":superType.getTypeDescriptor()));
out.annotate(4, "interfaces: " + out.annotate(4, "interfaces: " +
(implementedInterfaces==null?"":implementedInterfaces.getTypeListString(" "))); (implementedInterfaces==null?"":implementedInterfaces.getTypeListString(" ")));
out.annotate(4, "source_file: " + (sourceFile==null?"":sourceFile.getStringValue())); out.annotate(4, "source_file: " + (sourceFile==null?"":sourceFile.getStringValue()));
out.annotate(4, "annotations_off: " + out.annotate(4, "annotations_off: " +
(annotations==null?"":"0x"+Integer.toHexString(annotations.getOffset()))); (annotations==null?"":"0x"+Integer.toHexString(annotations.getOffset())));
out.annotate(4, "class_data_off:" + out.annotate(4, "class_data_off:" +
(classData==null?"":"0x"+Integer.toHexString(classData.getOffset()))); (classData==null?"":"0x"+Integer.toHexString(classData.getOffset())));
out.annotate(4, "static_values_off: " + out.annotate(4, "static_values_off: " +
(staticFieldInitializers==null?"":"0x"+Integer.toHexString(staticFieldInitializers.getOffset()))); (staticFieldInitializers==null?"":"0x"+Integer.toHexString(staticFieldInitializers.getOffset())));
} }
out.writeInt(classType.getIndex()); out.writeInt(classType.getIndex());
out.writeInt(accessFlags); out.writeInt(accessFlags);
out.writeInt(superType==null?-1:superType.getIndex()); out.writeInt(superType==null?-1:superType.getIndex());
out.writeInt(implementedInterfaces==null?0:implementedInterfaces.getOffset()); out.writeInt(implementedInterfaces==null?0:implementedInterfaces.getOffset());
out.writeInt(sourceFile==null?-1:sourceFile.getIndex()); out.writeInt(sourceFile==null?-1:sourceFile.getIndex());
out.writeInt(annotations==null?0:annotations.getOffset()); out.writeInt(annotations==null?0:annotations.getOffset());
out.writeInt(classData==null?0:classData.getOffset()); out.writeInt(classData==null?0:classData.getOffset());
out.writeInt(staticFieldInitializers==null?0:staticFieldInitializers.getOffset()); out.writeInt(staticFieldInitializers==null?0:staticFieldInitializers.getOffset());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_CLASS_DEF_ITEM; return ItemType.TYPE_CLASS_DEF_ITEM;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "class_def_item: " + classType.getTypeDescriptor(); return "class_def_item: " + classType.getTypeDescriptor();
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(ClassDefItem o) { public int compareTo(ClassDefItem o) {
//The actual sorting for this class is implemented in SortClassDefItemSection. //The actual sorting for this class is implemented in SortClassDefItemSection.
//This method is just used for sorting the associated ClassDataItem items, so //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 //we can just do the comparison based on the offsets of the items
return this.getOffset() - o.getOffset(); return this.getOffset() - o.getOffset();
} }
public TypeIdItem getClassType() { public TypeIdItem getClassType() {
return classType; return classType;
} }
public int getAccessFlags() { public int getAccessFlags() {
return accessFlags; return accessFlags;
} }
public TypeIdItem getSuperclass() { public TypeIdItem getSuperclass() {
return superType; return superType;
} }
public TypeListItem getInterfaces() { public TypeListItem getInterfaces() {
return implementedInterfaces; return implementedInterfaces;
} }
public StringIdItem getSourceFile() { public StringIdItem getSourceFile() {
return sourceFile; return sourceFile;
} }
public AnnotationDirectoryItem getAnnotations() { public AnnotationDirectoryItem getAnnotations() {
return annotations; return annotations;
} }
public ClassDataItem getClassData() { public ClassDataItem getClassData() {
return classData; return classData;
} }
public EncodedArrayItem getStaticFieldInitializers() { public EncodedArrayItem getStaticFieldInitializers() {
return staticFieldInitializers; return staticFieldInitializers;
} }
public static int placeClassDefItems(IndexedSection<ClassDefItem> section, int offset) { public static int placeClassDefItems(IndexedSection<ClassDefItem> section, int offset) {
ClassDefPlacer cdp = new ClassDefPlacer(section); ClassDefPlacer cdp = new ClassDefPlacer(section);
return cdp.placeSection(offset); return cdp.placeSection(offset);
} }
/** /**
* This class places the items within a ClassDefItem section, such that superclasses and interfaces are * This class places the items within a ClassDefItem section, such that superclasses and interfaces are
* placed before sub/implementing classes * placed before sub/implementing classes
*/ */
private static class ClassDefPlacer { private static class ClassDefPlacer {
private final IndexedSection<ClassDefItem> section; private final IndexedSection<ClassDefItem> section;
private final HashMap<TypeIdItem, ClassDefItem> unplacedClassDefsByType = private final HashMap<TypeIdItem, ClassDefItem> unplacedClassDefsByType =
new HashMap<TypeIdItem, ClassDefItem>(); new HashMap<TypeIdItem, ClassDefItem>();
private int currentIndex = 0; private int currentIndex = 0;
private int currentOffset; private int currentOffset;
public ClassDefPlacer(IndexedSection<ClassDefItem> section) { public ClassDefPlacer(IndexedSection<ClassDefItem> section) {
this.section = section; this.section = section;
for (ClassDefItem classDefItem: section.items) { for (ClassDefItem classDefItem: section.items) {
TypeIdItem typeIdItem = classDefItem.classType; TypeIdItem typeIdItem = classDefItem.classType;
unplacedClassDefsByType.put(typeIdItem, classDefItem); unplacedClassDefsByType.put(typeIdItem, classDefItem);
} }
} }
public int placeSection(int offset) { public int placeSection(int offset) {
currentOffset = offset; currentOffset = offset;
if (section.DexFile.getSortAllItems()) { if (section.DexFile.getSortAllItems()) {
//presort the list, to guarantee a unique ordering //presort the list, to guarantee a unique ordering
Collections.sort(section.items, new Comparator<ClassDefItem>() { Collections.sort(section.items, new Comparator<ClassDefItem>() {
public int compare(ClassDefItem a, ClassDefItem b) { public int compare(ClassDefItem a, ClassDefItem b) {
return a.getClassType().compareTo(b.getClassType()); return a.getClassType().compareTo(b.getClassType());
} }
}); });
} }
//we need to initialize the offset for all the classes to -1, so we can tell which ones //we need to initialize the offset for all the classes to -1, so we can tell which ones
//have been placed //have been placed
for (ClassDefItem classDefItem: section.items) { for (ClassDefItem classDefItem: section.items) {
classDefItem.offset = -1; classDefItem.offset = -1;
} }
for (ClassDefItem classDefItem: section.items) { for (ClassDefItem classDefItem: section.items) {
placeClass(classDefItem); placeClass(classDefItem);
} }
for (ClassDefItem classDefItem: unplacedClassDefsByType.values()) { for (ClassDefItem classDefItem: unplacedClassDefsByType.values()) {
section.items.set(classDefItem.getIndex(), classDefItem); section.items.set(classDefItem.getIndex(), classDefItem);
} }
return currentOffset; return currentOffset;
} }
private void placeClass(ClassDefItem classDefItem) { private void placeClass(ClassDefItem classDefItem) {
if (classDefItem.getOffset() == -1) { if (classDefItem.getOffset() == -1) {
TypeIdItem superType = classDefItem.superType; TypeIdItem superType = classDefItem.superType;
ClassDefItem superClassDefItem = unplacedClassDefsByType.get(superType); ClassDefItem superClassDefItem = unplacedClassDefsByType.get(superType);
if (superClassDefItem != null) { if (superClassDefItem != null) {
placeClass(superClassDefItem); placeClass(superClassDefItem);
} }
TypeListItem interfaces = classDefItem.implementedInterfaces; TypeListItem interfaces = classDefItem.implementedInterfaces;
if (interfaces != null) { if (interfaces != null) {
for (TypeIdItem interfaceType: interfaces.getTypes()) { for (TypeIdItem interfaceType: interfaces.getTypes()) {
ClassDefItem interfaceClass = unplacedClassDefsByType.get(interfaceType); ClassDefItem interfaceClass = unplacedClassDefsByType.get(interfaceType);
if (interfaceClass != null) { if (interfaceClass != null) {
placeClass(interfaceClass); placeClass(interfaceClass);
} }
} }
} }
currentOffset = classDefItem.placeAt(currentOffset, currentIndex++); currentOffset = classDefItem.placeAt(currentOffset, currentIndex++);
unplacedClassDefsByType.remove(classDefItem.classType); unplacedClassDefsByType.remove(classDefItem.classType);
} }
} }
} }
public static class StaticFieldInitializer implements Comparable<StaticFieldInitializer> { public static class StaticFieldInitializer implements Comparable<StaticFieldInitializer> {
public final EncodedValue value; public final EncodedValue value;
public final ClassDataItem.EncodedField field; public final ClassDataItem.EncodedField field;
public StaticFieldInitializer(EncodedValue value, ClassDataItem.EncodedField field) { public StaticFieldInitializer(EncodedValue value, ClassDataItem.EncodedField field) {
this.value = value; this.value = value;
this.field = field; this.field = field;
} }
public int compareTo(StaticFieldInitializer other) { public int compareTo(StaticFieldInitializer other) {
return field.compareTo(other.field); return field.compareTo(other.field);
} }
} }
/** /**
* A helper method to sort the static field initializers and populate the default values as needed * A helper method to sort the static field initializers and populate the default values as needed
* @param dexFile the <code>DexFile</code> * @param dexFile the <code>DexFile</code>
* @param staticFieldInitializers the initial values * @param staticFieldInitializers the initial values
* @return an interned EncodedArrayItem containing the static field initializers * @return an interned EncodedArrayItem containing the static field initializers
*/ */
private static EncodedArrayItem makeStaticFieldInitializersItem(DexFile dexFile, private static EncodedArrayItem makeStaticFieldInitializersItem(DexFile dexFile,
List<StaticFieldInitializer> staticFieldInitializers) { List<StaticFieldInitializer> staticFieldInitializers) {
if (staticFieldInitializers == null || staticFieldInitializers.size() == 0) { if (staticFieldInitializers == null || staticFieldInitializers.size() == 0) {
return null; return null;
} }
int len = staticFieldInitializers.size(); int len = staticFieldInitializers.size();
Collections.sort(staticFieldInitializers); Collections.sort(staticFieldInitializers);
int lastIndex = -1; int lastIndex = -1;
for (int i=len-1; i>=0; i--) { for (int i=len-1; i>=0; i--) {
StaticFieldInitializer staticFieldInitializer = staticFieldInitializers.get(i); StaticFieldInitializer staticFieldInitializer = staticFieldInitializers.get(i);
if (staticFieldInitializer.value != null && if (staticFieldInitializer.value != null &&
(staticFieldInitializer.value.compareTo(TypeUtils.makeDefaultValueForType(dexFile, (staticFieldInitializer.value.compareTo(TypeUtils.makeDefaultValueForType(dexFile,
staticFieldInitializer.field.field.getFieldType().getTypeDescriptor())) != 0)) { staticFieldInitializer.field.field.getFieldType().getTypeDescriptor())) != 0)) {
lastIndex = i; lastIndex = i;
break; break;
} }
} }
//we don't have any non-null/non-default values, so we don't need to create an EncodedArrayItem //we don't have any non-null/non-default values, so we don't need to create an EncodedArrayItem
if (lastIndex == -1) { if (lastIndex == -1) {
return null; return null;
} }
EncodedValue[] values = new EncodedValue[lastIndex+1]; EncodedValue[] values = new EncodedValue[lastIndex+1];
for (int i=0; i<=lastIndex; i++) { for (int i=0; i<=lastIndex; i++) {
StaticFieldInitializer staticFieldInitializer = staticFieldInitializers.get(i); StaticFieldInitializer staticFieldInitializer = staticFieldInitializers.get(i);
EncodedValue encodedValue = staticFieldInitializer.value; EncodedValue encodedValue = staticFieldInitializer.value;
if (encodedValue == null) { if (encodedValue == null) {
encodedValue = TypeUtils.makeDefaultValueForType(dexFile, encodedValue = TypeUtils.makeDefaultValueForType(dexFile,
staticFieldInitializer.field.field.getFieldType().getTypeDescriptor()); staticFieldInitializer.field.field.getFieldType().getTypeDescriptor());
} }
values[i] = encodedValue; values[i] = encodedValue;
} }
ArrayEncodedSubValue encodedArrayValue = new ArrayEncodedSubValue(values); ArrayEncodedSubValue encodedArrayValue = new ArrayEncodedSubValue(values);
return EncodedArrayItem.getInternedEncodedArrayItem(dexFile, encodedArrayValue); return EncodedArrayItem.getInternedEncodedArrayItem(dexFile, encodedArrayValue);
} }
} }

View File

@ -1,138 +1,138 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import java.util.Iterator; import java.util.Iterator;
public class ArrayDataPseudoInstruction extends Instruction { public class ArrayDataPseudoInstruction extends Instruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
@Override @Override
public int getSize() { public int getSize() {
int size = getElementWidth() * getElementCount(); int size = getElementWidth() * getElementCount();
return size + (size & 0x01) + 8; return size + (size & 0x01) + 8;
} }
public static void emit(Output out, int elementWidth, byte[] encodedValues) { public static void emit(Output out, int elementWidth, byte[] encodedValues) {
if (encodedValues.length % elementWidth != 0) { if (encodedValues.length % elementWidth != 0) {
throw new RuntimeException("There are not a whole number of " + elementWidth + " byte elements"); throw new RuntimeException("There are not a whole number of " + elementWidth + " byte elements");
} }
//write out padding, if necessary //write out padding, if necessary
if (out.getCursor() % 4 != 0) { if (out.getCursor() % 4 != 0) {
out.writeShort(0); out.writeShort(0);
} }
int elementCount = encodedValues.length / elementWidth; int elementCount = encodedValues.length / elementWidth;
out.writeByte(0x00); out.writeByte(0x00);
out.writeByte(0x03); out.writeByte(0x03);
out.writeShort(elementWidth); out.writeShort(elementWidth);
out.writeInt(elementCount); out.writeInt(elementCount);
out.write(encodedValues); out.write(encodedValues);
if ((encodedValues.length % 2) != 0) { if ((encodedValues.length % 2) != 0) {
//must write out an even number of bytes //must write out an even number of bytes
out.writeByte(0); out.writeByte(0);
} }
} }
public ArrayDataPseudoInstruction(byte[] buffer, int bufferIndex) { public ArrayDataPseudoInstruction(byte[] buffer, int bufferIndex) {
super(Opcode.NOP, buffer, bufferIndex); super(Opcode.NOP, buffer, bufferIndex);
byte opcodeByte = buffer[bufferIndex++]; byte opcodeByte = buffer[bufferIndex++];
if (opcodeByte != 0x00) { if (opcodeByte != 0x00) {
throw new RuntimeException("Invalid opcode byte for an ArrayData pseudo-instruction"); throw new RuntimeException("Invalid opcode byte for an ArrayData pseudo-instruction");
} }
byte subopcodeByte = buffer[bufferIndex]; byte subopcodeByte = buffer[bufferIndex];
if (subopcodeByte != 0x03) { if (subopcodeByte != 0x03) {
throw new RuntimeException("Invalid sub-opcode byte for an ArrayData pseudo-instruction"); throw new RuntimeException("Invalid sub-opcode byte for an ArrayData pseudo-instruction");
} }
} }
public Format getFormat() { public Format getFormat() {
return Format.ArrayData; return Format.ArrayData;
} }
public int getElementWidth() { public int getElementWidth() {
return NumberUtils.decodeUnsignedShort(buffer[bufferIndex+2], buffer[bufferIndex+3]); return NumberUtils.decodeUnsignedShort(buffer[bufferIndex+2], buffer[bufferIndex+3]);
} }
public int getElementCount() { public int getElementCount() {
return NumberUtils.decodeInt(buffer, bufferIndex+4); return NumberUtils.decodeInt(buffer, bufferIndex+4);
} }
public static class ArrayElement { public static class ArrayElement {
public final byte[] buffer; public final byte[] buffer;
public int bufferIndex; public int bufferIndex;
public final int elementWidth; public final int elementWidth;
public ArrayElement(byte[] buffer, int elementWidth) { public ArrayElement(byte[] buffer, int elementWidth) {
this.buffer = buffer; this.buffer = buffer;
this.elementWidth = elementWidth; this.elementWidth = elementWidth;
} }
} }
public Iterator<ArrayElement> getElements() { public Iterator<ArrayElement> getElements() {
return new Iterator<ArrayElement>() { return new Iterator<ArrayElement>() {
final int elementCount = getElementCount(); final int elementCount = getElementCount();
int i=0; int i=0;
int position = bufferIndex + 8; int position = bufferIndex + 8;
final ArrayElement arrayElement = new ArrayElement(buffer, getElementWidth()); final ArrayElement arrayElement = new ArrayElement(buffer, getElementWidth());
public boolean hasNext() { public boolean hasNext() {
return i<elementCount; return i<elementCount;
} }
public ArrayElement next() { public ArrayElement next() {
arrayElement.bufferIndex = position; arrayElement.bufferIndex = position;
position += arrayElement.elementWidth; position += arrayElement.elementWidth;
i++; i++;
return arrayElement; return arrayElement;
} }
public void remove() { public void remove() {
} }
}; };
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
if (opcode != Opcode.NOP) { if (opcode != Opcode.NOP) {
throw new RuntimeException("The opcode for an ArrayDataPseudoInstruction must by NOP"); throw new RuntimeException("The opcode for an ArrayDataPseudoInstruction must by NOP");
} }
return new ArrayDataPseudoInstruction(buffer, bufferIndex); return new ArrayDataPseudoInstruction(buffer, bufferIndex);
} }
} }
} }

View File

@ -1,86 +1,86 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
public enum Format { public enum Format {
Format10t(Instruction10t.Factory, 2), Format10t(Instruction10t.Factory, 2),
Format10x(Instruction10x.Factory, 2), Format10x(Instruction10x.Factory, 2),
Format11n(Instruction11n.Factory, 2), Format11n(Instruction11n.Factory, 2),
Format11x(Instruction11x.Factory, 2), Format11x(Instruction11x.Factory, 2),
Format12x(Instruction12x.Factory, 2), Format12x(Instruction12x.Factory, 2),
Format20t(Instruction20t.Factory, 4), Format20t(Instruction20t.Factory, 4),
Format21c(Instruction21c.Factory, 4), Format21c(Instruction21c.Factory, 4),
Format21h(Instruction21h.Factory, 4), Format21h(Instruction21h.Factory, 4),
Format21s(Instruction21s.Factory, 4), Format21s(Instruction21s.Factory, 4),
Format21t(Instruction21t.Factory, 4), Format21t(Instruction21t.Factory, 4),
Format22b(Instruction22b.Factory, 4), Format22b(Instruction22b.Factory, 4),
Format22c(Instruction22c.Factory, 4), Format22c(Instruction22c.Factory, 4),
Format22cs(Instruction22cs.Factory, 4), Format22cs(Instruction22cs.Factory, 4),
Format22csf(null, 4), Format22csf(null, 4),
Format22s(Instruction22s.Factory, 4), Format22s(Instruction22s.Factory, 4),
Format22t(Instruction22t.Factory, 4), Format22t(Instruction22t.Factory, 4),
Format22x(Instruction22x.Factory, 4), Format22x(Instruction22x.Factory, 4),
Format23x(Instruction23x.Factory, 4), Format23x(Instruction23x.Factory, 4),
Format30t(Instruction30t.Factory, 6), Format30t(Instruction30t.Factory, 6),
Format31c(Instruction31c.Factory, 6), Format31c(Instruction31c.Factory, 6),
Format31i(Instruction31i.Factory, 6), Format31i(Instruction31i.Factory, 6),
Format31t(Instruction31t.Factory, 6), Format31t(Instruction31t.Factory, 6),
Format32x(Instruction32x.Factory, 6), Format32x(Instruction32x.Factory, 6),
Format35c(Instruction35c.Factory, 6), Format35c(Instruction35c.Factory, 6),
Format35s(Instruction35s.Factory, 6), Format35s(Instruction35s.Factory, 6),
Format35sf(null, 6), Format35sf(null, 6),
Format35ms(Instruction35ms.Factory, 6), Format35ms(Instruction35ms.Factory, 6),
Format35msf(null, 6), Format35msf(null, 6),
Format3rc(Instruction3rc.Factory, 6), Format3rc(Instruction3rc.Factory, 6),
Format3rms(Instruction3rms.Factory, 6), Format3rms(Instruction3rms.Factory, 6),
Format3rmsf(null, 6), Format3rmsf(null, 6),
Format51l(Instruction51l.Factory, 10), Format51l(Instruction51l.Factory, 10),
ArrayData(null, -1, true), ArrayData(null, -1, true),
PackedSwitchData(null, -1, true), PackedSwitchData(null, -1, true),
SparseSwitchData(null, -1, true), SparseSwitchData(null, -1, true),
UnresolvedNullReference(null, -1, false), UnresolvedNullReference(null, -1, false),
DeadInstruction(null, -1, false) DeadInstruction(null, -1, false)
; ;
public final Instruction.InstructionFactory Factory; public final Instruction.InstructionFactory Factory;
public final int size; public final int size;
public final boolean variableSizeFormat; public final boolean variableSizeFormat;
private Format(Instruction.InstructionFactory factory, int size) { private Format(Instruction.InstructionFactory factory, int size) {
this(factory, size, false); this(factory, size, false);
} }
private Format(Instruction.InstructionFactory factory, int size, boolean variableSizeFormat) { private Format(Instruction.InstructionFactory factory, int size, boolean variableSizeFormat) {
this.Factory = factory; this.Factory = factory;
this.size = size; this.size = size;
this.variableSizeFormat = variableSizeFormat; this.variableSizeFormat = variableSizeFormat;
} }
} }

View File

@ -1,70 +1,70 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction; import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction10t extends Instruction implements OffsetInstruction { public class Instruction10t extends Instruction implements OffsetInstruction {
public static final InstructionFactory Factory = new Factory(); public static final InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte offA) { public static void emit(Output out, Opcode opcode, byte offA) {
if (offA == 0) { if (offA == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead."); throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(offA); out.writeByte(offA);
} }
private Instruction10t(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction10t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
if (getOffset() == 0) { if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead."); throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
} }
} }
public Format getFormat() { public Format getFormat() {
return Format.Format10t; return Format.Format10t;
} }
public int getOffset() { public int getOffset() {
return buffer[bufferIndex + 1]; return buffer[bufferIndex + 1];
} }
private static class Factory implements InstructionFactory { private static class Factory implements InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction10t(opcode, buffer, bufferIndex); return new Instruction10t(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,61 +1,61 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction10x extends Instruction { public class Instruction10x extends Instruction {
public static final InstructionFactory Factory = new Factory(); public static final InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode) { public static void emit(Output out, Opcode opcode) {
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(0); out.writeByte(0);
} }
public Instruction10x(Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction10x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
if (buffer[bufferIndex + 1] != 0x00) { if (buffer[bufferIndex + 1] != 0x00) {
throw new RuntimeException("The second byte of the instruction must be 0"); throw new RuntimeException("The second byte of the instruction must be 0");
} }
} }
public Format getFormat() { public Format getFormat() {
return Format.Format10x; return Format.Format10x;
} }
private static class Factory implements InstructionFactory { private static class Factory implements InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction10x(opcode, buffer, bufferIndex); return new Instruction10x(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,77 +1,77 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction; import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.Code.LiteralInstruction; import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction11n extends Instruction implements SingleRegisterInstruction, LiteralInstruction { public class Instruction11n extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final InstructionFactory Factory = new Factory(); public static final InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte litB) { public static void emit(Output out, Opcode opcode, byte regA, byte litB) {
if (regA >= 1 << 4) { if (regA >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16"); throw new RuntimeException("The register number must be less than v16");
} }
if (litB < -(1 << 3) || if (litB < -(1 << 3) ||
litB >= 1 << 3) { litB >= 1 << 3) {
throw new RuntimeException("The literal value must be between -8 and 7 inclusive"); throw new RuntimeException("The literal value must be between -8 and 7 inclusive");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte((litB << 4) | regA); out.writeByte((litB << 4) | regA);
} }
private Instruction11n(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction11n(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format11n; return Format.Format11n;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
} }
public long getLiteral() { public long getLiteral() {
return NumberUtils.decodeHighSignedNibble(buffer[bufferIndex + 1]); return NumberUtils.decodeHighSignedNibble(buffer[bufferIndex + 1]);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction11n(opcode, buffer, bufferIndex); return new Instruction11n(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,67 +1,67 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction; import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction11x extends Instruction implements SingleRegisterInstruction { public class Instruction11x extends Instruction implements SingleRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA) { public static void emit(Output out, Opcode opcode, short regA) {
if (regA >= 1 << 8) { if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256"); throw new RuntimeException("The register number must be less than v256");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(regA); out.writeByte(regA);
} }
private Instruction11x(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction11x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format11x; return Format.Format11x;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction11x(opcode, buffer, bufferIndex); return new Instruction11x(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,72 +1,72 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction; import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction12x extends Instruction implements TwoRegisterInstruction { public class Instruction12x extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte regB) { public static void emit(Output out, Opcode opcode, byte regA, byte regB) {
if (regA >= 1 << 4 || if (regA >= 1 << 4 ||
regB >= 1 << 4) { regB >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16"); throw new RuntimeException("The register number must be less than v16");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte((regB << 4) | regA); out.writeByte((regB << 4) | regA);
} }
private Instruction12x(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction12x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format12x; return Format.Format12x;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
} }
public int getRegisterB() { public int getRegisterB() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction12x(opcode, buffer, bufferIndex); return new Instruction12x(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,72 +1,72 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction; import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction20t extends Instruction implements OffsetInstruction { public class Instruction20t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short offA) { public static void emit(Output out, Opcode opcode, short offA) {
if (offA == 0) { if (offA == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead."); throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(0); out.writeByte(0);
out.writeShort(offA); out.writeShort(offA);
} }
private Instruction20t(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction20t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
if (getOffset() == 0) { if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0. Use goto/32 instead."); throw new RuntimeException("The offset cannot be 0. Use goto/32 instead.");
} }
} }
public Format getFormat() { public Format getFormat() {
return Format.Format20t; return Format.Format20t;
} }
public int getOffset() { public int getOffset() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2); return NumberUtils.decodeShort(buffer, bufferIndex + 2);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction20t(opcode, buffer, bufferIndex); return new Instruction20t(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,82 +1,82 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference; import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction; import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Item; import org.jf.dexlib.Item;
import org.jf.dexlib.TypeIdItem; import org.jf.dexlib.TypeIdItem;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction21c extends InstructionWithReference implements SingleRegisterInstruction { public class Instruction21c extends InstructionWithReference implements SingleRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, Item referencedItem) { public static void emit(Output out, Opcode opcode, short regA, Item referencedItem) {
if (regA >= 1 << 8) { if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256"); throw new RuntimeException("The register number must be less than v256");
} }
if (opcode == Opcode.NEW_INSTANCE) { if (opcode == Opcode.NEW_INSTANCE) {
assert referencedItem instanceof TypeIdItem; assert referencedItem instanceof TypeIdItem;
if (((TypeIdItem)referencedItem).getTypeDescriptor().charAt(0) != 'L') { if (((TypeIdItem)referencedItem).getTypeDescriptor().charAt(0) != 'L') {
throw new RuntimeException("Only class references can be used with the new-instance opcode"); throw new RuntimeException("Only class references can be used with the new-instance opcode");
} }
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(regA); out.writeByte(regA);
out.writeShort(0); out.writeShort(0);
} }
private Instruction21c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction21c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex); super(dexFile, opcode, buffer, bufferIndex);
if (opcode == Opcode.NEW_INSTANCE && ((TypeIdItem) this.getReferencedItem()).getTypeDescriptor().charAt(0) != 'L') { 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"); throw new RuntimeException("Only class references can be used with the new-instance opcode");
} }
} }
public Format getFormat() { public Format getFormat() {
return Format.Format21c; return Format.Format21c;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction21c(dexFile, opcode, buffer, bufferIndex); return new Instruction21c(dexFile, opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,73 +1,73 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.LiteralInstruction; import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.Code.SingleRegisterInstruction; import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction21h extends Instruction implements SingleRegisterInstruction, LiteralInstruction { public class Instruction21h extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short litB) { public static void emit(Output out, Opcode opcode, short regA, short litB) {
if (regA >= 1 << 8) { if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256"); throw new RuntimeException("The register number must be less than v256");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(regA); out.writeByte(regA);
out.writeShort(litB); out.writeShort(litB);
} }
private Instruction21h(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction21h(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format21h; return Format.Format21h;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
} }
public long getLiteral() { public long getLiteral() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2); return NumberUtils.decodeShort(buffer, bufferIndex + 2);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction21h(opcode, buffer, bufferIndex); return new Instruction21h(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,73 +1,73 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.LiteralInstruction; import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.Code.SingleRegisterInstruction; import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction21s extends Instruction implements SingleRegisterInstruction, LiteralInstruction { public class Instruction21s extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short litB) { public static void emit(Output out, Opcode opcode, short regA, short litB) {
if (regA >= 1 << 8) { if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256"); throw new RuntimeException("The register number must be less than v256");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(regA); out.writeByte(regA);
out.writeShort(litB); out.writeShort(litB);
} }
private Instruction21s(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction21s(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format21s; return Format.Format21s;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
} }
public long getLiteral() { public long getLiteral() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2); return NumberUtils.decodeShort(buffer, bufferIndex + 2);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction21s(opcode, buffer, bufferIndex); return new Instruction21s(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,80 +1,80 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction; import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction21t extends Instruction implements OffsetInstruction { public class Instruction21t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short offB) { public static void emit(Output out, Opcode opcode, short regA, short offB) {
if (regA >= 1 << 8) { if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256"); throw new RuntimeException("The register number must be less than v256");
} }
if (offB == 0) { if (offB == 0) {
throw new RuntimeException("The offset cannot be 0."); throw new RuntimeException("The offset cannot be 0.");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(regA); out.writeByte(regA);
out.writeShort(offB); out.writeShort(offB);
} }
private Instruction21t(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction21t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
if (getOffset() == 0) { if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0."); throw new RuntimeException("The offset cannot be 0.");
} }
} }
public Format getFormat() { public Format getFormat() {
return Format.Format21t; return Format.Format21t;
} }
public short getRegister() { public short getRegister() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
} }
public int getOffset() { public int getOffset() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2); return NumberUtils.decodeShort(buffer, bufferIndex + 2);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction21t(opcode, buffer, bufferIndex); return new Instruction21t(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,78 +1,78 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction; import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction22b extends Instruction implements TwoRegisterInstruction { public class Instruction22b extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short regB, byte litC) { public static void emit(Output out, Opcode opcode, short regA, short regB, byte litC) {
if (regA >= 1 << 8 || if (regA >= 1 << 8 ||
regB >= 1 << 8) { regB >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256"); throw new RuntimeException("The register number must be less than v256");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(regA); out.writeByte(regA);
out.writeByte(regB); out.writeByte(regB);
out.writeByte(litC); out.writeByte(litC);
} }
private Instruction22b(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction22b(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format22b; return Format.Format22b;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
} }
public int getRegisterB() { public int getRegisterB() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 2]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 2]);
} }
public byte getLiteral() { public byte getLiteral() {
return buffer[bufferIndex + 3]; return buffer[bufferIndex + 3];
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22b(opcode, buffer, bufferIndex); return new Instruction22b(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,74 +1,74 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference; import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction; import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction22c extends InstructionWithReference implements TwoRegisterInstruction { public class Instruction22c extends InstructionWithReference implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte regB) { public static void emit(Output out, Opcode opcode, byte regA, byte regB) {
if (regA >= 1 << 4 || if (regA >= 1 << 4 ||
regB >= 1 << 4) { regB >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16"); throw new RuntimeException("The register number must be less than v16");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte((regB << 4) | regA); out.writeByte((regB << 4) | regA);
out.writeShort(0); out.writeShort(0);
} }
private Instruction22c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction22c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex); super(dexFile, opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format22c; return Format.Format22c;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
} }
public int getRegisterB() { public int getRegisterB() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22c(dexFile, opcode, buffer, bufferIndex); return new Instruction22c(dexFile, opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,77 +1,77 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction; import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction22s extends Instruction implements TwoRegisterInstruction { public class Instruction22s extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte regB, short litC) { public static void emit(Output out, Opcode opcode, byte regA, byte regB, short litC) {
if (regA >= 1 << 4 || if (regA >= 1 << 4 ||
regB >= 1 << 4) { regB >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16"); throw new RuntimeException("The register number must be less than v16");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte((regB << 4) | regA); out.writeByte((regB << 4) | regA);
out.writeShort(litC); out.writeShort(litC);
} }
private Instruction22s(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction22s(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format22s; return Format.Format22s;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
} }
public int getRegisterB() { public int getRegisterB() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
} }
public short getLiteral() { public short getLiteral() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2); return NumberUtils.decodeShort(buffer, bufferIndex + 2);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22s(opcode, buffer, bufferIndex); return new Instruction22s(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,85 +1,85 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction; import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction22t extends Instruction implements OffsetInstruction { public class Instruction22t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, byte regA, byte regB, short offC) { public static void emit(Output out, Opcode opcode, byte regA, byte regB, short offC) {
if (regA >= 1 << 4 || if (regA >= 1 << 4 ||
regB >= 1 << 4) { regB >= 1 << 4) {
throw new RuntimeException("The register number must be less than v16"); throw new RuntimeException("The register number must be less than v16");
} }
if (offC == 0) { if (offC == 0) {
throw new RuntimeException("The offset cannot be 0."); throw new RuntimeException("The offset cannot be 0.");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte((regB << 4) | regA); out.writeByte((regB << 4) | regA);
out.writeShort(offC); out.writeShort(offC);
} }
private Instruction22t(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction22t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
if (getOffset() == 0) { if (getOffset() == 0) {
throw new RuntimeException("The offset cannot be 0."); throw new RuntimeException("The offset cannot be 0.");
} }
} }
public Format getFormat() { public Format getFormat() {
return Format.Format22t; return Format.Format22t;
} }
public byte getRegisterA() { public byte getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
} }
public byte getRegisterB() { public byte getRegisterB() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
} }
public int getOffset() { public int getOffset() {
return NumberUtils.decodeShort(buffer, bufferIndex + 2); return NumberUtils.decodeShort(buffer, bufferIndex + 2);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22t(opcode, buffer, bufferIndex); return new Instruction22t(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,76 +1,76 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction; import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction22x extends Instruction implements TwoRegisterInstruction { public class Instruction22x extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, int regB) { public static void emit(Output out, Opcode opcode, short regA, int regB) {
if (regA >= 1 << 8) { if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v16"); throw new RuntimeException("The register number must be less than v16");
} }
if (regB >= 1 << 16) { if (regB >= 1 << 16) {
throw new RuntimeException("The register number must be less than v65536"); throw new RuntimeException("The register number must be less than v65536");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(regA); out.writeByte(regA);
out.writeShort(regB); out.writeShort(regB);
} }
private Instruction22x(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction22x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format22x; return Format.Format22x;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
} }
public int getRegisterB() { public int getRegisterB() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction22x(opcode, buffer, bufferIndex); return new Instruction22x(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,79 +1,79 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.ThreeRegisterInstruction; import org.jf.dexlib.Code.ThreeRegisterInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction23x extends Instruction implements ThreeRegisterInstruction { public class Instruction23x extends Instruction implements ThreeRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, short regB, short regC) { public static void emit(Output out, Opcode opcode, short regA, short regB, short regC) {
if (regA >= 1 << 8 || if (regA >= 1 << 8 ||
regB >= 1 << 8 || regB >= 1 << 8 ||
regC >= 1 << 8) { regC >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256"); throw new RuntimeException("The register number must be less than v256");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(regA); out.writeByte(regA);
out.writeByte(regB); out.writeByte(regB);
out.writeByte(regC); out.writeByte(regC);
} }
private Instruction23x(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction23x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format23x; return Format.Format23x;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
} }
public int getRegisterB() { public int getRegisterB() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 2]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 2]);
} }
public int getRegisterC() { public int getRegisterC() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 3]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 3]);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction23x(opcode, buffer, bufferIndex); return new Instruction23x(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,64 +1,64 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction; import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction30t extends Instruction implements OffsetInstruction { public class Instruction30t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, int offA) { public static void emit(Output out, Opcode opcode, int offA) {
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(0); out.writeByte(0);
out.writeInt(offA); out.writeInt(offA);
} }
private Instruction30t(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction30t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format30t; return Format.Format30t;
} }
public int getOffset() { public int getOffset() {
return NumberUtils.decodeInt(buffer, bufferIndex + 2); return NumberUtils.decodeInt(buffer, bufferIndex + 2);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction30t(opcode, buffer, bufferIndex); return new Instruction30t(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,74 +1,74 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference; import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction; import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Item; import org.jf.dexlib.Item;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction31c extends InstructionWithReference implements SingleRegisterInstruction { public class Instruction31c extends InstructionWithReference implements SingleRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA) { public static void emit(Output out, Opcode opcode, short regA) {
if (regA >= 1 << 8) { if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256"); throw new RuntimeException("The register number must be less than v256");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(regA); out.writeByte(regA);
out.writeInt(0); out.writeInt(0);
} }
private Instruction31c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction31c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex); super(dexFile, opcode, buffer, bufferIndex);
} }
protected int getReferencedItemIndex() { protected int getReferencedItemIndex() {
return NumberUtils.decodeInt(buffer, bufferIndex + 2); return NumberUtils.decodeInt(buffer, bufferIndex + 2);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format31c; return Format.Format31c;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction31c(dexFile, opcode, buffer, bufferIndex); return new Instruction31c(dexFile, opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,73 +1,73 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.LiteralInstruction; import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.Code.SingleRegisterInstruction; import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction31i extends Instruction implements SingleRegisterInstruction, LiteralInstruction { public class Instruction31i extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, int litB) { public static void emit(Output out, Opcode opcode, short regA, int litB) {
if (regA >= 1 << 8) { if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256"); throw new RuntimeException("The register number must be less than v256");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(regA); out.writeByte(regA);
out.writeInt(litB); out.writeInt(litB);
} }
private Instruction31i(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction31i(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format31i; return Format.Format31i;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
} }
public long getLiteral() { public long getLiteral() {
return NumberUtils.decodeInt(buffer, bufferIndex + 2); return NumberUtils.decodeInt(buffer, bufferIndex + 2);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction31i(opcode, buffer, bufferIndex); return new Instruction31i(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,72 +1,72 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.OffsetInstruction; import org.jf.dexlib.Code.OffsetInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction31t extends Instruction implements OffsetInstruction { public class Instruction31t extends Instruction implements OffsetInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, int offB) { public static void emit(Output out, Opcode opcode, short regA, int offB) {
if (regA >= 1 << 8) { if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256"); throw new RuntimeException("The register number must be less than v256");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(regA); out.writeByte(regA);
out.writeInt(offB); out.writeInt(offB);
} }
private Instruction31t(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction31t(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format31t; return Format.Format31t;
} }
public short getRegister() { public short getRegister() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
} }
public int getOffset() { public int getOffset() {
return NumberUtils.decodeInt(buffer, bufferIndex + 2); return NumberUtils.decodeInt(buffer, bufferIndex + 2);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction31t(opcode, buffer, bufferIndex); return new Instruction31t(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,74 +1,74 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.TwoRegisterInstruction; import org.jf.dexlib.Code.TwoRegisterInstruction;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction32x extends Instruction implements TwoRegisterInstruction { public class Instruction32x extends Instruction implements TwoRegisterInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, int regA, int regB) { public static void emit(Output out, Opcode opcode, int regA, int regB) {
if (regA >= 1<<16 || if (regA >= 1<<16 ||
regB >= 1<<16) { regB >= 1<<16) {
throw new RuntimeException("The register number must be less than v65536"); throw new RuntimeException("The register number must be less than v65536");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(0); out.writeByte(0);
out.writeShort(regA); out.writeShort(regA);
out.writeShort(regB); out.writeShort(regB);
} }
private Instruction32x(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction32x(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format32x; return Format.Format32x;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
} }
public int getRegisterB() { public int getRegisterB() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4); return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction32x(opcode, buffer, bufferIndex); return new Instruction32x(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,134 +1,134 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference; import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import static org.jf.dexlib.Code.Opcode.*; import static org.jf.dexlib.Code.Opcode.*;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Item; import org.jf.dexlib.Item;
import org.jf.dexlib.MethodIdItem; import org.jf.dexlib.MethodIdItem;
import org.jf.dexlib.TypeIdItem; import org.jf.dexlib.TypeIdItem;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction35c extends InstructionWithReference { public class Instruction35c extends InstructionWithReference {
public static final Instruction.InstructionFactory Factory = new Factory(); 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, public static void emit(Output out, Opcode opcode, int regCount, byte regD, byte regE, byte regF, byte regG,
byte regA, Item referencedItem) { byte regA, Item referencedItem) {
if (regCount > 5) { if (regCount > 5) {
throw new RuntimeException("regCount cannot be greater than 5"); throw new RuntimeException("regCount cannot be greater than 5");
} }
if (regD >= 1 << 4 || if (regD >= 1 << 4 ||
regE >= 1 << 4 || regE >= 1 << 4 ||
regF >= 1 << 4 || regF >= 1 << 4 ||
regG >= 1 << 4 || regG >= 1 << 4 ||
regA >= 1 << 4) { regA >= 1 << 4) {
throw new RuntimeException("All register args must fit in 4 bits"); throw new RuntimeException("All register args must fit in 4 bits");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte((regCount << 4) | regA); out.writeByte((regCount << 4) | regA);
out.writeShort(0); out.writeShort(0);
out.writeByte((regE << 4) | regD); out.writeByte((regE << 4) | regD);
out.writeByte((regG << 4) | regF); out.writeByte((regG << 4) | regF);
checkItem(opcode, referencedItem, regCount); checkItem(opcode, referencedItem, regCount);
} }
protected Instruction35c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { protected Instruction35c(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex); super(dexFile, opcode, buffer, bufferIndex);
if (getRegCount() > 5) { if (getRegCount() > 5) {
throw new RuntimeException("regCount cannot be greater than 5"); throw new RuntimeException("regCount cannot be greater than 5");
} }
checkItem(opcode, getReferencedItem(), getRegCount()); checkItem(opcode, getReferencedItem(), getRegCount());
} }
public Format getFormat() { public Format getFormat() {
return Format.Format35c; return Format.Format35c;
} }
public byte getRegisterA() { public byte getRegisterA() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]); return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 1]);
} }
public byte getRegCount() { public byte getRegCount() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]); return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 1]);
} }
public byte getRegisterD() { public byte getRegisterD() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 4]); return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 4]);
} }
public byte getRegisterE() { public byte getRegisterE() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 4]); return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 4]);
} }
public byte getRegisterF() { public byte getRegisterF() {
return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 5]); return NumberUtils.decodeLowUnsignedNibble(buffer[bufferIndex + 5]);
} }
public byte getRegisterG() { public byte getRegisterG() {
return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 5]); return NumberUtils.decodeHighUnsignedNibble(buffer[bufferIndex + 5]);
} }
private static void checkItem(Opcode opcode, Item item, int regCount) { private static void checkItem(Opcode opcode, Item item, int regCount) {
if (opcode == FILLED_NEW_ARRAY) { if (opcode == FILLED_NEW_ARRAY) {
//check data for filled-new-array opcode //check data for filled-new-array opcode
String type = ((TypeIdItem) item).getTypeDescriptor(); String type = ((TypeIdItem) item).getTypeDescriptor();
if (type.charAt(0) != '[') { if (type.charAt(0) != '[') {
throw new RuntimeException("The type must be an array type"); throw new RuntimeException("The type must be an array type");
} }
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') { if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
throw new RuntimeException("The type cannot be an array of longs or doubles"); 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) { } else if (opcode.value >= INVOKE_VIRTUAL.value && opcode.value <= INVOKE_INTERFACE.value) {
//check data for invoke-* opcodes //check data for invoke-* opcodes
MethodIdItem methodIdItem = (MethodIdItem) item; MethodIdItem methodIdItem = (MethodIdItem) item;
int parameterRegisterCount = methodIdItem.getPrototype().getParameterRegisterCount(); int parameterRegisterCount = methodIdItem.getPrototype().getParameterRegisterCount();
if (opcode != INVOKE_STATIC) { if (opcode != INVOKE_STATIC) {
parameterRegisterCount++; parameterRegisterCount++;
} }
if (parameterRegisterCount != regCount) { if (parameterRegisterCount != regCount) {
throw new RuntimeException("regCount does not match the number of arguments of the method"); throw new RuntimeException("regCount does not match the number of arguments of the method");
} }
} }
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction35c(dexFile, opcode, buffer, bufferIndex); return new Instruction35c(dexFile, opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,114 +1,114 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.InstructionWithReference; import org.jf.dexlib.Code.InstructionWithReference;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import static org.jf.dexlib.Code.Opcode.*; import static org.jf.dexlib.Code.Opcode.*;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Item; import org.jf.dexlib.Item;
import org.jf.dexlib.MethodIdItem; import org.jf.dexlib.MethodIdItem;
import org.jf.dexlib.TypeIdItem; import org.jf.dexlib.TypeIdItem;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction3rc extends InstructionWithReference { public class Instruction3rc extends InstructionWithReference {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regCount, int startReg, Item referencedItem) { public static void emit(Output out, Opcode opcode, short regCount, int startReg, Item referencedItem) {
if (regCount >= 1 << 8) { if (regCount >= 1 << 8) {
throw new RuntimeException("regCount must be less than 256"); throw new RuntimeException("regCount must be less than 256");
} }
if (regCount < 0) { if (regCount < 0) {
throw new RuntimeException("regCount cannot be negative"); throw new RuntimeException("regCount cannot be negative");
} }
if (startReg >= 1 << 16) { if (startReg >= 1 << 16) {
throw new RuntimeException("The beginning register of the range must be less than 65536"); throw new RuntimeException("The beginning register of the range must be less than 65536");
} }
if (startReg < 0) { if (startReg < 0) {
throw new RuntimeException("The beginning register of the range cannot be negative"); throw new RuntimeException("The beginning register of the range cannot be negative");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(regCount); out.writeByte(regCount);
out.writeShort(0); out.writeShort(0);
out.writeShort(startReg); out.writeShort(startReg);
checkItem(opcode, referencedItem, regCount); checkItem(opcode, referencedItem, regCount);
} }
private Instruction3rc(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction3rc(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
super(dexFile, opcode, buffer, bufferIndex); super(dexFile, opcode, buffer, bufferIndex);
checkItem(opcode, getReferencedItem(), getRegCount()); checkItem(opcode, getReferencedItem(), getRegCount());
} }
public Format getFormat() { public Format getFormat() {
return Format.Format3rc; return Format.Format3rc;
} }
public short getRegCount() { public short getRegCount() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
} }
public int getStartRegister() { public int getStartRegister() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4); return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 4);
} }
private static void checkItem(Opcode opcode, Item item, int regCount) { private static void checkItem(Opcode opcode, Item item, int regCount) {
if (opcode == FILLED_NEW_ARRAY_RANGE) { if (opcode == FILLED_NEW_ARRAY_RANGE) {
//check data for filled-new-array/range opcode //check data for filled-new-array/range opcode
String type = ((TypeIdItem) item).getTypeDescriptor(); String type = ((TypeIdItem) item).getTypeDescriptor();
if (type.charAt(0) != '[') { if (type.charAt(0) != '[') {
throw new RuntimeException("The type must be an array type"); throw new RuntimeException("The type must be an array type");
} }
if (type.charAt(1) == 'J' || type.charAt(1) == 'D') { if (type.charAt(1) == 'J' || type.charAt(1) == 'D') {
throw new RuntimeException("The type cannot be an array of longs or doubles"); 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) { } else if (opcode.value >= INVOKE_VIRTUAL_RANGE.value && opcode.value <= INVOKE_INTERFACE_RANGE.value) {
//check data for invoke-*/range opcodes //check data for invoke-*/range opcodes
MethodIdItem methodIdItem = (MethodIdItem) item; MethodIdItem methodIdItem = (MethodIdItem) item;
int parameterRegisterCount = methodIdItem.getPrototype().getParameterRegisterCount(); int parameterRegisterCount = methodIdItem.getPrototype().getParameterRegisterCount();
if (opcode != INVOKE_STATIC_RANGE) { if (opcode != INVOKE_STATIC_RANGE) {
parameterRegisterCount++; parameterRegisterCount++;
} }
if (parameterRegisterCount != regCount) { if (parameterRegisterCount != regCount) {
throw new RuntimeException("regCount does not match the number of arguments of the method"); throw new RuntimeException("regCount does not match the number of arguments of the method");
} }
} }
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction3rc(dexFile, opcode, buffer, bufferIndex); return new Instruction3rc(dexFile, opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,73 +1,73 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Code.SingleRegisterInstruction; import org.jf.dexlib.Code.SingleRegisterInstruction;
import org.jf.dexlib.Code.LiteralInstruction; import org.jf.dexlib.Code.LiteralInstruction;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
public class Instruction51l extends Instruction implements SingleRegisterInstruction, LiteralInstruction { public class Instruction51l extends Instruction implements SingleRegisterInstruction, LiteralInstruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
public static void emit(Output out, Opcode opcode, short regA, long litB) { public static void emit(Output out, Opcode opcode, short regA, long litB) {
if (regA >= 1 << 8) { if (regA >= 1 << 8) {
throw new RuntimeException("The register number must be less than v256"); throw new RuntimeException("The register number must be less than v256");
} }
out.writeByte(opcode.value); out.writeByte(opcode.value);
out.writeByte(regA); out.writeByte(regA);
out.writeLong(litB); out.writeLong(litB);
} }
private Instruction51l(Opcode opcode, byte[] buffer, int bufferIndex) { private Instruction51l(Opcode opcode, byte[] buffer, int bufferIndex) {
super(opcode, buffer, bufferIndex); super(opcode, buffer, bufferIndex);
} }
public Format getFormat() { public Format getFormat() {
return Format.Format51l; return Format.Format51l;
} }
public int getRegisterA() { public int getRegisterA() {
return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]); return NumberUtils.decodeUnsignedByte(buffer[bufferIndex + 1]);
} }
public long getLiteral() { public long getLiteral() {
return NumberUtils.decodeLong(buffer, bufferIndex + 2); return NumberUtils.decodeLong(buffer, bufferIndex + 2);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
return new Instruction51l(opcode, buffer, bufferIndex); return new Instruction51l(opcode, buffer, bufferIndex);
} }
} }
} }

View File

@ -1,136 +1,136 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import java.util.Iterator; import java.util.Iterator;
public class PackedSwitchDataPseudoInstruction extends Instruction { public class PackedSwitchDataPseudoInstruction extends Instruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
@Override @Override
public int getSize() { public int getSize() {
return getTargetCount() * 4 + 8; return getTargetCount() * 4 + 8;
} }
public static void emit(Output out, int firstKey, int[] targets) { public static void emit(Output out, int firstKey, int[] targets) {
if (targets.length > 0xFFFF) { if (targets.length > 0xFFFF) {
throw new RuntimeException("The packed-switch data contains too many elements. " + throw new RuntimeException("The packed-switch data contains too many elements. " +
"The maximum number of switch elements is 65535"); "The maximum number of switch elements is 65535");
} }
//write out padding, if necessary //write out padding, if necessary
if (out.getCursor() % 4 != 0) { if (out.getCursor() % 4 != 0) {
out.writeShort(0); out.writeShort(0);
} }
out.writeByte(0x00); out.writeByte(0x00);
out.writeByte(0x01); out.writeByte(0x01);
out.writeShort(targets.length); out.writeShort(targets.length);
out.writeInt(firstKey); out.writeInt(firstKey);
for (int target : targets) { for (int target : targets) {
out.writeInt(target); out.writeInt(target);
} }
} }
public PackedSwitchDataPseudoInstruction(byte[] buffer, int bufferIndex) { public PackedSwitchDataPseudoInstruction(byte[] buffer, int bufferIndex) {
super(Opcode.NOP, buffer, bufferIndex); super(Opcode.NOP, buffer, bufferIndex);
byte opcodeByte = buffer[bufferIndex++]; byte opcodeByte = buffer[bufferIndex++];
if (opcodeByte != 0x00) { if (opcodeByte != 0x00) {
throw new RuntimeException("Invalid opcode byte for a PackedSwitchData pseudo-instruction"); throw new RuntimeException("Invalid opcode byte for a PackedSwitchData pseudo-instruction");
} }
byte subopcodeByte = buffer[bufferIndex]; byte subopcodeByte = buffer[bufferIndex];
if (subopcodeByte != 0x01) { if (subopcodeByte != 0x01) {
throw new RuntimeException("Invalid sub-opcode byte for a PackedSwitchData pseudo-instruction"); throw new RuntimeException("Invalid sub-opcode byte for a PackedSwitchData pseudo-instruction");
} }
} }
public Format getFormat() { public Format getFormat() {
return Format.PackedSwitchData; return Format.PackedSwitchData;
} }
public int getTargetCount() { public int getTargetCount() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
} }
public int getFirstKey() { public int getFirstKey() {
return NumberUtils.decodeInt(buffer, bufferIndex + 4); return NumberUtils.decodeInt(buffer, bufferIndex + 4);
} }
public static class PackedSwitchTarget { public static class PackedSwitchTarget {
public int value; public int value;
public int target; public int target;
} }
public Iterator<PackedSwitchTarget> getTargets() { public Iterator<PackedSwitchTarget> getTargets() {
return new Iterator<PackedSwitchTarget>() { return new Iterator<PackedSwitchTarget>() {
final int targetCount = getTargetCount(); final int targetCount = getTargetCount();
int i = 0; int i = 0;
int position = bufferIndex + 8; int position = bufferIndex + 8;
int value = getFirstKey(); int value = getFirstKey();
PackedSwitchTarget packedSwitchTarget = new PackedSwitchTarget(); PackedSwitchTarget packedSwitchTarget = new PackedSwitchTarget();
public boolean hasNext() { public boolean hasNext() {
return i<targetCount; return i<targetCount;
} }
public PackedSwitchTarget next() { public PackedSwitchTarget next() {
packedSwitchTarget.value = value++; packedSwitchTarget.value = value++;
packedSwitchTarget.target = NumberUtils.decodeInt(buffer, position); packedSwitchTarget.target = NumberUtils.decodeInt(buffer, position);
position+=4; position+=4;
i++; i++;
return packedSwitchTarget; return packedSwitchTarget;
} }
public void remove() { public void remove() {
} }
}; };
} }
public static interface PackedSwitchTargetIteratorDelegate { public static interface PackedSwitchTargetIteratorDelegate {
void ProcessPackedSwitchTarget(int value, int target); void ProcessPackedSwitchTarget(int value, int target);
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
if (opcode != Opcode.NOP) { if (opcode != Opcode.NOP) {
throw new RuntimeException("The opcode for a PackedSwitchDataPseudoInstruction must by NOP"); throw new RuntimeException("The opcode for a PackedSwitchDataPseudoInstruction must by NOP");
} }
return new PackedSwitchDataPseudoInstruction(buffer, bufferIndex); return new PackedSwitchDataPseudoInstruction(buffer, bufferIndex);
} }
} }
} }

View File

@ -1,152 +1,151 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code.Format; package org.jf.dexlib.Code.Format;
import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Instruction;
import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.Opcode;
import org.jf.dexlib.Util.NumberUtils; import org.jf.dexlib.Util.NumberUtils;
import org.jf.dexlib.Util.Output; import org.jf.dexlib.Util.Output;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import java.util.Iterator; import java.util.Iterator;
public class SparseSwitchDataPseudoInstruction extends Instruction { public class SparseSwitchDataPseudoInstruction extends Instruction {
public static final Instruction.InstructionFactory Factory = new Factory(); public static final Instruction.InstructionFactory Factory = new Factory();
@Override @Override
public int getSize() { public int getSize() {
return getTargetCount() * 8 + 4; return getTargetCount() * 8 + 4;
} }
public static void emit(Output out, int[] keys, int[] targets) { public static void emit(Output out, int[] keys, int[] targets) {
if (keys.length != targets.length) { if (keys.length != targets.length) {
throw new RuntimeException("The number of keys and offsets don't match"); throw new RuntimeException("The number of keys and offsets don't match");
} }
if (targets.length == 0) { if (targets.length == 0) {
throw new RuntimeException("The sparse-switch data must contain at least 1 key/target"); throw new RuntimeException("The sparse-switch data must contain at least 1 key/target");
} }
if (targets.length > 0xFFFF) { if (targets.length > 0xFFFF) {
throw new RuntimeException("The sparse-switch data contains too many elements. " + throw new RuntimeException("The sparse-switch data contains too many elements. " +
"The maximum number of switch elements is 65535"); "The maximum number of switch elements is 65535");
} }
//write out padding, if necessary //write out padding, if necessary
if (out.getCursor() % 4 != 0) { if (out.getCursor() % 4 != 0) {
out.writeShort(0); out.writeShort(0);
} }
out.writeByte(0x00); out.writeByte(0x00);
out.writeByte(0x02); out.writeByte(0x02);
out.writeShort(targets.length); out.writeShort(targets.length);
if (targets.length > 0) { if (targets.length > 0) {
int key = keys[0]; int key = keys[0];
out.writeInt(key); out.writeInt(key);
for (int i = 1; i < keys.length; i++) { for (int i = 1; i < keys.length; i++) {
key = keys[i]; key = keys[i];
if (key <= keys[i - 1]) { if (key <= keys[i - 1]) {
throw new RuntimeException("The targets in a sparse switch block must be sorted in ascending" + throw new RuntimeException("The targets in a sparse switch block must be sorted in ascending" +
"order, by key"); "order, by key");
} }
out.writeInt(key); out.writeInt(key);
} }
for (int target : targets) { for (int target : targets) {
out.writeInt(target); out.writeInt(target);
} }
} }
} }
public SparseSwitchDataPseudoInstruction(byte[] buffer, int bufferIndex) { public SparseSwitchDataPseudoInstruction(byte[] buffer, int bufferIndex) {
super(Opcode.NOP, buffer, bufferIndex); super(Opcode.NOP, buffer, bufferIndex);
byte opcodeByte = buffer[bufferIndex++]; byte opcodeByte = buffer[bufferIndex++];
if (opcodeByte != 0x00) { if (opcodeByte != 0x00) {
throw new RuntimeException("Invalid opcode byte for a SparseSwitchData pseudo-instruction"); throw new RuntimeException("Invalid opcode byte for a SparseSwitchData pseudo-instruction");
} }
byte subopcodeByte = buffer[bufferIndex]; byte subopcodeByte = buffer[bufferIndex];
if (subopcodeByte != 0x02) { if (subopcodeByte != 0x02) {
throw new RuntimeException("Invalid sub-opcode byte for a SparseSwitchData pseudo-instruction"); throw new RuntimeException("Invalid sub-opcode byte for a SparseSwitchData pseudo-instruction");
} }
} }
public Format getFormat() { public Format getFormat() {
return Format.SparseSwitchData; return Format.SparseSwitchData;
} }
public int getTargetCount() { public int getTargetCount() {
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2); return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
} }
public static class SparseSwitchTarget { public static class SparseSwitchTarget {
public int value; public int value;
public int target; public int target;
} }
public Iterator<SparseSwitchTarget> getTargets() { public Iterator<SparseSwitchTarget> getTargets() {
return new Iterator<SparseSwitchTarget>() { return new Iterator<SparseSwitchTarget>() {
final int targetCount = getTargetCount(); final int targetCount = getTargetCount();
int i = 0; int i = 0;
int valuePosition = bufferIndex + 4; int valuePosition = bufferIndex + 4;
int targetPosition = bufferIndex + 4 + targetCount * 4; int targetPosition = bufferIndex + 4 + targetCount * 4;
SparseSwitchTarget sparseSwitchTarget = new SparseSwitchTarget(); SparseSwitchTarget sparseSwitchTarget = new SparseSwitchTarget();
public boolean hasNext() { public boolean hasNext() {
return i<targetCount; return i<targetCount;
} }
public SparseSwitchTarget next() { public SparseSwitchTarget next() {
sparseSwitchTarget.value = NumberUtils.decodeInt(buffer, valuePosition); sparseSwitchTarget.value = NumberUtils.decodeInt(buffer, valuePosition);
sparseSwitchTarget.target = NumberUtils.decodeInt(buffer, targetPosition); sparseSwitchTarget.target = NumberUtils.decodeInt(buffer, targetPosition);
valuePosition+=4; valuePosition+=4;
targetPosition+=4; targetPosition+=4;
i++; i++;
return sparseSwitchTarget; return sparseSwitchTarget;
} }
public void remove() { public void remove() {
} }
}; };
} }
private static class Factory implements Instruction.InstructionFactory { private static class Factory implements Instruction.InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) { public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
if (opcode != Opcode.NOP) { if (opcode != Opcode.NOP) {
throw new RuntimeException("The opcode for a SparseSwitchDataPseudoInstruction must by NOP"); throw new RuntimeException("The opcode for a SparseSwitchDataPseudoInstruction must by NOP");
} }
return new SparseSwitchDataPseudoInstruction(buffer, bufferIndex); return new SparseSwitchDataPseudoInstruction(buffer, bufferIndex);
} }
} }
}
}

View File

@ -1,73 +1,73 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code; package org.jf.dexlib.Code;
import org.jf.dexlib.*; import org.jf.dexlib.*;
import org.jf.dexlib.Code.Format.Format; import org.jf.dexlib.Code.Format.Format;
public abstract class Instruction { public abstract class Instruction {
public final Opcode opcode; public final Opcode opcode;
protected final byte[] buffer; protected final byte[] buffer;
protected final int bufferIndex; protected final int bufferIndex;
public int getSize() { public int getSize() {
return opcode.format.size; return opcode.format.size;
} }
protected Instruction(Opcode opcode) { protected Instruction(Opcode opcode) {
this.opcode = opcode; this.opcode = opcode;
this.bufferIndex = 0; this.bufferIndex = 0;
this.buffer = new byte[opcode.format.size]; this.buffer = new byte[opcode.format.size];
} }
protected Instruction(Opcode opcode, int bufferSize) { protected Instruction(Opcode opcode, int bufferSize) {
this.opcode = opcode; this.opcode = opcode;
this.bufferIndex = 0; this.bufferIndex = 0;
this.buffer = new byte[bufferSize]; this.buffer = new byte[bufferSize];
} }
protected Instruction(Opcode opcode, byte[] buffer, int bufferIndex) { protected Instruction(Opcode opcode, byte[] buffer, int bufferIndex) {
this.opcode = opcode; this.opcode = opcode;
this.buffer = buffer; this.buffer = buffer;
this.bufferIndex = bufferIndex; this.bufferIndex = bufferIndex;
if (buffer[bufferIndex] != opcode.value) { if (buffer[bufferIndex] != opcode.value) {
throw new RuntimeException("The given opcode doesn't match the opcode byte"); throw new RuntimeException("The given opcode doesn't match the opcode byte");
} }
} }
public abstract Format getFormat(); public abstract Format getFormat();
public static interface InstructionFactory { public static interface InstructionFactory {
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex); public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex);
} }
} }

View File

@ -1,310 +1,310 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code; package org.jf.dexlib.Code;
import org.jf.dexlib.Code.Format.Format; import org.jf.dexlib.Code.Format.Format;
import java.util.HashMap; import java.util.HashMap;
public enum Opcode public enum Opcode
{ {
NOP((byte)0x00, "nop", ReferenceType.none, Format.Format10x), NOP((byte)0x00, "nop", ReferenceType.none, Format.Format10x),
MOVE((byte)0x01, "move", ReferenceType.none, Format.Format12x), MOVE((byte)0x01, "move", ReferenceType.none, Format.Format12x),
MOVE_FROM16((byte)0x02, "move/from16", ReferenceType.none, Format.Format22x), MOVE_FROM16((byte)0x02, "move/from16", ReferenceType.none, Format.Format22x),
MOVE_16((byte)0x03, "move/16", ReferenceType.none, Format.Format32x), MOVE_16((byte)0x03, "move/16", ReferenceType.none, Format.Format32x),
MOVE_WIDE((byte)0x04, "move-wide", ReferenceType.none, Format.Format12x), MOVE_WIDE((byte)0x04, "move-wide", ReferenceType.none, Format.Format12x),
MOVE_WIDE_FROM16((byte)0x05, "move-wide/from16", ReferenceType.none, Format.Format22x), 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_WIDE_16((byte)0x06, "move-wide/16", ReferenceType.none, Format.Format32x),
MOVE_OBJECT((byte)0x07, "move-object", ReferenceType.none, Format.Format12x), MOVE_OBJECT((byte)0x07, "move-object", ReferenceType.none, Format.Format12x),
MOVE_OBJECT_FROM16((byte)0x08, "move-object/from16", ReferenceType.none, Format.Format22x), 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_OBJECT_16((byte)0x09, "move-object/16", ReferenceType.none, Format.Format32x),
MOVE_RESULT((byte)0x0a, "move-result", ReferenceType.none, Format.Format11x), MOVE_RESULT((byte)0x0a, "move-result", ReferenceType.none, Format.Format11x),
MOVE_RESULT_WIDE((byte)0x0b, "move-result-wide", 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_RESULT_OBJECT((byte)0x0c, "move-result-object", ReferenceType.none, Format.Format11x),
MOVE_EXCEPTION((byte)0x0d, "move-exception", 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_VOID((byte)0x0e, "return-void", ReferenceType.none, Format.Format10x),
RETURN((byte)0x0f, "return", ReferenceType.none, Format.Format11x), RETURN((byte)0x0f, "return", ReferenceType.none, Format.Format11x),
RETURN_WIDE((byte)0x10, "return-wide", ReferenceType.none, Format.Format11x), RETURN_WIDE((byte)0x10, "return-wide", ReferenceType.none, Format.Format11x),
RETURN_OBJECT((byte)0x11, "return-object", 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_4((byte)0x12, "const/4", ReferenceType.none, Format.Format11n),
CONST_16((byte)0x13, "const/16", ReferenceType.none, Format.Format21s), CONST_16((byte)0x13, "const/16", ReferenceType.none, Format.Format21s),
CONST((byte)0x14, "const", ReferenceType.none, Format.Format31i), CONST((byte)0x14, "const", ReferenceType.none, Format.Format31i),
CONST_HIGH16((byte)0x15, "const/high16", ReferenceType.none, Format.Format21h), CONST_HIGH16((byte)0x15, "const/high16", ReferenceType.none, Format.Format21h),
CONST_WIDE_16((byte)0x16, "const-wide/16", ReferenceType.none, Format.Format21s), 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_32((byte)0x17, "const-wide/32", ReferenceType.none, Format.Format31i),
CONST_WIDE((byte)0x18, "const-wide", ReferenceType.none, Format.Format51l), CONST_WIDE((byte)0x18, "const-wide", ReferenceType.none, Format.Format51l),
CONST_WIDE_HIGH16((byte)0x19, "const-wide/high16", ReferenceType.none, Format.Format21h), CONST_WIDE_HIGH16((byte)0x19, "const-wide/high16", ReferenceType.none, Format.Format21h),
CONST_STRING((byte)0x1a, "const-string", ReferenceType.string, Format.Format21c), CONST_STRING((byte)0x1a, "const-string", ReferenceType.string, Format.Format21c),
CONST_STRING_JUMBO((byte)0x1b, "const-string/jumbo", ReferenceType.string, Format.Format31c), CONST_STRING_JUMBO((byte)0x1b, "const-string/jumbo", ReferenceType.string, Format.Format31c),
CONST_CLASS((byte)0x1c, "const-class", ReferenceType.type, Format.Format21c), CONST_CLASS((byte)0x1c, "const-class", ReferenceType.type, Format.Format21c),
MONITOR_ENTER((byte)0x1d, "monitor-enter", ReferenceType.none, Format.Format11x), MONITOR_ENTER((byte)0x1d, "monitor-enter", ReferenceType.none, Format.Format11x),
MONITOR_EXIT((byte)0x1e, "monitor-exit", ReferenceType.none, Format.Format11x), MONITOR_EXIT((byte)0x1e, "monitor-exit", ReferenceType.none, Format.Format11x),
CHECK_CAST((byte)0x1f, "check-cast", ReferenceType.type, Format.Format21c), CHECK_CAST((byte)0x1f, "check-cast", ReferenceType.type, Format.Format21c),
INSTANCE_OF((byte)0x20, "instance-of", ReferenceType.type, Format.Format22c), INSTANCE_OF((byte)0x20, "instance-of", ReferenceType.type, Format.Format22c),
ARRAY_LENGTH((byte)0x21, "array-length", ReferenceType.none, Format.Format12x), ARRAY_LENGTH((byte)0x21, "array-length", ReferenceType.none, Format.Format12x),
NEW_INSTANCE((byte)0x22, "new-instance", ReferenceType.type, Format.Format21c), NEW_INSTANCE((byte)0x22, "new-instance", ReferenceType.type, Format.Format21c),
NEW_ARRAY((byte)0x23, "new-array", ReferenceType.type, Format.Format22c), 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((byte)0x24, "filled-new-array", ReferenceType.type, Format.Format35c),
FILLED_NEW_ARRAY_RANGE((byte)0x25, "filled-new-array/range", ReferenceType.type, Format.Format3rc), 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), FILL_ARRAY_DATA((byte)0x26, "fill-array-data", ReferenceType.none, Format.Format31t),
THROW((byte)0x27, "throw", ReferenceType.none, Format.Format11x), THROW((byte)0x27, "throw", ReferenceType.none, Format.Format11x),
GOTO((byte)0x28, "goto", ReferenceType.none, Format.Format10t), GOTO((byte)0x28, "goto", ReferenceType.none, Format.Format10t),
GOTO_16((byte)0x29, "goto/16", ReferenceType.none, Format.Format20t), GOTO_16((byte)0x29, "goto/16", ReferenceType.none, Format.Format20t),
GOTO_32((byte)0x2a, "goto/32", ReferenceType.none, Format.Format30t), GOTO_32((byte)0x2a, "goto/32", ReferenceType.none, Format.Format30t),
PACKED_SWITCH((byte)0x2b, "packed-switch", ReferenceType.none, Format.Format31t), PACKED_SWITCH((byte)0x2b, "packed-switch", ReferenceType.none, Format.Format31t),
SPARSE_SWITCH((byte)0x2c, "sparse-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), CMPL_FLOAT((byte)0x2d, "cmpl-float", ReferenceType.none, Format.Format23x),
CMPG_FLOAT((byte)0x2e, "cmpg-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), CMPL_DOUBLE((byte)0x2f, "cmpl-double", ReferenceType.none, Format.Format23x),
CMPG_DOUBLE((byte)0x30, "cmpg-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), CMP_LONG((byte)0x31, "cmp-long", ReferenceType.none, Format.Format23x),
IF_EQ((byte)0x32, "if-eq", ReferenceType.none, Format.Format22t), IF_EQ((byte)0x32, "if-eq", ReferenceType.none, Format.Format22t),
IF_NE((byte)0x33, "if-ne", 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_LT((byte)0x34, "if-lt", ReferenceType.none, Format.Format22t),
IF_GE((byte)0x35, "if-ge", 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_GT((byte)0x36, "if-gt", ReferenceType.none, Format.Format22t),
IF_LE((byte)0x37, "if-le", 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_EQZ((byte)0x38, "if-eqz", ReferenceType.none, Format.Format21t),
IF_NEZ((byte)0x39, "if-nez", 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_LTZ((byte)0x3a, "if-ltz", ReferenceType.none, Format.Format21t),
IF_GEZ((byte)0x3b, "if-gez", 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_GTZ((byte)0x3c, "if-gtz", ReferenceType.none, Format.Format21t),
IF_LEZ((byte)0x3d, "if-lez", ReferenceType.none, Format.Format21t), IF_LEZ((byte)0x3d, "if-lez", ReferenceType.none, Format.Format21t),
AGET((byte)0x44, "aget", ReferenceType.none, Format.Format23x), AGET((byte)0x44, "aget", ReferenceType.none, Format.Format23x),
AGET_WIDE((byte)0x45, "aget-wide", 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_OBJECT((byte)0x46, "aget-object", ReferenceType.none, Format.Format23x),
AGET_BOOLEAN((byte)0x47, "aget-boolean", 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_BYTE((byte)0x48, "aget-byte", ReferenceType.none, Format.Format23x),
AGET_CHAR((byte)0x49, "aget-char", ReferenceType.none, Format.Format23x), AGET_CHAR((byte)0x49, "aget-char", ReferenceType.none, Format.Format23x),
AGET_SHORT((byte)0x4a, "aget-short", ReferenceType.none, Format.Format23x), AGET_SHORT((byte)0x4a, "aget-short", ReferenceType.none, Format.Format23x),
APUT((byte)0x4b, "aput", ReferenceType.none, Format.Format23x), APUT((byte)0x4b, "aput", ReferenceType.none, Format.Format23x),
APUT_WIDE((byte)0x4c, "aput-wide", 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_OBJECT((byte)0x4d, "aput-object", ReferenceType.none, Format.Format23x),
APUT_BOOLEAN((byte)0x4e, "aput-boolean", 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_BYTE((byte)0x4f, "aput-byte", ReferenceType.none, Format.Format23x),
APUT_CHAR((byte)0x50, "aput-char", ReferenceType.none, Format.Format23x), APUT_CHAR((byte)0x50, "aput-char", ReferenceType.none, Format.Format23x),
APUT_SHORT((byte)0x51, "aput-short", ReferenceType.none, Format.Format23x), APUT_SHORT((byte)0x51, "aput-short", ReferenceType.none, Format.Format23x),
IGET((byte)0x52, "iget", ReferenceType.field, Format.Format22c), IGET((byte)0x52, "iget", ReferenceType.field, Format.Format22c),
IGET_WIDE((byte)0x53, "iget-wide", 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_OBJECT((byte)0x54, "iget-object", ReferenceType.field, Format.Format22c),
IGET_BOOLEAN((byte)0x55, "iget-boolean", 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_BYTE((byte)0x56, "iget-byte", ReferenceType.field, Format.Format22c),
IGET_CHAR((byte)0x57, "iget-char", ReferenceType.field, Format.Format22c), IGET_CHAR((byte)0x57, "iget-char", ReferenceType.field, Format.Format22c),
IGET_SHORT((byte)0x58, "iget-short", ReferenceType.field, Format.Format22c), IGET_SHORT((byte)0x58, "iget-short", ReferenceType.field, Format.Format22c),
IPUT((byte)0x59, "iput", ReferenceType.field, Format.Format22c), IPUT((byte)0x59, "iput", ReferenceType.field, Format.Format22c),
IPUT_WIDE((byte)0x5a, "iput-wide", 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_OBJECT((byte)0x5b, "iput-object", ReferenceType.field, Format.Format22c),
IPUT_BOOLEAN((byte)0x5c, "iput-boolean", 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_BYTE((byte)0x5d, "iput-byte", ReferenceType.field, Format.Format22c),
IPUT_CHAR((byte)0x5e, "iput-char", ReferenceType.field, Format.Format22c), IPUT_CHAR((byte)0x5e, "iput-char", ReferenceType.field, Format.Format22c),
IPUT_SHORT((byte)0x5f, "iput-short", ReferenceType.field, Format.Format22c), IPUT_SHORT((byte)0x5f, "iput-short", ReferenceType.field, Format.Format22c),
SGET((byte)0x60, "sget", ReferenceType.field, Format.Format21c), SGET((byte)0x60, "sget", ReferenceType.field, Format.Format21c),
SGET_WIDE((byte)0x61, "sget-wide", 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_OBJECT((byte)0x62, "sget-object", ReferenceType.field, Format.Format21c),
SGET_BOOLEAN((byte)0x63, "sget-boolean", 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_BYTE((byte)0x64, "sget-byte", ReferenceType.field, Format.Format21c),
SGET_CHAR((byte)0x65, "sget-char", ReferenceType.field, Format.Format21c), SGET_CHAR((byte)0x65, "sget-char", ReferenceType.field, Format.Format21c),
SGET_SHORT((byte)0x66, "sget-short", ReferenceType.field, Format.Format21c), SGET_SHORT((byte)0x66, "sget-short", ReferenceType.field, Format.Format21c),
SPUT((byte)0x67, "sput", ReferenceType.field, Format.Format21c), SPUT((byte)0x67, "sput", ReferenceType.field, Format.Format21c),
SPUT_WIDE((byte)0x68, "sput-wide", 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_OBJECT((byte)0x69, "sput-object", ReferenceType.field, Format.Format21c),
SPUT_BOOLEAN((byte)0x6a, "sput-boolean", 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_BYTE((byte)0x6b, "sput-byte", ReferenceType.field, Format.Format21c),
SPUT_CHAR((byte)0x6c, "sput-char", ReferenceType.field, Format.Format21c), SPUT_CHAR((byte)0x6c, "sput-char", ReferenceType.field, Format.Format21c),
SPUT_SHORT((byte)0x6d, "sput-short", 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_VIRTUAL((byte)0x6e, "invoke-virtual", ReferenceType.method, Format.Format35c),
INVOKE_SUPER((byte)0x6f, "invoke-super", 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_DIRECT((byte)0x70, "invoke-direct", ReferenceType.method, Format.Format35c),
INVOKE_STATIC((byte)0x71, "invoke-static", 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_INTERFACE((byte)0x72, "invoke-interface", ReferenceType.method, Format.Format35c),
INVOKE_VIRTUAL_RANGE((byte)0x74, "invoke-virtual/range", ReferenceType.method, Format.Format3rc), 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_SUPER_RANGE((byte)0x75, "invoke-super/range", ReferenceType.method, Format.Format3rc),
INVOKE_DIRECT_RANGE((byte)0x76, "invoke-direct/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_STATIC_RANGE((byte)0x77, "invoke-static/range", ReferenceType.method, Format.Format3rc),
INVOKE_INTERFACE_RANGE((byte)0x78, "invoke-interface/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), NEG_INT((byte)0x7b, "neg-int", ReferenceType.none, Format.Format12x),
NOT_INT((byte)0x7c, "not-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), NEG_LONG((byte)0x7d, "neg-long", ReferenceType.none, Format.Format12x),
NOT_LONG((byte)0x7e, "not-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_FLOAT((byte)0x7f, "neg-float", ReferenceType.none, Format.Format12x),
NEG_DOUBLE((byte)0x80, "neg-double", 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_LONG((byte)0x81, "int-to-long", ReferenceType.none, Format.Format12x),
INT_TO_FLOAT((byte)0x82, "int-to-float", 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), 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_INT((byte)0x84, "long-to-int", ReferenceType.none, Format.Format12x),
LONG_TO_FLOAT((byte)0x85, "long-to-float", 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), 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_INT((byte)0x87, "float-to-int", ReferenceType.none, Format.Format12x),
FLOAT_TO_LONG((byte)0x88, "float-to-long", 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), 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_INT((byte)0x8a, "double-to-int", ReferenceType.none, Format.Format12x),
DOUBLE_TO_LONG((byte)0x8b, "double-to-long", 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), 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_BYTE((byte)0x8d, "int-to-byte", ReferenceType.none, Format.Format12x),
INT_TO_CHAR((byte)0x8e, "int-to-char", 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), INT_TO_SHORT((byte)0x8f, "int-to-short", ReferenceType.none, Format.Format12x),
ADD_INT((byte)0x90, "add-int", ReferenceType.none, Format.Format23x), ADD_INT((byte)0x90, "add-int", ReferenceType.none, Format.Format23x),
SUB_INT((byte)0x91, "sub-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), MUL_INT((byte)0x92, "mul-int", ReferenceType.none, Format.Format23x),
DIV_INT((byte)0x93, "div-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), REM_INT((byte)0x94, "rem-int", ReferenceType.none, Format.Format23x),
AND_INT((byte)0x95, "and-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), OR_INT((byte)0x96, "or-int", ReferenceType.none, Format.Format23x),
XOR_INT((byte)0x97, "xor-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), SHL_INT((byte)0x98, "shl-int", ReferenceType.none, Format.Format23x),
SHR_INT((byte)0x99, "shr-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), USHR_INT((byte)0x9a, "ushr-int", ReferenceType.none, Format.Format23x),
ADD_LONG((byte)0x9b, "add-long", ReferenceType.none, Format.Format23x), ADD_LONG((byte)0x9b, "add-long", ReferenceType.none, Format.Format23x),
SUB_LONG((byte)0x9c, "sub-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), MUL_LONG((byte)0x9d, "mul-long", ReferenceType.none, Format.Format23x),
DIV_LONG((byte)0x9e, "div-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), REM_LONG((byte)0x9f, "rem-long", ReferenceType.none, Format.Format23x),
AND_LONG((byte)0xa0, "and-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), OR_LONG((byte)0xa1, "or-long", ReferenceType.none, Format.Format23x),
XOR_LONG((byte)0xa2, "xor-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), SHL_LONG((byte)0xa3, "shl-long", ReferenceType.none, Format.Format23x),
SHR_LONG((byte)0xa4, "shr-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), USHR_LONG((byte)0xa5, "ushr-long", ReferenceType.none, Format.Format23x),
ADD_FLOAT((byte)0xa6, "add-float", ReferenceType.none, Format.Format23x), ADD_FLOAT((byte)0xa6, "add-float", ReferenceType.none, Format.Format23x),
SUB_FLOAT((byte)0xa7, "sub-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), MUL_FLOAT((byte)0xa8, "mul-float", ReferenceType.none, Format.Format23x),
DIV_FLOAT((byte)0xa9, "div-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), REM_FLOAT((byte)0xaa, "rem-float", ReferenceType.none, Format.Format23x),
ADD_DOUBLE((byte)0xab, "add-double", ReferenceType.none, Format.Format23x), ADD_DOUBLE((byte)0xab, "add-double", ReferenceType.none, Format.Format23x),
SUB_DOUBLE((byte)0xac, "sub-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), MUL_DOUBLE((byte)0xad, "mul-double", ReferenceType.none, Format.Format23x),
DIV_DOUBLE((byte)0xae, "div-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), REM_DOUBLE((byte)0xaf, "rem-double", ReferenceType.none, Format.Format23x),
ADD_INT_2ADDR((byte)0xb0, "add-int/2addr", ReferenceType.none, Format.Format12x), ADD_INT_2ADDR((byte)0xb0, "add-int/2addr", ReferenceType.none, Format.Format12x),
SUB_INT_2ADDR((byte)0xb1, "sub-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), MUL_INT_2ADDR((byte)0xb2, "mul-int/2addr", ReferenceType.none, Format.Format12x),
DIV_INT_2ADDR((byte)0xb3, "div-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), REM_INT_2ADDR((byte)0xb4, "rem-int/2addr", ReferenceType.none, Format.Format12x),
AND_INT_2ADDR((byte)0xb5, "and-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), OR_INT_2ADDR((byte)0xb6, "or-int/2addr", ReferenceType.none, Format.Format12x),
XOR_INT_2ADDR((byte)0xb7, "xor-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), SHL_INT_2ADDR((byte)0xb8, "shl-int/2addr", ReferenceType.none, Format.Format12x),
SHR_INT_2ADDR((byte)0xb9, "shr-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), USHR_INT_2ADDR((byte)0xba, "ushr-int/2addr", ReferenceType.none, Format.Format12x),
ADD_LONG_2ADDR((byte)0xbb, "add-long/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), SUB_LONG_2ADDR((byte)0xbc, "sub-long/2addr", ReferenceType.none, Format.Format12x),
MUL_LONG_2ADDR((byte)0xbd, "mul-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), DIV_LONG_2ADDR((byte)0xbe, "div-long/2addr", ReferenceType.none, Format.Format12x),
REM_LONG_2ADDR((byte)0xbf, "rem-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), AND_LONG_2ADDR((byte)0xc0, "and-long/2addr", ReferenceType.none, Format.Format12x),
OR_LONG_2ADDR((byte)0xc1, "or-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), XOR_LONG_2ADDR((byte)0xc2, "xor-long/2addr", ReferenceType.none, Format.Format12x),
SHL_LONG_2ADDR((byte)0xc3, "shl-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), SHR_LONG_2ADDR((byte)0xc4, "shr-long/2addr", ReferenceType.none, Format.Format12x),
USHR_LONG_2ADDR((byte)0xc5, "ushr-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), ADD_FLOAT_2ADDR((byte)0xc6, "add-float/2addr", ReferenceType.none, Format.Format12x),
SUB_FLOAT_2ADDR((byte)0xc7, "sub-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), MUL_FLOAT_2ADDR((byte)0xc8, "mul-float/2addr", ReferenceType.none, Format.Format12x),
DIV_FLOAT_2ADDR((byte)0xc9, "div-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), REM_FLOAT_2ADDR((byte)0xca, "rem-float/2addr", ReferenceType.none, Format.Format12x),
ADD_DOUBLE_2ADDR((byte)0xcb, "add-double/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), SUB_DOUBLE_2ADDR((byte)0xcc, "sub-double/2addr", ReferenceType.none, Format.Format12x),
MUL_DOUBLE_2ADDR((byte)0xcd, "mul-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), DIV_DOUBLE_2ADDR((byte)0xce, "div-double/2addr", ReferenceType.none, Format.Format12x),
REM_DOUBLE_2ADDR((byte)0xcf, "rem-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), ADD_INT_LIT16((byte)0xd0, "add-int/lit16", ReferenceType.none, Format.Format22s),
RSUB_INT((byte)0xd1, "rsub-int", 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), MUL_INT_LIT16((byte)0xd2, "mul-int/lit16", ReferenceType.none, Format.Format22s),
DIV_INT_LIT16((byte)0xd3, "div-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), REM_INT_LIT16((byte)0xd4, "rem-int/lit16", ReferenceType.none, Format.Format22s),
AND_INT_LIT16((byte)0xd5, "and-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), OR_INT_LIT16((byte)0xd6, "or-int/lit16", ReferenceType.none, Format.Format22s),
XOR_INT_LIT16((byte)0xd7, "xor-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), ADD_INT_LIT8((byte)0xd8, "add-int/lit8", ReferenceType.none, Format.Format22b),
RSUB_INT_LIT8((byte)0xd9, "rsub-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), MUL_INT_LIT8((byte)0xda, "mul-int/lit8", ReferenceType.none, Format.Format22b),
DIV_INT_LIT8((byte)0xdb, "div-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), REM_INT_LIT8((byte)0xdc, "rem-int/lit8", ReferenceType.none, Format.Format22b),
AND_INT_LIT8((byte)0xdd, "and-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), OR_INT_LIT8((byte)0xde, "or-int/lit8", ReferenceType.none, Format.Format22b),
XOR_INT_LIT8((byte)0xdf, "xor-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), SHL_INT_LIT8((byte)0xe0, "shl-int/lit8", ReferenceType.none, Format.Format22b),
SHR_INT_LIT8((byte)0xe1, "shr-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), 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_EXECUTE_INLINE((byte)0xee, "execute_inline", ReferenceType.none, Format.Format35ms, true),
INVOKE_DIRECT_EMPTY((byte)0xf0, "invoke-direct-empty", ReferenceType.method, Format.Format35s, 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_QUICK((byte)0xf2, "iget-quick", ReferenceType.none, Format.Format22cs, true),
IGET_WIDE_QUICK((byte)0xf3, "iget-wide-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), 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_QUICK((byte)0xf5, "iput-quick", ReferenceType.none, Format.Format22cs, true),
IPUT_WIDE_QUICK((byte)0xf6, "iput-wide-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), 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_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_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_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); INVOKE_SUPER_RANGE_QUICK((byte)0xfb, "invoke-super-range-quick", ReferenceType.none, Format.Format3rms, true);
private static Opcode[] opcodesByValue; private static Opcode[] opcodesByValue;
private static HashMap<Integer, Opcode> opcodesByName; private static HashMap<Integer, Opcode> opcodesByName;
static { static {
opcodesByValue = new Opcode[256]; opcodesByValue = new Opcode[256];
opcodesByName = new HashMap<Integer, Opcode>(); opcodesByName = new HashMap<Integer, Opcode>();
for (Opcode opcode: Opcode.values()) { for (Opcode opcode: Opcode.values()) {
opcodesByValue[opcode.value & 0xFF] = opcode; opcodesByValue[opcode.value & 0xFF] = opcode;
opcodesByName.put(opcode.name.hashCode(), opcode); opcodesByName.put(opcode.name.hashCode(), opcode);
} }
} }
public static Opcode getOpcodeByName(String opcodeName) { public static Opcode getOpcodeByName(String opcodeName) {
return opcodesByName.get(opcodeName.toLowerCase().hashCode()); return opcodesByName.get(opcodeName.toLowerCase().hashCode());
} }
public static Opcode getOpcodeByValue(byte opcodeValue) { public static Opcode getOpcodeByValue(byte opcodeValue) {
return opcodesByValue[opcodeValue & 0xFF]; return opcodesByValue[opcodeValue & 0xFF];
} }
public final byte value; public final byte value;
public final String name; public final String name;
public final ReferenceType referenceType; public final ReferenceType referenceType;
public final Format format; public final Format format;
public final boolean odexOnly; public final boolean odexOnly;
Opcode(byte opcodeValue, String opcodeName, ReferenceType referenceType, Format format) { Opcode(byte opcodeValue, String opcodeName, ReferenceType referenceType, Format format) {
this(opcodeValue, opcodeName, referenceType, format, false); this(opcodeValue, opcodeName, referenceType, format, false);
} }
Opcode(byte opcodeValue, String opcodeName, ReferenceType referenceType, Format format, boolean odexOnly) { Opcode(byte opcodeValue, String opcodeName, ReferenceType referenceType, Format format, boolean odexOnly) {
this.value = opcodeValue; this.value = opcodeValue;
this.name = opcodeName; this.name = opcodeName;
this.referenceType = referenceType; this.referenceType = referenceType;
this.format = format; this.format = format;
this.odexOnly = odexOnly; this.odexOnly = odexOnly;
} }
} }

View File

@ -1,56 +1,56 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Code; package org.jf.dexlib.Code;
import org.jf.dexlib.*; import org.jf.dexlib.*;
public enum ReferenceType public enum ReferenceType
{ {
string, string,
type, type,
field, field,
method, method,
none; none;
public boolean checkItem(Item item) { public boolean checkItem(Item item) {
switch (this) { switch (this) {
case string: case string:
return item instanceof StringIdItem; return item instanceof StringIdItem;
case type: case type:
return item instanceof TypeIdItem; return item instanceof TypeIdItem;
case field: case field:
return item instanceof FieldIdItem; return item instanceof FieldIdItem;
case method: case method:
return item instanceof MethodIdItem; return item instanceof MethodIdItem;
case none: case none:
return item == null; return item == null;
} }
return false; 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"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.EncodedValue.ArrayEncodedSubValue; import org.jf.dexlib.EncodedValue.ArrayEncodedSubValue;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
public class EncodedArrayItem extends Item<EncodedArrayItem> { public class EncodedArrayItem extends Item<EncodedArrayItem> {
private int hashCode = 0; private int hashCode = 0;
private ArrayEncodedSubValue encodedArray; private ArrayEncodedSubValue encodedArray;
/** /**
* Creates a new uninitialized <code>EncodedArrayItem</code> * Creates a new uninitialized <code>EncodedArrayItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected EncodedArrayItem(DexFile dexFile) { protected EncodedArrayItem(DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** /**
* Creates a new <code>EncodedArrayItem</code> with the given values * Creates a new <code>EncodedArrayItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param encodedArray The encoded array value * @param encodedArray The encoded array value
*/ */
private EncodedArrayItem(DexFile dexFile, ArrayEncodedSubValue encodedArray) { private EncodedArrayItem(DexFile dexFile, ArrayEncodedSubValue encodedArray) {
super(dexFile); super(dexFile);
this.encodedArray = encodedArray; this.encodedArray = encodedArray;
} }
/** /**
* Returns an <code>EncodedArrayItem</code> for the given values, and that has been interned into the given * Returns an <code>EncodedArrayItem</code> for the given values, and that has been interned into the given
* <code>DexFile</code> * <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param encodedArray The encoded array value * @param encodedArray The encoded array value
* @return an <code>EncodedArrayItem</code> for the given values, and that has been interned into the given * @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) { public static EncodedArrayItem getInternedEncodedArrayItem(DexFile dexFile, ArrayEncodedSubValue encodedArray) {
EncodedArrayItem encodedArrayItem = new EncodedArrayItem(dexFile, encodedArray); EncodedArrayItem encodedArrayItem = new EncodedArrayItem(dexFile, encodedArray);
return dexFile.EncodedArraysSection.intern(encodedArrayItem); return dexFile.EncodedArraysSection.intern(encodedArrayItem);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
encodedArray = new ArrayEncodedSubValue(dexFile, in); encodedArray = new ArrayEncodedSubValue(dexFile, in);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return encodedArray.placeValue(offset); return encodedArray.placeValue(offset);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
encodedArray.writeValue(out); encodedArray.writeValue(out);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_ENCODED_ARRAY_ITEM; return ItemType.TYPE_ENCODED_ARRAY_ITEM;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "encoded_array @0x" + Integer.toHexString(getOffset()); return "encoded_array @0x" + Integer.toHexString(getOffset());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(EncodedArrayItem encodedArrayItem) { public int compareTo(EncodedArrayItem encodedArrayItem) {
return encodedArray.compareTo(encodedArrayItem.encodedArray); return encodedArray.compareTo(encodedArrayItem.encodedArray);
} }
/** /**
* @return The encoded array value * @return The encoded array value
*/ */
public ArrayEncodedSubValue getEncodedArray() { public ArrayEncodedSubValue getEncodedArray() {
return encodedArray; return encodedArray;
} }
/** /**
* calculate and cache the hashcode * calculate and cache the hashcode
*/ */
private void calcHashCode() { private void calcHashCode() {
hashCode = encodedArray.hashCode(); hashCode = encodedArray.hashCode();
} }
@Override @Override
public int hashCode() { public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll //there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time //just end up recalculating it each time
if (hashCode == 0) if (hashCode == 0)
calcHashCode(); calcHashCode();
return hashCode; return hashCode;
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this==o) { if (this==o) {
return true; return true;
} }
if (o==null || !this.getClass().equals(o.getClass())) { if (o==null || !this.getClass().equals(o.getClass())) {
return false; return false;
} }
EncodedArrayItem other = (EncodedArrayItem)o; EncodedArrayItem other = (EncodedArrayItem)o;
return (encodedArray.compareTo(other.encodedArray) == 0); return (encodedArray.compareTo(other.encodedArray) == 0);
} }
} }

View File

@ -1,86 +1,86 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.EncodedValue; package org.jf.dexlib.EncodedValue;
import org.jf.dexlib.Util.SparseArray; import org.jf.dexlib.Util.SparseArray;
public enum ValueType { public enum ValueType {
VALUE_BYTE((byte) 0x00), VALUE_BYTE((byte) 0x00),
VALUE_SHORT((byte) 0x02), VALUE_SHORT((byte) 0x02),
VALUE_CHAR((byte) 0x03), VALUE_CHAR((byte) 0x03),
VALUE_INT((byte) 0x04), VALUE_INT((byte) 0x04),
VALUE_LONG((byte) 0x06), VALUE_LONG((byte) 0x06),
VALUE_FLOAT((byte) 0x10), VALUE_FLOAT((byte) 0x10),
VALUE_DOUBLE((byte) 0x11), VALUE_DOUBLE((byte) 0x11),
VALUE_STRING((byte) 0x17), VALUE_STRING((byte) 0x17),
VALUE_TYPE((byte) 0x18), VALUE_TYPE((byte) 0x18),
VALUE_FIELD((byte) 0x19), VALUE_FIELD((byte) 0x19),
VALUE_METHOD((byte) 0x1a), VALUE_METHOD((byte) 0x1a),
VALUE_ENUM((byte) 0x1b), VALUE_ENUM((byte) 0x1b),
VALUE_ARRAY((byte) 0x1c), VALUE_ARRAY((byte) 0x1c),
VALUE_ANNOTATION((byte) 0x1d), VALUE_ANNOTATION((byte) 0x1d),
VALUE_NULL((byte) 0x1e), VALUE_NULL((byte) 0x1e),
VALUE_BOOLEAN((byte) 0x1f); VALUE_BOOLEAN((byte) 0x1f);
/** /**
* A map to facilitate looking up a <code>ValueType</code> by byte value * A map to facilitate looking up a <code>ValueType</code> by byte value
*/ */
private final static SparseArray<ValueType> valueTypeIntegerMap; private final static SparseArray<ValueType> valueTypeIntegerMap;
static { static {
/** build the <code>valueTypeIntegerMap</code> object */ /** build the <code>valueTypeIntegerMap</code> object */
valueTypeIntegerMap = new SparseArray<ValueType>(16); valueTypeIntegerMap = new SparseArray<ValueType>(16);
for (ValueType valueType : ValueType.values()) { for (ValueType valueType : ValueType.values()) {
valueTypeIntegerMap.put(valueType.value, valueType); valueTypeIntegerMap.put(valueType.value, valueType);
} }
} }
/** /**
* The byte value for this ValueType * The byte value for this ValueType
*/ */
public final byte value; public final byte value;
private ValueType(byte value) { private ValueType(byte value) {
this.value = value; this.value = value;
} }
/** /**
* Converts a byte value to the corresponding ValueType enum value, * Converts a byte value to the corresponding ValueType enum value,
* or null if the value isn't a valid ValueType value * or null if the value isn't a valid ValueType value
* *
* @param valueType the byte value to convert to a ValueType * @param valueType the byte value to convert to a ValueType
* @return the ValueType enum value corresponding to valueType, or null * @return the ValueType enum value corresponding to valueType, or null
* if not a valid ValueType value * if not a valid ValueType value
*/ */
public static ValueType fromByte(byte valueType) { public static ValueType fromByte(byte valueType) {
return valueTypeIntegerMap.get(valueType); return valueTypeIntegerMap.get(valueType);
} }
} }

View File

@ -1,217 +1,217 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
public class FieldIdItem extends Item<FieldIdItem> { public class FieldIdItem extends Item<FieldIdItem> {
private int hashCode = 0; private int hashCode = 0;
private TypeIdItem classType; private TypeIdItem classType;
private TypeIdItem fieldType; private TypeIdItem fieldType;
private StringIdItem fieldName; private StringIdItem fieldName;
/** /**
* Creates a new uninitialized <code>FieldIdItem</code> * Creates a new uninitialized <code>FieldIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected FieldIdItem(DexFile dexFile) { protected FieldIdItem(DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** /**
* Creates a new <code>FieldIdItem</code> for the given class, type and name * 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 dexFile The <code>DexFile</code> that this item belongs to
* @param classType the class that the field is a member of * @param classType the class that the field is a member of
* @param fieldType the type of the field * @param fieldType the type of the field
* @param fieldName the name of the field * @param fieldName the name of the field
*/ */
private FieldIdItem(DexFile dexFile, TypeIdItem classType, TypeIdItem fieldType, StringIdItem fieldName) { private FieldIdItem(DexFile dexFile, TypeIdItem classType, TypeIdItem fieldType, StringIdItem fieldName) {
this(dexFile); this(dexFile);
assert classType.dexFile == dexFile; assert classType.dexFile == dexFile;
assert fieldType.dexFile == dexFile; assert fieldType.dexFile == dexFile;
assert fieldName.dexFile == dexFile; assert fieldName.dexFile == dexFile;
this.classType = classType; this.classType = classType;
this.fieldType = fieldType; this.fieldType = fieldType;
this.fieldName = fieldName; this.fieldName = fieldName;
} }
/** /**
* Returns a <code>FieldIdItem</code> for the given values, and that has been interned into * Returns a <code>FieldIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType the class that the field is a member of * @param classType the class that the field is a member of
* @param fieldType the type of the field * @param fieldType the type of the field
* @param fieldName the name 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 * @return a <code>FieldIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
*/ */
public static FieldIdItem getInternedFieldIdItem(DexFile dexFile, TypeIdItem classType, TypeIdItem fieldType, public static FieldIdItem getInternedFieldIdItem(DexFile dexFile, TypeIdItem classType, TypeIdItem fieldType,
StringIdItem fieldName) { StringIdItem fieldName) {
FieldIdItem fieldIdItem = new FieldIdItem(dexFile, classType, fieldType, fieldName); FieldIdItem fieldIdItem = new FieldIdItem(dexFile, classType, fieldType, fieldName);
return dexFile.FieldIdsSection.intern(fieldIdItem); return dexFile.FieldIdsSection.intern(fieldIdItem);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
classType = dexFile.TypeIdsSection.getItemByIndex(in.readShort()); classType = dexFile.TypeIdsSection.getItemByIndex(in.readShort());
fieldType = dexFile.TypeIdsSection.getItemByIndex(in.readShort()); fieldType = dexFile.TypeIdsSection.getItemByIndex(in.readShort());
fieldName = dexFile.StringIdsSection.getItemByIndex(in.readInt()); fieldName = dexFile.StringIdsSection.getItemByIndex(in.readInt());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return offset + 8; return offset + 8;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(2, "class_type: " + classType.getTypeDescriptor()); out.annotate(2, "class_type: " + classType.getTypeDescriptor());
out.annotate(2, "field_type: " + fieldType.getTypeDescriptor()); out.annotate(2, "field_type: " + fieldType.getTypeDescriptor());
out.annotate(4, "field_name: " + fieldName.getStringValue()); out.annotate(4, "field_name: " + fieldName.getStringValue());
} }
out.writeShort(classType.getIndex()); out.writeShort(classType.getIndex());
out.writeShort(fieldType.getIndex()); out.writeShort(fieldType.getIndex());
out.writeInt(fieldName.getIndex()); out.writeInt(fieldName.getIndex());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_FIELD_ID_ITEM; return ItemType.TYPE_FIELD_ID_ITEM;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
String parentClass = classType.getTypeDescriptor(); String parentClass = classType.getTypeDescriptor();
//strip off the leading L and trailing ; //strip off the leading L and trailing ;
parentClass = parentClass.substring(1, parentClass.length() - 1); parentClass = parentClass.substring(1, parentClass.length() - 1);
return parentClass + "/" + fieldName.getStringValue() + return parentClass + "/" + fieldName.getStringValue() +
":" + fieldType.getTypeDescriptor(); ":" + fieldType.getTypeDescriptor();
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(FieldIdItem o) { public int compareTo(FieldIdItem o) {
int result = classType.compareTo(o.classType); int result = classType.compareTo(o.classType);
if (result != 0) { if (result != 0) {
return result; return result;
} }
result = fieldName.compareTo(o.fieldName); result = fieldName.compareTo(o.fieldName);
if (result != 0) { if (result != 0) {
return result; return result;
} }
return fieldType.compareTo(o.fieldType); return fieldType.compareTo(o.fieldType);
} }
/** /**
* @return the class that this field is a member of * @return the class that this field is a member of
*/ */
public TypeIdItem getContainingClass() { public TypeIdItem getContainingClass() {
return classType; return classType;
} }
/** /**
* @return the type of this field * @return the type of this field
*/ */
public TypeIdItem getFieldType() { public TypeIdItem getFieldType() {
return fieldType; return fieldType;
} }
/** /**
* @return the field name * @return the field name
*/ */
public StringIdItem getFieldName() { public StringIdItem getFieldName() {
return fieldName; return fieldName;
} }
String cachedFieldString = null; String cachedFieldString = null;
/** /**
* @return a string formatted like LclassName;->fieldName:fieldType * @return a string formatted like LclassName;->fieldName:fieldType
*/ */
public String getFieldString() { public String getFieldString() {
if (cachedFieldString == null) { if (cachedFieldString == null) {
String typeDescriptor = classType.getTypeDescriptor(); String typeDescriptor = classType.getTypeDescriptor();
String fieldName = this.fieldName.getStringValue(); String fieldName = this.fieldName.getStringValue();
String fieldType = this.fieldType.getTypeDescriptor(); String fieldType = this.fieldType.getTypeDescriptor();
StringBuffer sb = new StringBuffer(typeDescriptor.length() + fieldName.length() + fieldType.length() + 3); StringBuffer sb = new StringBuffer(typeDescriptor.length() + fieldName.length() + fieldType.length() + 3);
sb.append(typeDescriptor); sb.append(typeDescriptor);
sb.append("->"); sb.append("->");
sb.append(fieldName); sb.append(fieldName);
sb.append(":"); sb.append(":");
sb.append(fieldType); sb.append(fieldType);
cachedFieldString = sb.toString(); cachedFieldString = sb.toString();
} }
return cachedFieldString; return cachedFieldString;
} }
/** /**
* calculate and cache the hashcode * calculate and cache the hashcode
*/ */
private void calcHashCode() { private void calcHashCode() {
hashCode = classType.hashCode(); hashCode = classType.hashCode();
hashCode = 31 * hashCode + fieldType.hashCode(); hashCode = 31 * hashCode + fieldType.hashCode();
hashCode = 31 * hashCode + fieldName.hashCode(); hashCode = 31 * hashCode + fieldName.hashCode();
} }
@Override @Override
public int hashCode() { public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll //there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time //just end up recalculating it each time
if (hashCode == 0) if (hashCode == 0)
calcHashCode(); calcHashCode();
return hashCode; return hashCode;
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this==o) { if (this==o) {
return true; return true;
} }
if (o==null || !this.getClass().equals(o.getClass())) { if (o==null || !this.getClass().equals(o.getClass())) {
return false; return false;
} }
//This assumes that the referenced items have been interned in both objects. //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 //This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created //"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned //internally is guaranteed to be interned
FieldIdItem other = (FieldIdItem)o; FieldIdItem other = (FieldIdItem)o;
return (classType == other.classType && return (classType == other.classType &&
fieldType == other.fieldType && fieldType == other.fieldType &&
fieldName == other.fieldName); fieldName == other.fieldName);
} }
} }

View File

@ -1,234 +1,234 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.Utf8Utils; import org.jf.dexlib.Util.Utf8Utils;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
public class HeaderItem extends Item<HeaderItem> { public class HeaderItem extends Item<HeaderItem> {
/** /**
* the file format magic number, represented as the * the file format magic number, represented as the
* low-order bytes of a string * low-order bytes of a string
*/ */
public static final byte[] MAGIC = new byte[] {0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x35, 0x00};//"dex\n035" + '\0'; public static final byte[] MAGIC = new byte[] {0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x35, 0x00};//"dex\n035" + '\0';
/** size of this section, in bytes */ /** size of this section, in bytes */
private static final int HEADER_SIZE = 0x70; private static final int HEADER_SIZE = 0x70;
/** the endianness constants */ /** the endianness constants */
private static final int LITTLE_ENDIAN = 0x12345678; private static final int LITTLE_ENDIAN = 0x12345678;
private static final int BIG_ENDIAN = 0x78562312; private static final int BIG_ENDIAN = 0x78562312;
/** /**
* Create a new uninitialized <code>HeaderItem</code> * Create a new uninitialized <code>HeaderItem</code>
* @param dexFile The <code>DexFile</code> containing this <code>HeaderItem</code> * @param dexFile The <code>DexFile</code> containing this <code>HeaderItem</code>
*/ */
protected HeaderItem(final DexFile dexFile) { protected HeaderItem(final DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
byte[] readMagic = in.readBytes(8); byte[] readMagic = in.readBytes(8);
for (int i=0; i<8; i++) { for (int i=0; i<8; i++) {
if (MAGIC[i] != readMagic[i]) { if (MAGIC[i] != readMagic[i]) {
throw new RuntimeException("The magic value is not the expected value"); throw new RuntimeException("The magic value is not the expected value");
} }
} }
in.readBytes(20); //checksum in.readBytes(20); //checksum
in.readInt(); //signature in.readInt(); //signature
in.readInt(); //filesize in.readInt(); //filesize
if (in.readInt() != HEADER_SIZE) { if (in.readInt() != HEADER_SIZE) {
throw new RuntimeException("The header size is not the expected value (0x70)"); throw new RuntimeException("The header size is not the expected value (0x70)");
} }
int endianTag = in.readInt(); int endianTag = in.readInt();
if (endianTag == BIG_ENDIAN) { if (endianTag == BIG_ENDIAN) {
throw new RuntimeException("This dex file is big endian. Only little endian is currently supported."); throw new RuntimeException("This dex file is big endian. Only little endian is currently supported.");
} else if (endianTag != LITTLE_ENDIAN) { } else if (endianTag != LITTLE_ENDIAN) {
throw new RuntimeException("The endian tag is not 0x12345678 or 0x78563412"); throw new RuntimeException("The endian tag is not 0x12345678 or 0x78563412");
} }
//link_size //link_size
if (in.readInt() != 0) { if (in.readInt() != 0) {
throw new RuntimeException("This dex file has a link section, which is not supported"); throw new RuntimeException("This dex file has a link section, which is not supported");
} }
//link_off //link_off
if (in.readInt() != 0) { if (in.readInt() != 0) {
throw new RuntimeException("This dex file has a link section, which is not supported"); throw new RuntimeException("This dex file has a link section, which is not supported");
} }
int sectionSize; int sectionSize;
int sectionOffset; int sectionOffset;
//map_offset //map_offset
sectionOffset = in.readInt(); sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_MAP_LIST, 1, sectionOffset); readContext.addSection(ItemType.TYPE_MAP_LIST, 1, sectionOffset);
//string_id_item //string_id_item
sectionSize = in.readInt(); sectionSize = in.readInt();
sectionOffset = in.readInt(); sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_STRING_ID_ITEM, sectionSize, sectionOffset); readContext.addSection(ItemType.TYPE_STRING_ID_ITEM, sectionSize, sectionOffset);
//type_id_item //type_id_item
sectionSize = in.readInt(); sectionSize = in.readInt();
sectionOffset = in.readInt(); sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_TYPE_ID_ITEM, sectionSize, sectionOffset); readContext.addSection(ItemType.TYPE_TYPE_ID_ITEM, sectionSize, sectionOffset);
//proto_id_item //proto_id_item
sectionSize = in.readInt(); sectionSize = in.readInt();
sectionOffset = in.readInt(); sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_PROTO_ID_ITEM, sectionSize, sectionOffset); readContext.addSection(ItemType.TYPE_PROTO_ID_ITEM, sectionSize, sectionOffset);
//field_id_item //field_id_item
sectionSize = in.readInt(); sectionSize = in.readInt();
sectionOffset = in.readInt(); sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_FIELD_ID_ITEM, sectionSize, sectionOffset); readContext.addSection(ItemType.TYPE_FIELD_ID_ITEM, sectionSize, sectionOffset);
//method_id_item //method_id_item
sectionSize = in.readInt(); sectionSize = in.readInt();
sectionOffset = in.readInt(); sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_METHOD_ID_ITEM, sectionSize, sectionOffset); readContext.addSection(ItemType.TYPE_METHOD_ID_ITEM, sectionSize, sectionOffset);
//class_data_item //class_data_item
sectionSize = in.readInt(); sectionSize = in.readInt();
sectionOffset = in.readInt(); sectionOffset = in.readInt();
readContext.addSection(ItemType.TYPE_CLASS_DEF_ITEM, sectionSize, sectionOffset); readContext.addSection(ItemType.TYPE_CLASS_DEF_ITEM, sectionSize, sectionOffset);
in.readInt(); //data_size in.readInt(); //data_size
in.readInt(); //data_off in.readInt(); //data_off
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return HEADER_SIZE; return HEADER_SIZE;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
StringBuilder magicBuilder = new StringBuilder(); StringBuilder magicBuilder = new StringBuilder();
for (int i=0; i<8; i++) { for (int i=0; i<8; i++) {
magicBuilder.append((char)MAGIC[i]); magicBuilder.append((char)MAGIC[i]);
} }
out.annotate("magic: " + Utf8Utils.escapeString(magicBuilder.toString())); out.annotate("magic: " + Utf8Utils.escapeString(magicBuilder.toString()));
out.write(MAGIC); out.write(MAGIC);
out.annotate("checksum"); out.annotate("checksum");
out.writeInt(0); out.writeInt(0);
out.annotate("signature"); out.annotate("signature");
out.write(new byte[20]); out.write(new byte[20]);
out.annotate("file_size: 0x" + Integer.toHexString(dexFile.getFileSize()) + " (" + dexFile.getFileSize() + out.annotate("file_size: 0x" + Integer.toHexString(dexFile.getFileSize()) + " (" + dexFile.getFileSize() +
" bytes)"); " bytes)");
out.writeInt(dexFile.getFileSize()); out.writeInt(dexFile.getFileSize());
out.annotate("header_size: 0x" + Integer.toHexString(HEADER_SIZE)); out.annotate("header_size: 0x" + Integer.toHexString(HEADER_SIZE));
out.writeInt(HEADER_SIZE); out.writeInt(HEADER_SIZE);
out.annotate("endian_tag: 0x" + Integer.toHexString(LITTLE_ENDIAN)); out.annotate("endian_tag: 0x" + Integer.toHexString(LITTLE_ENDIAN));
out.writeInt(LITTLE_ENDIAN); out.writeInt(LITTLE_ENDIAN);
out.annotate("link_size: 0"); out.annotate("link_size: 0");
out.writeInt(0); out.writeInt(0);
out.annotate("link_off: 0"); out.annotate("link_off: 0");
out.writeInt(0); out.writeInt(0);
out.annotate("map_off: 0x" + Integer.toHexString(dexFile.MapItem.getOffset())); out.annotate("map_off: 0x" + Integer.toHexString(dexFile.MapItem.getOffset()));
out.writeInt(dexFile.MapItem.getOffset()); out.writeInt(dexFile.MapItem.getOffset());
out.annotate("string_ids_size: " + dexFile.StringIdsSection.getItems().size()); out.annotate("string_ids_size: " + dexFile.StringIdsSection.getItems().size());
out.writeInt(dexFile.StringIdsSection.getItems().size()); out.writeInt(dexFile.StringIdsSection.getItems().size());
out.annotate("string_ids_off: 0x" + Integer.toHexString(dexFile.StringIdsSection.getOffset())); out.annotate("string_ids_off: 0x" + Integer.toHexString(dexFile.StringIdsSection.getOffset()));
out.writeInt(dexFile.StringIdsSection.getOffset()); out.writeInt(dexFile.StringIdsSection.getOffset());
out.annotate("type_ids_size: " + dexFile.TypeIdsSection.getItems().size()); out.annotate("type_ids_size: " + dexFile.TypeIdsSection.getItems().size());
out.writeInt(dexFile.TypeIdsSection.getItems().size()); out.writeInt(dexFile.TypeIdsSection.getItems().size());
out.annotate("type_ids_off: 0x" + Integer.toHexString(dexFile.TypeIdsSection.getOffset())); out.annotate("type_ids_off: 0x" + Integer.toHexString(dexFile.TypeIdsSection.getOffset()));
out.writeInt(dexFile.TypeIdsSection.getOffset()); out.writeInt(dexFile.TypeIdsSection.getOffset());
out.annotate("proto_ids_size: " + dexFile.ProtoIdsSection.getItems().size()); out.annotate("proto_ids_size: " + dexFile.ProtoIdsSection.getItems().size());
out.writeInt(dexFile.ProtoIdsSection.getItems().size()); out.writeInt(dexFile.ProtoIdsSection.getItems().size());
out.annotate("proto_ids_off: 0x" + Integer.toHexString(dexFile.ProtoIdsSection.getOffset())); out.annotate("proto_ids_off: 0x" + Integer.toHexString(dexFile.ProtoIdsSection.getOffset()));
out.writeInt(dexFile.ProtoIdsSection.getOffset()); out.writeInt(dexFile.ProtoIdsSection.getOffset());
out.annotate("field_ids_size: " + dexFile.FieldIdsSection.getItems().size()); out.annotate("field_ids_size: " + dexFile.FieldIdsSection.getItems().size());
out.writeInt(dexFile.FieldIdsSection.getItems().size()); out.writeInt(dexFile.FieldIdsSection.getItems().size());
out.annotate("field_ids_off: 0x" + Integer.toHexString(dexFile.FieldIdsSection.getOffset())); out.annotate("field_ids_off: 0x" + Integer.toHexString(dexFile.FieldIdsSection.getOffset()));
out.writeInt(dexFile.FieldIdsSection.getOffset()); out.writeInt(dexFile.FieldIdsSection.getOffset());
out.annotate("method_ids_size: " + dexFile.MethodIdsSection.getItems().size()); out.annotate("method_ids_size: " + dexFile.MethodIdsSection.getItems().size());
out.writeInt(dexFile.MethodIdsSection.getItems().size()); out.writeInt(dexFile.MethodIdsSection.getItems().size());
out.annotate("method_ids_off: 0x" + Integer.toHexString(dexFile.MethodIdsSection.getOffset())); out.annotate("method_ids_off: 0x" + Integer.toHexString(dexFile.MethodIdsSection.getOffset()));
out.writeInt(dexFile.MethodIdsSection.getOffset()); out.writeInt(dexFile.MethodIdsSection.getOffset());
out.annotate("class_defs_size: " + dexFile.ClassDefsSection.getItems().size()); out.annotate("class_defs_size: " + dexFile.ClassDefsSection.getItems().size());
out.writeInt(dexFile.ClassDefsSection.getItems().size()); out.writeInt(dexFile.ClassDefsSection.getItems().size());
out.annotate("class_defs_off: 0x" + Integer.toHexString(dexFile.ClassDefsSection.getOffset())); out.annotate("class_defs_off: 0x" + Integer.toHexString(dexFile.ClassDefsSection.getOffset()));
out.writeInt(dexFile.ClassDefsSection.getOffset()); out.writeInt(dexFile.ClassDefsSection.getOffset());
out.annotate("data_size: 0x" + Integer.toHexString(dexFile.getDataSize()) + " (" + dexFile.getDataSize() + out.annotate("data_size: 0x" + Integer.toHexString(dexFile.getDataSize()) + " (" + dexFile.getDataSize() +
" bytes)"); " bytes)");
out.writeInt(dexFile.getDataSize()); out.writeInt(dexFile.getDataSize());
out.annotate("data_off: 0x" + Integer.toHexString(dexFile.getDataOffset())); out.annotate("data_off: 0x" + Integer.toHexString(dexFile.getDataOffset()));
out.writeInt(dexFile.getDataOffset()); out.writeInt(dexFile.getDataOffset());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_HEADER_ITEM; return ItemType.TYPE_HEADER_ITEM;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "header_item"; return "header_item";
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(HeaderItem o) { public int compareTo(HeaderItem o) {
//there is only 1 header item //there is only 1 header item
return 0; return 0;
} }
} }

View File

@ -1,67 +1,67 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
public class IndexedSection<T extends Item> extends Section<T> { public class IndexedSection<T extends Item> extends Section<T> {
/** /**
* Create a new indexed section * Create a new indexed section
* @param dexFile The <code>DexFile</code> that this section belongs to * @param dexFile The <code>DexFile</code> that this section belongs to
* @param itemType The itemType that this section will hold * @param itemType The itemType that this section will hold
*/ */
public IndexedSection(DexFile dexFile, ItemType itemType) { public IndexedSection(DexFile dexFile, ItemType itemType) {
super(dexFile, itemType); super(dexFile, itemType);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItems(Input in, ReadContext readContext) { protected void readItems(Input in, ReadContext readContext) {
for (int i = 0; i < items.size(); i++) { for (int i = 0; i < items.size(); i++) {
T item = (T)ItemFactory.makeItem(ItemType, DexFile); T item = (T)ItemFactory.makeItem(ItemType, DexFile);
items.set(i, item); items.set(i, item);
item.readFrom(in, i, readContext); item.readFrom(in, i, readContext);
} }
} }
/** /**
* Gets the item at the specified index in this section * Gets the item at the specified index in this section
* @param index the index of the item to get * @param index the index of the item to get
* @return the item at the specified index in this section * @return the item at the specified index in this section
* @throws IndexOutOfBoundsException if index is outside the bounds of this section * @throws IndexOutOfBoundsException if index is outside the bounds of this section
*/ */
public T getItemByIndex(int index) { public T getItemByIndex(int index) {
if (index == -1) { if (index == -1) {
return null; return null;
} }
//if index is out of bounds, just let it throw an exception //if index is out of bounds, just let it throw an exception
return items.get(index); return items.get(index);
} }
} }

View File

@ -1,182 +1,182 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AlignmentUtils; import org.jf.dexlib.Util.AlignmentUtils;
public abstract class Item<T extends Item> implements Comparable<T> { public abstract class Item<T extends Item> implements Comparable<T> {
/** /**
* The offset of this item in the dex file, or -1 if not known * The offset of this item in the dex file, or -1 if not known
*/ */
protected int offset = -1; protected int offset = -1;
/** /**
* The index of this item in the containing section, or -1 if not known * The index of this item in the containing section, or -1 if not known
*/ */
protected int index = -1; protected int index = -1;
/** /**
* The DexFile that this item is associatedr with * The DexFile that this item is associatedr with
*/ */
protected final DexFile dexFile; protected final DexFile dexFile;
/** /**
* The constructor that is used when reading in a <code>DexFile</code> * The constructor that is used when reading in a <code>DexFile</code>
* @param dexFile the <code>DexFile</code> that this item is associated with * @param dexFile the <code>DexFile</code> that this item is associated with
*/ */
protected Item(DexFile dexFile) { protected Item(DexFile dexFile) {
this.dexFile = dexFile; this.dexFile = dexFile;
} }
/** /**
* Read in the item from the given input stream, and initialize the index * Read in the item from the given input stream, and initialize the index
* @param in the <code>Input</code> object to read from * @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 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 * @param readContext a <code>ReadContext</code> object to hold information that is
* only needed while reading in a file * only needed while reading in a file
*/ */
protected void readFrom(Input in, int index, ReadContext readContext) { protected void readFrom(Input in, int index, ReadContext readContext) {
assert in.getCursor() % getItemType().ItemAlignment == 0; assert in.getCursor() % getItemType().ItemAlignment == 0;
this.offset = in.getCursor(); this.offset = in.getCursor();
this.index = index; this.index = index;
this.readItem(in, readContext); this.readItem(in, readContext);
} }
/** /**
* Place the item at the given offset and index, and return the offset of the byte following this item * 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 offset The offset to place the item at
* @param index The index of the item within the containing section * @param index The index of the item within the containing section
* @return The offset of the byte following this item * @return The offset of the byte following this item
*/ */
protected int placeAt(int offset, int index) { protected int placeAt(int offset, int index) {
assert offset % getItemType().ItemAlignment == 0; assert offset % getItemType().ItemAlignment == 0;
assert !dexFile.getInplace() || (offset == this.offset && this.index == index); assert !dexFile.getInplace() || (offset == this.offset && this.index == index);
this.offset = offset; this.offset = offset;
this.index = index; this.index = index;
return this.placeItem(offset); return this.placeItem(offset);
} }
/** /**
* Write and annotate this item to the output stream * Write and annotate this item to the output stream
* @param out The output stream to write and annotate to * @param out The output stream to write and annotate to
*/ */
protected void writeTo(AnnotatedOutput out) { protected void writeTo(AnnotatedOutput out) {
assert out.getCursor() % getItemType().ItemAlignment == 0; assert out.getCursor() % getItemType().ItemAlignment == 0;
assert out.getCursor() == offset; assert out.getCursor() == offset;
if (out.annotates()) { if (out.annotates()) {
out.annotate(0, "[" + index + "] " + this.getItemType().TypeName); out.annotate(0, "[" + index + "] " + this.getItemType().TypeName);
} }
out.indent(); out.indent();
writeItem(out); writeItem(out);
out.deindent(); out.deindent();
} }
/** /**
* Returns a human readable form of this item * Returns a human readable form of this item
* @return a human readable form of this item * @return a human readable form of this item
*/ */
public String toString() { public String toString() {
return getConciseIdentity(); return getConciseIdentity();
} }
/** /**
* The method in the concrete item subclass that actually reads in the data for the item * 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 * The logic in this method can assume that the given Input object is valid and is
* aligned as neccessary. * aligned as neccessary.
* *
* This method is for internal use only * This method is for internal use only
* @param in the <code>Input</code> object to read from * @param in the <code>Input</code> object to read from
* @param readContext a <code>ReadContext</code> object to hold information that is * @param readContext a <code>ReadContext</code> object to hold information that is
* only needed while reading in a file * only needed while reading in a file
*/ */
protected abstract void readItem(Input in, ReadContext readContext); protected abstract void readItem(Input in, ReadContext readContext);
/** /**
* The method should finalize the layout of the item and return the offset of the byte * The method should finalize the layout of the item and return the offset of the byte
* immediately following the item. * immediately following the item.
* *
* The implementation of this method can assume that the offset argument has already been * The implementation of this method can assume that the offset argument has already been
* aligned based on the item's alignment requirements * aligned based on the item's alignment requirements
* *
* This method is for internal use only * This method is for internal use only
* @param offset the (pre-aligned) offset to place the item at * @param offset the (pre-aligned) offset to place the item at
* @return the size of the item, in bytes * @return the size of the item, in bytes
*/ */
protected abstract int placeItem(int offset); protected abstract int placeItem(int offset);
/** /**
* The method in the concrete item subclass that actually writes and annotates the data * The method in the concrete item subclass that actually writes and annotates the data
* for the item. * for the item.
* *
* The logic in this method can assume that the given Output object is valid and is * The logic in this method can assume that the given Output object is valid and is
* aligned as neccessary * aligned as neccessary
* *
* @param out The <code>AnnotatedOutput</code> object to write/annotate to * @param out The <code>AnnotatedOutput</code> object to write/annotate to
*/ */
protected abstract void writeItem(AnnotatedOutput out); protected abstract void writeItem(AnnotatedOutput out);
/** /**
* @return An ItemType enum that represents the item type of this item * @return An ItemType enum that represents the item type of this item
*/ */
public abstract ItemType getItemType(); public abstract ItemType getItemType();
/** /**
* @return A concise (human-readable) string value that conveys the identity of this item * @return A concise (human-readable) string value that conveys the identity of this item
*/ */
public abstract String getConciseIdentity(); public abstract String getConciseIdentity();
/** /**
* @return the offset in the dex file where this item is located * @return the offset in the dex file where this item is located
*/ */
public int getOffset() { public int getOffset() {
return offset; return offset;
} }
/** /**
* @return the index of this item within the item's containing section * @return the index of this item within the item's containing section
*/ */
public int getIndex() { public int getIndex() {
return index; return index;
} }
/** /**
* @return the <code>DexFile</code> that contains this item * @return the <code>DexFile</code> that contains this item
*/ */
public DexFile getDexFile() { public DexFile getDexFile() {
return dexFile; return dexFile;
} }
} }

View File

@ -1,138 +1,138 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
/** /**
* This item represents a map_list item from the dex specification. It contains a * 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 * SectionInfo instance for every section in the DexFile, with the number of items
* in and offset of that section. * in and offset of that section.
*/ */
public class MapItem extends Item<MapItem> { public class MapItem extends Item<MapItem> {
/** /**
* This item is read in immediately after the HeaderItem, and the section info contained * 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 * by this item is added to the ReadContext object, which is used when reading in the other
* sections in the dex file. * sections in the dex file.
* *
* This item should be placed last. It depends on the fact that the other sections * This item should be placed last. It depends on the fact that the other sections
* in the file have been placed. * in the file have been placed.
*/ */
/** /**
* Create a new uninitialized <code>MapItem</code> * Create a new uninitialized <code>MapItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected MapItem(final DexFile dexFile) { protected MapItem(final DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
Section[] sections = dexFile.getOrderedSections(); Section[] sections = dexFile.getOrderedSections();
//the list returned by getOrderedSections doesn't contain the header //the list returned by getOrderedSections doesn't contain the header
//or map section, so add 2 to the length //or map section, so add 2 to the length
return offset + 4 + (sections.length + 2) * 12; return offset + 4 + (sections.length + 2) * 12;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
int size = in.readInt(); int size = in.readInt();
for (int i=0; i<size; i++) { for (int i=0; i<size; i++) {
ItemType itemType = ItemType.fromInt(in.readShort()); ItemType itemType = ItemType.fromInt(in.readShort());
//unused //unused
in.readShort(); in.readShort();
int sectionSize = in.readInt(); int sectionSize = in.readInt();
int sectionOffset = in.readInt(); int sectionOffset = in.readInt();
readContext.addSection(itemType, sectionSize, sectionOffset); readContext.addSection(itemType, sectionSize, sectionOffset);
} }
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
assert getOffset() > 0; assert getOffset() > 0;
Section[] sections = dexFile.getOrderedSections(); Section[] sections = dexFile.getOrderedSections();
out.annotate("map_size: 0x" + Integer.toHexString(sections.length + 2) + " (" + out.annotate("map_size: 0x" + Integer.toHexString(sections.length + 2) + " (" +
Integer.toString(sections.length + 2) + ")"); Integer.toString(sections.length + 2) + ")");
out.writeInt(sections.length + 2); out.writeInt(sections.length + 2);
int index = 0; int index = 0;
out.annotate(0, "[" + index++ + "]"); out.annotate(0, "[" + index++ + "]");
out.indent(); out.indent();
writeSectionInfo(out, ItemType.TYPE_HEADER_ITEM, 1, 0); writeSectionInfo(out, ItemType.TYPE_HEADER_ITEM, 1, 0);
out.deindent(); out.deindent();
for (Section section: dexFile.getOrderedSections()) { for (Section section: dexFile.getOrderedSections()) {
out.annotate(0, "[" + index++ + "]"); out.annotate(0, "[" + index++ + "]");
out.indent(); out.indent();
writeSectionInfo(out, section.ItemType, section.getItems().size(), section.getOffset()); writeSectionInfo(out, section.ItemType, section.getItems().size(), section.getOffset());
out.deindent(); out.deindent();
} }
out.annotate(0, "[" + index++ + "]"); out.annotate(0, "[" + index++ + "]");
out.indent(); out.indent();
writeSectionInfo(out, ItemType.TYPE_MAP_LIST, 1, dexFile.MapItem.getOffset()); writeSectionInfo(out, ItemType.TYPE_MAP_LIST, 1, dexFile.MapItem.getOffset());
out.deindent(); out.deindent();
} }
private void writeSectionInfo(AnnotatedOutput out, ItemType itemType, int sectionSize, int sectionOffset) { private void writeSectionInfo(AnnotatedOutput out, ItemType itemType, int sectionSize, int sectionOffset) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(2, "item_type: " + itemType); out.annotate(2, "item_type: " + itemType);
out.annotate(2, "unused"); out.annotate(2, "unused");
out.annotate(4, "section_size: 0x" + Integer.toHexString(sectionSize) + " (" + sectionSize + ")"); out.annotate(4, "section_size: 0x" + Integer.toHexString(sectionSize) + " (" + sectionSize + ")");
out.annotate(4, "section_off: 0x" + Integer.toHexString(sectionOffset)); out.annotate(4, "section_off: 0x" + Integer.toHexString(sectionOffset));
} }
out.writeShort(itemType.MapValue); out.writeShort(itemType.MapValue);
out.writeShort(0); out.writeShort(0);
out.writeInt(sectionSize); out.writeInt(sectionSize);
out.writeInt(sectionOffset); out.writeInt(sectionOffset);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_MAP_LIST; return ItemType.TYPE_MAP_LIST;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(MapItem o) { public int compareTo(MapItem o) {
return 0; return 0;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "map_item"; return "map_item";
} }
} }

View File

@ -1,207 +1,207 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
public class MethodIdItem extends Item<MethodIdItem> { public class MethodIdItem extends Item<MethodIdItem> {
private int hashCode = 0; private int hashCode = 0;
private TypeIdItem classType; private TypeIdItem classType;
private ProtoIdItem methodPrototype; private ProtoIdItem methodPrototype;
private StringIdItem methodName; private StringIdItem methodName;
/** /**
* Creates a new uninitialized <code>MethodIdItem</code> * Creates a new uninitialized <code>MethodIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected MethodIdItem(DexFile dexFile) { protected MethodIdItem(DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** /**
* Creates a new <code>MethodIdItem</code> for the given class, type and name * 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 dexFile The <code>DexFile</code> that this item belongs to
* @param classType the class that the method is a member of * @param classType the class that the method is a member of
* @param methodPrototype the type of the method * @param methodPrototype the type of the method
* @param methodName the name of the method * @param methodName the name of the method
*/ */
private MethodIdItem(DexFile dexFile, TypeIdItem classType, ProtoIdItem methodPrototype, StringIdItem methodName) { private MethodIdItem(DexFile dexFile, TypeIdItem classType, ProtoIdItem methodPrototype, StringIdItem methodName) {
this(dexFile); this(dexFile);
this.classType = classType; this.classType = classType;
this.methodPrototype = methodPrototype; this.methodPrototype = methodPrototype;
this.methodName = methodName; this.methodName = methodName;
} }
/** /**
* Returns a <code>MethodIdItem</code> for the given values, and that has been interned into * Returns a <code>MethodIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param classType the class that the method is a member of * @param classType the class that the method is a member of
* @param methodPrototype the type of the method * @param methodPrototype the type of the method
* @param methodName the name 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 * @return a <code>MethodIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
*/ */
public static MethodIdItem getInternedMethodIdItem(DexFile dexFile, TypeIdItem classType, public static MethodIdItem getInternedMethodIdItem(DexFile dexFile, TypeIdItem classType,
ProtoIdItem methodPrototype, StringIdItem methodName) { ProtoIdItem methodPrototype, StringIdItem methodName) {
MethodIdItem methodIdItem = new MethodIdItem(dexFile, classType, methodPrototype, methodName); MethodIdItem methodIdItem = new MethodIdItem(dexFile, classType, methodPrototype, methodName);
return dexFile.MethodIdsSection.intern(methodIdItem); return dexFile.MethodIdsSection.intern(methodIdItem);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
classType = dexFile.TypeIdsSection.getItemByIndex(in.readShort()); classType = dexFile.TypeIdsSection.getItemByIndex(in.readShort());
methodPrototype = dexFile.ProtoIdsSection.getItemByIndex(in.readShort()); methodPrototype = dexFile.ProtoIdsSection.getItemByIndex(in.readShort());
methodName = dexFile.StringIdsSection.getItemByIndex(in.readInt()); methodName = dexFile.StringIdsSection.getItemByIndex(in.readInt());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return offset + 8; return offset + 8;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(2, "class_type: " + classType.getTypeDescriptor()); out.annotate(2, "class_type: " + classType.getTypeDescriptor());
out.annotate(2, "method_prototype: " + methodPrototype.getPrototypeString()); out.annotate(2, "method_prototype: " + methodPrototype.getPrototypeString());
out.annotate(4, "method_name: " + methodName.getStringValue()); out.annotate(4, "method_name: " + methodName.getStringValue());
} }
out.writeShort(classType.getIndex()); out.writeShort(classType.getIndex());
out.writeShort(methodPrototype.getIndex()); out.writeShort(methodPrototype.getIndex());
out.writeInt(methodName.getIndex()); out.writeInt(methodName.getIndex());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_METHOD_ID_ITEM; return ItemType.TYPE_METHOD_ID_ITEM;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "method_id_item: " + getMethodString(); return "method_id_item: " + getMethodString();
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(MethodIdItem o) { public int compareTo(MethodIdItem o) {
int result = classType.compareTo(o.classType); int result = classType.compareTo(o.classType);
if (result != 0) { if (result != 0) {
return result; return result;
} }
result = methodName.compareTo(o.methodName); result = methodName.compareTo(o.methodName);
if (result != 0) { if (result != 0) {
return result; return result;
} }
return methodPrototype.compareTo(o.methodPrototype); return methodPrototype.compareTo(o.methodPrototype);
} }
private String cachedMethodString = null; private String cachedMethodString = null;
/** /**
* @return a string formatted like LclassName;->methodName(TTTT..)R * @return a string formatted like LclassName;->methodName(TTTT..)R
*/ */
public String getMethodString() { public String getMethodString() {
if (cachedMethodString == null) { if (cachedMethodString == null) {
String classType = this.classType.getTypeDescriptor(); String classType = this.classType.getTypeDescriptor();
String methodName = this.methodName.getStringValue(); String methodName = this.methodName.getStringValue();
String prototypeString = methodPrototype.getPrototypeString(); String prototypeString = methodPrototype.getPrototypeString();
StringBuilder sb = new StringBuilder(classType.length() + methodName.length() + prototypeString.length() + StringBuilder sb = new StringBuilder(classType.length() + methodName.length() + prototypeString.length() +
2); 2);
sb.append(classType); sb.append(classType);
sb.append("->"); sb.append("->");
sb.append(methodName); sb.append(methodName);
sb.append(prototypeString); sb.append(prototypeString);
cachedMethodString = sb.toString(); cachedMethodString = sb.toString();
} }
return cachedMethodString; return cachedMethodString;
} }
/** /**
* @return the method prototype * @return the method prototype
*/ */
public ProtoIdItem getPrototype() { public ProtoIdItem getPrototype() {
return methodPrototype; return methodPrototype;
} }
/** /**
* @return the name of the method * @return the name of the method
*/ */
public StringIdItem getMethodName() { public StringIdItem getMethodName() {
return methodName; return methodName;
} }
/** /**
* @return the class this method is a member of * @return the class this method is a member of
*/ */
public TypeIdItem getContainingClass() { public TypeIdItem getContainingClass() {
return classType; return classType;
} }
/** /**
* calculate and cache the hashcode * calculate and cache the hashcode
*/ */
private void calcHashCode() { private void calcHashCode() {
hashCode = classType.hashCode(); hashCode = classType.hashCode();
hashCode = 31 * hashCode + methodPrototype.hashCode(); hashCode = 31 * hashCode + methodPrototype.hashCode();
hashCode = 31 * hashCode + methodName.hashCode(); hashCode = 31 * hashCode + methodName.hashCode();
} }
@Override @Override
public int hashCode() { public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll //there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time //just end up recalculating it each time
if (hashCode == 0) if (hashCode == 0)
calcHashCode(); calcHashCode();
return hashCode; return hashCode;
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this==o) { if (this==o) {
return true; return true;
} }
if (o==null || !this.getClass().equals(o.getClass())) { if (o==null || !this.getClass().equals(o.getClass())) {
return false; return false;
} }
//This assumes that the referenced items have been interned in both objects. //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 //This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created //"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned //internally is guaranteed to be interned
MethodIdItem other = (MethodIdItem)o; MethodIdItem other = (MethodIdItem)o;
return (classType == other.classType && return (classType == other.classType &&
methodPrototype == other.methodPrototype && methodPrototype == other.methodPrototype &&
methodName == other.methodName); methodName == other.methodName);
} }
} }

View File

@ -1,83 +1,83 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.SparseArray; import org.jf.dexlib.Util.SparseArray;
import org.jf.dexlib.Util.Hex; import org.jf.dexlib.Util.Hex;
import junit.framework.Assert; import junit.framework.Assert;
public class OffsettedSection<T extends Item> extends Section<T> { public class OffsettedSection<T extends Item> extends Section<T> {
public OffsettedSection(DexFile dexFile, ItemType itemType) { public OffsettedSection(DexFile dexFile, ItemType itemType) {
super(dexFile, itemType); super(dexFile, itemType);
} }
public void readItems(Input in, ReadContext readContext) { public void readItems(Input in, ReadContext readContext) {
SparseArray<T> precreatedItems = (SparseArray<T>)readContext.getItemsByType(ItemType); SparseArray<T> precreatedItems = (SparseArray<T>)readContext.getItemsByType(ItemType);
assert precreatedItems.size() <= items.size(): "Trying to read " + items.size() + " items, but this section " + assert precreatedItems.size() <= items.size(): "Trying to read " + items.size() + " items, but this section " +
"already contains " + precreatedItems.size() + " items."; "already contains " + precreatedItems.size() + " items.";
int precreatedIndex = 0; int precreatedIndex = 0;
int nextPrecreatedOffset = Integer.MAX_VALUE; int nextPrecreatedOffset = Integer.MAX_VALUE;
if (precreatedItems.size() > 0) { if (precreatedItems.size() > 0) {
nextPrecreatedOffset = precreatedItems.keyAt(0); nextPrecreatedOffset = precreatedItems.keyAt(0);
} }
for (int i = 0; i < items.size(); i++) { for (int i = 0; i < items.size(); i++) {
assert items.get(i) == null; assert items.get(i) == null;
T item = null; T item = null;
in.alignTo(ItemType.ItemAlignment); in.alignTo(ItemType.ItemAlignment);
int currentOffset = in.getCursor(); int currentOffset = in.getCursor();
if (currentOffset == nextPrecreatedOffset) { if (currentOffset == nextPrecreatedOffset) {
item = precreatedItems.valueAt(precreatedIndex++); item = precreatedItems.valueAt(precreatedIndex++);
if (precreatedIndex < precreatedItems.size()) { if (precreatedIndex < precreatedItems.size()) {
nextPrecreatedOffset = precreatedItems.keyAt(precreatedIndex); nextPrecreatedOffset = precreatedItems.keyAt(precreatedIndex);
} else { } else {
nextPrecreatedOffset = Integer.MAX_VALUE; nextPrecreatedOffset = Integer.MAX_VALUE;
} }
} else if (currentOffset > nextPrecreatedOffset) { } else if (currentOffset > nextPrecreatedOffset) {
//we passed by the next precreated item, something is wrong //we passed by the next precreated item, something is wrong
throw new RuntimeException("The pre-created item at offset 0x" + Hex.u4(nextPrecreatedOffset) throw new RuntimeException("The pre-created item at offset 0x" + Hex.u4(nextPrecreatedOffset)
+ " was not read"); + " was not read");
} else { } else {
item = (T)ItemFactory.makeItem(ItemType, DexFile); item = (T)ItemFactory.makeItem(ItemType, DexFile);
} }
items.set(i, item); items.set(i, item);
item.readFrom(in, i, readContext); item.readFrom(in, i, readContext);
} }
readContext.setItemsForSection(ItemType, items); readContext.setItemsForSection(ItemType, items);
} }
} }

View File

@ -1,217 +1,217 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
public class ProtoIdItem extends Item<ProtoIdItem> { public class ProtoIdItem extends Item<ProtoIdItem> {
private int hashCode = 0; private int hashCode = 0;
private StringIdItem shortyDescriptor; private StringIdItem shortyDescriptor;
private TypeIdItem returnType; private TypeIdItem returnType;
private TypeListItem parameters; private TypeListItem parameters;
/** /**
* Creates a new uninitialized <code>ProtoIdItem</code> * Creates a new uninitialized <code>ProtoIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected ProtoIdItem(DexFile dexFile) { protected ProtoIdItem(DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** /**
* Creates a new <code>ProtoIdItem</code> with the given values * Creates a new <code>ProtoIdItem</code> with the given values
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param returnType the return type * @param returnType the return type
* @param parameters a <code>TypeListItem</code> containing a list of the parameter types * @param parameters a <code>TypeListItem</code> containing a list of the parameter types
*/ */
private ProtoIdItem(DexFile dexFile, TypeIdItem returnType, TypeListItem parameters) { private ProtoIdItem(DexFile dexFile, TypeIdItem returnType, TypeListItem parameters) {
this(dexFile); this(dexFile);
String shortyString = returnType.toShorty(); String shortyString = returnType.toShorty();
if (parameters != null) { if (parameters != null) {
shortyString += parameters.getShortyString(); shortyString += parameters.getShortyString();
} }
this.shortyDescriptor = StringIdItem.getInternedStringIdItem(dexFile, shortyString); this.shortyDescriptor = StringIdItem.getInternedStringIdItem(dexFile, shortyString);
this.returnType = returnType; this.returnType = returnType;
this.parameters = parameters; this.parameters = parameters;
} }
/** /**
* Returns a <code>ProtoIdItem</code> for the given values, and that has been interned into * Returns a <code>ProtoIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param returnType the return type * @param returnType the return type
* @param parameters a <code>TypeListItem</code> containing a list of the parameter types * @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 * @return a <code>ProtoIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
*/ */
public static ProtoIdItem getInternedProtoIdItem(DexFile dexFile, TypeIdItem returnType, TypeListItem parameters) { public static ProtoIdItem getInternedProtoIdItem(DexFile dexFile, TypeIdItem returnType, TypeListItem parameters) {
ProtoIdItem protoIdItem = new ProtoIdItem(dexFile, returnType, parameters); ProtoIdItem protoIdItem = new ProtoIdItem(dexFile, returnType, parameters);
return dexFile.ProtoIdsSection.intern(protoIdItem); return dexFile.ProtoIdsSection.intern(protoIdItem);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
shortyDescriptor = dexFile.StringIdsSection.getItemByIndex(in.readInt()); shortyDescriptor = dexFile.StringIdsSection.getItemByIndex(in.readInt());
returnType = dexFile.TypeIdsSection.getItemByIndex(in.readInt()); returnType = dexFile.TypeIdsSection.getItemByIndex(in.readInt());
parameters = (TypeListItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_TYPE_LIST, in.readInt()); parameters = (TypeListItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_TYPE_LIST, in.readInt());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return offset + 12; return offset + 12;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(4, "shorty_descriptor: " + shortyDescriptor.getStringValue()); out.annotate(4, "shorty_descriptor: " + shortyDescriptor.getStringValue());
out.annotate(4, "return_type: " + returnType.getTypeDescriptor()); out.annotate(4, "return_type: " + returnType.getTypeDescriptor());
if (parameters == null) { if (parameters == null) {
out.annotate(4, "parameters:"); out.annotate(4, "parameters:");
} else { } else {
out.annotate(4, "parameters: " + parameters.getTypeListString("")); out.annotate(4, "parameters: " + parameters.getTypeListString(""));
} }
} }
out.writeInt(shortyDescriptor.getIndex()); out.writeInt(shortyDescriptor.getIndex());
out.writeInt(returnType.getIndex()); out.writeInt(returnType.getIndex());
out.writeInt(parameters == null?0:parameters.getOffset()); out.writeInt(parameters == null?0:parameters.getOffset());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_PROTO_ID_ITEM; return ItemType.TYPE_PROTO_ID_ITEM;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(ProtoIdItem o) { public int compareTo(ProtoIdItem o) {
int result = returnType.compareTo(o.returnType); int result = returnType.compareTo(o.returnType);
if (result != 0) { if (result != 0) {
return result; return result;
} }
if (parameters == null) { if (parameters == null) {
if (o.parameters == null) { if (o.parameters == null) {
return 0; return 0;
} }
return -1; return -1;
} else if (o.parameters == null) { } else if (o.parameters == null) {
return 1; return 1;
} }
return parameters.compareTo(o.parameters); return parameters.compareTo(o.parameters);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "proto_id_item: " + getPrototypeString(); return "proto_id_item: " + getPrototypeString();
} }
private String cachedPrototypeString = null; private String cachedPrototypeString = null;
/** /**
* @return a string in the format (TTTT..)R where TTTT.. are the parameter types and R is the return type * @return a string in the format (TTTT..)R where TTTT.. are the parameter types and R is the return type
*/ */
public String getPrototypeString() { public String getPrototypeString() {
if (cachedPrototypeString == null) { if (cachedPrototypeString == null) {
StringBuilder sb = new StringBuilder("("); StringBuilder sb = new StringBuilder("(");
if (parameters != null) { if (parameters != null) {
sb.append(parameters.getTypeListString("")); sb.append(parameters.getTypeListString(""));
} }
sb.append(")"); sb.append(")");
sb.append(returnType.getTypeDescriptor()); sb.append(returnType.getTypeDescriptor());
cachedPrototypeString = sb.toString(); cachedPrototypeString = sb.toString();
} }
return cachedPrototypeString; return cachedPrototypeString;
} }
/** /**
* @return the return type of the method * @return the return type of the method
*/ */
public TypeIdItem getReturnType() { public TypeIdItem getReturnType() {
return returnType; return returnType;
} }
/** /**
* @return a <code>TypeListItem</code> containing the method parameter types * @return a <code>TypeListItem</code> containing the method parameter types
*/ */
public TypeListItem getParameters() { public TypeListItem getParameters() {
return parameters; return parameters;
} }
/** /**
* @return the number of registers required for the parameters of this <code>ProtoIdItem</code> * @return the number of registers required for the parameters of this <code>ProtoIdItem</code>
*/ */
public int getParameterRegisterCount() { public int getParameterRegisterCount() {
if (parameters == null) { if (parameters == null) {
return 0; return 0;
} else { } else {
return parameters.getRegisterCount(); return parameters.getRegisterCount();
} }
} }
/** /**
* calculate and cache the hashcode * calculate and cache the hashcode
*/ */
private void calcHashCode() { private void calcHashCode() {
hashCode = returnType.hashCode(); hashCode = returnType.hashCode();
hashCode = 31 * hashCode + (parameters==null?0:parameters.hashCode()); hashCode = 31 * hashCode + (parameters==null?0:parameters.hashCode());
} }
@Override @Override
public int hashCode() { public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll //there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time //just end up recalculating it each time
if (hashCode == 0) if (hashCode == 0)
calcHashCode(); calcHashCode();
return hashCode; return hashCode;
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this==o) { if (this==o) {
return true; return true;
} }
if (o==null || !this.getClass().equals(o.getClass())) { if (o==null || !this.getClass().equals(o.getClass())) {
return false; return false;
} }
//This assumes that the referenced items have been interned in both objects. //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 //This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created //"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned //internally is guaranteed to be interned
ProtoIdItem other = (ProtoIdItem)o; ProtoIdItem other = (ProtoIdItem)o;
return (returnType == other.returnType && return (returnType == other.returnType &&
parameters == other.parameters); parameters == other.parameters);
} }
} }

View File

@ -1,218 +1,218 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AlignmentUtils; import org.jf.dexlib.Util.AlignmentUtils;
import java.util.*; import java.util.*;
public abstract class Section<T extends Item> { public abstract class Section<T extends Item> {
/** /**
* A list of the items that this section contains. * 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 * If the section has been placed, this list should be in the order that the items
* will written to the dex file * will written to the dex file
*/ */
protected final ArrayList<T> items; protected final ArrayList<T> items;
/** /**
* A HashMap of the items in this section. This is used when interning items, to determine * 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. * 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 * Both the key and the value should be the same object
*/ */
protected HashMap<T,T> uniqueItems = null; protected HashMap<T,T> uniqueItems = null;
/** /**
* The offset of this section within the <code>DexFile</code> * The offset of this section within the <code>DexFile</code>
*/ */
protected int offset = 0; protected int offset = 0;
/** /**
* The type of item that this section holds * The type of item that this section holds
*/ */
public final ItemType ItemType; public final ItemType ItemType;
/** /**
* The <code>DexFile</code> that this section belongs to * The <code>DexFile</code> that this section belongs to
*/ */
public final DexFile DexFile; public final DexFile DexFile;
/** /**
* Create a new section * Create a new section
* @param dexFile The <code>DexFile</code> that this section belongs to * @param dexFile The <code>DexFile</code> that this section belongs to
* @param itemType The itemType that this section will hold * @param itemType The itemType that this section will hold
*/ */
protected Section(DexFile dexFile, ItemType itemType) { protected Section(DexFile dexFile, ItemType itemType) {
this.DexFile = dexFile; this.DexFile = dexFile;
items = new ArrayList<T>(); items = new ArrayList<T>();
this.ItemType = itemType; this.ItemType = itemType;
} }
/** /**
* Finalize the location of all items, and place them starting at the given offset * Finalize the location of all items, and place them starting at the given offset
* @param offset The offset where this section should be placed * @param offset The offset where this section should be placed
* @return the offset of the byte immediate after the last item in this section * @return the offset of the byte immediate after the last item in this section
*/ */
protected int placeAt(int offset) { protected int placeAt(int offset) {
if (items.size() > 0) { if (items.size() > 0) {
offset = AlignmentUtils.alignOffset(offset, ItemType.ItemAlignment); offset = AlignmentUtils.alignOffset(offset, ItemType.ItemAlignment);
assert !DexFile.getInplace() || offset == this.offset; assert !DexFile.getInplace() || offset == this.offset;
this.offset = offset; this.offset = offset;
for (int i=0; i < items.size(); i++) { for (int i=0; i < items.size(); i++) {
T item = items.get(i); T item = items.get(i);
assert item != null; assert item != null;
offset = AlignmentUtils.alignOffset(offset, ItemType.ItemAlignment); offset = AlignmentUtils.alignOffset(offset, ItemType.ItemAlignment);
offset = item.placeAt(offset, i); offset = item.placeAt(offset, i);
} }
} else { } else {
this.offset = 0; this.offset = 0;
} }
return offset; return offset;
} }
/** /**
* Write the items to the given <code>AnnotatedOutput</code> * Write the items to the given <code>AnnotatedOutput</code>
* @param out the <code>AnnotatedOutput</code> object to write to * @param out the <code>AnnotatedOutput</code> object to write to
*/ */
protected void writeTo(AnnotatedOutput out) { protected void writeTo(AnnotatedOutput out) {
out.annotate(0, " "); out.annotate(0, " ");
out.annotate(0, "-----------------------------"); out.annotate(0, "-----------------------------");
out.annotate(0, this.ItemType.TypeName + " section"); out.annotate(0, this.ItemType.TypeName + " section");
out.annotate(0, "-----------------------------"); out.annotate(0, "-----------------------------");
out.annotate(0, " "); out.annotate(0, " ");
for (Item item: items) { for (Item item: items) {
assert item!=null; assert item!=null;
out.alignTo(ItemType.ItemAlignment); out.alignTo(ItemType.ItemAlignment);
item.writeTo(out); item.writeTo(out);
out.annotate(0, " "); out.annotate(0, " ");
} }
} }
/** /**
* Read the specified number of items from the given <code>Input</code> object * Read the specified number of items from the given <code>Input</code> object
* @param size The number of items to read * @param size The number of items to read
* @param in The <code>Input</code> object to read from * @param in The <code>Input</code> object to read from
* @param readContext a <code>ReadContext</code> object to hold information that is * @param readContext a <code>ReadContext</code> object to hold information that is
* only needed while reading in a file * only needed while reading in a file
*/ */
protected void readFrom(int size, Input in, ReadContext readContext) { protected void readFrom(int size, Input in, ReadContext readContext) {
//readItems() expects that the list will already be the correct size, so add null items //readItems() expects that the list will already be the correct size, so add null items
//until we reach the specified size //until we reach the specified size
items.ensureCapacity(size); items.ensureCapacity(size);
for (int i = items.size(); i < size; i++) { for (int i = items.size(); i < size; i++) {
items.add(null); items.add(null);
} }
in.alignTo(ItemType.ItemAlignment); in.alignTo(ItemType.ItemAlignment);
offset = in.getCursor(); offset = in.getCursor();
//call the subclass's method that actually reads in the items //call the subclass's method that actually reads in the items
readItems(in, readContext); readItems(in, readContext);
} }
/** /**
* This method in the concrete item subclass should read in all the items from the given <code>Input</code> * 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 * 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) * section, by other items requesting items from this section that they reference by index/offset)
* @param in the <code>Input</code> * @param in the <code>Input</code>
* @param readContext a <code>ReadContext</code> object to hold information that is * @param readContext a <code>ReadContext</code> object to hold information that is
* only needed while reading in a file * only needed while reading in a file
*/ */
protected abstract void readItems(Input in, ReadContext readContext); protected abstract void readItems(Input in, ReadContext readContext);
/** /**
* Gets the offset where the first item in this section is placed * Gets the offset where the first item in this section is placed
* @return the ofset where the first item in this section is placed * @return the ofset where the first item in this section is placed
*/ */
public int getOffset() { public int getOffset() {
return offset; return offset;
} }
/** /**
* Gets a the items contained in this section as a read-only list * 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 * @return A read-only <code>List</code> object containing the items in this section
*/ */
public List<T> getItems() { public List<T> getItems() {
return Collections.unmodifiableList(items); return Collections.unmodifiableList(items);
} }
/** /**
* This method checks if an item that is equivalent to the given item has already been added. If found, * 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. * it returns that item. If not found, it adds the given item to this section and returns it.
* @param item the item to intern * @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 * @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. * as the item passed to this method.
*/ */
protected T intern(T item) { protected T intern(T item) {
if (item == null) { if (item == null) {
return null; return null;
} }
T internedItem = getInternedItem(item); T internedItem = getInternedItem(item);
if (internedItem == null && !item.dexFile.getInterningDisabled()) { if (internedItem == null && !item.dexFile.getInterningDisabled()) {
uniqueItems.put(item, item); uniqueItems.put(item, item);
items.add(item); items.add(item);
return item; return item;
} }
return internedItem; return internedItem;
} }
/** /**
* Returns the interned item that is equivalent to the given item, or null * Returns the interned item that is equivalent to the given item, or null
* @param item the item to check * @param item the item to check
* @return the interned item that is equivalent to the given item, or null * @return the interned item that is equivalent to the given item, or null
*/ */
protected T getInternedItem(T item) { protected T getInternedItem(T item) {
if (uniqueItems == null) { if (uniqueItems == null) {
buildInternedItemMap(); buildInternedItemMap();
} }
return uniqueItems.get(item); return uniqueItems.get(item);
} }
/** /**
* Builds the interned item map from the items that are in this section * Builds the interned item map from the items that are in this section
*/ */
private void buildInternedItemMap() { private void buildInternedItemMap() {
uniqueItems = new HashMap<T,T>(); uniqueItems = new HashMap<T,T>();
for (T item: items) { for (T item: items) {
assert item != null; assert item != null;
uniqueItems.put(item, item); uniqueItems.put(item, item);
} }
} }
/** /**
* Sorts the items in the section * Sorts the items in the section
*/ */
protected void sortSection() { protected void sortSection() {
Collections.sort(items); Collections.sort(items);
} }
} }

View File

@ -1,153 +1,153 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.*; import org.jf.dexlib.Util.*;
public class StringDataItem extends Item<StringDataItem> { public class StringDataItem extends Item<StringDataItem> {
private int hashCode = 0; private int hashCode = 0;
private String stringValue; private String stringValue;
/** /**
* Creates a new uninitialized <code>StringDataItem</code> * Creates a new uninitialized <code>StringDataItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected StringDataItem(DexFile dexFile) { protected StringDataItem(DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** /**
* Creates a new <code>StringDataItem</code> for the given string * Creates a new <code>StringDataItem</code> for the given string
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param stringValue The string value that this item represents * @param stringValue The string value that this item represents
*/ */
private StringDataItem(DexFile dexFile, String stringValue) { private StringDataItem(DexFile dexFile, String stringValue) {
super(dexFile); super(dexFile);
this.stringValue = stringValue; this.stringValue = stringValue;
} }
/** /**
* Returns a <code>StringDataItem</code> for the given values, and that has been interned into * Returns a <code>StringDataItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param value The string value that this item represents * @param value The string value that this item represents
* @return a <code>StringDataItem</code> for the given values, and that has been interned into * @return a <code>StringDataItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
*/ */
public static StringDataItem getInternedStringDataItem(DexFile dexFile, String value) { public static StringDataItem getInternedStringDataItem(DexFile dexFile, String value) {
StringDataItem StringDataItem = new StringDataItem(dexFile, value); StringDataItem StringDataItem = new StringDataItem(dexFile, value);
return dexFile.StringDataSection.intern(StringDataItem); return dexFile.StringDataSection.intern(StringDataItem);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
in.readUnsignedLeb128(); //string length in.readUnsignedLeb128(); //string length
stringValue = Utf8Utils.utf8BytesToString(in.readNullTerminatedBytes()); stringValue = Utf8Utils.utf8BytesToString(in.readNullTerminatedBytes());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return offset + Leb128Utils.unsignedLeb128Size(stringValue.length()) + return offset + Leb128Utils.unsignedLeb128Size(stringValue.length()) +
Utf8Utils.stringToUtf8Bytes(stringValue).length + 1; Utf8Utils.stringToUtf8Bytes(stringValue).length + 1;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
byte[] encodedValue = Utf8Utils.stringToUtf8Bytes(stringValue); byte[] encodedValue = Utf8Utils.stringToUtf8Bytes(stringValue);
if (out.annotates()) { if (out.annotates()) {
out.annotate("string_size: 0x" + Integer.toHexString(stringValue.length()) + " (" + stringValue.length() + out.annotate("string_size: 0x" + Integer.toHexString(stringValue.length()) + " (" + stringValue.length() +
")"); ")");
out.writeUnsignedLeb128(stringValue.length()); out.writeUnsignedLeb128(stringValue.length());
out.annotate(encodedValue.length + 1, "string_data: \"" + Utf8Utils.escapeString(stringValue) + "\""); out.annotate(encodedValue.length + 1, "string_data: \"" + Utf8Utils.escapeString(stringValue) + "\"");
} else { } else {
out.writeUnsignedLeb128(stringValue.length()); out.writeUnsignedLeb128(stringValue.length());
} }
out.write(encodedValue); out.write(encodedValue);
out.writeByte(0); out.writeByte(0);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_STRING_DATA_ITEM; return ItemType.TYPE_STRING_DATA_ITEM;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "string_data_item: \"" + Utf8Utils.escapeString(getStringValue()) + "\""; return "string_data_item: \"" + Utf8Utils.escapeString(getStringValue()) + "\"";
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(StringDataItem o) { public int compareTo(StringDataItem o) {
return getStringValue().compareTo(o.getStringValue()); return getStringValue().compareTo(o.getStringValue());
} }
/** /**
* Get the string value of this item as a <code>String</code> * Get the string value of this item as a <code>String</code>
* @return the string value of this item as a String * @return the string value of this item as a String
*/ */
public String getStringValue() { public String getStringValue() {
return stringValue; return stringValue;
} }
/** /**
* calculate and cache the hashcode * calculate and cache the hashcode
*/ */
private void calcHashCode() { private void calcHashCode() {
hashCode = getStringValue().hashCode(); hashCode = getStringValue().hashCode();
} }
@Override @Override
public int hashCode() { public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll //there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time //just end up recalculating it each time
if (hashCode == 0) if (hashCode == 0)
calcHashCode(); calcHashCode();
return hashCode; return hashCode;
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this==o) { if (this==o) {
return true; return true;
} }
if (o==null || !this.getClass().equals(o.getClass())) { if (o==null || !this.getClass().equals(o.getClass())) {
return false; return false;
} }
//This assumes that the referenced items have been interned in both objects. //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 //This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created //"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned //internally is guaranteed to be interned
StringDataItem other = (StringDataItem)o; StringDataItem other = (StringDataItem)o;
return getStringValue().equals(other.getStringValue()); return getStringValue().equals(other.getStringValue());
} }
} }

View File

@ -1,148 +1,148 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.Utf8Utils; import org.jf.dexlib.Util.Utf8Utils;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
public class StringIdItem extends Item<StringIdItem> { public class StringIdItem extends Item<StringIdItem> {
private StringDataItem stringDataItem; private StringDataItem stringDataItem;
/** /**
* Creates a new uninitialized <code>StringIdItem</code> * Creates a new uninitialized <code>StringIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected StringIdItem(DexFile dexFile) { protected StringIdItem(DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** /**
* Creates a new <code>StringIdItem</code> for the given <code>StringDataItem</code> * Creates a new <code>StringIdItem</code> for the given <code>StringDataItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param stringDataItem The <code>StringDataItem</code> that this <code>StringIdItem</code> represents * @param stringDataItem The <code>StringDataItem</code> that this <code>StringIdItem</code> represents
*/ */
protected StringIdItem(DexFile dexFile, StringDataItem stringDataItem) { protected StringIdItem(DexFile dexFile, StringDataItem stringDataItem) {
super(dexFile); super(dexFile);
this.stringDataItem = stringDataItem; this.stringDataItem = stringDataItem;
} }
/** /**
* Returns a <code>StringIdItem</code> for the given values, and that has been interned into * Returns a <code>StringIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item will belong to * @param dexFile The <code>DexFile</code> that this item will belong to
* @param stringValue The string value that this item represents * @param stringValue The string value that this item represents
* @return a <code>StringIdItem</code> for the given values, and that has been interned into * @return a <code>StringIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
*/ */
public static StringIdItem getInternedStringIdItem(DexFile dexFile, String stringValue) { public static StringIdItem getInternedStringIdItem(DexFile dexFile, String stringValue) {
StringDataItem stringDataItem = StringDataItem.getInternedStringDataItem(dexFile, stringValue); StringDataItem stringDataItem = StringDataItem.getInternedStringDataItem(dexFile, stringValue);
if (stringDataItem == null) { if (stringDataItem == null) {
return null; return null;
} }
StringIdItem stringIdItem = new StringIdItem(dexFile, stringDataItem); StringIdItem stringIdItem = new StringIdItem(dexFile, stringDataItem);
return dexFile.StringIdsSection.intern(stringIdItem); return dexFile.StringIdsSection.intern(stringIdItem);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
int stringDataOffset = in.readInt(); int stringDataOffset = in.readInt();
stringDataItem = (StringDataItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_STRING_DATA_ITEM, stringDataItem = (StringDataItem)readContext.getOffsettedItemByOffset(ItemType.TYPE_STRING_DATA_ITEM,
stringDataOffset); stringDataOffset);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return offset + 4; return offset + 4;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(4, stringDataItem.getConciseIdentity()); out.annotate(4, stringDataItem.getConciseIdentity());
} }
out.writeInt(stringDataItem.getOffset()); out.writeInt(stringDataItem.getOffset());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_STRING_ID_ITEM; return ItemType.TYPE_STRING_ID_ITEM;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "string_id_item: " + Utf8Utils.escapeString(getStringValue()); return "string_id_item: " + Utf8Utils.escapeString(getStringValue());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(StringIdItem o) { public int compareTo(StringIdItem o) {
//sort by the string value //sort by the string value
return getStringValue().compareTo(o.getStringValue()); return getStringValue().compareTo(o.getStringValue());
} }
/** /**
* Get the <code>String</code> value that this <code>StringIdItem</code> represents * Get the <code>String</code> value that this <code>StringIdItem</code> represents
* @return 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() { public String getStringValue() {
return stringDataItem.getStringValue(); return stringDataItem.getStringValue();
} }
/** /**
* Get the <code>StringDataItem</code> that this <code>StringIdItem</code> references * Get the <code>StringDataItem</code> that this <code>StringIdItem</code> references
* @return the <code>StringDataItem</code> that this <code>StringIdItem</code> references * @return the <code>StringDataItem</code> that this <code>StringIdItem</code> references
*/ */
public StringDataItem getStringDataItem() { public StringDataItem getStringDataItem() {
return stringDataItem; return stringDataItem;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return stringDataItem.hashCode(); return stringDataItem.hashCode();
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this==o) { if (this==o) {
return true; return true;
} }
if (o==null || !this.getClass().equals(o.getClass())) { if (o==null || !this.getClass().equals(o.getClass())) {
return false; return false;
} }
//This assumes that the referenced items have been interned in both objects. //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 //This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created //"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned //internally is guaranteed to be interned
StringIdItem other = (StringIdItem)o; StringIdItem other = (StringIdItem)o;
return stringDataItem == other.stringDataItem; return stringDataItem == other.stringDataItem;
} }
} }

View File

@ -1,182 +1,182 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
public class TypeIdItem extends Item<TypeIdItem> { public class TypeIdItem extends Item<TypeIdItem> {
private StringIdItem typeDescriptor; private StringIdItem typeDescriptor;
/** /**
* Creates a new uninitialized <code>TypeIdItem</code> * Creates a new uninitialized <code>TypeIdItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected TypeIdItem(DexFile dexFile) { protected TypeIdItem(DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** /**
* Creates a new <code>TypeIdItem</code> for the given <code>StringIdItem</code> * 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 dexFile The <code>DexFile</code> that this item will belong to
* @param typeDescriptor The <code>StringIdItem</code> containing the type descriptor that * @param typeDescriptor The <code>StringIdItem</code> containing the type descriptor that
* this <code>TypeIdItem</code> represents * this <code>TypeIdItem</code> represents
*/ */
private TypeIdItem(DexFile dexFile, StringIdItem typeDescriptor) { private TypeIdItem(DexFile dexFile, StringIdItem typeDescriptor) {
super(dexFile); super(dexFile);
this.typeDescriptor = typeDescriptor; this.typeDescriptor = typeDescriptor;
} }
/** /**
* Returns a <code>TypeIdItem</code> for the given values, and that has been interned into * Returns a <code>TypeIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item will belong to * @param dexFile The <code>DexFile</code> that this item will belong to
* @param typeDescriptor The <code>StringIdItem</code> containing the type descriptor that * @param typeDescriptor The <code>StringIdItem</code> containing the type descriptor that
* this <code>TypeIdItem</code> represents * this <code>TypeIdItem</code> represents
* @return a <code>TypeIdItem</code> for the given values, and that has been interned into * @return a <code>TypeIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
*/ */
public static TypeIdItem getInternedTypeIdItem(DexFile dexFile, StringIdItem typeDescriptor) { public static TypeIdItem getInternedTypeIdItem(DexFile dexFile, StringIdItem typeDescriptor) {
TypeIdItem typeIdItem = new TypeIdItem(dexFile, typeDescriptor); TypeIdItem typeIdItem = new TypeIdItem(dexFile, typeDescriptor);
return dexFile.TypeIdsSection.intern(typeIdItem); return dexFile.TypeIdsSection.intern(typeIdItem);
} }
/** /**
* Returns a <code>TypeIdItem</code> for the given values, and that has been interned into * Returns a <code>TypeIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item will belong to * @param dexFile The <code>DexFile</code> that this item will belong to
* @param typeDescriptor The string containing the type descriptor that this * @param typeDescriptor The string containing the type descriptor that this
* <code>TypeIdItem</code> represents * <code>TypeIdItem</code> represents
* @return a <code>TypeIdItem</code> for the given values, and that has been interned into * @return a <code>TypeIdItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
*/ */
public static TypeIdItem getInternedTypeIdItem(DexFile dexFile, String typeDescriptor) { public static TypeIdItem getInternedTypeIdItem(DexFile dexFile, String typeDescriptor) {
StringIdItem stringIdItem = StringIdItem.getInternedStringIdItem(dexFile, typeDescriptor); StringIdItem stringIdItem = StringIdItem.getInternedStringIdItem(dexFile, typeDescriptor);
if (stringIdItem == null) { if (stringIdItem == null) {
return null; return null;
} }
TypeIdItem typeIdItem = new TypeIdItem(dexFile, stringIdItem); TypeIdItem typeIdItem = new TypeIdItem(dexFile, stringIdItem);
return dexFile.TypeIdsSection.intern(typeIdItem); return dexFile.TypeIdsSection.intern(typeIdItem);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
int stringIdIndex = in.readInt(); int stringIdIndex = in.readInt();
this.typeDescriptor = dexFile.StringIdsSection.getItemByIndex(stringIdIndex); this.typeDescriptor = dexFile.StringIdsSection.getItemByIndex(stringIdIndex);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return offset + 4; return offset + 4;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
if (out.annotates()) { if (out.annotates()) {
out.annotate(4, typeDescriptor.getConciseIdentity()); out.annotate(4, typeDescriptor.getConciseIdentity());
} }
out.writeInt(typeDescriptor.getIndex()); out.writeInt(typeDescriptor.getIndex());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_TYPE_ID_ITEM; return ItemType.TYPE_TYPE_ID_ITEM;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "type_id_item: " + getTypeDescriptor(); return "type_id_item: " + getTypeDescriptor();
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(TypeIdItem o) { public int compareTo(TypeIdItem o) {
//sort by the index of the StringIdItem //sort by the index of the StringIdItem
return typeDescriptor.compareTo(o.typeDescriptor); return typeDescriptor.compareTo(o.typeDescriptor);
} }
/** /**
* Returns the type descriptor as a <code>String</code> for this type * Returns the type descriptor as a <code>String</code> for this type
* @return 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() { public String getTypeDescriptor() {
return typeDescriptor.getStringValue(); return typeDescriptor.getStringValue();
} }
/** /**
* Returns the "shorty" representation of this type, used to create the shorty prototype string for a method * 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 * @return the "shorty" representation of this type, used to create the shorty prototype string for a method
*/ */
public String toShorty() { public String toShorty() {
String type = getTypeDescriptor(); String type = getTypeDescriptor();
if (type.length() > 1) { if (type.length() > 1) {
return "L"; return "L";
} else { } else {
return type; return type;
} }
} }
/** /**
* Calculates the number of 2-byte registers that an instance of this type requires * 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 * @return The number of 2-byte registers that an instance of this type requires
*/ */
public int getRegisterCount() { public int getRegisterCount() {
String type = this.getTypeDescriptor(); String type = this.getTypeDescriptor();
/** Only the long and double primitive types are 2 words, /** Only the long and double primitive types are 2 words,
* everything else is a single word * everything else is a single word
*/ */
if (type.equals("J") || type.equals("D")) { if (type.equals("J") || type.equals("D")) {
return 2; return 2;
} else { } else {
return 1; return 1;
} }
} }
@Override @Override
public int hashCode() { public int hashCode() {
return typeDescriptor.hashCode(); return typeDescriptor.hashCode();
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this==o) { if (this==o) {
return true; return true;
} }
if (o==null || !this.getClass().equals(o.getClass())) { if (o==null || !this.getClass().equals(o.getClass())) {
return false; return false;
} }
//This assumes that the referenced items have been interned in both objects. //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 //This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created //"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned //internally is guaranteed to be interned
TypeIdItem other = (TypeIdItem)o; TypeIdItem other = (TypeIdItem)o;
return typeDescriptor == other.typeDescriptor; return typeDescriptor == other.typeDescriptor;
} }
} }

View File

@ -1,258 +1,258 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib; package org.jf.dexlib;
import org.jf.dexlib.Util.Input; import org.jf.dexlib.Util.Input;
import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.AnnotatedOutput;
import org.jf.dexlib.Util.ReadOnlyArrayList; import org.jf.dexlib.Util.ReadOnlyArrayList;
import java.util.List; import java.util.List;
public class TypeListItem extends Item<TypeListItem> { public class TypeListItem extends Item<TypeListItem> {
private int hashCode = 0; private int hashCode = 0;
private TypeIdItem[] typeList; private TypeIdItem[] typeList;
/** /**
* Creates a new uninitialized <code>TypeListItem</code> * Creates a new uninitialized <code>TypeListItem</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
*/ */
protected TypeListItem(DexFile dexFile) { protected TypeListItem(DexFile dexFile) {
super(dexFile); super(dexFile);
} }
/** /**
* Creates a new <code>TypeListItem</code> for the given string * Creates a new <code>TypeListItem</code> for the given string
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param typeList A list of the types that this <code>TypeListItem</code> represents * @param typeList A list of the types that this <code>TypeListItem</code> represents
*/ */
private TypeListItem(DexFile dexFile, TypeIdItem[] typeList) { private TypeListItem(DexFile dexFile, TypeIdItem[] typeList) {
super(dexFile); super(dexFile);
this.typeList = typeList; this.typeList = typeList;
} }
/** /**
* Returns a <code>TypeListItem</code> for the given values, and that has been interned into * Returns a <code>TypeListItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
* @param dexFile The <code>DexFile</code> that this item belongs to * @param dexFile The <code>DexFile</code> that this item belongs to
* @param typeList A list of the types that this <code>TypeListItem</code> represents * @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 * @return a <code>TypeListItem</code> for the given values, and that has been interned into
* the given <code>DexFile</code> * the given <code>DexFile</code>
*/ */
public static TypeListItem getInternedTypeListItem(DexFile dexFile, List<TypeIdItem> typeList) { public static TypeListItem getInternedTypeListItem(DexFile dexFile, List<TypeIdItem> typeList) {
TypeIdItem[] typeArray = new TypeIdItem[typeList.size()]; TypeIdItem[] typeArray = new TypeIdItem[typeList.size()];
typeList.toArray(typeArray); typeList.toArray(typeArray);
TypeListItem typeListItem = new TypeListItem(dexFile, typeArray); TypeListItem typeListItem = new TypeListItem(dexFile, typeArray);
return dexFile.TypeListsSection.intern(typeListItem); return dexFile.TypeListsSection.intern(typeListItem);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void readItem(Input in, ReadContext readContext) { protected void readItem(Input in, ReadContext readContext) {
int size = in.readInt(); int size = in.readInt();
typeList = new TypeIdItem[size]; typeList = new TypeIdItem[size];
for (int i=0; i<size; i++) { for (int i=0; i<size; i++) {
int typeIndex = in.readShort(); int typeIndex = in.readShort();
typeList[i] = dexFile.TypeIdsSection.getItemByIndex(typeIndex); typeList[i] = dexFile.TypeIdsSection.getItemByIndex(typeIndex);
} }
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected int placeItem(int offset) { protected int placeItem(int offset) {
return offset + 4 + typeList.length * 2; return offset + 4 + typeList.length * 2;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
protected void writeItem(AnnotatedOutput out) { protected void writeItem(AnnotatedOutput out) {
//yes, the code to write the item is duplicated. This eliminates the need to iterate over the list twice //yes, the code to write the item is duplicated. This eliminates the need to iterate over the list twice
if (out.annotates()) { if (out.annotates()) {
out.annotate(4, "size: 0x" + Integer.toHexString(typeList.length) + " (" + typeList.length +")"); out.annotate(4, "size: 0x" + Integer.toHexString(typeList.length) + " (" + typeList.length +")");
for (TypeIdItem typeIdItem: typeList) { for (TypeIdItem typeIdItem: typeList) {
out.annotate(2, "type_id_item: " + typeIdItem.getTypeDescriptor()); out.annotate(2, "type_id_item: " + typeIdItem.getTypeDescriptor());
} }
} }
out.writeInt(typeList.length); out.writeInt(typeList.length);
for (TypeIdItem typeIdItem: typeList) { for (TypeIdItem typeIdItem: typeList) {
out.writeShort(typeIdItem.getIndex()); out.writeShort(typeIdItem.getIndex());
} }
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public ItemType getItemType() { public ItemType getItemType() {
return ItemType.TYPE_TYPE_LIST; return ItemType.TYPE_TYPE_LIST;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public String getConciseIdentity() { public String getConciseIdentity() {
return "type_list: " + getTypeListString(""); return "type_list: " + getTypeListString("");
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int compareTo(TypeListItem o) { public int compareTo(TypeListItem o) {
if (o == null) { if (o == null) {
return 1; return 1;
} }
int thisSize = typeList.length; int thisSize = typeList.length;
int otherSize = o.typeList.length; int otherSize = o.typeList.length;
int size = Math.min(thisSize, otherSize); int size = Math.min(thisSize, otherSize);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
int result = typeList[i].compareTo(o.typeList[i]); int result = typeList[i].compareTo(o.typeList[i]);
if (result != 0) { if (result != 0) {
return result; return result;
} }
} }
if (thisSize < otherSize) { if (thisSize < otherSize) {
return -1; return -1;
} else if (thisSize > otherSize) { } else if (thisSize > otherSize) {
return 1; return 1;
} else { } else {
return 0; return 0;
} }
} }
/** /**
* @return the number of registers required for this <code>TypeListItem</code> * @return the number of registers required for this <code>TypeListItem</code>
*/ */
public int getRegisterCount() { public int getRegisterCount() {
int wordCount = 0; int wordCount = 0;
for (TypeIdItem typeIdItem: typeList) { for (TypeIdItem typeIdItem: typeList) {
wordCount += typeIdItem.getRegisterCount(); wordCount += typeIdItem.getRegisterCount();
} }
return wordCount; return wordCount;
} }
/** /**
* @return a string consisting of the type descriptors in this <code>TypeListItem</code> * @return a string consisting of the type descriptors in this <code>TypeListItem</code>
* that are separated by the given separator * that are separated by the given separator
* @param separator the separator between each type * @param separator the separator between each type
*/ */
public String getTypeListString(String separator) { public String getTypeListString(String separator) {
int size = 0; int size = 0;
for (TypeIdItem typeIdItem: typeList) { for (TypeIdItem typeIdItem: typeList) {
size += typeIdItem.getTypeDescriptor().length(); size += typeIdItem.getTypeDescriptor().length();
size += separator.length(); size += separator.length();
} }
StringBuilder sb = new StringBuilder(size); StringBuilder sb = new StringBuilder(size);
for (TypeIdItem typeIdItem: typeList) { for (TypeIdItem typeIdItem: typeList) {
sb.append(typeIdItem.getTypeDescriptor()); sb.append(typeIdItem.getTypeDescriptor());
sb.append(separator); sb.append(separator);
} }
if (typeList.length > 0) { if (typeList.length > 0) {
sb.delete(sb.length() - separator.length(), sb.length()); sb.delete(sb.length() - separator.length(), sb.length());
} }
return sb.toString(); return sb.toString();
} }
/** /**
* @return a string consisting of the shorty form of the type descriptors in this * @return a string consisting of the shorty form of the type descriptors in this
* <code>TypeListItem</code> that are directly concatenated together * <code>TypeListItem</code> that are directly concatenated together
*/ */
public String getShortyString() { public String getShortyString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (TypeIdItem typeIdItem: typeList) { for (TypeIdItem typeIdItem: typeList) {
sb.append(typeIdItem.toShorty()); sb.append(typeIdItem.toShorty());
} }
return sb.toString(); return sb.toString();
} }
/** /**
* @param index the index of the <code>TypeIdItem</code> to get * @param index the index of the <code>TypeIdItem</code> to get
* @return the <code>TypeIdItem</code> at the given index * @return the <code>TypeIdItem</code> at the given index
*/ */
public TypeIdItem getTypeIdItem(int index) { public TypeIdItem getTypeIdItem(int index) {
return typeList[index]; return typeList[index];
} }
/** /**
* @return the number of types in this <code>TypeListItem</code> * @return the number of types in this <code>TypeListItem</code>
*/ */
public int getTypeCount() { public int getTypeCount() {
return typeList.length; return typeList.length;
} }
/** /**
* @return an array of the <code>TypeIdItems</code> in this <code>TypeListItem</code> * @return an array of the <code>TypeIdItems</code> in this <code>TypeListItem</code>
*/ */
public List<TypeIdItem> getTypes() { public List<TypeIdItem> getTypes() {
return new ReadOnlyArrayList<TypeIdItem>(typeList); return new ReadOnlyArrayList<TypeIdItem>(typeList);
} }
/** /**
* calculate and cache the hashcode * calculate and cache the hashcode
*/ */
private void calcHashCode() { private void calcHashCode() {
int hashCode = 1; int hashCode = 1;
for (TypeIdItem typeIdItem: typeList) { for (TypeIdItem typeIdItem: typeList) {
hashCode = 31 * hashCode + typeIdItem.hashCode(); hashCode = 31 * hashCode + typeIdItem.hashCode();
} }
this.hashCode = hashCode; this.hashCode = hashCode;
} }
@Override @Override
public int hashCode() { public int hashCode() {
//there's a small possibility that the actual hash code will be 0. If so, we'll //there's a small possibility that the actual hash code will be 0. If so, we'll
//just end up recalculating it each time //just end up recalculating it each time
if (hashCode == 0) if (hashCode == 0)
calcHashCode(); calcHashCode();
return hashCode; return hashCode;
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this==o) { if (this==o) {
return true; return true;
} }
if (o==null || !this.getClass().equals(o.getClass())) { if (o==null || !this.getClass().equals(o.getClass())) {
return false; return false;
} }
//This assumes that the referenced items have been interned in both objects. //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 //This is a valid assumption because all outside code must use the static
//"getInterned..." style methods to make new items, and any item created //"getInterned..." style methods to make new items, and any item created
//internally is guaranteed to be interned //internally is guaranteed to be interned
TypeListItem other = (TypeListItem)o; TypeListItem other = (TypeListItem)o;
if (typeList.length != other.typeList.length) { if (typeList.length != other.typeList.length) {
return false; return false;
} }
for (int i=0; i<typeList.length; i++) { for (int i=0; i<typeList.length; i++) {
if (typeList[i] != other.typeList[i]) { if (typeList[i] != other.typeList[i]) {
return false; return false;
} }
} }
return true; return true;
} }
} }

View File

@ -1,175 +1,175 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Util; package org.jf.dexlib.Util;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
public enum AccessFlags public enum AccessFlags
{ {
PUBLIC(0x1, "public", true, true, true), PUBLIC(0x1, "public", true, true, true),
PRIVATE(0x2, "private", true, true, true), PRIVATE(0x2, "private", true, true, true),
PROTECTED(0x4, "protected", true, true, true), PROTECTED(0x4, "protected", true, true, true),
STATIC(0x8, "static", true, true, true), STATIC(0x8, "static", true, true, true),
FINAL(0x10, "final", true, true, true), FINAL(0x10, "final", true, true, true),
SYNCHRONIZED(0x20, "synchronized", false, true, false), SYNCHRONIZED(0x20, "synchronized", false, true, false),
VOLATILE(0x40, "volatile", false, false, true), VOLATILE(0x40, "volatile", false, false, true),
BRIDGE(0x40, "bridge", false, true, false), BRIDGE(0x40, "bridge", false, true, false),
TRANSIENT(0x80, "transient", false, false, true), TRANSIENT(0x80, "transient", false, false, true),
VARARGS(0x80, "varargs", false, true, false), VARARGS(0x80, "varargs", false, true, false),
NATIVE(0x100, "native", false, true, false), NATIVE(0x100, "native", false, true, false),
INTERFACE(0x200, "interface", true, false, false), INTERFACE(0x200, "interface", true, false, false),
ABSTRACT(0x400, "abstract", true, true, false), ABSTRACT(0x400, "abstract", true, true, false),
STRICTFP(0x800, "strictfp", false, true, false), STRICTFP(0x800, "strictfp", false, true, false),
SYNTHETIC(0x1000, "synthetic", true, true, true), SYNTHETIC(0x1000, "synthetic", true, true, true),
ANNOTATION(0x2000, "annotation", true, false, false), ANNOTATION(0x2000, "annotation", true, false, false),
ENUM(0x4000, "enum", true, false, true), ENUM(0x4000, "enum", true, false, true),
CONSTRUCTOR(0x10000, "constructor", false, true, false), CONSTRUCTOR(0x10000, "constructor", false, true, false),
DECLARED_SYNCHRONIZED(0x20000, "declared-synchronized", false, true, false); DECLARED_SYNCHRONIZED(0x20000, "declared-synchronized", false, true, false);
private int value; private int value;
private String accessFlagName; private String accessFlagName;
private boolean validForClass; private boolean validForClass;
private boolean validForMethod; private boolean validForMethod;
private boolean validForField; private boolean validForField;
private static HashMap<String, AccessFlags> accessFlagsByName; private static HashMap<String, AccessFlags> accessFlagsByName;
static { static {
accessFlagsByName = new HashMap<String, AccessFlags>(); accessFlagsByName = new HashMap<String, AccessFlags>();
for (AccessFlags accessFlag: AccessFlags.values()) { for (AccessFlags accessFlag: AccessFlags.values()) {
accessFlagsByName.put(accessFlag.accessFlagName, accessFlag); accessFlagsByName.put(accessFlag.accessFlagName, accessFlag);
} }
} }
private AccessFlags(int value, String accessFlagName, boolean validForClass, boolean validForMethod, private AccessFlags(int value, String accessFlagName, boolean validForClass, boolean validForMethod,
boolean validForField) { boolean validForField) {
this.value = value; this.value = value;
this.accessFlagName = accessFlagName; this.accessFlagName = accessFlagName;
this.validForClass = validForClass; this.validForClass = validForClass;
this.validForMethod = validForMethod; this.validForMethod = validForMethod;
this.validForField = validForField; this.validForField = validForField;
} }
public static AccessFlags[] getAccessFlagsForClass(int accessFlagValue) { public static AccessFlags[] getAccessFlagsForClass(int accessFlagValue) {
int size = 0; int size = 0;
for (AccessFlags accessFlag: AccessFlags.values()) { for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) { if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
size++; size++;
} }
} }
AccessFlags[] accessFlags = new AccessFlags[size]; AccessFlags[] accessFlags = new AccessFlags[size];
int accessFlagsPosition = 0; int accessFlagsPosition = 0;
for (AccessFlags accessFlag: AccessFlags.values()) { for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) { if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
accessFlags[accessFlagsPosition++] = accessFlag; accessFlags[accessFlagsPosition++] = accessFlag;
} }
} }
return accessFlags; return accessFlags;
} }
private static String formatAccessFlags(AccessFlags[] accessFlags) { private static String formatAccessFlags(AccessFlags[] accessFlags) {
int size = 0; int size = 0;
for (AccessFlags accessFlag: accessFlags) { for (AccessFlags accessFlag: accessFlags) {
size += accessFlag.toString().length() + 1; size += accessFlag.toString().length() + 1;
} }
StringBuilder sb = new StringBuilder(size); StringBuilder sb = new StringBuilder(size);
for (AccessFlags accessFlag: accessFlags) { for (AccessFlags accessFlag: accessFlags) {
sb.append(accessFlag.toString()); sb.append(accessFlag.toString());
sb.append(" "); sb.append(" ");
} }
if (accessFlags.length > 0) { if (accessFlags.length > 0) {
sb.delete(sb.length() - 1, sb.length()); sb.delete(sb.length() - 1, sb.length());
} }
return sb.toString(); return sb.toString();
} }
public static String formatAccessFlagsForClass(int accessFlagValue) { public static String formatAccessFlagsForClass(int accessFlagValue) {
return formatAccessFlags(getAccessFlagsForClass(accessFlagValue)); return formatAccessFlags(getAccessFlagsForClass(accessFlagValue));
} }
public static AccessFlags[] getAccessFlagsForMethod(int accessFlagValue) { public static AccessFlags[] getAccessFlagsForMethod(int accessFlagValue) {
int size = 0; int size = 0;
for (AccessFlags accessFlag: AccessFlags.values()) { for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) { if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) {
size++; size++;
} }
} }
AccessFlags[] accessFlags = new AccessFlags[size]; AccessFlags[] accessFlags = new AccessFlags[size];
int accessFlagsPosition = 0; int accessFlagsPosition = 0;
for (AccessFlags accessFlag: AccessFlags.values()) { for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) { if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) {
accessFlags[accessFlagsPosition++] = accessFlag; accessFlags[accessFlagsPosition++] = accessFlag;
} }
} }
return accessFlags; return accessFlags;
} }
public static String formatAccessFlagsForMethod(int accessFlagValue) { public static String formatAccessFlagsForMethod(int accessFlagValue) {
return formatAccessFlags(getAccessFlagsForMethod(accessFlagValue)); return formatAccessFlags(getAccessFlagsForMethod(accessFlagValue));
} }
public static AccessFlags[] getAccessFlagsForField(int accessFlagValue) { public static AccessFlags[] getAccessFlagsForField(int accessFlagValue) {
int size = 0; int size = 0;
for (AccessFlags accessFlag: AccessFlags.values()) { for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) { if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) {
size++; size++;
} }
} }
AccessFlags[] accessFlags = new AccessFlags[size]; AccessFlags[] accessFlags = new AccessFlags[size];
int accessFlagsPosition = 0; int accessFlagsPosition = 0;
for (AccessFlags accessFlag: AccessFlags.values()) { for (AccessFlags accessFlag: AccessFlags.values()) {
if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) { if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) {
accessFlags[accessFlagsPosition++] = accessFlag; accessFlags[accessFlagsPosition++] = accessFlag;
} }
} }
return accessFlags; return accessFlags;
} }
public static String formatAccessFlagsForField(int accessFlagValue) { public static String formatAccessFlagsForField(int accessFlagValue) {
return formatAccessFlags(getAccessFlagsForField(accessFlagValue)); return formatAccessFlags(getAccessFlagsForField(accessFlagValue));
} }
public static AccessFlags getAccessFlag(String accessFlag) { public static AccessFlags getAccessFlag(String accessFlag) {
return accessFlagsByName.get(accessFlag); return accessFlagsByName.get(accessFlag);
} }
public int getValue() { public int getValue() {
return value; return value;
} }
public String toString() { public String toString() {
return accessFlagName; return accessFlagName;
} }
} }

View File

@ -1,364 +1,364 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Util; package org.jf.dexlib.Util;
/** /**
* Implementation of {@link Input} which reads the data from a * Implementation of {@link Input} which reads the data from a
* <code>byte[]</code> instance. * <code>byte[]</code> instance.
* *
* <p><b>Note:</b> As per the {@link Input } interface, multi-byte * <p><b>Note:</b> As per the {@link Input } interface, multi-byte
* reads all use little-endian order.</p> * reads all use little-endian order.</p>
*/ */
public class ByteArrayInput public class ByteArrayInput
implements Input { implements Input {
/** non-null; the data itself */ /** non-null; the data itself */
private byte[] data; private byte[] data;
/** &gt;= 0; current read cursor */ /** &gt;= 0; current read cursor */
private int cursor; private int cursor;
/** /**
* Constructs an instance with the given data * Constructs an instance with the given data
* *
* @param data non-null; data array to use for input * @param data non-null; data array to use for input
*/ */
public ByteArrayInput(byte[] data) { public ByteArrayInput(byte[] data) {
if (data == null) { if (data == null) {
throw new NullPointerException("data == null"); throw new NullPointerException("data == null");
} }
this.data = data; this.data = data;
this.cursor = 0; this.cursor = 0;
} }
/** /**
* Gets the underlying <code>byte[]</code> of this instance * Gets the underlying <code>byte[]</code> of this instance
* *
* @return non-null; the <code>byte[]</code> * @return non-null; the <code>byte[]</code>
*/ */
public byte[] getArray() { public byte[] getArray() {
return data; return data;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int getCursor() { public int getCursor() {
return cursor; return cursor;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public void setCursor(int cursor) { public void setCursor(int cursor) {
if (cursor < 0 || cursor >= data.length) if (cursor < 0 || cursor >= data.length)
throw new IndexOutOfBoundsException("The provided cursor value " + throw new IndexOutOfBoundsException("The provided cursor value " +
"is not within the bounds of this instance's data array"); "is not within the bounds of this instance's data array");
this.cursor = cursor; this.cursor = cursor;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public void assertCursor(int expectedCursor) { public void assertCursor(int expectedCursor) {
if (cursor != expectedCursor) { if (cursor != expectedCursor) {
throw new ExceptionWithContext("expected cursor " + throw new ExceptionWithContext("expected cursor " +
expectedCursor + "; actual value: " + cursor); expectedCursor + "; actual value: " + cursor);
} }
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public byte readByte() { public byte readByte() {
int readAt = cursor; int readAt = cursor;
int end = readAt + 1; int end = readAt + 1;
if (end > data.length) { if (end > data.length) {
throwBounds(); throwBounds();
} }
cursor = end; cursor = end;
return data[readAt]; return data[readAt];
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int readShort() { public int readShort() {
int readAt = cursor; int readAt = cursor;
int end = readAt + 2; int end = readAt + 2;
if (end > data.length) { if (end > data.length) {
throwBounds(); throwBounds();
} }
cursor = end; cursor = end;
return (int)((data[readAt] & 0xff) + return (int)((data[readAt] & 0xff) +
((data[readAt + 1] & 0xff) << 8)); ((data[readAt + 1] & 0xff) << 8));
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int readInt() { public int readInt() {
int readAt = cursor; int readAt = cursor;
int end = readAt + 4; int end = readAt + 4;
if (end > data.length) { if (end > data.length) {
throwBounds(); throwBounds();
} }
cursor = end; cursor = end;
return (data[readAt] & 0xff) + return (data[readAt] & 0xff) +
((data[readAt + 1] & 0xff) << 8) + ((data[readAt + 1] & 0xff) << 8) +
((data[readAt + 2] & 0xff) << 16) + ((data[readAt + 2] & 0xff) << 16) +
((data[readAt + 3] & 0xff) << 24); ((data[readAt + 3] & 0xff) << 24);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public long readLong() { public long readLong() {
int readAt = cursor; int readAt = cursor;
int end = readAt + 8; int end = readAt + 8;
if (end > data.length) { if (end > data.length) {
throwBounds(); throwBounds();
} }
cursor = end; cursor = end;
return (data[readAt] & 0xffL) | return (data[readAt] & 0xffL) |
((data[readAt + 1] & 0xffL) << 8) | ((data[readAt + 1] & 0xffL) << 8) |
((data[readAt + 2] & 0xffL) << 16) | ((data[readAt + 2] & 0xffL) << 16) |
((data[readAt + 3] & 0xffL) << 24) | ((data[readAt + 3] & 0xffL) << 24) |
((data[readAt + 4] & 0xffL) << 32) | ((data[readAt + 4] & 0xffL) << 32) |
((data[readAt + 5] & 0xffL) << 40) | ((data[readAt + 5] & 0xffL) << 40) |
((data[readAt + 6] & 0xffL) << 48) | ((data[readAt + 6] & 0xffL) << 48) |
((data[readAt + 7] & 0xffL) << 58); ((data[readAt + 7] & 0xffL) << 58);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int readUnsignedOrSignedLeb128() { public int readUnsignedOrSignedLeb128() {
int end = cursor; int end = cursor;
int currentByteValue; int currentByteValue;
int result; int result;
result = data[end++] & 0xff; result = data[end++] & 0xff;
if (result > 0x7f) { if (result > 0x7f) {
currentByteValue = data[end++] & 0xff; currentByteValue = data[end++] & 0xff;
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
if (currentByteValue > 0x7f) { if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff; currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 14; result |= (currentByteValue & 0x7f) << 14;
if (currentByteValue > 0x7f) { if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff; currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 21; result |= (currentByteValue & 0x7f) << 21;
if (currentByteValue > 0x7f) { if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff; currentByteValue = data[end++] & 0xff;
if (currentByteValue > 0x0f) { if (currentByteValue > 0x0f) {
throwInvalidLeb(); throwInvalidLeb();
} }
result |= currentByteValue << 28; result |= currentByteValue << 28;
} }
} }
} }
} else { } else {
cursor = end; cursor = end;
return result; return result;
} }
cursor = end; cursor = end;
//If the last byte is 0, then this was an unsigned value (incorrectly) written in a signed format //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 //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 //If there was only a single byte that had a value of 0, then we would have returned in the above
//"else" //"else"
if (data[end-1] == 0) { if (data[end-1] == 0) {
return ~result; return ~result;
} }
return result; return result;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int readUnsignedLeb128() { public int readUnsignedLeb128() {
int end = cursor; int end = cursor;
int currentByteValue; int currentByteValue;
int result; int result;
result = data[end++] & 0xff; result = data[end++] & 0xff;
if (result > 0x7f) { if (result > 0x7f) {
currentByteValue = data[end++] & 0xff; currentByteValue = data[end++] & 0xff;
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
if (currentByteValue > 0x7f) { if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff; currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 14; result |= (currentByteValue & 0x7f) << 14;
if (currentByteValue > 0x7f) { if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff; currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 21; result |= (currentByteValue & 0x7f) << 21;
if (currentByteValue > 0x7f) { if (currentByteValue > 0x7f) {
currentByteValue = data[end++] & 0xff; currentByteValue = data[end++] & 0xff;
if (currentByteValue > 0x0f) { if (currentByteValue > 0x0f) {
throwInvalidLeb(); throwInvalidLeb();
} }
result |= currentByteValue << 28; result |= currentByteValue << 28;
} }
} }
} }
} }
cursor = end; cursor = end;
return result; return result;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public int readSignedLeb128() { public int readSignedLeb128() {
int end = cursor; int end = cursor;
int currentByteValue; int currentByteValue;
int result; int result;
result = data[end++] & 0xff; result = data[end++] & 0xff;
if (result <= 0x7f) { if (result <= 0x7f) {
result = (result << 25) >> 25; result = (result << 25) >> 25;
} else { } else {
currentByteValue = data[end++] & 0xff; currentByteValue = data[end++] & 0xff;
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
if (currentByteValue <= 0x7f) { if (currentByteValue <= 0x7f) {
result = (result << 18) >> 18; result = (result << 18) >> 18;
} else { } else {
currentByteValue = data[end++] & 0xff; currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 14; result |= (currentByteValue & 0x7f) << 14;
if (currentByteValue <= 0x7f) { if (currentByteValue <= 0x7f) {
result = (result << 11) >> 11; result = (result << 11) >> 11;
} else { } else {
currentByteValue = data[end++] & 0xff; currentByteValue = data[end++] & 0xff;
result |= (currentByteValue & 0x7f) << 21; result |= (currentByteValue & 0x7f) << 21;
if (currentByteValue <= 0x7f) { if (currentByteValue <= 0x7f) {
result = (result << 4) >> 4; result = (result << 4) >> 4;
} else { } else {
currentByteValue = data[end++] & 0xff; currentByteValue = data[end++] & 0xff;
if (currentByteValue > 0x0f) { if (currentByteValue > 0x0f) {
throwInvalidLeb(); throwInvalidLeb();
} }
result |= currentByteValue << 28; result |= currentByteValue << 28;
} }
} }
} }
} }
cursor = end; cursor = end;
return result; return result;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public void read(byte[] bytes, int offset, int length) { public void read(byte[] bytes, int offset, int length) {
int end = cursor + length; int end = cursor + length;
if (end > data.length) { if (end > data.length) {
throwBounds(); throwBounds();
} }
System.arraycopy(data, cursor, bytes, offset, length); System.arraycopy(data, cursor, bytes, offset, length);
cursor = end; cursor = end;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public void read(byte[] bytes) { public void read(byte[] bytes) {
int length = bytes.length; int length = bytes.length;
int end = cursor + length; int end = cursor + length;
if (end > data.length) { if (end > data.length) {
throwBounds(); throwBounds();
} }
System.arraycopy(data, cursor, bytes, 0, length); System.arraycopy(data, cursor, bytes, 0, length);
cursor = end; cursor = end;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public byte[] readBytes(int length) { public byte[] readBytes(int length) {
int end = cursor + length; int end = cursor + length;
if (end > data.length) { if (end > data.length) {
throwBounds(); throwBounds();
} }
byte[] result = new byte[length]; byte[] result = new byte[length];
System.arraycopy(data, cursor, result, 0, length); System.arraycopy(data, cursor, result, 0, length);
cursor = end; cursor = end;
return result; return result;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public byte[] readNullTerminatedBytes() { public byte[] readNullTerminatedBytes() {
int startPosition = cursor; int startPosition = cursor;
while (data[cursor] != 0) { while (data[cursor] != 0) {
cursor++; cursor++;
if (cursor >= data.length) { if (cursor >= data.length) {
throwBounds(); throwBounds();
} }
} }
int byteCount = cursor - startPosition; int byteCount = cursor - startPosition;
//skip the terminating null //skip the terminating null
cursor++; cursor++;
byte[] result = new byte[byteCount]; byte[] result = new byte[byteCount];
System.arraycopy(data, startPosition, result, 0, byteCount); System.arraycopy(data, startPosition, result, 0, byteCount);
return result; return result;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public void skipBytes(int count) { public void skipBytes(int count) {
int end = cursor + count; int end = cursor + count;
if (end > data.length) { if (end > data.length) {
throwBounds(); throwBounds();
} }
cursor = end; cursor = end;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public void alignTo(int alignment) { public void alignTo(int alignment) {
int end = AlignmentUtils.alignOffset(cursor, alignment); int end = AlignmentUtils.alignOffset(cursor, alignment);
if (end > data.length) { if (end > data.length) {
throwBounds(); throwBounds();
} }
cursor = end; cursor = end;
} }
/** /**
* Throws the excpetion for when an attempt is made to read past the * Throws the excpetion for when an attempt is made to read past the
* end of the instance. * end of the instance.
*/ */
private static void throwBounds() { private static void throwBounds() {
throw new IndexOutOfBoundsException("attempt to read past the end"); throw new IndexOutOfBoundsException("attempt to read past the end");
} }
/** /**
* Throws the exception for when an invalid LEB128 value is encountered * Throws the exception for when an invalid LEB128 value is encountered
*/ */
private static void throwInvalidLeb() { private static void throwInvalidLeb() {
throw new RuntimeException("invalid LEB128 integer encountered"); throw new RuntimeException("invalid LEB128 integer encountered");
} }
} }

View File

@ -1,451 +1,451 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Util; package org.jf.dexlib.Util;
import org.jf.dexlib.*; import org.jf.dexlib.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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 * 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. * 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 * 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. * generally behave, and is intended to increase performance.
*/ */
public class DebugInfoBuilder public class DebugInfoBuilder
{ {
private static final int LINE_BASE = -4; private static final int LINE_BASE = -4;
private static final int LINE_RANGE = 15; private static final int LINE_RANGE = 15;
private static final int FIRST_SPECIAL = 0x0a; private static final int FIRST_SPECIAL = 0x0a;
private int lineStart = 0; private int lineStart = 0;
private ArrayList<String> parameterNames = new ArrayList<String>(); private ArrayList<String> parameterNames = new ArrayList<String>();
private ArrayList<Event> events = new ArrayList<Event>(); private ArrayList<Event> events = new ArrayList<Event>();
private int lastAddress = 0; private int lastAddress = 0;
private boolean hasData; private boolean hasData;
private int currentAddress; private int currentAddress;
private int currentLine; private int currentLine;
public DebugInfoBuilder() { public DebugInfoBuilder() {
} }
private void checkAddress(int address) { private void checkAddress(int address) {
if (lastAddress > address) { if (lastAddress > address) {
throw new RuntimeException("Cannot add an event with an address before the address of the prior event"); throw new RuntimeException("Cannot add an event with an address before the address of the prior event");
} }
} }
public void addParameterName(String parameterName) { public void addParameterName(String parameterName) {
if (parameterName != null) { if (parameterName != null) {
hasData = true; hasData = true;
} }
parameterNames.add(parameterName); parameterNames.add(parameterName);
} }
public void addLine(int address, int line) { public void addLine(int address, int line) {
hasData = true; hasData = true;
checkAddress(address); checkAddress(address);
if (lineStart == 0) { if (lineStart == 0) {
lineStart = line; lineStart = line;
} }
events.add(new LineEvent(address, line)); events.add(new LineEvent(address, line));
} }
public void addLocal(int address, int registerNumber, String localName, String localType) { public void addLocal(int address, int registerNumber, String localName, String localType) {
hasData = true; hasData = true;
checkAddress(address); checkAddress(address);
events.add(new StartLocalEvent(address, registerNumber, localName, localType)); events.add(new StartLocalEvent(address, registerNumber, localName, localType));
} }
public void addLocalExtended(int address, int registerNumber, String localName, String localType, public void addLocalExtended(int address, int registerNumber, String localName, String localType,
String signature) { String signature) {
hasData = true; hasData = true;
checkAddress(address); checkAddress(address);
events.add(new StartLocalExtendedEvent(address, registerNumber, localName, localType, signature)); events.add(new StartLocalExtendedEvent(address, registerNumber, localName, localType, signature));
} }
public void addEndLocal(int address, int registerNumber) { public void addEndLocal(int address, int registerNumber) {
hasData = true; hasData = true;
checkAddress(address); checkAddress(address);
events.add(new EndLocalEvent(address, registerNumber)); events.add(new EndLocalEvent(address, registerNumber));
} }
public void addRestartLocal(int address, int registerNumber) { public void addRestartLocal(int address, int registerNumber) {
hasData = true; hasData = true;
checkAddress(address); checkAddress(address);
events.add(new RestartLocalEvent(address, registerNumber)); events.add(new RestartLocalEvent(address, registerNumber));
} }
public void addPrologue(int address) { public void addPrologue(int address) {
hasData = true; hasData = true;
checkAddress(address); checkAddress(address);
events.add(new PrologueEvent(address)); events.add(new PrologueEvent(address));
} }
public void addEpilogue(int address) { public void addEpilogue(int address) {
hasData = true; hasData = true;
checkAddress(address); checkAddress(address);
events.add(new EpilogueEvent(address)); events.add(new EpilogueEvent(address));
} }
public void addSetFile(int address, String fileName) { public void addSetFile(int address, String fileName) {
hasData = true; hasData = true;
checkAddress(address); checkAddress(address);
events.add(new SetFileEvent(address, fileName)); events.add(new SetFileEvent(address, fileName));
} }
public int getParameterNameCount() { public int getParameterNameCount() {
return parameterNames.size(); return parameterNames.size();
} }
public DebugInfoItem encodeDebugInfo(DexFile dexFile) { public DebugInfoItem encodeDebugInfo(DexFile dexFile) {
if (!hasData) { if (!hasData) {
return null; return null;
} }
ByteArrayOutput out = new ByteArrayOutput(); ByteArrayOutput out = new ByteArrayOutput();
StringIdItem[] parameterNamesArray = new StringIdItem[parameterNames.size()]; StringIdItem[] parameterNamesArray = new StringIdItem[parameterNames.size()];
ArrayList<Item> referencedItems = new ArrayList<Item>(); ArrayList<Item> referencedItems = new ArrayList<Item>();
if (lineStart == 0) { if (lineStart == 0) {
lineStart = 1; lineStart = 1;
} }
currentLine = lineStart; currentLine = lineStart;
for (Event event: events) { for (Event event: events) {
event.emit(dexFile, out, referencedItems); event.emit(dexFile, out, referencedItems);
} }
emitEndSequence(out); emitEndSequence(out);
int index = 0; int index = 0;
for (String parameterName: parameterNames) { for (String parameterName: parameterNames) {
if (parameterName == null) { if (parameterName == null) {
parameterNamesArray[index++] = null; parameterNamesArray[index++] = null;
} else { } else {
parameterNamesArray[index++] = StringIdItem.getInternedStringIdItem(dexFile, parameterName); parameterNamesArray[index++] = StringIdItem.getInternedStringIdItem(dexFile, parameterName);
} }
} }
Item[] referencedItemsArray = new Item[referencedItems.size()]; Item[] referencedItemsArray = new Item[referencedItems.size()];
referencedItems.toArray(referencedItemsArray); referencedItems.toArray(referencedItemsArray);
return DebugInfoItem.getInternedDebugInfoItem(dexFile, lineStart, parameterNamesArray, out.getArray(), return DebugInfoItem.getInternedDebugInfoItem(dexFile, lineStart, parameterNamesArray, out.getArray(),
referencedItemsArray); referencedItemsArray);
} }
private interface Event private interface Event
{ {
int getAddress(); int getAddress();
void emit(DexFile dexFile, Output out, List<Item> referencedItems); void emit(DexFile dexFile, Output out, List<Item> referencedItems);
} }
private void emitEndSequence(Output out) { private void emitEndSequence(Output out) {
out.writeByte(0); out.writeByte(0);
} }
private void emitAdvancePC(Output out, int address) { private void emitAdvancePC(Output out, int address) {
int addressDelta = address-currentAddress; int addressDelta = address-currentAddress;
if (addressDelta > 0) { if (addressDelta > 0) {
out.writeByte(1); out.writeByte(1);
out.writeUnsignedLeb128(addressDelta); out.writeUnsignedLeb128(addressDelta);
currentAddress = address; currentAddress = address;
} }
} }
private void emitAdvanceLine(Output out, int lineDelta) { private void emitAdvanceLine(Output out, int lineDelta) {
out.writeByte(2); out.writeByte(2);
out.writeSignedLeb128(lineDelta); out.writeSignedLeb128(lineDelta);
} }
private void emitStartLocal(Output out, int registerNum) { private void emitStartLocal(Output out, int registerNum) {
out.writeByte(3); out.writeByte(3);
out.writeUnsignedLeb128(registerNum); out.writeUnsignedLeb128(registerNum);
out.writeByte(1); out.writeByte(1);
out.writeByte(1); out.writeByte(1);
} }
private void emitStartLocalExtended(Output out, int registerNum) { private void emitStartLocalExtended(Output out, int registerNum) {
out.writeByte(4); out.writeByte(4);
out.writeUnsignedLeb128(registerNum); out.writeUnsignedLeb128(registerNum);
out.writeByte(1); out.writeByte(1);
out.writeByte(1); out.writeByte(1);
out.writeByte(1); out.writeByte(1);
} }
private void emitEndLocal(Output out, int registerNum) { private void emitEndLocal(Output out, int registerNum) {
out.writeByte(5); out.writeByte(5);
out.writeUnsignedLeb128(registerNum); out.writeUnsignedLeb128(registerNum);
} }
private void emitRestartLocal(Output out, int registerNum) { private void emitRestartLocal(Output out, int registerNum) {
out.writeByte(6); out.writeByte(6);
out.writeUnsignedLeb128(registerNum); out.writeUnsignedLeb128(registerNum);
} }
private void emitSetPrologueEnd(Output out) { private void emitSetPrologueEnd(Output out) {
out.writeByte(7); out.writeByte(7);
} }
private void emitSetEpilogueBegin(Output out) { private void emitSetEpilogueBegin(Output out) {
out.writeByte(8); out.writeByte(8);
} }
private void emitSetFile(Output out) { private void emitSetFile(Output out) {
out.writeByte(9); out.writeByte(9);
out.writeByte(1); out.writeByte(1);
} }
private void emitSpecialOpcode(Output out, byte opcode) { private void emitSpecialOpcode(Output out, byte opcode) {
out.writeByte(opcode); out.writeByte(opcode);
} }
private class LineEvent implements Event private class LineEvent implements Event
{ {
private final int address; private final int address;
private final int line; private final int line;
public LineEvent(int address, int line) { public LineEvent(int address, int line) {
this.address = address; this.address = address;
this.line = line; this.line = line;
} }
public int getAddress() { public int getAddress() {
return address; return address;
} }
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) { public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
int lineDelta = line - currentLine; int lineDelta = line - currentLine;
int addressDelta = address - currentAddress; int addressDelta = address - currentAddress;
if (lineDelta < -4 || lineDelta > 10) { if (lineDelta < -4 || lineDelta > 10) {
emitAdvanceLine(out, lineDelta); emitAdvanceLine(out, lineDelta);
lineDelta = 0; lineDelta = 0;
} }
if (lineDelta < 2 && addressDelta > 16 || lineDelta > 1 && addressDelta > 15) { if (lineDelta < 2 && addressDelta > 16 || lineDelta > 1 && addressDelta > 15) {
emitAdvancePC(out, address); emitAdvancePC(out, address);
addressDelta = 0; addressDelta = 0;
} }
//TODO: need to handle the case when the line delta is larger than a signed int //TODO: need to handle the case when the line delta is larger than a signed int
emitSpecialOpcode(out, calculateSpecialOpcode(lineDelta, addressDelta)); emitSpecialOpcode(out, calculateSpecialOpcode(lineDelta, addressDelta));
currentAddress = address; currentAddress = address;
currentLine = line; currentLine = line;
} }
private byte calculateSpecialOpcode(int lineDelta, int addressDelta) { private byte calculateSpecialOpcode(int lineDelta, int addressDelta) {
return (byte)(FIRST_SPECIAL + (addressDelta * LINE_RANGE) + (lineDelta - LINE_BASE)); return (byte)(FIRST_SPECIAL + (addressDelta * LINE_RANGE) + (lineDelta - LINE_BASE));
} }
} }
private class StartLocalEvent implements Event private class StartLocalEvent implements Event
{ {
private final int address; private final int address;
private final int registerNum; private final int registerNum;
private final String localName; private final String localName;
private final String localType; private final String localType;
public StartLocalEvent(int address, int registerNum, String localName, String localType) { public StartLocalEvent(int address, int registerNum, String localName, String localType) {
this.address = address; this.address = address;
this.registerNum = registerNum; this.registerNum = registerNum;
this.localName = localName; this.localName = localName;
this.localType = localType; this.localType = localType;
} }
public int getAddress() { public int getAddress() {
return address; return address;
} }
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) { public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address); emitAdvancePC(out, address);
emitStartLocal(out, registerNum); emitStartLocal(out, registerNum);
referencedItems.add(localName==null?null:StringIdItem.getInternedStringIdItem(dexFile, localName)); referencedItems.add(localName==null?null:StringIdItem.getInternedStringIdItem(dexFile, localName));
referencedItems.add(localType==null?null:TypeIdItem.getInternedTypeIdItem(dexFile, referencedItems.add(localType==null?null:TypeIdItem.getInternedTypeIdItem(dexFile,
StringIdItem.getInternedStringIdItem(dexFile, localType))); StringIdItem.getInternedStringIdItem(dexFile, localType)));
} }
} }
private class StartLocalExtendedEvent implements Event private class StartLocalExtendedEvent implements Event
{ {
private final int address; private final int address;
private final int registerNum; private final int registerNum;
private final String localName; private final String localName;
private final String localType; private final String localType;
private final String signature; private final String signature;
public StartLocalExtendedEvent(int address, int registerNum, String localName, String localType, public StartLocalExtendedEvent(int address, int registerNum, String localName, String localType,
String signature) { String signature) {
this.address = address; this.address = address;
this.registerNum = registerNum; this.registerNum = registerNum;
this.localName = localName; this.localName = localName;
this.localType = localType; this.localType = localType;
this.signature = signature; this.signature = signature;
} }
public int getAddress() { public int getAddress() {
return address; return address;
} }
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) { public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address); emitAdvancePC(out, address);
emitStartLocalExtended(out, registerNum); emitStartLocalExtended(out, registerNum);
if (localName != null) { if (localName != null) {
referencedItems.add(StringIdItem.getInternedStringIdItem(dexFile, localName)); referencedItems.add(StringIdItem.getInternedStringIdItem(dexFile, localName));
} }
if (localType != null) { if (localType != null) {
referencedItems.add(TypeIdItem.getInternedTypeIdItem(dexFile, referencedItems.add(TypeIdItem.getInternedTypeIdItem(dexFile,
StringIdItem.getInternedStringIdItem(dexFile, localType))); StringIdItem.getInternedStringIdItem(dexFile, localType)));
} }
if (signature != null) { if (signature != null) {
referencedItems.add(StringIdItem.getInternedStringIdItem(dexFile, signature)); referencedItems.add(StringIdItem.getInternedStringIdItem(dexFile, signature));
} }
} }
} }
private class EndLocalEvent implements Event private class EndLocalEvent implements Event
{ {
private final int address; private final int address;
private final int registerNum; private final int registerNum;
public EndLocalEvent(int address, int registerNum) { public EndLocalEvent(int address, int registerNum) {
this.address = address; this.address = address;
this.registerNum = registerNum; this.registerNum = registerNum;
} }
public int getAddress() { public int getAddress() {
return address; return address;
} }
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) { public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address); emitAdvancePC(out, address);
emitEndLocal(out, registerNum); emitEndLocal(out, registerNum);
} }
} }
private class RestartLocalEvent implements Event private class RestartLocalEvent implements Event
{ {
private final int address; private final int address;
private final int registerNum; private final int registerNum;
public RestartLocalEvent(int address, int registerNum) { public RestartLocalEvent(int address, int registerNum) {
this.address = address; this.address = address;
this.registerNum = registerNum; this.registerNum = registerNum;
} }
public int getAddress() { public int getAddress() {
return address; return address;
} }
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) { public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address); emitAdvancePC(out, address);
emitRestartLocal(out, registerNum); emitRestartLocal(out, registerNum);
} }
} }
private class PrologueEvent implements Event private class PrologueEvent implements Event
{ {
private final int address; private final int address;
public PrologueEvent(int address) { public PrologueEvent(int address) {
this.address = address; this.address = address;
} }
public int getAddress() { public int getAddress() {
return address; return address;
} }
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) { public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address); emitAdvancePC(out, address);
emitSetPrologueEnd(out); emitSetPrologueEnd(out);
} }
} }
private class EpilogueEvent implements Event private class EpilogueEvent implements Event
{ {
private final int address; private final int address;
public EpilogueEvent(int address) { public EpilogueEvent(int address) {
this.address = address; this.address = address;
} }
public int getAddress() { public int getAddress() {
return address; return address;
} }
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) { public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address); emitAdvancePC(out, address);
emitSetEpilogueBegin(out); emitSetEpilogueBegin(out);
} }
} }
private class SetFileEvent implements Event private class SetFileEvent implements Event
{ {
private final int address; private final int address;
private final String fileName; private final String fileName;
public SetFileEvent(int address, String fileName) { public SetFileEvent(int address, String fileName) {
this.address = address; this.address = address;
this.fileName = fileName; this.fileName = fileName;
} }
public int getAddress() { public int getAddress() {
return address; return address;
} }
public void emit(DexFile dexFile, Output out, List<Item> referencedItems) { public void emit(DexFile dexFile, Output out, List<Item> referencedItems) {
emitAdvancePC(out, address); emitAdvancePC(out, address);
emitSetFile(out); emitSetFile(out);
if (fileName != null) { if (fileName != null) {
referencedItems.add(StringIdItem.getInternedStringIdItem(dexFile, fileName)); referencedItems.add(StringIdItem.getInternedStringIdItem(dexFile, fileName));
} }
} }
} }
} }

View File

@ -1,143 +1,143 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Util; package org.jf.dexlib.Util;
public class EncodedValueUtils { public class EncodedValueUtils {
public static byte getRequiredBytesForSignedIntegralValue(long value) { public static byte getRequiredBytesForSignedIntegralValue(long value) {
/* /*
* Figure out how many bits are needed to represent the value, * Figure out how many bits are needed to represent the value,
* including a sign bit: The bit count is subtracted from 65 * including a sign bit: The bit count is subtracted from 65
* and not 64 to account for the sign bit. The xor operation * and not 64 to account for the sign bit. The xor operation
* has the effect of leaving non-negative values alone and * has the effect of leaving non-negative values alone and
* unary complementing negative values (so that a leading zero * unary complementing negative values (so that a leading zero
* count always returns a useful number for our present * count always returns a useful number for our present
* purpose). * purpose).
*/ */
int requiredBits = int requiredBits =
65 - Long.numberOfLeadingZeros(value ^ (value >> 63)); 65 - Long.numberOfLeadingZeros(value ^ (value >> 63));
// Round up the requiredBits to a number of bytes. // Round up the requiredBits to a number of bytes.
return (byte)((requiredBits + 0x07) >> 3); return (byte)((requiredBits + 0x07) >> 3);
} }
public static long decodeSignedIntegralValue(byte[] bytes) { public static long decodeSignedIntegralValue(byte[] bytes) {
long value = 0; long value = 0;
for (int i = 0; i < bytes.length; i++) { for (int i = 0; i < bytes.length; i++) {
value |= (((long)(bytes[i] & 0xFF)) << (i * 8)); value |= (((long)(bytes[i] & 0xFF)) << (i * 8));
} }
int shift = (8 - bytes.length) * 8; int shift = (8 - bytes.length) * 8;
return value << shift >> shift; return value << shift >> shift;
} }
public static byte[] encodeSignedIntegralValue(long value) { public static byte[] encodeSignedIntegralValue(long value) {
int requiredBytes = getRequiredBytesForSignedIntegralValue(value); int requiredBytes = getRequiredBytesForSignedIntegralValue(value);
byte[] bytes = new byte[requiredBytes]; byte[] bytes = new byte[requiredBytes];
for (int i = 0; i < requiredBytes; i++) { for (int i = 0; i < requiredBytes; i++) {
bytes[i] = (byte) value; bytes[i] = (byte) value;
value >>= 8; value >>= 8;
} }
return bytes; return bytes;
} }
public static byte getRequiredBytesForUnsignedIntegralValue(long value) { public static byte getRequiredBytesForUnsignedIntegralValue(long value) {
// Figure out how many bits are needed to represent the value. // Figure out how many bits are needed to represent the value.
int requiredBits = 64 - Long.numberOfLeadingZeros(value); int requiredBits = 64 - Long.numberOfLeadingZeros(value);
if (requiredBits == 0) { if (requiredBits == 0) {
requiredBits = 1; requiredBits = 1;
} }
// Round up the requiredBits to a number of bytes. // Round up the requiredBits to a number of bytes.
return (byte)((requiredBits + 0x07) >> 3); return (byte)((requiredBits + 0x07) >> 3);
} }
public static long decodeUnsignedIntegralValue(byte[] bytes) { public static long decodeUnsignedIntegralValue(byte[] bytes) {
long value = 0; long value = 0;
for (int i = 0; i < bytes.length; i++) { for (int i = 0; i < bytes.length; i++) {
value |= (((long)(bytes[i] & 0xFF)) << i * 8); value |= (((long)(bytes[i] & 0xFF)) << i * 8);
} }
return value; return value;
} }
public static byte[] encodeUnsignedIntegralValue(long value) { public static byte[] encodeUnsignedIntegralValue(long value) {
int requiredBytes = getRequiredBytesForUnsignedIntegralValue(value); int requiredBytes = getRequiredBytesForUnsignedIntegralValue(value);
byte[] bytes = new byte[requiredBytes]; byte[] bytes = new byte[requiredBytes];
for (int i = 0; i < requiredBytes; i++) { for (int i = 0; i < requiredBytes; i++) {
bytes[i] = (byte) value; bytes[i] = (byte) value;
value >>= 8; value >>= 8;
} }
return bytes; return bytes;
} }
public static int getRequiredBytesForRightZeroExtendedValue(long value) { public static int getRequiredBytesForRightZeroExtendedValue(long value) {
// Figure out how many bits are needed to represent the value. // Figure out how many bits are needed to represent the value.
int requiredBits = 64 - Long.numberOfTrailingZeros(value); int requiredBits = 64 - Long.numberOfTrailingZeros(value);
if (requiredBits == 0) { if (requiredBits == 0) {
requiredBits = 1; requiredBits = 1;
} }
// Round up the requiredBits to a number of bytes. // Round up the requiredBits to a number of bytes.
return (requiredBits + 0x07) >> 3; return (requiredBits + 0x07) >> 3;
} }
public static long decodeRightZeroExtendedValue(byte[] bytes) { public static long decodeRightZeroExtendedValue(byte[] bytes) {
long value = 0; long value = 0;
for (int i = 0; i < bytes.length; i++) { for (int i = 0; i < bytes.length; i++) {
value |= (((long)(bytes[i] & 0xFF)) << (i * 8)); value |= (((long)(bytes[i] & 0xFF)) << (i * 8));
} }
return value << (8 - bytes.length) * 8; return value << (8 - bytes.length) * 8;
} }
public static byte[] encodeRightZeroExtendedValue(long value) { public static byte[] encodeRightZeroExtendedValue(long value) {
int requiredBytes = getRequiredBytesForRightZeroExtendedValue(value); int requiredBytes = getRequiredBytesForRightZeroExtendedValue(value);
// Scootch the first bits to be written down to the low-order bits. // Scootch the first bits to be written down to the low-order bits.
value >>= 64 - (requiredBytes * 8); value >>= 64 - (requiredBytes * 8);
byte[] bytes = new byte[requiredBytes]; byte[] bytes = new byte[requiredBytes];
for(int i = 0; i < requiredBytes; i++) { for(int i = 0; i < requiredBytes; i++) {
bytes[i] = (byte)value; bytes[i] = (byte)value;
value >>= 8; value >>= 8;
} }
return bytes; return bytes;
} }
} }

View File

@ -1,167 +1,167 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Util; package org.jf.dexlib.Util;
/** /**
* Interface for a source for binary input. This is similar to * Interface for a source for binary input. This is similar to
* <code>java.util.DataInput</code>, but no <code>IOExceptions</code> * <code>java.util.DataInput</code>, but no <code>IOExceptions</code>
* are declared, and multibyte input is defined to be little-endian. * are declared, and multibyte input is defined to be little-endian.
*/ */
public interface Input { public interface Input {
/** /**
* Gets the current cursor position. This is the same as the number of * Gets the current cursor position. This is the same as the number of
* bytes read from this instance. * bytes read from this instance.
* *
* @return &gt;= 0; the cursor position * @return &gt;= 0; the cursor position
*/ */
public int getCursor(); public int getCursor();
/** /**
* Sets the current cursor position. * Sets the current cursor position.
* *
* @return &gt;= 0; the cursor position * @return &gt;= 0; the cursor position
*/ */
public void setCursor(int cursor); public void setCursor(int cursor);
/** /**
* Asserts that the cursor is the given value. * Asserts that the cursor is the given value.
* *
* @param expectedCursor the expected cursor value * @param expectedCursor the expected cursor value
* @throws RuntimeException thrown if <code>getCursor() != * @throws RuntimeException thrown if <code>getCursor() !=
* expectedCursor</code> * expectedCursor</code>
*/ */
public void assertCursor(int expectedCursor); public void assertCursor(int expectedCursor);
/** /**
* Reads a <code>byte</code> from this instance. * Reads a <code>byte</code> from this instance.
* *
* @return the byte value that was read * @return the byte value that was read
*/ */
public byte readByte(); public byte readByte();
/** /**
* Reads a <code>short</code> from this instance. * Reads a <code>short</code> from this instance.
* *
* @return the short value that was read, as an int * @return the short value that was read, as an int
*/ */
public int readShort(); public int readShort();
/** /**
* Reads an <code>int</code> from this instance. * Reads an <code>int</code> from this instance.
* *
* @return the unsigned int value that was read * @return the unsigned int value that was read
*/ */
public int readInt(); public int readInt();
/** /**
* Reads a <code>long</code> from this instance. * Reads a <code>long</code> from this instance.
* *
* @return the long value that was read * @return the long value that was read
*/ */
public long readLong(); public long readLong();
/** /**
* Reads a DWARFv3-style signed LEB128 integer. For details, * Reads a DWARFv3-style signed LEB128 integer. For details,
* see the "Dalvik Executable Format" document or DWARF v3 section * see the "Dalvik Executable Format" document or DWARF v3 section
* 7.6. * 7.6.
* *
* @return the integer value that was read * @return the integer value that was read
*/ */
public int readSignedLeb128(); public int readSignedLeb128();
/** /**
* Reads a DWARFv3-style unsigned LEB128 integer. For details, * Reads a DWARFv3-style unsigned LEB128 integer. For details,
* see the "Dalvik Executable Format" document or DWARF v3 section * see the "Dalvik Executable Format" document or DWARF v3 section
* 7.6. * 7.6.
* *
* @return the integer value that was read * @return the integer value that was read
*/ */
public int readUnsignedLeb128(); public int readUnsignedLeb128();
/** /**
* Reads a unsigned value as a DWARFv3-style LEB128 integer. It specifically * 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 * checks for the case when the value was incorrectly formatted as a signed
* LEB128, and returns the appropriate unsigned value, but negated * LEB128, and returns the appropriate unsigned value, but negated
* @return If the value was formatted as a ULEB128, it returns the actual unsigned * @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 * value. Otherwise, if the value was formatted as a signed LEB128, it negates the
* "correct" unsigned value and returns that * "correct" unsigned value and returns that
*/ */
public int readUnsignedOrSignedLeb128(); public int readUnsignedOrSignedLeb128();
/** /**
* reads a <code>byte[]</code> from this instance. * reads a <code>byte[]</code> from this instance.
* *
* @param bytes non-null; the buffer to read the data into * @param bytes non-null; the buffer to read the data into
* @param offset &gt;= 0; offset into <code>bytes</code> for the first * @param offset &gt;= 0; offset into <code>bytes</code> for the first
* byte to write * byte to write
* @param length &gt;= 0; number of bytes to read * @param length &gt;= 0; number of bytes to read
*/ */
public void read(byte[] bytes, int offset, int length); public void read(byte[] bytes, int offset, int length);
/** /**
* reads a <code>byte[]</code> from this instance. This is just * reads a <code>byte[]</code> from this instance. This is just
* a convenient shorthand for <code>read(bytes, 0, bytes.length)</code>. * a convenient shorthand for <code>read(bytes, 0, bytes.length)</code>.
* *
* @param bytes non-null; the buffer to read the data into * @param bytes non-null; the buffer to read the data into
*/ */
public void read(byte[] bytes); public void read(byte[] bytes);
/** /**
* reads a <code>byte[]</code> from this instance * reads a <code>byte[]</code> from this instance
* *
* @param length &gt;= 0; number of bytes to read * @param length &gt;= 0; number of bytes to read
* @return a byte array containing <code>length</code> bytes * @return a byte array containing <code>length</code> bytes
*/ */
public byte[] readBytes(int length); public byte[] readBytes(int length);
/** /**
* reads a <code>byte[]</code> from this instance, from the current cursor up to but not including * 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 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 * the cursor is positioned at the byte immediately after the terminating null
*/ */
public byte[] readNullTerminatedBytes(); public byte[] readNullTerminatedBytes();
/** /**
* Skips the given number of bytes. * Skips the given number of bytes.
* *
* @param count &gt;= 0; the number of bytes to skip * @param count &gt;= 0; the number of bytes to skip
*/ */
public void skipBytes(int count); public void skipBytes(int count);
/** /**
* Skip extra bytes if necessary to force alignment of the output * Skip extra bytes if necessary to force alignment of the output
* cursor as given. * cursor as given.
* *
* @param alignment &gt; 0; the alignment; must be a power of two * @param alignment &gt; 0; the alignment; must be a power of two
*/ */
public void alignTo(int alignment); public void alignTo(int alignment);
} }

View File

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

View File

@ -1,347 +1,347 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Util; package org.jf.dexlib.Util;
import org.jf.dexlib.CodeItem; import org.jf.dexlib.CodeItem;
import org.jf.dexlib.TypeIdItem; import org.jf.dexlib.TypeIdItem;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
public class TryListBuilder public class TryListBuilder
{ {
/*TODO: add logic to merge adjacent, identical try blocks, and remove superflous handlers /*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 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)*/ exactly reproduce the original .dex file (for testing/verification purposes)*/
private TryRange firstTryRange = new TryRange(0,0); private TryRange firstTryRange = new TryRange(0,0);
private TryRange lastTryRange = new TryRange(0,0); private TryRange lastTryRange = new TryRange(0,0);
public TryListBuilder() { public TryListBuilder() {
firstTryRange.next = lastTryRange; firstTryRange.next = lastTryRange;
lastTryRange.previous = firstTryRange; lastTryRange.previous = firstTryRange;
} }
private class TryRange private class TryRange
{ {
public TryRange previous = null; public TryRange previous = null;
public TryRange next = null; public TryRange next = null;
public int startAddress; public int startAddress;
public int endAddress; public int endAddress;
public LinkedList<Handler> handlers; public LinkedList<Handler> handlers;
public int catchAllHandlerAddress; public int catchAllHandlerAddress;
public TryRange(int startAddress, int endAddress) { public TryRange(int startAddress, int endAddress) {
this.startAddress = startAddress; this.startAddress = startAddress;
this.endAddress = endAddress; this.endAddress = endAddress;
this.handlers = new LinkedList<Handler>(); this.handlers = new LinkedList<Handler>();
this.previous = null; this.previous = null;
this.next = null; this.next = null;
catchAllHandlerAddress = -1; catchAllHandlerAddress = -1;
} }
public void append(TryRange tryRange) { public void append(TryRange tryRange) {
/*we use a dummy last item, so this.next will always /*we use a dummy last item, so this.next will always
have a value*/ have a value*/
this.next.previous = tryRange; this.next.previous = tryRange;
tryRange.next = this.next; tryRange.next = this.next;
this.next = tryRange; this.next = tryRange;
tryRange.previous = this; tryRange.previous = this;
} }
public void prepend(TryRange tryRange){ public void prepend(TryRange tryRange){
/*we use a dummy first item, so this.previous will always /*we use a dummy first item, so this.previous will always
have a value*/ have a value*/
this.previous.next = tryRange; this.previous.next = tryRange;
tryRange.previous = this.previous; tryRange.previous = this.previous;
this.previous = tryRange; this.previous = tryRange;
tryRange.next = this; tryRange.next = this;
} }
/** /**
* This splits the current range into two ranges at the given * This splits the current range into two ranges at the given
* address. The existing range will be shortened to the first * address. The existing range will be shortened to the first
* half, and a new range will be created and returned for the * half, and a new range will be created and returned for the
* 2nd half. * 2nd half.
* @param address The address to split at * @param address The address to split at
* @return The 2nd half of the * @return The 2nd half of the
*/ */
public TryRange split(int address) { public TryRange split(int address) {
//this is a private class, so address is assumed //this is a private class, so address is assumed
//to be valid //to be valid
TryRange tryRange = new TryRange(address, endAddress); TryRange tryRange = new TryRange(address, endAddress);
tryRange.catchAllHandlerAddress = this.catchAllHandlerAddress; tryRange.catchAllHandlerAddress = this.catchAllHandlerAddress;
tryRange.handlers.addAll(this.handlers); tryRange.handlers.addAll(this.handlers);
append(tryRange); append(tryRange);
this.endAddress = address; this.endAddress = address;
return tryRange; return tryRange;
} }
public void appendHandler(Handler handler) { public void appendHandler(Handler handler) {
handlers.addLast(handler); handlers.addLast(handler);
} }
public void prependHandler(Handler handler) { public void prependHandler(Handler handler) {
handlers.addFirst(handler); handlers.addFirst(handler);
} }
} }
private class Handler private class Handler
{ {
public final TypeIdItem type; public final TypeIdItem type;
public final int handlerAddress; public final int handlerAddress;
public Handler(TypeIdItem type, int handlerAddress) { public Handler(TypeIdItem type, int handlerAddress) {
this.type = type; this.type = type;
this.handlerAddress = handlerAddress; this.handlerAddress = handlerAddress;
} }
} }
public Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>> encodeTries() { public Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>> encodeTries() {
if (firstTryRange.next == lastTryRange) { if (firstTryRange.next == lastTryRange) {
return new Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>>(null, null); return new Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>>(null, null);
} }
ArrayList<CodeItem.TryItem> tries = new ArrayList<CodeItem.TryItem>(); ArrayList<CodeItem.TryItem> tries = new ArrayList<CodeItem.TryItem>();
ArrayList<CodeItem.EncodedCatchHandler> handlers = new ArrayList<CodeItem.EncodedCatchHandler>(); ArrayList<CodeItem.EncodedCatchHandler> handlers = new ArrayList<CodeItem.EncodedCatchHandler>();
HashMap<CodeItem.EncodedCatchHandler, CodeItem.EncodedCatchHandler> handlerDict = HashMap<CodeItem.EncodedCatchHandler, CodeItem.EncodedCatchHandler> handlerDict =
new HashMap<CodeItem.EncodedCatchHandler, CodeItem.EncodedCatchHandler>(); new HashMap<CodeItem.EncodedCatchHandler, CodeItem.EncodedCatchHandler>();
TryRange tryRange = firstTryRange.next; TryRange tryRange = firstTryRange.next;
while (tryRange != lastTryRange) { while (tryRange != lastTryRange) {
CodeItem.EncodedTypeAddrPair[] encodedTypeAddrPairs = CodeItem.EncodedTypeAddrPair[] encodedTypeAddrPairs =
new CodeItem.EncodedTypeAddrPair[tryRange.handlers.size()]; new CodeItem.EncodedTypeAddrPair[tryRange.handlers.size()];
int index = 0; int index = 0;
for (Handler handler: tryRange.handlers) { for (Handler handler: tryRange.handlers) {
CodeItem.EncodedTypeAddrPair encodedTypeAddrPair = new CodeItem.EncodedTypeAddrPair( CodeItem.EncodedTypeAddrPair encodedTypeAddrPair = new CodeItem.EncodedTypeAddrPair(
handler.type, handler.type,
handler.handlerAddress); handler.handlerAddress);
encodedTypeAddrPairs[index++] = encodedTypeAddrPair; encodedTypeAddrPairs[index++] = encodedTypeAddrPair;
} }
CodeItem.EncodedCatchHandler encodedCatchHandler = new CodeItem.EncodedCatchHandler( CodeItem.EncodedCatchHandler encodedCatchHandler = new CodeItem.EncodedCatchHandler(
encodedTypeAddrPairs, encodedTypeAddrPairs,
tryRange.catchAllHandlerAddress); tryRange.catchAllHandlerAddress);
CodeItem.EncodedCatchHandler internedEncodedCatchHandler = handlerDict.get(encodedCatchHandler); CodeItem.EncodedCatchHandler internedEncodedCatchHandler = handlerDict.get(encodedCatchHandler);
if (internedEncodedCatchHandler == null) { if (internedEncodedCatchHandler == null) {
handlerDict.put(encodedCatchHandler, encodedCatchHandler); handlerDict.put(encodedCatchHandler, encodedCatchHandler);
handlers.add(encodedCatchHandler); handlers.add(encodedCatchHandler);
} else { } else {
encodedCatchHandler = internedEncodedCatchHandler; encodedCatchHandler = internedEncodedCatchHandler;
} }
CodeItem.TryItem tryItem = new CodeItem.TryItem( CodeItem.TryItem tryItem = new CodeItem.TryItem(
tryRange.startAddress, tryRange.startAddress,
tryRange.endAddress - tryRange.startAddress, tryRange.endAddress - tryRange.startAddress,
encodedCatchHandler); encodedCatchHandler);
tries.add(tryItem); tries.add(tryItem);
tryRange = tryRange.next; tryRange = tryRange.next;
} }
return new Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>>(tries, handlers); return new Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>>(tries, handlers);
} }
public void addCatchAllHandler(int startAddress, int endAddress, int handlerAddress) { public void addCatchAllHandler(int startAddress, int endAddress, int handlerAddress) {
TryRange startRange; TryRange startRange;
TryRange endRange; TryRange endRange;
Pair<TryRange, TryRange> ranges = getBoundingRanges(startAddress, endAddress); Pair<TryRange, TryRange> ranges = getBoundingRanges(startAddress, endAddress);
startRange = ranges.first; startRange = ranges.first;
endRange = ranges.second; endRange = ranges.second;
int previousEnd = startAddress; int previousEnd = startAddress;
TryRange tryRange = startRange; TryRange tryRange = startRange;
/*Now we have the start and end ranges that exactly match the start and end /*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 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 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*/ list. We also need to create a new range for any "holes" in the existing ranges*/
do do
{ {
//is there a hole? If so, add a new range to fill the hole //is there a hole? If so, add a new range to fill the hole
if (tryRange.startAddress > previousEnd) { if (tryRange.startAddress > previousEnd) {
TryRange newRange = new TryRange(previousEnd, tryRange.startAddress); TryRange newRange = new TryRange(previousEnd, tryRange.startAddress);
tryRange.prepend(newRange); tryRange.prepend(newRange);
tryRange = newRange; tryRange = newRange;
} }
if (tryRange.catchAllHandlerAddress == -1) { if (tryRange.catchAllHandlerAddress == -1) {
tryRange.catchAllHandlerAddress = handlerAddress; tryRange.catchAllHandlerAddress = handlerAddress;
} }
previousEnd = tryRange.endAddress; previousEnd = tryRange.endAddress;
tryRange = tryRange.next; tryRange = tryRange.next;
} while (tryRange.previous != endRange); } while (tryRange.previous != endRange);
} }
public Pair<TryRange, TryRange> getBoundingRanges(int startAddress, int endAddress) { public Pair<TryRange, TryRange> getBoundingRanges(int startAddress, int endAddress) {
TryRange startRange = null; TryRange startRange = null;
TryRange endRange = null; TryRange endRange = null;
TryRange tryRange = firstTryRange.next; TryRange tryRange = firstTryRange.next;
while (tryRange != lastTryRange) { while (tryRange != lastTryRange) {
if (startAddress == tryRange.startAddress) { if (startAddress == tryRange.startAddress) {
//|-----| //|-----|
//^------ //^------
/*Bam. We hit the start of the range right on the head*/ /*Bam. We hit the start of the range right on the head*/
startRange = tryRange; startRange = tryRange;
break; break;
} else if (startAddress > tryRange.startAddress && startAddress < tryRange.endAddress) { } else if (startAddress > tryRange.startAddress && startAddress < tryRange.endAddress) {
//|-----| //|-----|
// ^---- // ^----
/*Almost. The start of the range being added is in the middle /*Almost. The start of the range being added is in the middle
of an existing try range. We need to split the existing range of an existing try range. We need to split the existing range
at the start address of the range being added*/ at the start address of the range being added*/
startRange = tryRange.split(startAddress); startRange = tryRange.split(startAddress);
break; break;
}else if (startAddress < tryRange.startAddress) { }else if (startAddress < tryRange.startAddress) {
if (endAddress <= tryRange.startAddress) { if (endAddress <= tryRange.startAddress) {
// |-----| // |-----|
//^--^ //^--^
/*Oops, totally too far! The new range doesn't overlap any existing /*Oops, totally too far! The new range doesn't overlap any existing
ones, so we just add it and return*/ ones, so we just add it and return*/
startRange = new TryRange(startAddress, endAddress); startRange = new TryRange(startAddress, endAddress);
tryRange.prepend(startRange); tryRange.prepend(startRange);
return new Pair<TryRange, TryRange>(startRange, startRange); return new Pair<TryRange, TryRange>(startRange, startRange);
} else { } else {
// |-----| // |-----|
//^--------- //^---------
/*Oops, too far! We've passed the start of the range being added, but /*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 the new range does overlap this one. We need to add a new range just
before this one*/ before this one*/
startRange = new TryRange(startAddress, tryRange.startAddress); startRange = new TryRange(startAddress, tryRange.startAddress);
tryRange.prepend(startRange); tryRange.prepend(startRange);
break; break;
} }
} }
tryRange = tryRange.next; tryRange = tryRange.next;
} }
//|-----| //|-----|
// ^----- // ^-----
/*Either the list of tries is blank, or all the tries in the list /*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 end before the range being added starts. In either case, we just need
to add a new range at the end of the list*/ to add a new range at the end of the list*/
if (startRange == null) { if (startRange == null) {
startRange = new TryRange(startAddress, endAddress); startRange = new TryRange(startAddress, endAddress);
lastTryRange.prepend(startRange); lastTryRange.prepend(startRange);
return new Pair<TryRange, TryRange>(startRange, startRange); return new Pair<TryRange, TryRange>(startRange, startRange);
} }
tryRange = startRange; tryRange = startRange;
while (tryRange != lastTryRange) { while (tryRange != lastTryRange) {
if (tryRange.endAddress == endAddress) { if (tryRange.endAddress == endAddress) {
//|-----| //|-----|
//------^ //------^
/*Bam! We hit the end right on the head.*/ /*Bam! We hit the end right on the head.*/
endRange = tryRange; endRange = tryRange;
break; break;
} else if (tryRange.startAddress < endAddress && tryRange.endAddress > endAddress) { } else if (tryRange.startAddress < endAddress && tryRange.endAddress > endAddress) {
//|-----| //|-----|
//--^ //--^
/*Almost. The range being added ends in the middle of an /*Almost. The range being added ends in the middle of an
existing range. We need to split the existing range existing range. We need to split the existing range
at the end of the range being added.*/ at the end of the range being added.*/
tryRange.split(endAddress); tryRange.split(endAddress);
endRange = tryRange; endRange = tryRange;
break; break;
} else if (tryRange.startAddress >= endAddress) { } else if (tryRange.startAddress >= endAddress) {
//|-----| |-----| //|-----| |-----|
//-----------^ //-----------^
/*Oops, too far! The current range starts after the range being added /*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 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*/ previous range, and ends at the end of the range being added*/
endRange = new TryRange(tryRange.previous.endAddress, endAddress); endRange = new TryRange(tryRange.previous.endAddress, endAddress);
tryRange.prepend(endRange); tryRange.prepend(endRange);
break; break;
} }
tryRange = tryRange.next; tryRange = tryRange.next;
} }
//|-----| //|-----|
//--------^ //--------^
/*The last range in the list ended before the end of the range being added. /*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 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.*/ list, and ends at the end of the range being added.*/
if (endRange == null) { if (endRange == null) {
endRange = new TryRange(lastTryRange.previous.endAddress, endAddress); endRange = new TryRange(lastTryRange.previous.endAddress, endAddress);
lastTryRange.prepend(endRange); lastTryRange.prepend(endRange);
} }
return new Pair<TryRange, TryRange>(startRange, endRange); return new Pair<TryRange, TryRange>(startRange, endRange);
} }
public void addHandler(TypeIdItem type, int startAddress, int endAddress, int handlerAddress) { public void addHandler(TypeIdItem type, int startAddress, int endAddress, int handlerAddress) {
TryRange startRange; TryRange startRange;
TryRange endRange; TryRange endRange;
//TODO: need to check for pre-existing exception types in the handler list? //TODO: need to check for pre-existing exception types in the handler list?
Pair<TryRange, TryRange> ranges = getBoundingRanges(startAddress, endAddress); Pair<TryRange, TryRange> ranges = getBoundingRanges(startAddress, endAddress);
startRange = ranges.first; startRange = ranges.first;
endRange = ranges.second; endRange = ranges.second;
Handler handler = new Handler(type, handlerAddress); Handler handler = new Handler(type, handlerAddress);
int previousEnd = startAddress; int previousEnd = startAddress;
TryRange tryRange = startRange; TryRange tryRange = startRange;
/*Now we have the start and end ranges that exactly match the start and end /*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 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 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*/ list. We also need to create a new range for any "holes" in the existing ranges*/
do do
{ {
//is there a hole? If so, add a new range to fill the hole //is there a hole? If so, add a new range to fill the hole
if (tryRange.startAddress > previousEnd) { if (tryRange.startAddress > previousEnd) {
TryRange newRange = new TryRange(previousEnd, tryRange.startAddress); TryRange newRange = new TryRange(previousEnd, tryRange.startAddress);
tryRange.prepend(newRange); tryRange.prepend(newRange);
tryRange = newRange; tryRange = newRange;
} }
tryRange.appendHandler(handler); tryRange.appendHandler(handler);
previousEnd = tryRange.endAddress; previousEnd = tryRange.endAddress;
tryRange = tryRange.next; tryRange = tryRange.next;
} while (tryRange.previous != endRange); } while (tryRange.previous != endRange);
} }
} }

View File

@ -1,61 +1,61 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.dexlib.Util; package org.jf.dexlib.Util;
import org.jf.dexlib.DexFile; import org.jf.dexlib.DexFile;
import org.jf.dexlib.EncodedValue.*; import org.jf.dexlib.EncodedValue.*;
public class TypeUtils public class TypeUtils
{ {
public static EncodedValue makeDefaultValueForType(DexFile dexFile, String type) { public static EncodedValue makeDefaultValueForType(DexFile dexFile, String type) {
EncodedValue subField; EncodedValue subField;
switch (type.charAt(0)) { switch (type.charAt(0)) {
case 'Z': case 'Z':
return BooleanEncodedValue.FalseValue; return BooleanEncodedValue.FalseValue;
case 'B': case 'B':
return new ByteEncodedValue((byte)0); return new ByteEncodedValue((byte)0);
case 'S': case 'S':
return new ShortEncodedValue((short)0); return new ShortEncodedValue((short)0);
case 'C': case 'C':
return new CharEncodedValue((char)0); return new CharEncodedValue((char)0);
case 'I': case 'I':
return new IntEncodedValue(0); return new IntEncodedValue(0);
case 'J': case 'J':
return new LongEncodedValue(0); return new LongEncodedValue(0);
case 'F': case 'F':
return new FloatEncodedValue(0); return new FloatEncodedValue(0);
case 'D': case 'D':
return new DoubleEncodedValue(0); return new DoubleEncodedValue(0);
case 'L': case 'L':
case '[': case '[':
return NullEncodedValue.NullValue; return NullEncodedValue.NullValue;
} }
return null; return null;
} }
} }

View File

@ -1,378 +1,378 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.jf.smali; package org.jf.smali;
public class literalTools public class literalTools
{ {
public static byte parseByte(String byteLiteral) public static byte parseByte(String byteLiteral)
throws NumberFormatException { throws NumberFormatException {
if (byteLiteral == null) { if (byteLiteral == null) {
throw new NumberFormatException("string is null"); throw new NumberFormatException("string is null");
} }
if (byteLiteral.length() == 0) { if (byteLiteral.length() == 0) {
throw new NumberFormatException("string is blank"); throw new NumberFormatException("string is blank");
} }
char[] byteChars; char[] byteChars;
if (byteLiteral.toUpperCase().endsWith("T")) { if (byteLiteral.toUpperCase().endsWith("T")) {
byteChars = byteLiteral.substring(0, byteLiteral.length()-1).toCharArray(); byteChars = byteLiteral.substring(0, byteLiteral.length()-1).toCharArray();
} else { } else {
byteChars = byteLiteral.toCharArray(); byteChars = byteLiteral.toCharArray();
} }
int position = 0; int position = 0;
int radix = 10; int radix = 10;
boolean negative = false; boolean negative = false;
if (byteChars[position] == '-') { if (byteChars[position] == '-') {
position++; position++;
negative = true; negative = true;
} }
if (byteChars[position] == '0') { if (byteChars[position] == '0') {
position++; position++;
if (position == byteChars.length) { if (position == byteChars.length) {
return 0; return 0;
} else if (byteChars[position] == 'x' || byteChars[position] == 'X') { } else if (byteChars[position] == 'x' || byteChars[position] == 'X') {
radix = 16; radix = 16;
position++; position++;
} else if (Character.digit(byteChars[position], 8) >= 0) { } else if (Character.digit(byteChars[position], 8) >= 0) {
radix = 8; radix = 8;
} }
} }
byte result = 0; byte result = 0;
byte shiftedResult; byte shiftedResult;
int digit; int digit;
byte maxValue = (byte)(Byte.MAX_VALUE / (radix / 2)); byte maxValue = (byte)(Byte.MAX_VALUE / (radix / 2));
while (position < byteChars.length) { while (position < byteChars.length) {
digit = Character.digit(byteChars[position], radix); digit = Character.digit(byteChars[position], radix);
if (digit < 0) { if (digit < 0) {
throw new NumberFormatException("The string contains invalid an digit - '" + byteChars[position] + "'"); throw new NumberFormatException("The string contains invalid an digit - '" + byteChars[position] + "'");
} }
shiftedResult = (byte)(result * radix); shiftedResult = (byte)(result * radix);
if (result > maxValue) { if (result > maxValue) {
throw new NumberFormatException(byteLiteral + " cannot fit into a byte"); throw new NumberFormatException(byteLiteral + " cannot fit into a byte");
} }
if (shiftedResult < 0 && shiftedResult >= -digit) { if (shiftedResult < 0 && shiftedResult >= -digit) {
throw new NumberFormatException(byteLiteral + " cannot fit into a byte"); throw new NumberFormatException(byteLiteral + " cannot fit into a byte");
} }
result = (byte)(shiftedResult + digit); result = (byte)(shiftedResult + digit);
position++; position++;
} }
if (negative) { if (negative) {
//allow -0x80, which is = 0x80 //allow -0x80, which is = 0x80
if (result == Byte.MIN_VALUE) { if (result == Byte.MIN_VALUE) {
return result; return result;
} else if (result < 0) { } else if (result < 0) {
throw new NumberFormatException(byteLiteral + " cannot fit into a byte"); throw new NumberFormatException(byteLiteral + " cannot fit into a byte");
} }
return (byte)(result * -1); return (byte)(result * -1);
} else { } else {
return result; return result;
} }
} }
public static short parseShort(String shortLiteral) public static short parseShort(String shortLiteral)
throws NumberFormatException { throws NumberFormatException {
if (shortLiteral == null) { if (shortLiteral == null) {
throw new NumberFormatException("string is null"); throw new NumberFormatException("string is null");
} }
if (shortLiteral.length() == 0) { if (shortLiteral.length() == 0) {
throw new NumberFormatException("string is blank"); throw new NumberFormatException("string is blank");
} }
char[] shortChars; char[] shortChars;
if (shortLiteral.toUpperCase().endsWith("S")) { if (shortLiteral.toUpperCase().endsWith("S")) {
shortChars = shortLiteral.substring(0, shortLiteral.length()-1).toCharArray(); shortChars = shortLiteral.substring(0, shortLiteral.length()-1).toCharArray();
} else { } else {
shortChars = shortLiteral.toCharArray(); shortChars = shortLiteral.toCharArray();
} }
int position = 0; int position = 0;
int radix = 10; int radix = 10;
boolean negative = false; boolean negative = false;
if (shortChars[position] == '-') { if (shortChars[position] == '-') {
position++; position++;
negative = true; negative = true;
} }
if (shortChars[position] == '0') { if (shortChars[position] == '0') {
position++; position++;
if (position == shortChars.length) { if (position == shortChars.length) {
return 0; return 0;
} else if (shortChars[position] == 'x' || shortChars[position] == 'X') { } else if (shortChars[position] == 'x' || shortChars[position] == 'X') {
radix = 16; radix = 16;
position++; position++;
} else if (Character.digit(shortChars[position], 8) >= 0) { } else if (Character.digit(shortChars[position], 8) >= 0) {
radix = 8; radix = 8;
} }
} }
short result = 0; short result = 0;
short shiftedResult; short shiftedResult;
int digit; int digit;
short maxValue = (short)(Short.MAX_VALUE / (radix / 2)); short maxValue = (short)(Short.MAX_VALUE / (radix / 2));
while (position < shortChars.length) { while (position < shortChars.length) {
digit = Character.digit(shortChars[position], radix); digit = Character.digit(shortChars[position], radix);
if (digit < 0) { if (digit < 0) {
throw new NumberFormatException("The string contains invalid an digit - '" + shortChars[position] + "'"); throw new NumberFormatException("The string contains invalid an digit - '" + shortChars[position] + "'");
} }
shiftedResult = (short)(result * radix); shiftedResult = (short)(result * radix);
if (result > maxValue) { if (result > maxValue) {
throw new NumberFormatException(shortLiteral + " cannot fit into a short"); throw new NumberFormatException(shortLiteral + " cannot fit into a short");
} }
if (shiftedResult < 0 && shiftedResult >= -digit) { if (shiftedResult < 0 && shiftedResult >= -digit) {
throw new NumberFormatException(shortLiteral + " cannot fit into a short"); throw new NumberFormatException(shortLiteral + " cannot fit into a short");
} }
result = (short)(shiftedResult + digit); result = (short)(shiftedResult + digit);
position++; position++;
} }
if (negative) { if (negative) {
//allow -0x8000, which is = 0x8000 //allow -0x8000, which is = 0x8000
if (result == Short.MIN_VALUE) { if (result == Short.MIN_VALUE) {
return result; return result;
} else if (result < 0) { } else if (result < 0) {
throw new NumberFormatException(shortLiteral + " cannot fit into a short"); throw new NumberFormatException(shortLiteral + " cannot fit into a short");
} }
return (short)(result * -1); return (short)(result * -1);
} else { } else {
return result; return result;
} }
} }
public static int parseInt(String intLiteral) public static int parseInt(String intLiteral)
throws NumberFormatException { throws NumberFormatException {
if (intLiteral == null) { if (intLiteral == null) {
throw new NumberFormatException("string is null"); throw new NumberFormatException("string is null");
} }
if (intLiteral.length() == 0) { if (intLiteral.length() == 0) {
throw new NumberFormatException("string is blank"); throw new NumberFormatException("string is blank");
} }
char[] intChars = intLiteral.toCharArray(); char[] intChars = intLiteral.toCharArray();
int position = 0; int position = 0;
int radix = 10; int radix = 10;
boolean negative = false; boolean negative = false;
if (intChars[position] == '-') { if (intChars[position] == '-') {
position++; position++;
negative = true; negative = true;
} }
if (intChars[position] == '0') { if (intChars[position] == '0') {
position++; position++;
if (position == intChars.length) { if (position == intChars.length) {
return 0; return 0;
} else if (intChars[position] == 'x' || intChars[position] == 'X') { } else if (intChars[position] == 'x' || intChars[position] == 'X') {
radix = 16; radix = 16;
position++; position++;
} else if (Character.digit(intChars[position], 8) >= 0) { } else if (Character.digit(intChars[position], 8) >= 0) {
radix = 8; radix = 8;
} }
} }
int result = 0; int result = 0;
int shiftedResult; int shiftedResult;
int digit; int digit;
int maxValue = Integer.MAX_VALUE / (radix / 2); int maxValue = Integer.MAX_VALUE / (radix / 2);
while (position < intChars.length) { while (position < intChars.length) {
digit = Character.digit(intChars[position], radix); digit = Character.digit(intChars[position], radix);
if (digit < 0) { if (digit < 0) {
throw new NumberFormatException("The string contains an invalid digit - '" + intChars[position] + "'"); throw new NumberFormatException("The string contains an invalid digit - '" + intChars[position] + "'");
} }
shiftedResult = result * radix; shiftedResult = result * radix;
if (result > maxValue) { if (result > maxValue) {
throw new NumberFormatException(intLiteral + " cannot fit into an int"); throw new NumberFormatException(intLiteral + " cannot fit into an int");
} }
if (shiftedResult < 0 && shiftedResult >= -digit) { if (shiftedResult < 0 && shiftedResult >= -digit) {
throw new NumberFormatException(intLiteral + " cannot fit into an int"); throw new NumberFormatException(intLiteral + " cannot fit into an int");
} }
result = shiftedResult + digit; result = shiftedResult + digit;
position++; position++;
} }
if (negative) { if (negative) {
//allow -0x80000000, which is = 0x80000000 //allow -0x80000000, which is = 0x80000000
if (result == Integer.MIN_VALUE) { if (result == Integer.MIN_VALUE) {
return result; return result;
} else if (result < 0) { } else if (result < 0) {
throw new NumberFormatException(intLiteral + " cannot fit into an int"); throw new NumberFormatException(intLiteral + " cannot fit into an int");
} }
return result * -1; return result * -1;
} else { } else {
return result; return result;
} }
} }
public static long parseLong(String longLiteral) public static long parseLong(String longLiteral)
throws NumberFormatException { throws NumberFormatException {
if (longLiteral == null) { if (longLiteral == null) {
throw new NumberFormatException("string is null"); throw new NumberFormatException("string is null");
} }
if (longLiteral.length() == 0) { if (longLiteral.length() == 0) {
throw new NumberFormatException("string is blank"); throw new NumberFormatException("string is blank");
} }
char[] longChars; char[] longChars;
if (longLiteral.toUpperCase().endsWith("L")) { if (longLiteral.toUpperCase().endsWith("L")) {
longChars = longLiteral.substring(0, longLiteral.length()-1).toCharArray(); longChars = longLiteral.substring(0, longLiteral.length()-1).toCharArray();
} else { } else {
longChars = longLiteral.toCharArray(); longChars = longLiteral.toCharArray();
} }
int position = 0; int position = 0;
int radix = 10; int radix = 10;
boolean negative = false; boolean negative = false;
if (longChars[position] == '-') { if (longChars[position] == '-') {
position++; position++;
negative = true; negative = true;
} }
if (longChars[position] == '0') { if (longChars[position] == '0') {
position++; position++;
if (position == longChars.length) { if (position == longChars.length) {
return 0; return 0;
} else if (longChars[position] == 'x' || longChars[position] == 'X') { } else if (longChars[position] == 'x' || longChars[position] == 'X') {
radix = 16; radix = 16;
position++; position++;
} else if (Character.digit(longChars[position], 8) >= 0) { } else if (Character.digit(longChars[position], 8) >= 0) {
radix = 8; radix = 8;
} }
} }
long result = 0; long result = 0;
long shiftedResult; long shiftedResult;
int digit; int digit;
long maxValue = Long.MAX_VALUE / (radix / 2); long maxValue = Long.MAX_VALUE / (radix / 2);
while (position < longChars.length) { while (position < longChars.length) {
digit = Character.digit(longChars[position], radix); digit = Character.digit(longChars[position], radix);
if (digit < 0) { if (digit < 0) {
throw new NumberFormatException("The string contains an invalid digit - '" + longChars[position] + "'"); throw new NumberFormatException("The string contains an invalid digit - '" + longChars[position] + "'");
} }
shiftedResult = result * radix; shiftedResult = result * radix;
if (result > maxValue) { if (result > maxValue) {
throw new NumberFormatException(longLiteral + " cannot fit into a long"); throw new NumberFormatException(longLiteral + " cannot fit into a long");
} }
if (shiftedResult < 0 && shiftedResult >= -digit) { if (shiftedResult < 0 && shiftedResult >= -digit) {
throw new NumberFormatException(longLiteral + " cannot fit into a long"); throw new NumberFormatException(longLiteral + " cannot fit into a long");
} }
result = shiftedResult + digit; result = shiftedResult + digit;
position++; position++;
} }
if (negative) { if (negative) {
//allow -0x8000000000000000, which is = 0x8000000000000000 //allow -0x8000000000000000, which is = 0x8000000000000000
if (result == Long.MIN_VALUE) { if (result == Long.MIN_VALUE) {
return result; return result;
} else if (result < 0) { } else if (result < 0) {
throw new NumberFormatException(longLiteral + " cannot fit into a long"); throw new NumberFormatException(longLiteral + " cannot fit into a long");
} }
return result * -1; return result * -1;
} else { } else {
return result; return result;
} }
} }
public static byte[] longToBytes(long value) { public static byte[] longToBytes(long value) {
byte[] bytes = new byte[8]; byte[] bytes = new byte[8];
for (int i=0; value != 0; i++) { for (int i=0; value != 0; i++) {
bytes[i] = (byte)value; bytes[i] = (byte)value;
value = value >>> 8; value = value >>> 8;
} }
return bytes; return bytes;
} }
public static byte[] intToBytes(int value) { public static byte[] intToBytes(int value) {
byte[] bytes = new byte[4]; byte[] bytes = new byte[4];
for (int i=0; value != 0; i++) { for (int i=0; value != 0; i++) {
bytes[i] = (byte)value; bytes[i] = (byte)value;
value = value >>> 8; value = value >>> 8;
} }
return bytes; return bytes;
} }
public static byte[] shortToBytes(short value) { public static byte[] shortToBytes(short value) {
byte[] bytes = new byte[2]; byte[] bytes = new byte[2];
bytes[0] = (byte)value; bytes[0] = (byte)value;
bytes[1] = (byte)(value >>> 8); bytes[1] = (byte)(value >>> 8);
return bytes; return bytes;
} }
public static byte[] floatToBytes(float value) { public static byte[] floatToBytes(float value) {
return intToBytes(Float.floatToRawIntBits(value)); return intToBytes(Float.floatToRawIntBits(value));
} }
public static byte[] doubleToBytes(double value) { public static byte[] doubleToBytes(double value) {
return longToBytes(Double.doubleToRawLongBits(value)); return longToBytes(Double.doubleToRawLongBits(value));
} }
public static byte[] charToBytes(char value) { public static byte[] charToBytes(char value) {
return shortToBytes((short)value); return shortToBytes((short)value);
} }
public static byte[] boolToBytes(boolean value) { public static byte[] boolToBytes(boolean value) {
if (value) { if (value) {
return new byte[] { 0x01 }; return new byte[] { 0x01 };
} else { } else {
return new byte[] { 0x00 }; return new byte[] { 0x00 };
} }
} }
public static void checkInt(long value) { public static void checkInt(long value) {
if (value > 0xFFFFFFFF || value < -0x80000000) { if (value > 0xFFFFFFFF || value < -0x80000000) {
throw new NumberFormatException(Long.toString(value) + " cannot fit into an int"); throw new NumberFormatException(Long.toString(value) + " cannot fit into an int");
} }
} }
public static void checkShort(long value) { public static void checkShort(long value) {
if (value > 0xFFFF | value < -0x8000) { if (value > 0xFFFF | value < -0x8000) {
throw new NumberFormatException(Long.toString(value) + " cannot fit into a short"); throw new NumberFormatException(Long.toString(value) + " cannot fit into a short");
} }
} }
public static void checkByte(long value) { public static void checkByte(long value) {
if (value > 0xFF | value < -0x80) { if (value > 0xFF | value < -0x80) {
throw new NumberFormatException(Long.toString(value) + " cannot fit into a byte"); throw new NumberFormatException(Long.toString(value) + " cannot fit into a byte");
} }
} }
public static void checkNibble(long value) { public static void checkNibble(long value) {
if (value > 0x0F | value < -0x08) { if (value > 0x0F | value < -0x08) {
throw new NumberFormatException(Long.toString(value) + " cannot fit into a nibble"); throw new NumberFormatException(Long.toString(value) + " cannot fit into a nibble");
} }
} }
} }

View File

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

View File

@ -1,139 +1,139 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
import org.jf.smali.literalTools; import org.jf.smali.literalTools;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
public class ByteLiteralTest public class ByteLiteralTest
{ {
@Test @Test
public void SuccessHexTests() { public void SuccessHexTests() {
Assert.assertTrue(literalTools.parseByte("0x0T") == 0x0); Assert.assertTrue(literalTools.parseByte("0x0T") == 0x0);
Assert.assertTrue(literalTools.parseByte("0x00") == 0x0); Assert.assertTrue(literalTools.parseByte("0x00") == 0x0);
Assert.assertTrue(literalTools.parseByte("0x1T") == 0x1); Assert.assertTrue(literalTools.parseByte("0x1T") == 0x1);
Assert.assertTrue(literalTools.parseByte("0x12") == 0x12); Assert.assertTrue(literalTools.parseByte("0x12") == 0x12);
Assert.assertTrue(literalTools.parseByte("0x7fT") == 0x7f); Assert.assertTrue(literalTools.parseByte("0x7fT") == 0x7f);
Assert.assertTrue(literalTools.parseByte("0x80t") == Byte.MIN_VALUE); Assert.assertTrue(literalTools.parseByte("0x80t") == Byte.MIN_VALUE);
Assert.assertTrue(literalTools.parseByte("0xFFt") == -1); Assert.assertTrue(literalTools.parseByte("0xFFt") == -1);
Assert.assertTrue(literalTools.parseByte("-0x00") == 0); Assert.assertTrue(literalTools.parseByte("-0x00") == 0);
Assert.assertTrue(literalTools.parseByte("-0x01") == -1); Assert.assertTrue(literalTools.parseByte("-0x01") == -1);
Assert.assertTrue(literalTools.parseByte("-0x12") == -0x12); Assert.assertTrue(literalTools.parseByte("-0x12") == -0x12);
Assert.assertTrue(literalTools.parseByte("-0x80") == Byte.MIN_VALUE); Assert.assertTrue(literalTools.parseByte("-0x80") == Byte.MIN_VALUE);
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FaileHexTest1() { public void FaileHexTest1() {
literalTools.parseByte("-0x81"); literalTools.parseByte("-0x81");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailHexTest2() { public void FailHexTest2() {
literalTools.parseByte("-0xFF"); literalTools.parseByte("-0xFF");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailHexTest3() { public void FailHexTest3() {
literalTools.parseByte("0x100"); literalTools.parseByte("0x100");
} }
@Test @Test
public void SuccessDecTests() { public void SuccessDecTests() {
Assert.assertTrue(literalTools.parseByte("0") == 0); Assert.assertTrue(literalTools.parseByte("0") == 0);
Assert.assertTrue(literalTools.parseByte("1t") == 1); Assert.assertTrue(literalTools.parseByte("1t") == 1);
Assert.assertTrue(literalTools.parseByte("123") == 123); Assert.assertTrue(literalTools.parseByte("123") == 123);
Assert.assertTrue(literalTools.parseByte("127T") == 127); Assert.assertTrue(literalTools.parseByte("127T") == 127);
Assert.assertTrue(literalTools.parseByte("128") == Byte.MIN_VALUE); Assert.assertTrue(literalTools.parseByte("128") == Byte.MIN_VALUE);
Assert.assertTrue(literalTools.parseByte("255") == -1); Assert.assertTrue(literalTools.parseByte("255") == -1);
Assert.assertTrue(literalTools.parseByte("-0") == 0); Assert.assertTrue(literalTools.parseByte("-0") == 0);
Assert.assertTrue(literalTools.parseByte("-1") == -1); Assert.assertTrue(literalTools.parseByte("-1") == -1);
Assert.assertTrue(literalTools.parseByte("-123") == -123); Assert.assertTrue(literalTools.parseByte("-123") == -123);
Assert.assertTrue(literalTools.parseByte("-127") == -127); Assert.assertTrue(literalTools.parseByte("-127") == -127);
Assert.assertTrue(literalTools.parseByte("-128") == Byte.MIN_VALUE); Assert.assertTrue(literalTools.parseByte("-128") == Byte.MIN_VALUE);
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FaileDecTest1() { public void FaileDecTest1() {
literalTools.parseByte("-129"); literalTools.parseByte("-129");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailDecTest2() { public void FailDecTest2() {
literalTools.parseByte("-255"); literalTools.parseByte("-255");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailDecTest3() { public void FailDecTest3() {
literalTools.parseByte("256"); literalTools.parseByte("256");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailDecTest4() { public void FailDecTest4() {
literalTools.parseByte("260"); literalTools.parseByte("260");
} }
@Test @Test
public void SuccessOctTests() { public void SuccessOctTests() {
Assert.assertTrue(literalTools.parseByte("00") == 00); Assert.assertTrue(literalTools.parseByte("00") == 00);
Assert.assertTrue(literalTools.parseByte("01") == 01); Assert.assertTrue(literalTools.parseByte("01") == 01);
Assert.assertTrue(literalTools.parseByte("0123t") == 0123); Assert.assertTrue(literalTools.parseByte("0123t") == 0123);
Assert.assertTrue(literalTools.parseByte("0177") == Byte.MAX_VALUE); Assert.assertTrue(literalTools.parseByte("0177") == Byte.MAX_VALUE);
Assert.assertTrue(literalTools.parseByte("0200T") == Byte.MIN_VALUE); Assert.assertTrue(literalTools.parseByte("0200T") == Byte.MIN_VALUE);
Assert.assertTrue(literalTools.parseByte("0377") == -1); Assert.assertTrue(literalTools.parseByte("0377") == -1);
Assert.assertTrue(literalTools.parseByte("-00") == 0); Assert.assertTrue(literalTools.parseByte("-00") == 0);
Assert.assertTrue(literalTools.parseByte("-01") == -1); Assert.assertTrue(literalTools.parseByte("-01") == -1);
Assert.assertTrue(literalTools.parseByte("-0123") == -0123); Assert.assertTrue(literalTools.parseByte("-0123") == -0123);
Assert.assertTrue(literalTools.parseByte("-0177") == -0177); Assert.assertTrue(literalTools.parseByte("-0177") == -0177);
Assert.assertTrue(literalTools.parseByte("-0200") == Byte.MIN_VALUE); Assert.assertTrue(literalTools.parseByte("-0200") == Byte.MIN_VALUE);
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FaileOctTest1() { public void FaileOctTest1() {
literalTools.parseByte("-0201"); literalTools.parseByte("-0201");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailOctTest2() { public void FailOctTest2() {
literalTools.parseByte("-0377"); literalTools.parseByte("-0377");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailOctTest3() { public void FailOctTest3() {
literalTools.parseByte("0400"); literalTools.parseByte("0400");
} }
} }

View File

@ -1,144 +1,144 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
import org.jf.smali.literalTools; import org.jf.smali.literalTools;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
public class IntLiteralTest public class IntLiteralTest
{ {
@Test @Test
public void SuccessHexTests() { public void SuccessHexTests() {
Assert.assertTrue(literalTools.parseInt("0x0") == 0x0); Assert.assertTrue(literalTools.parseInt("0x0") == 0x0);
Assert.assertTrue(literalTools.parseInt("0x00") == 0x0); Assert.assertTrue(literalTools.parseInt("0x00") == 0x0);
Assert.assertTrue(literalTools.parseInt("0x1") == 0x1); Assert.assertTrue(literalTools.parseInt("0x1") == 0x1);
Assert.assertTrue(literalTools.parseInt("0x12345678") == 0x12345678); Assert.assertTrue(literalTools.parseInt("0x12345678") == 0x12345678);
Assert.assertTrue(literalTools.parseInt("0x7fffffff") == 0x7fffffff); Assert.assertTrue(literalTools.parseInt("0x7fffffff") == 0x7fffffff);
Assert.assertTrue(literalTools.parseInt("0x80000000") == Integer.MIN_VALUE); Assert.assertTrue(literalTools.parseInt("0x80000000") == Integer.MIN_VALUE);
Assert.assertTrue(literalTools.parseInt("0xFFFFFFFF") == -1); Assert.assertTrue(literalTools.parseInt("0xFFFFFFFF") == -1);
Assert.assertTrue(literalTools.parseInt("-0x00") == 0); Assert.assertTrue(literalTools.parseInt("-0x00") == 0);
Assert.assertTrue(literalTools.parseInt("-0x01") == -1); Assert.assertTrue(literalTools.parseInt("-0x01") == -1);
Assert.assertTrue(literalTools.parseInt("-0x12345678") == -0x12345678); Assert.assertTrue(literalTools.parseInt("-0x12345678") == -0x12345678);
Assert.assertTrue(literalTools.parseInt("-0x80000000") == Integer.MIN_VALUE); Assert.assertTrue(literalTools.parseInt("-0x80000000") == Integer.MIN_VALUE);
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FaileHexTest1() { public void FaileHexTest1() {
literalTools.parseInt("-0x80000001"); literalTools.parseInt("-0x80000001");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailHexTest2() { public void FailHexTest2() {
literalTools.parseInt("-0xFFFFFFFF"); literalTools.parseInt("-0xFFFFFFFF");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailHexTest3() { public void FailHexTest3() {
literalTools.parseInt("0x100000000"); literalTools.parseInt("0x100000000");
} }
@Test @Test
public void SuccessDecTests() { public void SuccessDecTests() {
Assert.assertTrue(literalTools.parseInt("0") == 0); Assert.assertTrue(literalTools.parseInt("0") == 0);
Assert.assertTrue(literalTools.parseInt("1") == 1); Assert.assertTrue(literalTools.parseInt("1") == 1);
Assert.assertTrue(literalTools.parseInt("1234567890") == 1234567890); Assert.assertTrue(literalTools.parseInt("1234567890") == 1234567890);
Assert.assertTrue(literalTools.parseInt("2147483647") == 2147483647); Assert.assertTrue(literalTools.parseInt("2147483647") == 2147483647);
Assert.assertTrue(literalTools.parseInt("2147483648") == Integer.MIN_VALUE); Assert.assertTrue(literalTools.parseInt("2147483648") == Integer.MIN_VALUE);
Assert.assertTrue(literalTools.parseInt("4294967295") == -1); Assert.assertTrue(literalTools.parseInt("4294967295") == -1);
Assert.assertTrue(literalTools.parseInt("-0") == 0); Assert.assertTrue(literalTools.parseInt("-0") == 0);
Assert.assertTrue(literalTools.parseInt("-1") == -1); Assert.assertTrue(literalTools.parseInt("-1") == -1);
Assert.assertTrue(literalTools.parseInt("-1234567890") == -1234567890); Assert.assertTrue(literalTools.parseInt("-1234567890") == -1234567890);
Assert.assertTrue(literalTools.parseInt("-2147483647") == -2147483647); Assert.assertTrue(literalTools.parseInt("-2147483647") == -2147483647);
Assert.assertTrue(literalTools.parseInt("-2147483648") == Integer.MIN_VALUE); Assert.assertTrue(literalTools.parseInt("-2147483648") == Integer.MIN_VALUE);
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FaileDecTest1() { public void FaileDecTest1() {
literalTools.parseInt("-2147483649"); literalTools.parseInt("-2147483649");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailDecTest2() { public void FailDecTest2() {
literalTools.parseInt("-4294967295"); literalTools.parseInt("-4294967295");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailDecTest3() { public void FailDecTest3() {
literalTools.parseInt("4294967296"); literalTools.parseInt("4294967296");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailDecTest4() { public void FailDecTest4() {
literalTools.parseInt("4294967300"); literalTools.parseInt("4294967300");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailDecTest5() { public void FailDecTest5() {
literalTools.parseInt("8589934592"); literalTools.parseInt("8589934592");
} }
@Test @Test
public void SuccessOctTests() { public void SuccessOctTests() {
Assert.assertTrue(literalTools.parseInt("00") == 00); Assert.assertTrue(literalTools.parseInt("00") == 00);
Assert.assertTrue(literalTools.parseInt("01") == 01); Assert.assertTrue(literalTools.parseInt("01") == 01);
Assert.assertTrue(literalTools.parseInt("012345670123") == 012345670123); Assert.assertTrue(literalTools.parseInt("012345670123") == 012345670123);
Assert.assertTrue(literalTools.parseInt("017777777777") == Integer.MAX_VALUE); Assert.assertTrue(literalTools.parseInt("017777777777") == Integer.MAX_VALUE);
Assert.assertTrue(literalTools.parseInt("020000000000") == Integer.MIN_VALUE); Assert.assertTrue(literalTools.parseInt("020000000000") == Integer.MIN_VALUE);
Assert.assertTrue(literalTools.parseInt("037777777777") == -1); Assert.assertTrue(literalTools.parseInt("037777777777") == -1);
Assert.assertTrue(literalTools.parseInt("-00") == 0); Assert.assertTrue(literalTools.parseInt("-00") == 0);
Assert.assertTrue(literalTools.parseInt("-01") == -1); Assert.assertTrue(literalTools.parseInt("-01") == -1);
Assert.assertTrue(literalTools.parseInt("-012345670123") == -012345670123); Assert.assertTrue(literalTools.parseInt("-012345670123") == -012345670123);
Assert.assertTrue(literalTools.parseInt("-017777777777") == -017777777777); Assert.assertTrue(literalTools.parseInt("-017777777777") == -017777777777);
Assert.assertTrue(literalTools.parseInt("-020000000000") == Integer.MIN_VALUE); Assert.assertTrue(literalTools.parseInt("-020000000000") == Integer.MIN_VALUE);
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FaileOctTest1() { public void FaileOctTest1() {
literalTools.parseInt("-020000000001"); literalTools.parseInt("-020000000001");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailOctTest2() { public void FailOctTest2() {
literalTools.parseInt("-037777777777"); literalTools.parseInt("-037777777777");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailOctTest3() { public void FailOctTest3() {
literalTools.parseInt("040000000000"); literalTools.parseInt("040000000000");
} }
} }

View File

@ -1,139 +1,139 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
import org.jf.smali.literalTools; import org.jf.smali.literalTools;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
public class LongLiteralTest public class LongLiteralTest
{ {
@Test @Test
public void SuccessHexTests() { public void SuccessHexTests() {
Assert.assertTrue(literalTools.parseLong("0x0L") == 0x0); Assert.assertTrue(literalTools.parseLong("0x0L") == 0x0);
Assert.assertTrue(literalTools.parseLong("0x00") == 0x0); Assert.assertTrue(literalTools.parseLong("0x00") == 0x0);
Assert.assertTrue(literalTools.parseLong("0x1L") == 0x1); Assert.assertTrue(literalTools.parseLong("0x1L") == 0x1);
Assert.assertTrue(literalTools.parseLong("0x1234567890123456L") == 0x1234567890123456L); Assert.assertTrue(literalTools.parseLong("0x1234567890123456L") == 0x1234567890123456L);
Assert.assertTrue(literalTools.parseLong("0x7fffffffffffffffL") == 0x7fffffffffffffffL); Assert.assertTrue(literalTools.parseLong("0x7fffffffffffffffL") == 0x7fffffffffffffffL);
Assert.assertTrue(literalTools.parseLong("0x8000000000000000L") == Long.MIN_VALUE); Assert.assertTrue(literalTools.parseLong("0x8000000000000000L") == Long.MIN_VALUE);
Assert.assertTrue(literalTools.parseLong("0xFFFFFFFFFFFFFFFFL") == -1); Assert.assertTrue(literalTools.parseLong("0xFFFFFFFFFFFFFFFFL") == -1);
Assert.assertTrue(literalTools.parseLong("-0x00L") == 0); Assert.assertTrue(literalTools.parseLong("-0x00L") == 0);
Assert.assertTrue(literalTools.parseLong("-0x01L") == -1); Assert.assertTrue(literalTools.parseLong("-0x01L") == -1);
Assert.assertTrue(literalTools.parseLong("-0x1234567890123456L") == -0x1234567890123456L); Assert.assertTrue(literalTools.parseLong("-0x1234567890123456L") == -0x1234567890123456L);
Assert.assertTrue(literalTools.parseLong("-0x8000000000000000") == Long.MIN_VALUE); Assert.assertTrue(literalTools.parseLong("-0x8000000000000000") == Long.MIN_VALUE);
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FaileHexTest1() { public void FaileHexTest1() {
literalTools.parseLong("-0x8000000000000001"); literalTools.parseLong("-0x8000000000000001");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailHexTest2() { public void FailHexTest2() {
literalTools.parseLong("-0xFFFFFFFFFFFFFFFF"); literalTools.parseLong("-0xFFFFFFFFFFFFFFFF");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailHexTest3() { public void FailHexTest3() {
literalTools.parseLong("0x10000000000000000"); literalTools.parseLong("0x10000000000000000");
} }
@Test @Test
public void SuccessDecTests() { public void SuccessDecTests() {
Assert.assertTrue(literalTools.parseLong("0L") == 0); Assert.assertTrue(literalTools.parseLong("0L") == 0);
Assert.assertTrue(literalTools.parseLong("1") == 1); Assert.assertTrue(literalTools.parseLong("1") == 1);
Assert.assertTrue(literalTools.parseLong("1234567890123456789") == 1234567890123456789L); Assert.assertTrue(literalTools.parseLong("1234567890123456789") == 1234567890123456789L);
Assert.assertTrue(literalTools.parseLong("9223372036854775807") == 9223372036854775807L); Assert.assertTrue(literalTools.parseLong("9223372036854775807") == 9223372036854775807L);
Assert.assertTrue(literalTools.parseLong("9223372036854775808") == Long.MIN_VALUE); Assert.assertTrue(literalTools.parseLong("9223372036854775808") == Long.MIN_VALUE);
Assert.assertTrue(literalTools.parseLong("18446744073709551615L") == -1); Assert.assertTrue(literalTools.parseLong("18446744073709551615L") == -1);
Assert.assertTrue(literalTools.parseLong("-0") == 0); Assert.assertTrue(literalTools.parseLong("-0") == 0);
Assert.assertTrue(literalTools.parseLong("-1") == -1); Assert.assertTrue(literalTools.parseLong("-1") == -1);
Assert.assertTrue(literalTools.parseLong("-1234567890123456789") == -1234567890123456789L); Assert.assertTrue(literalTools.parseLong("-1234567890123456789") == -1234567890123456789L);
Assert.assertTrue(literalTools.parseLong("-9223372036854775807") == -9223372036854775807L); Assert.assertTrue(literalTools.parseLong("-9223372036854775807") == -9223372036854775807L);
Assert.assertTrue(literalTools.parseLong("-9223372036854775808") == Long.MIN_VALUE); Assert.assertTrue(literalTools.parseLong("-9223372036854775808") == Long.MIN_VALUE);
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FaileDecTest1() { public void FaileDecTest1() {
literalTools.parseLong("-9223372036854775809"); literalTools.parseLong("-9223372036854775809");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailDecTest2() { public void FailDecTest2() {
literalTools.parseLong("-18446744073709551616"); literalTools.parseLong("-18446744073709551616");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailDecTest3() { public void FailDecTest3() {
literalTools.parseLong("18446744073709551617"); literalTools.parseLong("18446744073709551617");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailDecTest4() { public void FailDecTest4() {
literalTools.parseLong("18446744073709551700"); literalTools.parseLong("18446744073709551700");
} }
@Test @Test
public void SuccessOctTests() { public void SuccessOctTests() {
Assert.assertTrue(literalTools.parseLong("00") == 00); Assert.assertTrue(literalTools.parseLong("00") == 00);
Assert.assertTrue(literalTools.parseLong("01") == 01); Assert.assertTrue(literalTools.parseLong("01") == 01);
Assert.assertTrue(literalTools.parseLong("0123456701234567012345") == 0123456701234567012345L); Assert.assertTrue(literalTools.parseLong("0123456701234567012345") == 0123456701234567012345L);
Assert.assertTrue(literalTools.parseLong("0777777777777777777777") == Long.MAX_VALUE); Assert.assertTrue(literalTools.parseLong("0777777777777777777777") == Long.MAX_VALUE);
Assert.assertTrue(literalTools.parseLong("01000000000000000000000") == Long.MIN_VALUE); Assert.assertTrue(literalTools.parseLong("01000000000000000000000") == Long.MIN_VALUE);
Assert.assertTrue(literalTools.parseLong("01777777777777777777777") == -1); Assert.assertTrue(literalTools.parseLong("01777777777777777777777") == -1);
Assert.assertTrue(literalTools.parseLong("-00") == 0); Assert.assertTrue(literalTools.parseLong("-00") == 0);
Assert.assertTrue(literalTools.parseLong("-01") == -1); Assert.assertTrue(literalTools.parseLong("-01") == -1);
Assert.assertTrue(literalTools.parseLong("-0123456701234567012345") == -0123456701234567012345L); Assert.assertTrue(literalTools.parseLong("-0123456701234567012345") == -0123456701234567012345L);
Assert.assertTrue(literalTools.parseLong("-0777777777777777777777") == -0777777777777777777777L); Assert.assertTrue(literalTools.parseLong("-0777777777777777777777") == -0777777777777777777777L);
Assert.assertTrue(literalTools.parseLong("-01000000000000000000000") == Long.MIN_VALUE); Assert.assertTrue(literalTools.parseLong("-01000000000000000000000") == Long.MIN_VALUE);
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FaileOctTest1() { public void FaileOctTest1() {
literalTools.parseLong("-01000000000000000000001"); literalTools.parseLong("-01000000000000000000001");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailOctTest2() { public void FailOctTest2() {
literalTools.parseLong("-01777777777777777777777"); literalTools.parseLong("-01777777777777777777777");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailOctTest3() { public void FailOctTest3() {
literalTools.parseLong("02000000000000000000000"); literalTools.parseLong("02000000000000000000000");
} }
} }

View File

@ -1,139 +1,139 @@
/* /*
* [The "BSD licence"] * [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver * Copyright (c) 2009 Ben Gruver
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products * 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
import org.jf.smali.literalTools; import org.jf.smali.literalTools;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
public class ShortLiteralTest public class ShortLiteralTest
{ {
@Test @Test
public void SuccessHexTests() { public void SuccessHexTests() {
Assert.assertTrue(literalTools.parseShort("0x0") == 0x0); Assert.assertTrue(literalTools.parseShort("0x0") == 0x0);
Assert.assertTrue(literalTools.parseShort("0x00") == 0x0); Assert.assertTrue(literalTools.parseShort("0x00") == 0x0);
Assert.assertTrue(literalTools.parseShort("0x1") == 0x1); Assert.assertTrue(literalTools.parseShort("0x1") == 0x1);
Assert.assertTrue(literalTools.parseShort("0x1234") == 0x1234); Assert.assertTrue(literalTools.parseShort("0x1234") == 0x1234);
Assert.assertTrue(literalTools.parseShort("0x7fff") == 0x7fff); Assert.assertTrue(literalTools.parseShort("0x7fff") == 0x7fff);
Assert.assertTrue(literalTools.parseShort("0x8000") == Short.MIN_VALUE); Assert.assertTrue(literalTools.parseShort("0x8000") == Short.MIN_VALUE);
Assert.assertTrue(literalTools.parseShort("0xFFFF") == -1); Assert.assertTrue(literalTools.parseShort("0xFFFF") == -1);
Assert.assertTrue(literalTools.parseShort("-0x00") == 0); Assert.assertTrue(literalTools.parseShort("-0x00") == 0);
Assert.assertTrue(literalTools.parseShort("-0x01") == -1); Assert.assertTrue(literalTools.parseShort("-0x01") == -1);
Assert.assertTrue(literalTools.parseShort("-0x1234") == -0x1234); Assert.assertTrue(literalTools.parseShort("-0x1234") == -0x1234);
Assert.assertTrue(literalTools.parseShort("-0x8000") == Short.MIN_VALUE); Assert.assertTrue(literalTools.parseShort("-0x8000") == Short.MIN_VALUE);
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FaileHexTest1() { public void FaileHexTest1() {
literalTools.parseShort("-0x8001"); literalTools.parseShort("-0x8001");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailHexTest2() { public void FailHexTest2() {
literalTools.parseShort("-0xFFFF"); literalTools.parseShort("-0xFFFF");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailHexTest3() { public void FailHexTest3() {
literalTools.parseShort("0x100000"); literalTools.parseShort("0x100000");
} }
@Test @Test
public void SuccessDecTests() { public void SuccessDecTests() {
Assert.assertTrue(literalTools.parseShort("0") == 0); Assert.assertTrue(literalTools.parseShort("0") == 0);
Assert.assertTrue(literalTools.parseShort("1") == 1); Assert.assertTrue(literalTools.parseShort("1") == 1);
Assert.assertTrue(literalTools.parseShort("12345") == 12345); Assert.assertTrue(literalTools.parseShort("12345") == 12345);
Assert.assertTrue(literalTools.parseShort("32767") == 32767); Assert.assertTrue(literalTools.parseShort("32767") == 32767);
Assert.assertTrue(literalTools.parseShort("32768") == Short.MIN_VALUE); Assert.assertTrue(literalTools.parseShort("32768") == Short.MIN_VALUE);
Assert.assertTrue(literalTools.parseShort("65535") == -1); Assert.assertTrue(literalTools.parseShort("65535") == -1);
Assert.assertTrue(literalTools.parseShort("-0") == 0); Assert.assertTrue(literalTools.parseShort("-0") == 0);
Assert.assertTrue(literalTools.parseShort("-1") == -1); Assert.assertTrue(literalTools.parseShort("-1") == -1);
Assert.assertTrue(literalTools.parseShort("-12345") == -12345); Assert.assertTrue(literalTools.parseShort("-12345") == -12345);
Assert.assertTrue(literalTools.parseShort("-32767") == -32767); Assert.assertTrue(literalTools.parseShort("-32767") == -32767);
Assert.assertTrue(literalTools.parseShort("-32768") == Short.MIN_VALUE); Assert.assertTrue(literalTools.parseShort("-32768") == Short.MIN_VALUE);
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FaileDecTest1() { public void FaileDecTest1() {
literalTools.parseShort("-32769"); literalTools.parseShort("-32769");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailDecTest2() { public void FailDecTest2() {
literalTools.parseShort("-65535"); literalTools.parseShort("-65535");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailDecTest3() { public void FailDecTest3() {
literalTools.parseShort("65536"); literalTools.parseShort("65536");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailDecTest4() { public void FailDecTest4() {
literalTools.parseShort("65600"); literalTools.parseShort("65600");
} }
@Test @Test
public void SuccessOctTests() { public void SuccessOctTests() {
Assert.assertTrue(literalTools.parseShort("00") == 00); Assert.assertTrue(literalTools.parseShort("00") == 00);
Assert.assertTrue(literalTools.parseShort("01") == 01); Assert.assertTrue(literalTools.parseShort("01") == 01);
Assert.assertTrue(literalTools.parseShort("012345") == 012345); Assert.assertTrue(literalTools.parseShort("012345") == 012345);
Assert.assertTrue(literalTools.parseShort("077777") == Short.MAX_VALUE); Assert.assertTrue(literalTools.parseShort("077777") == Short.MAX_VALUE);
Assert.assertTrue(literalTools.parseShort("0100000") == Short.MIN_VALUE); Assert.assertTrue(literalTools.parseShort("0100000") == Short.MIN_VALUE);
Assert.assertTrue(literalTools.parseShort("0177777") == -1); Assert.assertTrue(literalTools.parseShort("0177777") == -1);
Assert.assertTrue(literalTools.parseShort("-00") == 0); Assert.assertTrue(literalTools.parseShort("-00") == 0);
Assert.assertTrue(literalTools.parseShort("-01") == -1); Assert.assertTrue(literalTools.parseShort("-01") == -1);
Assert.assertTrue(literalTools.parseShort("-012345") == -012345); Assert.assertTrue(literalTools.parseShort("-012345") == -012345);
Assert.assertTrue(literalTools.parseShort("-077777") == -077777); Assert.assertTrue(literalTools.parseShort("-077777") == -077777);
Assert.assertTrue(literalTools.parseShort("-0100000") == Short.MIN_VALUE); Assert.assertTrue(literalTools.parseShort("-0100000") == Short.MIN_VALUE);
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FaileOctTest1() { public void FaileOctTest1() {
literalTools.parseShort("-0100001"); literalTools.parseShort("-0100001");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailOctTest2() { public void FailOctTest2() {
literalTools.parseShort("-0177777"); literalTools.parseShort("-0177777");
} }
@Test(expected=NumberFormatException.class) @Test(expected=NumberFormatException.class)
public void FailOctTest3() { public void FailOctTest3() {
literalTools.parseShort("0200000"); literalTools.parseShort("0200000");
} }
} }