Item.java revision d8b31a17aee6519c2086ccac3e11f7cd40cba9c1
1/* 2 * [The "BSD licence"] 3 * Copyright (c) 2009 Ben Gruver 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; 33import org.jf.dexlib.Util.AlignmentUtils; 34 35public abstract class Item<T extends Item> implements Comparable<T> { 36 /** 37 * The offset of this item in the dex file, or -1 if not known 38 */ 39 private int offset = -1; 40 41 /** 42 * The index of this item in the containing section, or -1 if not known 43 */ 44 private int index = -1; 45 46 /** 47 * The DexFile that this item is associatedr with 48 */ 49 protected final DexFile dexFile; 50 51 /** 52 * The constructor that is used when reading in a <code>DexFile</code> 53 * @param dexFile the <code>DexFile</code> that this item is associated with 54 */ 55 protected Item(DexFile dexFile) { 56 this.dexFile = dexFile; 57 } 58 59 /** 60 * Read in the item from the given input stream, and initialize the index 61 * @param in the <code>Input</code> object to read from 62 * @param index the index within the containing section of the item being read in 63 * @param readContext a <code>ReadContext</code> object to hold information that is 64 * only needed while reading in a file 65 */ 66 protected void readFrom(Input in, int index, ReadContext readContext) { 67 assert in.getCursor() % getItemType().ItemAlignment == 0:"The Input cursor is not aligned"; 68 69 this.offset = in.getCursor(); 70 this.index = index; 71 this.readItem(in, readContext); 72 } 73 74 /** 75 * Place the item at the given offset and index, and return the offset of the byte following this item 76 * @param offset The offset to place the item at 77 * @param index The index of the item within the containing section 78 * @return The offset of the byte following this item 79 */ 80 protected int placeAt(int offset, int index) { 81 assert offset % getItemType().ItemAlignment == 0; 82 assert !dexFile.getInplace() || (offset == this.offset && this.index == index); 83 84 this.offset = offset; 85 this.index = index; 86 return this.placeItem(offset); 87 } 88 89 /** 90 * Write and annotate this item to the output stream 91 * @param out The output stream to write and annotate to 92 */ 93 protected void writeTo(AnnotatedOutput out) { 94 assert out.getCursor() % getItemType().ItemAlignment == 0; 95 assert out.getCursor() == offset; 96 97 if (out.annotates()) { 98 out.annotate(0, "[0x" + Integer.toHexString(index) + "] " + this.getItemType().TypeName); 99 } 100 101 out.indent(); 102 writeItem(out); 103 out.deindent(); 104 } 105 106 /** 107 * Returns a human readable form of this item 108 * @return a human readable form of this item 109 */ 110 public String toString() { 111 return getConciseIdentity(); 112 } 113 114 /** 115 * The method in the concrete item subclass that actually reads in the data for the item 116 * 117 * The logic in this method can assume that the given Input object is valid and is 118 * aligned as neccessary. 119 * 120 * This method is for internal use only 121 * @param in the <code>Input</code> object to read from 122 * @param readContext a <code>ReadContext</code> object to hold information that is 123 * only needed while reading in a file 124 */ 125 protected abstract void readItem(Input in, ReadContext readContext); 126 127 /** 128 * The method should finalize the layout of the item and return the offset of the byte 129 * immediately following the item. 130 * 131 * The implementation of this method can assume that the offset argument has already been 132 * aligned based on the item's alignment requirements 133 * 134 * This method is for internal use only 135 * @param offset the (pre-aligned) offset to place the item at 136 * @return the size of the item, in bytes 137 */ 138 protected abstract int placeItem(int offset); 139 140 /** 141 * The method in the concrete item subclass that actually writes and annotates the data 142 * for the item. 143 * 144 * The logic in this method can assume that the given Output object is valid and is 145 * aligned as neccessary 146 * 147 * @param out The <code>AnnotatedOutput</code> object to write/annotate to 148 */ 149 protected abstract void writeItem(AnnotatedOutput out); 150 151 /** 152 * @return An ItemType enum that represents the item type of this item 153 */ 154 public abstract ItemType getItemType(); 155 156 /** 157 * @return A concise (human-readable) string value that conveys the identity of this item 158 */ 159 public abstract String getConciseIdentity(); 160 161 162 /** 163 * @return the offset in the dex file where this item is located 164 */ 165 public int getOffset() { 166 return offset; 167 } 168 169 /** 170 * @return the index of this item within the item's containing section 171 */ 172 public int getIndex() { 173 return index; 174 } 175 176 /** 177 * @return the <code>DexFile</code> that contains this item 178 */ 179 public DexFile getDexFile() { 180 return dexFile; 181 } 182} 183