FileDocCategorySizeDatePackage
Output.javaAPI DocAndroid 5.1 API11122Thu Mar 12 22:18:30 GMT 2015com.android.dexdeps

Output

public class Output extends Object
Generate fancy output.

Fields Summary
private static final String
IN0
private static final String
IN1
private static final String
IN2
private static final String
IN3
private static final String
IN4
private static final PrintStream
out
Constructors Summary
Methods Summary
static java.lang.StringclassNameOnly(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.StringdescriptorToDot(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 voidgenerate(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 voidgenerateFirstHeader(java.lang.String fileName, java.lang.String format)

        generateHeader0(fileName, format);
    
public static voidgenerateFooter(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 voidgenerateHeader(java.lang.String fileName, java.lang.String format)

        out.println();
        generateHeader0(fileName, format);
    
private static voidgenerateHeader0(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.StringpackageNameOnly(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.StringprimitiveTypeLabel(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 voidprintBrief(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 voidprintClassRefs(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 voidprintFieldRefs(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 voidprintMethodRefs(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 voidprintXml(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 voidprintXmlFields(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 voidprintXmlMethods(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>");
            }
        }