1/* 2 * [The "BSD licence"] 3 * Copyright (c) 2010 Ben Gruver (JesusFreke) 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29package org.jf.dexlib; 30 31import org.jf.dexlib.Util.AnnotatedOutput; 32import org.jf.dexlib.Util.Input; 33 34/** 35 * This item represents a map_list item from the dex specification. It contains a 36 * SectionInfo instance for every section in the DexFile, with the number of items 37 * in and offset of that section. 38 */ 39public class MapItem extends Item<MapItem> { 40 /** 41 * This item is read in immediately after the HeaderItem, and the section info contained 42 * by this item is added to the ReadContext object, which is used when reading in the other 43 * sections in the dex file. 44 * 45 * This item should be placed last. It depends on the fact that the other sections 46 * in the file have been placed. 47 */ 48 49 /** 50 * Create a new uninitialized <code>MapItem</code> 51 * @param dexFile The <code>DexFile</code> that this item belongs to 52 */ 53 protected MapItem(final DexFile dexFile) { 54 super(dexFile); 55 } 56 57 /** {@inheritDoc} */ 58 protected int placeItem(int offset) { 59 Section[] sections = dexFile.getOrderedSections(); 60 //the list returned by getOrderedSections doesn't contain the header 61 //or map section, so add 2 to the length 62 return offset + 4 + (sections.length + 2) * 12; 63 } 64 65 /** {@inheritDoc} */ 66 protected void readItem(Input in, ReadContext readContext) { 67 int size = in.readInt(); 68 69 for (int i=0; i<size; i++) { 70 ItemType itemType = ItemType.fromInt(in.readShort()); 71 72 //unused 73 in.readShort(); 74 75 int sectionSize = in.readInt(); 76 int sectionOffset = in.readInt(); 77 78 readContext.addSection(itemType, sectionSize, sectionOffset); 79 } 80 } 81 82 /** {@inheritDoc} */ 83 protected void writeItem(AnnotatedOutput out) { 84 assert getOffset() > 0; 85 Section[] sections = dexFile.getOrderedSections(); 86 87 out.annotate("map_size: 0x" + Integer.toHexString(sections.length + 2) + " (" + 88 Integer.toString(sections.length + 2) + ")"); 89 out.writeInt(sections.length + 2); 90 91 int index = 0; 92 out.annotate(0, "[" + index++ + "]"); 93 out.indent(); 94 writeSectionInfo(out, ItemType.TYPE_HEADER_ITEM, 1, 0); 95 out.deindent(); 96 97 for (Section section: dexFile.getOrderedSections()) { 98 out.annotate(0, "[" + index++ + "]"); 99 out.indent(); 100 writeSectionInfo(out, section.ItemType, section.getItems().size(), section.getOffset()); 101 out.deindent(); 102 } 103 104 out.annotate(0, "[" + index++ + "]"); 105 out.indent(); 106 writeSectionInfo(out, ItemType.TYPE_MAP_LIST, 1, dexFile.MapItem.getOffset()); 107 out.deindent(); 108 } 109 110 private void writeSectionInfo(AnnotatedOutput out, ItemType itemType, int sectionSize, int sectionOffset) { 111 if (out.annotates()) { 112 out.annotate(2, "item_type: " + itemType); 113 out.annotate(2, "unused"); 114 out.annotate(4, "section_size: 0x" + Integer.toHexString(sectionSize) + " (" + sectionSize + ")"); 115 out.annotate(4, "section_off: 0x" + Integer.toHexString(sectionOffset)); 116 } 117 118 out.writeShort(itemType.MapValue); 119 out.writeShort(0); 120 out.writeInt(sectionSize); 121 out.writeInt(sectionOffset); 122 } 123 124 /** {@inheritDoc} */ 125 public ItemType getItemType() { 126 return ItemType.TYPE_MAP_LIST; 127 } 128 129 /** {@inheritDoc} */ 130 public int compareTo(MapItem o) { 131 return 0; 132 } 133 134 /** {@inheritDoc} */ 135 public String getConciseIdentity() { 136 return "map_item"; 137 } 138} 139