/* * [The "BSD licence"] * Copyright (c) 2010 Ben Gruver (JesusFreke) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.jf.dexlib; import org.jf.dexlib.Util.AnnotatedOutput; import org.jf.dexlib.Util.Input; /** * This item represents a map_list item from the dex specification. It contains a * SectionInfo instance for every section in the DexFile, with the number of items * in and offset of that section. */ public class MapItem extends Item<MapItem> { /** * This item is read in immediately after the HeaderItem, and the section info contained * by this item is added to the ReadContext object, which is used when reading in the other * sections in the dex file. * * This item should be placed last. It depends on the fact that the other sections * in the file have been placed. */ /** * Create a new uninitialized <code>MapItem</code> * @param dexFile The <code>DexFile</code> that this item belongs to */ protected MapItem(final DexFile dexFile) { super(dexFile); } /** {@inheritDoc} */ protected int placeItem(int offset) { Section[] sections = dexFile.getOrderedSections(); //the list returned by getOrderedSections doesn't contain the header //or map section, so add 2 to the length return offset + 4 + (sections.length + 2) * 12; } /** {@inheritDoc} */ protected void readItem(Input in, ReadContext readContext) { int size = in.readInt(); for (int i=0; i<size; i++) { ItemType itemType = ItemType.fromInt(in.readShort()); //unused in.readShort(); int sectionSize = in.readInt(); int sectionOffset = in.readInt(); readContext.addSection(itemType, sectionSize, sectionOffset); } } /** {@inheritDoc} */ protected void writeItem(AnnotatedOutput out) { assert getOffset() > 0; Section[] sections = dexFile.getOrderedSections(); out.annotate("map_size: 0x" + Integer.toHexString(sections.length + 2) + " (" + Integer.toString(sections.length + 2) + ")"); out.writeInt(sections.length + 2); int index = 0; out.annotate(0, "[" + index++ + "]"); out.indent(); writeSectionInfo(out, ItemType.TYPE_HEADER_ITEM, 1, 0); out.deindent(); for (Section section: dexFile.getOrderedSections()) { out.annotate(0, "[" + index++ + "]"); out.indent(); writeSectionInfo(out, section.ItemType, section.getItems().size(), section.getOffset()); out.deindent(); } out.annotate(0, "[" + index++ + "]"); out.indent(); writeSectionInfo(out, ItemType.TYPE_MAP_LIST, 1, dexFile.MapItem.getOffset()); out.deindent(); } private void writeSectionInfo(AnnotatedOutput out, ItemType itemType, int sectionSize, int sectionOffset) { if (out.annotates()) { out.annotate(2, "item_type: " + itemType); out.annotate(2, "unused"); out.annotate(4, "section_size: 0x" + Integer.toHexString(sectionSize) + " (" + sectionSize + ")"); out.annotate(4, "section_off: 0x" + Integer.toHexString(sectionOffset)); } out.writeShort(itemType.MapValue); out.writeShort(0); out.writeInt(sectionSize); out.writeInt(sectionOffset); } /** {@inheritDoc} */ public ItemType getItemType() { return ItemType.TYPE_MAP_LIST; } /** {@inheritDoc} */ public int compareTo(MapItem o) { return 0; } /** {@inheritDoc} */ public String getConciseIdentity() { return "map_item"; } }