| /* |
| * [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"; |
| } |
| } |