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.dx.dex.file;
     18 
     19 import com.android.dex.Leb128;
     20 import com.android.dx.rop.code.AccessFlags;
     21 import com.android.dx.rop.cst.CstFieldRef;
     22 import com.android.dx.rop.cst.CstString;
     23 import com.android.dx.util.AnnotatedOutput;
     24 import com.android.dx.util.Hex;
     25 import java.io.PrintWriter;
     26 
     27 /**
     28  * Representation of a field of a class, of any sort.
     29  */
     30 public final class EncodedField extends EncodedMember
     31         implements Comparable<EncodedField> {
     32     /** {@code non-null;} constant for the field */
     33     private final CstFieldRef field;
     34 
     35     /**
     36      * Constructs an instance.
     37      *
     38      * @param field {@code non-null;} constant for the field
     39      * @param accessFlags access flags
     40      */
     41     public EncodedField(CstFieldRef field, int accessFlags) {
     42         super(accessFlags);
     43 
     44         if (field == null) {
     45             throw new NullPointerException("field == null");
     46         }
     47 
     48         /*
     49          * TODO: Maybe check accessFlags, at least for
     50          * easily-checked stuff?
     51          */
     52 
     53         this.field = field;
     54     }
     55 
     56     /** {@inheritDoc} */
     57     @Override
     58     public int hashCode() {
     59         return field.hashCode();
     60     }
     61 
     62     /** {@inheritDoc} */
     63     @Override
     64     public boolean equals(Object other) {
     65         if (! (other instanceof EncodedField)) {
     66             return false;
     67         }
     68 
     69         return compareTo((EncodedField) other) == 0;
     70     }
     71 
     72     /**
     73      * {@inheritDoc}
     74      *
     75      * <p><b>Note:</b> This compares the method constants only,
     76      * ignoring any associated code, because it should never be the
     77      * case that two different items with the same method constant
     78      * ever appear in the same list (or same file, even).</p>
     79      */
     80     @Override
     81     public int compareTo(EncodedField other) {
     82         return field.compareTo(other.field);
     83     }
     84 
     85     /** {@inheritDoc} */
     86     @Override
     87     public String toString() {
     88         StringBuilder sb = new StringBuilder(100);
     89 
     90         sb.append(getClass().getName());
     91         sb.append('{');
     92         sb.append(Hex.u2(getAccessFlags()));
     93         sb.append(' ');
     94         sb.append(field);
     95         sb.append('}');
     96         return sb.toString();
     97     }
     98 
     99     /** {@inheritDoc} */
    100     @Override
    101     public void addContents(DexFile file) {
    102         FieldIdsSection fieldIds = file.getFieldIds();
    103         fieldIds.intern(field);
    104     }
    105 
    106     /** {@inheritDoc} */
    107     @Override
    108     public CstString getName() {
    109         return field.getNat().getName();
    110     }
    111 
    112     /** {@inheritDoc} */
    113     @Override
    114     public String toHuman() {
    115         return field.toHuman();
    116     }
    117 
    118     /** {@inheritDoc} */
    119     @Override
    120     public void debugPrint(PrintWriter out, boolean verbose) {
    121         // TODO: Maybe put something better here?
    122         out.println(toString());
    123     }
    124 
    125     /**
    126      * Gets the constant for the field.
    127      *
    128      * @return {@code non-null;} the constant
    129      */
    130     public CstFieldRef getRef() {
    131         return field;
    132     }
    133 
    134     /** {@inheritDoc} */
    135     @Override
    136     public int encode(DexFile file, AnnotatedOutput out,
    137             int lastIndex, int dumpSeq) {
    138         int fieldIdx = file.getFieldIds().indexOf(field);
    139         int diff = fieldIdx - lastIndex;
    140         int accessFlags = getAccessFlags();
    141 
    142         if (out.annotates()) {
    143             out.annotate(0, String.format("  [%x] %s", dumpSeq,
    144                             field.toHuman()));
    145             out.annotate(Leb128.unsignedLeb128Size(diff),
    146                     "    field_idx:    " + Hex.u4(fieldIdx));
    147             out.annotate(Leb128.unsignedLeb128Size(accessFlags),
    148                     "    access_flags: " +
    149                     AccessFlags.fieldString(accessFlags));
    150         }
    151 
    152         out.writeUleb128(diff);
    153         out.writeUleb128(accessFlags);
    154 
    155         return fieldIdx;
    156     }
    157 }
    158