diff options
Diffstat (limited to 'dx/src/com/android/dx/dex/file/MixedItemSection.java')
-rw-r--r-- | dx/src/com/android/dx/dex/file/MixedItemSection.java | 362 |
1 files changed, 0 insertions, 362 deletions
diff --git a/dx/src/com/android/dx/dex/file/MixedItemSection.java b/dx/src/com/android/dx/dex/file/MixedItemSection.java deleted file mode 100644 index f03a9a387..000000000 --- a/dx/src/com/android/dx/dex/file/MixedItemSection.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.dex.file; - -import com.android.dx.util.AnnotatedOutput; -import com.android.dx.util.ExceptionWithContext; -import com.android.dx.util.Hex; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.TreeMap; - -/** - * A section of a <code>.dex</code> file which consists of a sequence of - * {@link OffsettedItem} objects, which may each be of a different concrete - * class and/or size. - * - * <b>Note:</b> It is invalid for an item in an instance of this class to - * have a larger alignment requirement than the alignment of this instance. - */ -public final class MixedItemSection extends Section { - static enum SortType { - /** no sorting */ - NONE, - - /** sort by type only */ - TYPE, - - /** sort in class-major order, with instances sorted per-class */ - INSTANCE; - }; - - /** non-null; sorter which sorts instances by type */ - private static final Comparator<OffsettedItem> TYPE_SORTER = - new Comparator<OffsettedItem>() { - public int compare(OffsettedItem item1, OffsettedItem item2) { - ItemType type1 = item1.itemType(); - ItemType type2 = item2.itemType(); - return type1.compareTo(type2); - } - }; - - /** non-null; the items in this part */ - private final ArrayList<OffsettedItem> items; - - /** non-null; items that have been explicitly interned */ - private final HashMap<OffsettedItem, OffsettedItem> interns; - - /** non-null; how to sort the items */ - private final SortType sort; - - /** - * >= -1; the current size of this part, in bytes, or <code>-1</code> - * if not yet calculated - */ - private int writeSize; - - /** - * Constructs an instance. The file offset is initially unknown. - * - * @param name null-ok; the name of this instance, for annotation - * purposes - * @param file non-null; file that this instance is part of - * @param alignment > 0; alignment requirement for the final output; - * must be a power of 2 - * @param sort how the items should be sorted in the final output - */ - public MixedItemSection(String name, DexFile file, int alignment, - SortType sort) { - super(name, file, alignment); - - this.items = new ArrayList<OffsettedItem>(100); - this.interns = new HashMap<OffsettedItem, OffsettedItem>(100); - this.sort = sort; - this.writeSize = -1; - } - - /** {@inheritDoc} */ - @Override - public Collection<? extends Item> items() { - return items; - } - - /** {@inheritDoc} */ - @Override - public int writeSize() { - throwIfNotPrepared(); - return writeSize; - } - - /** {@inheritDoc} */ - @Override - public int getAbsoluteItemOffset(Item item) { - OffsettedItem oi = (OffsettedItem) item; - return oi.getAbsoluteOffset(); - } - - /** - * Gets the size of this instance, in items. - * - * @return >= 0; the size - */ - public int size() { - return items.size(); - } - - /** - * Writes the portion of the file header that refers to this instance. - * - * @param out non-null; where to write - */ - public void writeHeaderPart(AnnotatedOutput out) { - throwIfNotPrepared(); - - if (writeSize == -1) { - throw new RuntimeException("write size not yet set"); - } - - int sz = writeSize; - int offset = (sz == 0) ? 0 : getFileOffset(); - String name = getName(); - - if (name == null) { - name = "<unnamed>"; - } - - int spaceCount = 15 - name.length(); - char[] spaceArr = new char[spaceCount]; - Arrays.fill(spaceArr, ' '); - String spaces = new String(spaceArr); - - if (out.annotates()) { - out.annotate(4, name + "_size:" + spaces + Hex.u4(sz)); - out.annotate(4, name + "_off: " + spaces + Hex.u4(offset)); - } - - out.writeInt(sz); - out.writeInt(offset); - } - - /** - * Adds an item to this instance. This will in turn tell the given item - * that it has been added to this instance. It is invalid to add the - * same item to more than one instance, nor to add the same items - * multiple times to a single instance. - * - * @param item non-null; the item to add - */ - public void add(OffsettedItem item) { - throwIfPrepared(); - - try { - if (item.getAlignment() > getAlignment()) { - throw new IllegalArgumentException( - "incompatible item alignment"); - } - } catch (NullPointerException ex) { - // Elucidate the exception. - throw new NullPointerException("item == null"); - } - - items.add(item); - } - - /** - * Interns an item in this instance, returning the interned instance - * (which may not be the one passed in). This will add the item if no - * equal item has been added. - * - * @param item non-null; the item to intern - * @return non-null; the equivalent interned instance - */ - public <T extends OffsettedItem> T intern(T item) { - throwIfPrepared(); - - OffsettedItem result = interns.get(item); - - if (result != null) { - return (T) result; - } - - add(item); - interns.put(item, item); - return item; - } - - /** - * Gets an item which was previously interned. - * - * @param item non-null; the item to look for - * @return non-null; the equivalent already-interned instance - */ - public <T extends OffsettedItem> T get(T item) { - throwIfNotPrepared(); - - OffsettedItem result = interns.get(item); - - if (result != null) { - return (T) result; - } - - throw new NoSuchElementException(item.toString()); - } - - /** - * Writes an index of contents of the items in this instance of the - * given type. If there are none, this writes nothing. If there are any, - * then the index is preceded by the given intro string. - * - * @param out non-null; where to write to - * @param itemType non-null; the item type of interest - * @param intro non-null; the introductory string for non-empty indices - */ - public void writeIndexAnnotation(AnnotatedOutput out, ItemType itemType, - String intro) { - throwIfNotPrepared(); - - TreeMap<String, OffsettedItem> index = - new TreeMap<String, OffsettedItem>(); - - for (OffsettedItem item : items) { - if (item.itemType() == itemType) { - String label = item.toHuman(); - index.put(label, item); - } - } - - if (index.size() == 0) { - return; - } - - out.annotate(0, intro); - - for (Map.Entry<String, OffsettedItem> entry : index.entrySet()) { - String label = entry.getKey(); - OffsettedItem item = entry.getValue(); - out.annotate(0, item.offsetString() + ' ' + label + '\n'); - } - } - - /** {@inheritDoc} */ - @Override - protected void prepare0() { - DexFile file = getFile(); - - /* - * It's okay for new items to be added as a result of an - * addContents() call; we just have to deal with the possibility. - */ - - int i = 0; - for (;;) { - int sz = items.size(); - if (i >= sz) { - break; - } - - for (/*i*/; i < sz; i++) { - OffsettedItem one = items.get(i); - one.addContents(file); - } - } - } - - /** - * Places all the items in this instance at particular offsets. This - * will call {@link OffsettedItem#place} on each item. If an item - * does not know its write size before the call to <code>place</code>, - * it is that call which is responsible for setting the write size. - * This method may only be called once per instance; subsequent calls - * will throw an exception. - */ - public void placeItems() { - throwIfNotPrepared(); - - switch (sort) { - case INSTANCE: { - Collections.sort(items); - break; - } - case TYPE: { - Collections.sort(items, TYPE_SORTER); - break; - } - } - - int sz = items.size(); - int outAt = 0; - for (int i = 0; i < sz; i++) { - OffsettedItem one = items.get(i); - try { - int placedAt = one.place(this, outAt); - - if (placedAt < outAt) { - throw new RuntimeException("bogus place() result for " + - one); - } - - outAt = placedAt + one.writeSize(); - } catch (RuntimeException ex) { - throw ExceptionWithContext.withContext(ex, - "...while placing " + one); - } - } - - writeSize = outAt; - } - - /** {@inheritDoc} */ - @Override - protected void writeTo0(AnnotatedOutput out) { - boolean annotates = out.annotates(); - boolean first = true; - DexFile file = getFile(); - int at = 0; - - for (OffsettedItem one : items) { - if (annotates) { - if (first) { - first = false; - } else { - out.annotate(0, "\n"); - } - } - - int alignMask = one.getAlignment() - 1; - int writeAt = (at + alignMask) & ~alignMask; - - if (at != writeAt) { - out.writeZeroes(writeAt - at); - at = writeAt; - } - - one.writeTo(file, out); - at += one.writeSize(); - } - - if (at != writeSize) { - throw new RuntimeException("output size mismatch"); - } - } -} |