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