Methods Summary |
---|
static java.lang.String | classNameOnly(java.lang.String typeName)Extracts the class name from a type descriptor.
String dotted = descriptorToDot(typeName);
int start = dotted.lastIndexOf(".");
if (start < 0) {
return dotted;
} else {
return dotted.substring(start+1);
}
|
static java.lang.String | descriptorToDot(java.lang.String descr)Converts a type descriptor to human-readable "dotted" form. For
example, "Ljava/lang/String;" becomes "java.lang.String", and
"[I" becomes "int[].
int targetLen = descr.length();
int offset = 0;
int arrayDepth = 0;
/* strip leading [s; will be added to end */
while (targetLen > 1 && descr.charAt(offset) == '[") {
offset++;
targetLen--;
}
arrayDepth = offset;
if (targetLen == 1) {
descr = primitiveTypeLabel(descr.charAt(offset));
offset = 0;
targetLen = descr.length();
} else {
/* account for leading 'L' and trailing ';' */
if (targetLen >= 2 && descr.charAt(offset) == 'L" &&
descr.charAt(offset+targetLen-1) == ';")
{
targetLen -= 2; /* two fewer chars to copy */
offset++; /* skip the 'L' */
}
}
char[] buf = new char[targetLen + arrayDepth * 2];
/* copy class name over */
int i;
for (i = 0; i < targetLen; i++) {
char ch = descr.charAt(offset + i);
buf[i] = (ch == '/") ? '." : ch;
}
/* add the appopriate number of brackets for arrays */
while (arrayDepth-- > 0) {
buf[i++] = '[";
buf[i++] = ']";
}
assert i == buf.length;
return new String(buf);
|
public static void | generate(DexData dexData, java.lang.String format, boolean justClasses)
if (format.equals("brief")) {
printBrief(dexData, justClasses);
} else if (format.equals("xml")) {
printXml(dexData, justClasses);
} else {
/* should've been trapped in arg handler */
throw new RuntimeException("unknown output format");
}
|
public static void | generateFirstHeader(java.lang.String fileName, java.lang.String format)
generateHeader0(fileName, format);
|
public static void | generateFooter(java.lang.String format)
if (format.equals("brief")) {
// Nothing to do.
} else if (format.equals("xml")) {
out.println("</external>");
} else {
/* should've been trapped in arg handler */
throw new RuntimeException("unknown output format");
}
|
public static void | generateHeader(java.lang.String fileName, java.lang.String format)
out.println();
generateHeader0(fileName, format);
|
private static void | generateHeader0(java.lang.String fileName, java.lang.String format)
if (format.equals("brief")) {
if (fileName != null) {
out.println("File: " + fileName);
}
} else if (format.equals("xml")) {
if (fileName != null) {
out.println(IN0 + "<external file=\"" + fileName + "\">");
} else {
out.println(IN0 + "<external>");
}
} else {
/* should've been trapped in arg handler */
throw new RuntimeException("unknown output format");
}
|
static java.lang.String | packageNameOnly(java.lang.String typeName)Extracts the package name from a type descriptor, and returns it in
dotted form.
String dotted = descriptorToDot(typeName);
int end = dotted.lastIndexOf(".");
if (end < 0) {
/* lives in default package */
return "";
} else {
return dotted.substring(0, end);
}
|
static java.lang.String | primitiveTypeLabel(char typeChar)Converts a single-character primitive type into its human-readable
equivalent.
/* primitive type; substitute human-readable name in */
switch (typeChar) {
case 'B": return "byte";
case 'C": return "char";
case 'D": return "double";
case 'F": return "float";
case 'I": return "int";
case 'J": return "long";
case 'S": return "short";
case 'V": return "void";
case 'Z": return "boolean";
default:
/* huh? */
System.err.println("Unexpected class char " + typeChar);
assert false;
return "UNKNOWN";
}
|
static void | printBrief(DexData dexData, boolean justClasses)Prints the data in a simple human-readable format.
ClassRef[] externClassRefs = dexData.getExternalReferences();
printClassRefs(externClassRefs, justClasses);
if (!justClasses) {
printFieldRefs(externClassRefs);
printMethodRefs(externClassRefs);
}
|
static void | printClassRefs(ClassRef[] classes, boolean justClasses)Prints the list of classes in a simple human-readable format.
if (!justClasses) {
out.println("Classes:");
}
for (int i = 0; i < classes.length; i++) {
ClassRef ref = classes[i];
out.println(descriptorToDot(ref.getName()));
}
|
static void | printFieldRefs(ClassRef[] classes)Prints the list of fields in a simple human-readable format.
out.println("\nFields:");
for (int i = 0; i < classes.length; i++) {
FieldRef[] fields = classes[i].getFieldArray();
for (int j = 0; j < fields.length; j++) {
FieldRef ref = fields[j];
out.println(descriptorToDot(ref.getDeclClassName()) +
"." + ref.getName() + " : " + ref.getTypeName());
}
}
|
static void | printMethodRefs(ClassRef[] classes)Prints the list of methods in a simple human-readable format.
out.println("\nMethods:");
for (int i = 0; i < classes.length; i++) {
MethodRef[] methods = classes[i].getMethodArray();
for (int j = 0; j < methods.length; j++) {
MethodRef ref = methods[j];
out.println(descriptorToDot(ref.getDeclClassName()) +
"." + ref.getName() + " : " + ref.getDescriptor());
}
}
|
static void | printXml(DexData dexData, boolean justClasses)Prints the output in XML format.
We shouldn't need to XML-escape the field/method info.
ClassRef[] externClassRefs = dexData.getExternalReferences();
/*
* Iterate through externClassRefs. For each class, dump all of
* the matching fields and methods.
*/
String prevPackage = null;
for (int i = 0; i < externClassRefs.length; i++) {
ClassRef cref = externClassRefs[i];
String declClassName = cref.getName();
String className = classNameOnly(declClassName);
String packageName = packageNameOnly(declClassName);
/*
* If we're in a different package, emit the appropriate tags.
*/
if (!packageName.equals(prevPackage)) {
if (prevPackage != null) {
out.println(IN1 + "</package>");
}
out.println(IN1 +
"<package name=\"" + packageName + "\">");
prevPackage = packageName;
}
out.println(IN2 + "<class name=\"" + className + "\">");
if (!justClasses) {
printXmlFields(cref);
printXmlMethods(cref);
}
out.println(IN2 + "</class>");
}
if (prevPackage != null)
out.println(IN1 + "</package>");
|
private static void | printXmlFields(ClassRef cref)Prints the externally-visible fields in XML format.
FieldRef[] fields = cref.getFieldArray();
for (int i = 0; i < fields.length; i++) {
FieldRef fref = fields[i];
out.println(IN3 + "<field name=\"" + fref.getName() +
"\" type=\"" + descriptorToDot(fref.getTypeName()) + "\"/>");
}
|
private static void | printXmlMethods(ClassRef cref)Prints the externally-visible methods in XML format.
MethodRef[] methods = cref.getMethodArray();
for (int i = 0; i < methods.length; i++) {
MethodRef mref = methods[i];
String declClassName = mref.getDeclClassName();
boolean constructor;
constructor = mref.getName().equals("<init>");
if (constructor) {
// use class name instead of method name
out.println(IN3 + "<constructor name=\"" +
classNameOnly(declClassName) + "\">");
} else {
out.println(IN3 + "<method name=\"" + mref.getName() +
"\" return=\"" + descriptorToDot(mref.getReturnTypeName()) +
"\">");
}
String[] args = mref.getArgumentTypeNames();
for (int j = 0; j < args.length; j++) {
out.println(IN4 + "<parameter type=\"" +
descriptorToDot(args[j]) + "\"/>");
}
if (constructor) {
out.println(IN3 + "</constructor>");
} else {
out.println(IN3 + "</method>");
}
}
|