Section.java revision 57b5423285167163893078ea08830c15d8313a93
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.Input; 32import org.jf.dexlib.util.AnnotatedOutput; 33 34import java.util.ArrayList; 35import java.util.HashMap; 36 37public abstract class Section<T extends Item> { 38 protected ArrayList<T> items; 39 protected HashMap<T, T> uniqueItems = null; 40 41 /** 42 * When offset > -1, this section is "placed" at the specified offset. All 43 * items should have sequential indexes, and be placed appropriately. 44 * 45 * To unplace the section, set offset to -1, and set the offset of all 46 * items to -1 47 */ 48 protected int offset = -1; 49 50 public Section() { 51 items = new ArrayList<T>(); 52 } 53 54 public int place(int offset) { 55 this.offset = offset; 56 for (int i=0; i < items.size(); i++) { 57 T item = items.get(i); 58 if (item == null) { 59 throw new RuntimeException("This section contains a null item"); 60 } 61 offset = item.place(i, offset); 62 if (i == 0) { 63 /** 64 * if this item type has an alignment requirement, 65 * then item.getOffset() may be different than the 66 * offset that was passed in to this method, so we have 67 * to initialize the section offset to the actual 68 * (post-alignment) offset of the first item 69 */ 70 this.offset = item.getOffset(); 71 } 72 } 73 74 return offset; 75 } 76 77 public void unplace() { 78 for (Item item: items) { 79 item.unplace(); 80 } 81 } 82 83 public void writeTo(AnnotatedOutput out) { 84 for (int i = 0; i < size(); i++) { 85 T item = items.get(i); 86 if (item == null) { 87 throw new RuntimeException("Cannot write section because all items haven't been initialized"); 88 } 89 item.writeTo(out); 90 out.annotate(0, " "); 91 } 92 out.annotate(0, " "); 93 } 94 95 public abstract void readFrom(int size, Input in); 96 97 protected void setSize(int size) { 98 if (items.size() > size) { 99 throw new RuntimeException("There are references elsewhere to items in this section, that are " + 100 "beyond the end of the section"); 101 } 102 103 items.ensureCapacity(size); 104 for (int i = items.size(); i < size; i++) { 105 items.add(null); 106 } 107 } 108 109 public int size() { 110 return items.size(); 111 } 112 113 public boolean isPlaced() { 114 return offset > -1; 115 } 116 117 public int getOffset() { 118 return offset; 119 } 120 121 protected T getInternedItem(T item) { 122 if (uniqueItems == null) { 123 buildInternedItemMap(); 124 } 125 return uniqueItems.get(item); 126 } 127 128 protected void buildInternedItemMap() { 129 uniqueItems = new HashMap<T,T>(); 130 for (T item: items) { 131 uniqueItems.put(item, item); 132 } 133 } 134 135 public abstract T intern(DexFile dexFile, T item); 136} 137