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     public int hashCode() {
     58         return field.hashCode();
     59     }
     60 
     61     /** {@inheritDoc} */
     62     public boolean equals(Object other) {
     63         if (! (other instanceof EncodedField)) {
     64             return false;
     65         }
     66 
     67         return compareTo((EncodedField) other) == 0;
     68     }
     69 
     70     /**
     71      * {@inheritDoc}
     72      *
     73      * <p><b>Note:</b> This compares the method constants only,
     74      * ignoring any associated code, because it should never be the
     75      * case that two different items with the same method constant
     76      * ever appear in the same list (or same file, even).</p>
     77      */
     78     public int compareTo(EncodedField other) {
     79         return field.compareTo(other.field);
     80     }
     81 
     82     /** {@inheritDoc} */
     83     @Override
     84     public String toString() {
     85         StringBuffer sb = new StringBuffer(100);
     86 
     87         sb.append(getClass().getName());
     88         sb.append('{');
     89         sb.append(Hex.u2(getAccessFlags()));
     90         sb.append(' ');
     91         sb.append(field);
     92         sb.append('}');
     93         return sb.toString();
     94     }
     95 
     96     /** {@inheritDoc} */
     97     @Override
     98     public void addContents(DexFile file) {
     99         FieldIdsSection fieldIds = file.getFieldIds();
    100         fieldIds.intern(field);
    101     }
    102 
    103     /** {@inheritDoc} */
    104     @Override
    105     public CstString getName() {
    106         return field.getNat().getName();
    107     }
    108 
    109     /** {@inheritDoc} */
    110     public String toHuman() {
    111         return field.toHuman();
    112     }
    113 
    114     /** {@inheritDoc} */
    115     @Override
    116     public void debugPrint(PrintWriter out, boolean verbose) {
    117         // TODO: Maybe put something better here?
    118         out.println(toString());
    119     }
    120 
    121     /**
    122      * Gets the constant for the field.
    123      *
    124      * @return {@code non-null;} the constant
    125      */
    126     public CstFieldRef getRef() {
    127         return field;
    128     }
    129 
    130     /** {@inheritDoc} */
    131     @Override
    132     public int encode(DexFile file, AnnotatedOutput out,
    133             int lastIndex, int dumpSeq) {
    134         int fieldIdx = file.getFieldIds().indexOf(field);
    135         int diff = fieldIdx - lastIndex;
    136         int accessFlags = getAccessFlags();
    137 
    138         if (out.annotates()) {
    139             out.annotate(0, String.format("  [%x] %s", dumpSeq,
    140                             field.toHuman()));
    141             out.annotate(Leb128.unsignedLeb128Size(diff),
    142                     "    field_idx:    " + Hex.u4(fieldIdx));
    143             out.annotate(Leb128.unsignedLeb128Size(accessFlags),
    144                     "    access_flags: " +
    145                     AccessFlags.fieldString(accessFlags));
    146         }
    147 
    148         out.writeUleb128(diff);
    149         out.writeUleb128(accessFlags);
    150 
    151         return fieldIdx;
    152     }
    153 }
    154