Home | History | Annotate | Download | only in file
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.dexgen.dex.file;
     18 
     19 import com.android.dexgen.rop.cst.Constant;
     20 import com.android.dexgen.util.AnnotatedOutput;
     21 
     22 import java.util.Collection;
     23 
     24 /**
     25  * A section of a {@code .dex} file which consists of a sequence of
     26  * {@link Item} objects. Each of the items must have the same size in
     27  * the output.
     28  */
     29 public abstract class UniformItemSection extends Section {
     30     /**
     31      * Constructs an instance. The file offset is initially unknown.
     32      *
     33      * @param name {@code null-ok;} the name of this instance, for annotation
     34      * purposes
     35      * @param file {@code non-null;} file that this instance is part of
     36      * @param alignment {@code > 0;} alignment requirement for the final output;
     37      * must be a power of 2
     38      */
     39     public UniformItemSection(String name, DexFile file, int alignment) {
     40         super(name, file, alignment);
     41     }
     42 
     43     /** {@inheritDoc} */
     44     @Override
     45     public final int writeSize() {
     46         Collection<? extends Item> items = items();
     47         int sz = items.size();
     48 
     49         if (sz == 0) {
     50             return 0;
     51         }
     52 
     53         // Since each item has to be the same size, we can pick any.
     54         return sz * items.iterator().next().writeSize();
     55     }
     56 
     57     /**
     58      * Gets the item corresponding to the given {@link Constant}. This
     59      * will throw an exception if the constant is not found, including
     60      * if this instance isn't the sort that maps constants to {@link
     61      * IndexedItem} instances.
     62      *
     63      * @param cst {@code non-null;} constant to look for
     64      * @return {@code non-null;} the corresponding item found in this instance
     65      */
     66     public abstract IndexedItem get(Constant cst);
     67 
     68     /** {@inheritDoc} */
     69     @Override
     70     protected final void prepare0() {
     71         DexFile file = getFile();
     72 
     73         orderItems();
     74 
     75         for (Item one : items()) {
     76             one.addContents(file);
     77         }
     78     }
     79 
     80     /** {@inheritDoc} */
     81     @Override
     82     protected final void writeTo0(AnnotatedOutput out) {
     83         DexFile file = getFile();
     84         int alignment = getAlignment();
     85 
     86         for (Item one : items()) {
     87             one.writeTo(file, out);
     88             out.alignTo(alignment);
     89         }
     90     }
     91 
     92     /** {@inheritDoc} */
     93     @Override
     94     public final int getAbsoluteItemOffset(Item item) {
     95         /*
     96          * Since all items must be the same size, we can use the size
     97          * of the one we're given to calculate its offset.
     98          */
     99         IndexedItem ii = (IndexedItem) item;
    100         int relativeOffset = ii.getIndex() * ii.writeSize();
    101 
    102         return getAbsoluteOffset(relativeOffset);
    103     }
    104 
    105     /**
    106      * Alters or picks the order for items in this instance if desired,
    107      * so that subsequent calls to {@link #items} will yield a
    108      * so-ordered collection. If the items in this instance are indexed,
    109      * then this method should also assign indices.
    110      */
    111     protected abstract void orderItems();
    112 }
    113