Home | History | Annotate | Download | only in file
      1 /*
      2  * Copyright (C) 2008 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.dx.dex.file;
     18 
     19 import com.android.dx.rop.cst.CstArray;
     20 import com.android.dx.util.ByteArrayAnnotatedOutput;
     21 import com.android.dx.util.AnnotatedOutput;
     22 
     23 /**
     24  * Encoded array of constant values.
     25  */
     26 public final class EncodedArrayItem extends OffsettedItem {
     27     /** the required alignment for instances of this class */
     28     private static final int ALIGNMENT = 1;
     29 
     30     /** {@code non-null;} the array to represent */
     31     private final CstArray array;
     32 
     33     /**
     34      * {@code null-ok;} encoded form, ready for writing to a file; set during
     35      * {@link #place0}
     36      */
     37     private byte[] encodedForm;
     38 
     39     /**
     40      * Constructs an instance.
     41      *
     42      * @param array {@code non-null;} array to represent
     43      */
     44     public EncodedArrayItem(CstArray array) {
     45         /*
     46          * The write size isn't known up-front because (the variable-lengthed)
     47          * leb128 type is used to represent some things.
     48          */
     49         super(ALIGNMENT, -1);
     50 
     51         if (array == null) {
     52             throw new NullPointerException("array == null");
     53         }
     54 
     55         this.array = array;
     56         this.encodedForm = null;
     57     }
     58 
     59     /** {@inheritDoc} */
     60     @Override
     61     public ItemType itemType() {
     62         return ItemType.TYPE_ENCODED_ARRAY_ITEM;
     63     }
     64 
     65     /** {@inheritDoc} */
     66     @Override
     67     public int hashCode() {
     68         return array.hashCode();
     69     }
     70 
     71     /** {@inheritDoc} */
     72     @Override
     73     protected int compareTo0(OffsettedItem other) {
     74         EncodedArrayItem otherArray = (EncodedArrayItem) other;
     75 
     76         return array.compareTo(otherArray.array);
     77     }
     78 
     79     /** {@inheritDoc} */
     80     @Override
     81     public String toHuman() {
     82         return array.toHuman();
     83     }
     84 
     85     /** {@inheritDoc} */
     86     public void addContents(DexFile file) {
     87         ValueEncoder.addContents(file, array);
     88     }
     89 
     90     /** {@inheritDoc} */
     91     @Override
     92     protected void place0(Section addedTo, int offset) {
     93         // Encode the data and note the size.
     94 
     95         ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();
     96         ValueEncoder encoder = new ValueEncoder(addedTo.getFile(), out);
     97 
     98         encoder.writeArray(array, false);
     99         encodedForm = out.toByteArray();
    100         setWriteSize(encodedForm.length);
    101     }
    102 
    103     /** {@inheritDoc} */
    104     @Override
    105     protected void writeTo0(DexFile file, AnnotatedOutput out) {
    106         boolean annotates = out.annotates();
    107 
    108         if (annotates) {
    109             out.annotate(0, offsetString() + " encoded array");
    110 
    111             /*
    112              * The output is to be annotated, so redo the work previously
    113              * done by place0(), except this time annotations will actually
    114              * get emitted.
    115              */
    116             ValueEncoder encoder = new ValueEncoder(file, out);
    117             encoder.writeArray(array, true);
    118         } else {
    119             out.write(encodedForm);
    120         }
    121     }
    122 }
    123