1be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver/*
2be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * Copyright 2012, Google Inc.
3be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * All rights reserved.
4be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver *
5be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * Redistribution and use in source and binary forms, with or without
6be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * modification, are permitted provided that the following conditions are
7be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * met:
8be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver *
9be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver *     * Redistributions of source code must retain the above copyright
10be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * notice, this list of conditions and the following disclaimer.
11be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver *     * Redistributions in binary form must reproduce the above
12be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * copyright notice, this list of conditions and the following disclaimer
13be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * in the documentation and/or other materials provided with the
14be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * distribution.
15be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver *     * Neither the name of Google Inc. nor the names of its
16be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * contributors may be used to endorse or promote products derived from
17be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * this software without specific prior written permission.
18be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver *
19be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver */
31be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
32be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverpackage org.jf.dexlib2.dexbacked;
33be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
34f81150ad43efac4d590f6b7ea1425896b7ffb011Ben Gruverimport org.jf.dexlib2.base.reference.BaseFieldReference;
35e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruverimport org.jf.dexlib2.dexbacked.raw.FieldIdItem;
36be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport org.jf.dexlib2.dexbacked.util.AnnotationsDirectory;
37be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport org.jf.dexlib2.dexbacked.util.StaticInitialValueIterator;
38a8e05220c14778d93c97911044ff5124aadbd77cBen Gruverimport org.jf.dexlib2.iface.ClassDef;
39be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport org.jf.dexlib2.iface.Field;
407c71ad420dbdfe2e36f205d335a261435181a25bBen Gruverimport org.jf.dexlib2.iface.value.EncodedValue;
41be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
42be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport javax.annotation.Nonnull;
43be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport javax.annotation.Nullable;
4422c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruverimport java.util.Set;
45be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
46f81150ad43efac4d590f6b7ea1425896b7ffb011Ben Gruverpublic class DexBackedField extends BaseFieldReference implements Field {
4784c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver    @Nonnull public final DexBackedDexFile dexFile;
48a8e05220c14778d93c97911044ff5124aadbd77cBen Gruver    @Nonnull public final ClassDef classDef;
49be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
50be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    public final int accessFlags;
517c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver    @Nullable public final EncodedValue initialValue;
52be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    public final int annotationSetOffset;
53be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
54be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    public final int fieldIndex;
55be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
56d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    private int fieldIdItemOffset;
57d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver
5836e2ee200517b36652a6e8fe1c5aa24ce249765eBen Gruver    public DexBackedField(@Nonnull DexReader reader,
59a8e05220c14778d93c97911044ff5124aadbd77cBen Gruver                          @Nonnull DexBackedClassDef classDef,
60be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                          int previousFieldIndex,
61be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                          @Nonnull StaticInitialValueIterator staticInitialValueIterator,
62be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                          @Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator) {
6384c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver        this.dexFile = reader.dexBuf;
64a8e05220c14778d93c97911044ff5124aadbd77cBen Gruver        this.classDef = classDef;
65be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
6645b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver        // large values may be used for the index delta, which cause the cumulative index to overflow upon
6745b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver        // addition, effectively allowing out of order entries.
6845b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver        int fieldIndexDiff = reader.readLargeUleb128();
69be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver        this.fieldIndex = fieldIndexDiff + previousFieldIndex;
7036e2ee200517b36652a6e8fe1c5aa24ce249765eBen Gruver        this.accessFlags = reader.readSmallUleb128();
71be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
72be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver        this.annotationSetOffset = annotationIterator.seekTo(fieldIndex);
73be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver        this.initialValue = staticInitialValueIterator.getNextOrNull();
74d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    }
75be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
760a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver    public DexBackedField(@Nonnull DexReader reader,
770a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver                          @Nonnull DexBackedClassDef classDef,
780a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver                          int previousFieldIndex,
790a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver                          @Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator) {
800a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver        this.dexFile = reader.dexBuf;
810a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver        this.classDef = classDef;
820a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver
8345b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver        // large values may be used for the index delta, which cause the cumulative index to overflow upon
8445b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver        // addition, effectively allowing out of order entries.
8545b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver        int fieldIndexDiff = reader.readLargeUleb128();
860a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver        this.fieldIndex = fieldIndexDiff + previousFieldIndex;
870a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver        this.accessFlags = reader.readSmallUleb128();
880a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver
890a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver        this.annotationSetOffset = annotationIterator.seekTo(fieldIndex);
900a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver        this.initialValue = null;
910a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver    }
920a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver
93d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    @Nonnull
94d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    @Override
95d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    public String getName() {
96e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver        return dexFile.getString(dexFile.readSmallUint(getFieldIdItemOffset() + FieldIdItem.NAME_OFFSET));
97d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    }
98d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver
99d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    @Nonnull
100d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    @Override
101d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    public String getType() {
102e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver        return dexFile.getType(dexFile.readUshort(getFieldIdItemOffset() + FieldIdItem.TYPE_OFFSET));
103be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    }
104be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
10522c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver    @Nonnull @Override public String getDefiningClass() { return classDef.getType(); }
106be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    @Override public int getAccessFlags() { return accessFlags; }
1077c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver    @Nullable @Override public EncodedValue getInitialValue() { return initialValue; }
108be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
109be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    @Nonnull
110be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    @Override
11122c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver    public Set<? extends DexBackedAnnotation> getAnnotations() {
11284c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver        return AnnotationsDirectory.getAnnotations(dexFile, annotationSetOffset);
113be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    }
114be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
115be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    /**
116be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver     * Skips the reader over the specified number of encoded_field structures
117be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver     *
11836e2ee200517b36652a6e8fe1c5aa24ce249765eBen Gruver     * @param reader The reader to skip
119be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver     * @param count The number of encoded_field structures to skip over
120be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver     */
121f939e912b53bccab66013c694442fa2f40d970e1Ben Gruver    public static void skipFields(@Nonnull DexReader reader, int count) {
122be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver        for (int i=0; i<count; i++) {
12336e2ee200517b36652a6e8fe1c5aa24ce249765eBen Gruver            reader.skipUleb128();
12436e2ee200517b36652a6e8fe1c5aa24ce249765eBen Gruver            reader.skipUleb128();
125be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver        }
126be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    }
127d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver
128d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    private int getFieldIdItemOffset() {
129d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver        if (fieldIdItemOffset == 0) {
13084c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver            fieldIdItemOffset = dexFile.getFieldIdItemOffset(fieldIndex);
131d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver        }
132d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver        return fieldIdItemOffset;
133d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    }
134be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver}
135