• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012, Google Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 package org.jf.dexlib2.dexbacked;
33 
34 import org.jf.dexlib2.base.reference.BaseFieldReference;
35 import org.jf.dexlib2.dexbacked.raw.FieldIdItem;
36 import org.jf.dexlib2.dexbacked.util.AnnotationsDirectory;
37 import org.jf.dexlib2.dexbacked.util.StaticInitialValueIterator;
38 import org.jf.dexlib2.iface.ClassDef;
39 import org.jf.dexlib2.iface.Field;
40 import org.jf.dexlib2.iface.value.EncodedValue;
41 
42 import javax.annotation.Nonnull;
43 import javax.annotation.Nullable;
44 import java.util.Set;
45 
46 public class DexBackedField extends BaseFieldReference implements Field {
47     @Nonnull public final DexBackedDexFile dexFile;
48     @Nonnull public final ClassDef classDef;
49 
50     public final int accessFlags;
51     @Nullable public final EncodedValue initialValue;
52     public final int annotationSetOffset;
53 
54     public final int fieldIndex;
55 
56     private int fieldIdItemOffset;
57 
DexBackedField(@onnull DexReader reader, @Nonnull DexBackedClassDef classDef, int previousFieldIndex, @Nonnull StaticInitialValueIterator staticInitialValueIterator, @Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator)58     public DexBackedField(@Nonnull DexReader reader,
59                           @Nonnull DexBackedClassDef classDef,
60                           int previousFieldIndex,
61                           @Nonnull StaticInitialValueIterator staticInitialValueIterator,
62                           @Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator) {
63         this.dexFile = reader.dexBuf;
64         this.classDef = classDef;
65 
66         // large values may be used for the index delta, which cause the cumulative index to overflow upon
67         // addition, effectively allowing out of order entries.
68         int fieldIndexDiff = reader.readLargeUleb128();
69         this.fieldIndex = fieldIndexDiff + previousFieldIndex;
70         this.accessFlags = reader.readSmallUleb128();
71 
72         this.annotationSetOffset = annotationIterator.seekTo(fieldIndex);
73         this.initialValue = staticInitialValueIterator.getNextOrNull();
74     }
75 
DexBackedField(@onnull DexReader reader, @Nonnull DexBackedClassDef classDef, int previousFieldIndex, @Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator)76     public DexBackedField(@Nonnull DexReader reader,
77                           @Nonnull DexBackedClassDef classDef,
78                           int previousFieldIndex,
79                           @Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator) {
80         this.dexFile = reader.dexBuf;
81         this.classDef = classDef;
82 
83         // large values may be used for the index delta, which cause the cumulative index to overflow upon
84         // addition, effectively allowing out of order entries.
85         int fieldIndexDiff = reader.readLargeUleb128();
86         this.fieldIndex = fieldIndexDiff + previousFieldIndex;
87         this.accessFlags = reader.readSmallUleb128();
88 
89         this.annotationSetOffset = annotationIterator.seekTo(fieldIndex);
90         this.initialValue = null;
91     }
92 
93     @Nonnull
94     @Override
getName()95     public String getName() {
96         return dexFile.getString(dexFile.readSmallUint(getFieldIdItemOffset() + FieldIdItem.NAME_OFFSET));
97     }
98 
99     @Nonnull
100     @Override
getType()101     public String getType() {
102         return dexFile.getType(dexFile.readUshort(getFieldIdItemOffset() + FieldIdItem.TYPE_OFFSET));
103     }
104 
getDefiningClass()105     @Nonnull @Override public String getDefiningClass() { return classDef.getType(); }
getAccessFlags()106     @Override public int getAccessFlags() { return accessFlags; }
getInitialValue()107     @Nullable @Override public EncodedValue getInitialValue() { return initialValue; }
108 
109     @Nonnull
110     @Override
getAnnotations()111     public Set<? extends DexBackedAnnotation> getAnnotations() {
112         return AnnotationsDirectory.getAnnotations(dexFile, annotationSetOffset);
113     }
114 
115     /**
116      * Skips the reader over the specified number of encoded_field structures
117      *
118      * @param reader The reader to skip
119      * @param count The number of encoded_field structures to skip over
120      */
skipFields(@onnull DexReader reader, int count)121     public static void skipFields(@Nonnull DexReader reader, int count) {
122         for (int i=0; i<count; i++) {
123             reader.skipUleb128();
124             reader.skipUleb128();
125         }
126     }
127 
getFieldIdItemOffset()128     private int getFieldIdItemOffset() {
129         if (fieldIdItemOffset == 0) {
130             fieldIdItemOffset = dexFile.getFieldIdItemOffset(fieldIndex);
131         }
132         return fieldIdItemOffset;
133     }
134 }
135