1373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver/*
2373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * Copyright 2013, Google Inc.
3373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * All rights reserved.
4373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver *
5373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * Redistribution and use in source and binary forms, with or without
6373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * modification, are permitted provided that the following conditions are
7373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * met:
8373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver *
9373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver *     * Redistributions of source code must retain the above copyright
10373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * notice, this list of conditions and the following disclaimer.
11373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver *     * Redistributions in binary form must reproduce the above
12373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * copyright notice, this list of conditions and the following disclaimer
13373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * in the documentation and/or other materials provided with the
14373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * distribution.
15373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver *     * Neither the name of Google Inc. nor the names of its
16373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * contributors may be used to endorse or promote products derived from
17373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * this software without specific prior written permission.
18373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver *
19373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver */
31373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver
32373ff22ec69bb6e93646994347b6d80502be1588Ben Gruverpackage org.jf.dexlib2.dexbacked.raw;
33373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver
348f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruverimport com.google.common.collect.Maps;
358f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruverimport org.jf.dexlib2.dexbacked.raw.util.DexAnnotator;
36373ff22ec69bb6e93646994347b6d80502be1588Ben Gruverimport org.jf.dexlib2.util.AnnotatedBytes;
37ff32d5cc147d4777b19e19692b3b196ddc460b51Ben Gruverimport org.jf.util.AlignmentUtils;
38373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver
39373ff22ec69bb6e93646994347b6d80502be1588Ben Gruverimport javax.annotation.Nonnull;
4078612c755447a47945d7179a688120856db0a76dBen Gruverimport javax.annotation.Nullable;
418f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruverimport java.util.Map;
42373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver
4378612c755447a47945d7179a688120856db0a76dBen Gruverpublic abstract class SectionAnnotator {
448f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    @Nonnull public final DexAnnotator annotator;
458f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    @Nonnull public final RawDexFile dexFile;
468f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    public final int itemType;
478f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    public final int sectionOffset;
488f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    public final int itemCount;
498f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver
508f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    private Map<Integer, String> itemIdentities = Maps.newHashMap();
518f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver
528f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    public SectionAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) {
538f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver        this.annotator = annotator;
548f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver        this.dexFile = annotator.dexFile;
558f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver        this.itemType = mapItem.getType();
568f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver
578f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver        this.sectionOffset = mapItem.getOffset();
588f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver        this.itemCount = mapItem.getItemCount();
598f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    }
608f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver
6178612c755447a47945d7179a688120856db0a76dBen Gruver    @Nonnull public abstract String getItemName();
628f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    protected abstract void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity);
63373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver
64373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver    /**
65373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver     * Write out annotations for this section
66373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver     *
67373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver     * @param out The AnnotatedBytes object to annotate to
68373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver     */
698f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    public void annotateSection(@Nonnull AnnotatedBytes out) {
708f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver        out.moveTo(sectionOffset);
7184dd76e52b1283bef7bc9a529a241690ea2191b8Ben Gruver        annotateSectionInner(out, itemCount);
728f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    }
738f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver
7484dd76e52b1283bef7bc9a529a241690ea2191b8Ben Gruver    protected void annotateSectionInner(@Nonnull AnnotatedBytes out, int itemCount) {
7578612c755447a47945d7179a688120856db0a76dBen Gruver        String itemName = getItemName();
76ff32d5cc147d4777b19e19692b3b196ddc460b51Ben Gruver        int itemAlignment = getItemAlignment();
77ff32d5cc147d4777b19e19692b3b196ddc460b51Ben Gruver        if (itemCount > 0) {
788f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver            out.annotate(0, "");
7978612c755447a47945d7179a688120856db0a76dBen Gruver            out.annotate(0, "-----------------------------");
8078612c755447a47945d7179a688120856db0a76dBen Gruver            out.annotate(0, "%s section", itemName);
8178612c755447a47945d7179a688120856db0a76dBen Gruver            out.annotate(0, "-----------------------------");
8278612c755447a47945d7179a688120856db0a76dBen Gruver            out.annotate(0, "");
8378612c755447a47945d7179a688120856db0a76dBen Gruver
84ff32d5cc147d4777b19e19692b3b196ddc460b51Ben Gruver            for (int i=0; i<itemCount; i++) {
8531d87776c459972f311a3527694e0d630d92a84bBen Gruver                out.moveTo(AlignmentUtils.alignOffset(out.getCursor(), itemAlignment));
86ff32d5cc147d4777b19e19692b3b196ddc460b51Ben Gruver
878f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver                String itemIdentity = getItemIdentity(out.getCursor());
8878612c755447a47945d7179a688120856db0a76dBen Gruver                if (itemIdentity != null) {
8978612c755447a47945d7179a688120856db0a76dBen Gruver                    out.annotate(0, "[%d] %s: %s", i, itemName, itemIdentity);
9078612c755447a47945d7179a688120856db0a76dBen Gruver                } else {
9178612c755447a47945d7179a688120856db0a76dBen Gruver                    out.annotate(0, "[%d] %s", i, itemName);
9278612c755447a47945d7179a688120856db0a76dBen Gruver                }
9378612c755447a47945d7179a688120856db0a76dBen Gruver                out.indent();
948f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver                annotateItem(out, i, itemIdentity);
9578612c755447a47945d7179a688120856db0a76dBen Gruver                out.deindent();
9678612c755447a47945d7179a688120856db0a76dBen Gruver            }
9778612c755447a47945d7179a688120856db0a76dBen Gruver        }
9878612c755447a47945d7179a688120856db0a76dBen Gruver    }
9978612c755447a47945d7179a688120856db0a76dBen Gruver
1008f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    @Nullable private String getItemIdentity(int itemOffset) {
1018f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver        return itemIdentities.get(itemOffset);
1028f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    }
1038f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver
1048f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    public void setItemIdentity(int itemOffset, String identity) {
1058f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver        itemIdentities.put(itemOffset, identity);
10678612c755447a47945d7179a688120856db0a76dBen Gruver    }
107ff32d5cc147d4777b19e19692b3b196ddc460b51Ben Gruver
108ff32d5cc147d4777b19e19692b3b196ddc460b51Ben Gruver    public int getItemAlignment() {
109ff32d5cc147d4777b19e19692b3b196ddc460b51Ben Gruver        return 1;
110ff32d5cc147d4777b19e19692b3b196ddc460b51Ben Gruver    }
111373ff22ec69bb6e93646994347b6d80502be1588Ben Gruver}
112