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