183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com/*
283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * [The "BSD licence"]
300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * Copyright (c) 2010 Ben Gruver (JesusFreke)
483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * All rights reserved.
583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *
683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Redistribution and use in source and binary forms, with or without
783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * modification, are permitted provided that the following conditions
883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * are met:
983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 1. Redistributions of source code must retain the above copyright
1083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *    notice, this list of conditions and the following disclaimer.
1183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 2. Redistributions in binary form must reproduce the above copyright
1283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *    notice, this list of conditions and the following disclaimer in the
1383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *    documentation and/or other materials provided with the distribution.
1483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 3. The name of the author may not be used to endorse or promote products
1583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *    derived from this software without specific prior written permission.
1683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *
1783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */
2883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
2983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.compackage org.jf.dexlib;
3083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
314b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.comimport org.jf.dexlib.Util.ExceptionWithContext;
3283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.comimport org.jf.dexlib.Util.SparseArray;
3383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
3483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.comimport java.util.List;
3583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
3683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
3783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com/**
3883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * This class stores context information that is only needed when reading in a dex file
3983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Namely, it handles "pre-creating" items when an item needs to resolve some other item
4083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * that it references, and keeps track of those pre-created items, so the corresponding section
4183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * for the pre-created items uses them, instead of creating new items
4283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */
434b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.compublic class ReadContext {
4483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    private SparseArray<TypeListItem> typeListItems = new SparseArray<TypeListItem>(0);
4583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    private SparseArray<AnnotationSetRefList> annotationSetRefLists = new SparseArray<AnnotationSetRefList>(0);
4683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    private SparseArray<AnnotationSetItem> annotationSetItems = new SparseArray<AnnotationSetItem>(0);
4783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    private SparseArray<ClassDataItem> classDataItems = new SparseArray<ClassDataItem>(0);
4883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    private SparseArray<CodeItem> codeItems = new SparseArray<CodeItem>(0);
4983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    private SparseArray<StringDataItem> stringDataItems = new SparseArray<StringDataItem>(0);
5083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    private SparseArray<DebugInfoItem> debugInfoItems = new SparseArray<DebugInfoItem>(0);
5183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    private SparseArray<AnnotationItem> annotationItems = new SparseArray<AnnotationItem>(0);
524b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com    private SparseArray<EncodedArrayItem> encodedArrayItems = new SparseArray<EncodedArrayItem>(0);
534b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com    private SparseArray<AnnotationDirectoryItem> annotationDirectoryItems = new SparseArray<AnnotationDirectoryItem>(0);
5483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
5583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    private SparseArray[] itemsByType = new SparseArray[] {
5683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            null, //string_id_item
5783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            null, //type_id_item
5883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            null, //proto_id_item
5983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            null, //field_id_item
6083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            null, //method_id_item
6183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            null, //class_def_item
6283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            typeListItems,
6383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            annotationSetRefLists,
6483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            annotationSetItems,
6583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            classDataItems,
6683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            codeItems,
6783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            stringDataItems,
6883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            debugInfoItems,
6983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            annotationItems,
7083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            encodedArrayItems,
7183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            annotationDirectoryItems,
7283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            null, //map_list
7383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            null //header_item
7483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    };
7516a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com
7683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
7783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
7883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * The section sizes that are passed in while reading HeaderItem/MapItem, via the
7983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * addSection method.
8083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
8183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    private int[] sectionSizes = new int[18];
8283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
8383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
8483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * The section offsets that are passed in while reading MapItem/HeaderItem, via the
8583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * addSection method.
8683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
8783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    private int[] sectionOffsets = new int[18];
8883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
8983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
9083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Creates a new ReadContext instance.
9183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
924b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com    public ReadContext() {
9383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        for (int i=0; i<18; i++) {
9483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            sectionSizes[i] = -1;
9583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            sectionOffsets[i] = -1;
9683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
9783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
9883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
9983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
1004b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com     * Gets the offsetted item of the specified type for the given offset. This method does not support retrieving an
1014b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com     * optional item where a value of 0 indicates "not present". Use getOptionalOffsettedItemByOffset instead.
10283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
10383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param itemType The type of item to get
10416a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com     * @param offset The offset of the item
1054b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com     * @return the offsetted item of the specified type at the specified offset
10683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
10783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public Item getOffsettedItemByOffset(ItemType itemType, int offset) {
10883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        assert !itemType.isIndexedItem();
10983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
11083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        SparseArray<Item> sa = itemsByType[itemType.SectionIndex];
11183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        Item item = sa.get(offset);
11283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (item == null) {
1134b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com            throw new ExceptionWithContext(String.format("Could not find the %s item at offset %#x",
1144b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com                    itemType.TypeName, offset));
11583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
11683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return item;
11783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
11883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
11983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
1204b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com     * Gets the optional offsetted item of the specified type for the given offset
1214b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com     *
12216a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com     * @param itemType The type of item to get
1234b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com     * @param offset The offset of the item
1244b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com     * @return the offsetted item of the specified type at the specified offset, or null if the offset is 0
12516a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com     */
12616a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com    public Item getOptionalOffsettedItemByOffset(ItemType itemType, int offset) {
12716a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com        assert !itemType.isIndexedItem();
12816a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com
1294b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com        assert !itemType.isIndexedItem();
13016a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com
1314b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com        SparseArray<Item> sa = itemsByType[itemType.SectionIndex];
1324b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com        Item item = sa.get(offset);
1334b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com        if (item == null && offset != 0) {
1344b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com            throw new ExceptionWithContext(String.format("Could not find the %s item at offset %#x",
1354b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com                    itemType.TypeName, offset));
1364b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com        }
1374b82fba3ba46eb3f7169f9db9d3118e7d73c3682JesusFreke@JesusFreke.com        return item;
13816a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com    }
13916a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com
14016a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com    /**
14116a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com     * Adds the size and offset information for the given offset
14283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param itemType the item type of the section
14383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param sectionSize the size of the section
14483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param sectionOffset the offset of the section
14583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
14683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public void addSection(final ItemType itemType, int sectionSize, int sectionOffset) {
14783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        int storedSectionSize = sectionSizes[itemType.SectionIndex];
14883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (storedSectionSize == -1) {
14983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            sectionSizes[itemType.SectionIndex] = sectionSize;
15083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        } else {
15183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            if (storedSectionSize  != sectionSize) {
15283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                throw new RuntimeException("The section size in the header and map for item type "
15383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                        + itemType + " do not match");
15416a911620ccf7b530b873fb71cf13e8dcb88ad28JesusFreke@JesusFreke.com            }
15583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
15683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
15783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        int storedSectionOffset = sectionOffsets[itemType.SectionIndex];
15883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (storedSectionOffset == -1) {
15983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            sectionOffsets[itemType.SectionIndex] = sectionOffset;
16083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        } else {
16183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            if (storedSectionOffset != sectionOffset) {
16283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                throw new RuntimeException("The section offset in the header and map for item type "
16383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com                        + itemType + " do not match");
16483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            }
16583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
16683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
16783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
16883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
16983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Sets the items for the specified section. This should be called by an offsetted section
17083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * after it is finished reading in all its items.
17183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param itemType the item type of the section. This must be an offsetted item type
17283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param items the full list of items in the section, ordered by offset
17383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
17483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public void setItemsForSection(ItemType itemType, List<? extends Item> items) {
17583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        assert !itemType.isIndexedItem();
17683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
17783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        SparseArray<Item> sa = itemsByType[itemType.SectionIndex];
17883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
17983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        sa.ensureCapacity(items.size());
18083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        for (Item item: items) {
18183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            sa.append(item.getOffset(), item);
18283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
18383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
18483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
18583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
18683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param itemType the item type of the section
18783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return the size of the given section as it was read in from the map item
18883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
18983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public int getSectionSize(ItemType itemType) {
19083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return sectionSizes[itemType.SectionIndex];
19183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
19283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
19383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
19483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param itemType the item type of the section
19583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return the offset of the given section as it was read in from the map item
19683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
19783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public int getSectionOffset(ItemType itemType) {
19883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return sectionOffsets[itemType.SectionIndex];
19983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
20083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com}
201