1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.dx.io;
18
19import com.android.dex.ClassDef;
20import com.android.dex.Dex;
21import com.android.dex.FieldId;
22import com.android.dex.MethodId;
23import com.android.dex.ProtoId;
24import com.android.dex.TableOfContents;
25import java.io.File;
26import java.io.IOException;
27
28/**
29 * Executable that prints all indices of a dex file.
30 */
31public final class DexIndexPrinter {
32    private final Dex dex;
33    private final TableOfContents tableOfContents;
34
35    public DexIndexPrinter(File file) throws IOException {
36        this.dex = new Dex(file);
37        this.tableOfContents = dex.getTableOfContents();
38    }
39
40    private void printMap() {
41        for (TableOfContents.Section section : tableOfContents.sections) {
42            if (section.off != -1) {
43                System.out.println("section " + Integer.toHexString(section.type)
44                        + " off=" + Integer.toHexString(section.off)
45                        + " size=" + Integer.toHexString(section.size)
46                        + " byteCount=" + Integer.toHexString(section.byteCount));
47            }
48        }
49    }
50
51    private void printStrings() throws IOException {
52        int index = 0;
53        for (String string : dex.strings()) {
54            System.out.println("string " + index + ": " + string);
55            index++;
56        }
57    }
58
59    private void printTypeIds() throws IOException {
60        int index = 0;
61        for (Integer type : dex.typeIds()) {
62            System.out.println("type " + index + ": " + dex.strings().get(type));
63            index++;
64        }
65    }
66
67    private void printProtoIds() throws IOException {
68        int index = 0;
69        for (ProtoId protoId : dex.protoIds()) {
70            System.out.println("proto " + index + ": " + protoId);
71            index++;
72        }
73    }
74
75    private void printFieldIds() throws IOException {
76        int index = 0;
77        for (FieldId fieldId : dex.fieldIds()) {
78            System.out.println("field " + index + ": " + fieldId);
79            index++;
80        }
81    }
82
83    private void printMethodIds() throws IOException {
84        int index = 0;
85        for (MethodId methodId : dex.methodIds()) {
86            System.out.println("methodId " + index + ": " + methodId);
87            index++;
88        }
89    }
90
91    private void printTypeLists() throws IOException {
92        if (tableOfContents.typeLists.off == -1) {
93            System.out.println("No type lists");
94            return;
95        }
96        Dex.Section in = dex.open(tableOfContents.typeLists.off);
97        for (int i = 0; i < tableOfContents.typeLists.size; i++) {
98            int size = in.readInt();
99            System.out.print("Type list i=" + i + ", size=" + size + ", elements=");
100            for (int t = 0; t < size; t++) {
101                System.out.print(" " + dex.typeNames().get((int) in.readShort()));
102            }
103            if (size % 2 == 1) {
104                in.readShort(); // retain alignment
105            }
106            System.out.println();
107        }
108    }
109
110    private void printClassDefs() {
111        int index = 0;
112        for (ClassDef classDef : dex.classDefs()) {
113            System.out.println("class def " + index + ": " + classDef);
114            index++;
115        }
116    }
117
118    public static void main(String[] args) throws IOException {
119        DexIndexPrinter indexPrinter = new DexIndexPrinter(new File(args[0]));
120        indexPrinter.printMap();
121        indexPrinter.printStrings();
122        indexPrinter.printTypeIds();
123        indexPrinter.printProtoIds();
124        indexPrinter.printFieldIds();
125        indexPrinter.printMethodIds();
126        indexPrinter.printTypeLists();
127        indexPrinter.printClassDefs();
128    }
129}
130