1 /*
2  * Copyright (C) 2009 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 dex.reader;
18 
19 import dex.reader.DexClassImpl.FieldAnnotation;
20 import dex.reader.DexFileReader.FieldIdItem;
21 import dex.structure.DexAnnotation;
22 import dex.structure.DexClass;
23 import dex.structure.DexField;
24 
25 import java.lang.reflect.Modifier;
26 import java.util.HashSet;
27 import java.util.Set;
28 
29 /* package */final class DexFieldImpl implements DexField {
30 
31     private DexBuffer buffer;
32     private String[] stringPool;
33     private FieldIdItem fieldIdItem;
34     private int[] typeIds;
35     private final int accessFlags;
36     private Set<DexAnnotation> annotations;
37     private FieldAnnotation fieldAnnotation;
38     private TypeFormatter formatter = new TypeFormatter();
39     private final DexClass declaringClass;
40     private final FieldIdItem[] fieldIdItems;
41 
DexFieldImpl(DexBuffer buffer, DexClass declaringClass, FieldIdItem fieldIdItem, int accessFlags, FieldAnnotation fieldAnnotation, String[] stringPool, int[] typeIds, FieldIdItem[] fieldIdItems)42     public DexFieldImpl(DexBuffer buffer, DexClass declaringClass,
43             FieldIdItem fieldIdItem, int accessFlags,
44             FieldAnnotation fieldAnnotation, String[] stringPool,
45             int[] typeIds, FieldIdItem[] fieldIdItems) {
46         this.buffer = buffer;
47         this.declaringClass = declaringClass;
48         this.fieldIdItem = fieldIdItem;
49         this.accessFlags = accessFlags;
50         this.fieldAnnotation = fieldAnnotation;
51         this.stringPool = stringPool;
52         this.typeIds = typeIds;
53         this.fieldIdItems = fieldIdItems;
54         parseAnnotations();
55     }
56 
parseAnnotations()57     private void parseAnnotations() {
58         annotations = new HashSet<DexAnnotation>();
59         if (fieldAnnotation != null) {
60             buffer.setPosition(fieldAnnotation.annotationsOff);
61             final int size = buffer.readUInt();
62             for (int i = 0; i < size; i++) {
63                 annotations.add(new DexAnnotationImpl(buffer.createCopy(),
64                         buffer.readUInt(), typeIds, stringPool, fieldIdItems));
65             }
66         }
67     }
68 
getName()69     public String getName() {
70         return stringPool[fieldIdItem.name_idx];
71     }
72 
getType()73     public String getType() {
74         return stringPool[typeIds[fieldIdItem.type_idx]];
75     }
76 
getModifiers()77     public int getModifiers() {
78         return accessFlags;
79     }
80 
getAnnotations()81     public synchronized Set<DexAnnotation> getAnnotations() {
82         return annotations;
83     }
84 
getDeclaringClass()85     public DexClass getDeclaringClass() {
86         return declaringClass;
87     }
88 
isEnumConstant()89     public boolean isEnumConstant() {
90         return (getModifiers() & 0x4000) > 0;
91     }
92 
93     @Override
toString()94     public String toString() {
95         StringBuilder builder = new StringBuilder();
96         builder.append(formatter.formatAnnotations(getAnnotations()));
97         builder.append(Modifier.toString(getModifiers()));
98         builder.append(" ");
99         builder.append(formatter.format(getType()));
100         builder.append(" ");
101         builder.append(getName());
102         return builder.toString();
103     }
104 }
105