1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2008 The Android Open Source Project 3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License. 6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at 7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and 14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License. 15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.dex.file; 18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.Constant; 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.type.Prototype; 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.AnnotatedOutput; 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.Hex; 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.Collection; 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.TreeMap; 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Proto (method prototype) identifiers list section of a 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code .dex} file. 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class ProtoIdsSection extends UniformItemSection { 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code non-null;} map from method prototypes to {@link ProtoIdItem} instances 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final TreeMap<Prototype, ProtoIdItem> protoIds; 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an instance. The file offset is initially unknown. 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param file {@code non-null;} file that this instance is part of 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public ProtoIdsSection(DexFile file) { 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson super("proto_ids", file, 4); 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protoIds = new TreeMap<Prototype, ProtoIdItem>(); 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Collection<? extends Item> items() { 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return protoIds.values(); 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public IndexedItem get(Constant cst) { 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new UnsupportedOperationException("unsupported"); 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Writes the portion of the file header that refers to this instance. 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param out {@code non-null;} where to write 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void writeHeaderPart(AnnotatedOutput out) { 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throwIfNotPrepared(); 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sz = protoIds.size(); 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int offset = (sz == 0) ? 0 : getFileOffset(); 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (sz > 65536) { 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new UnsupportedOperationException("too many proto ids"); 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (out.annotates()) { 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(4, "proto_ids_size: " + Hex.u4(sz)); 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(4, "proto_ids_off: " + Hex.u4(offset)); 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.writeInt(sz); 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.writeInt(offset); 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Interns an element into this instance. 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param prototype {@code non-null;} the prototype to intern 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the interned reference 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public ProtoIdItem intern(Prototype prototype) { 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (prototype == null) { 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("prototype == null"); 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throwIfPrepared(); 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ProtoIdItem result = protoIds.get(prototype); 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (result == null) { 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result = new ProtoIdItem(prototype); 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protoIds.put(prototype, result); 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the index of the given prototype, which must have 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * been added to this instance. 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param prototype {@code non-null;} the prototype to look up 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= 0;} the reference's index 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int indexOf(Prototype prototype) { 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (prototype == null) { 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("prototype == null"); 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throwIfNotPrepared(); 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ProtoIdItem item = protoIds.get(prototype); 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (item == null) { 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("not found"); 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return item.getIndex(); 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected void orderItems() { 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int idx = 0; 134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (Object i : items()) { 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ((ProtoIdItem) i).setIndex(idx); 137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson idx++; 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 141