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 3422c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruverimport com.google.common.collect.ImmutableSet; 350a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruverimport com.google.common.collect.Iterables; 36f81150ad43efac4d590f6b7ea1425896b7ffb011Ben Gruverimport org.jf.dexlib2.base.reference.BaseTypeReference; 37e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruverimport org.jf.dexlib2.dexbacked.raw.ClassDefItem; 3822c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruverimport org.jf.dexlib2.dexbacked.util.AnnotationsDirectory; 3922c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruverimport org.jf.dexlib2.dexbacked.util.FixedSizeSet; 4022c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruverimport org.jf.dexlib2.dexbacked.util.StaticInitialValueIterator; 410a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruverimport org.jf.dexlib2.dexbacked.util.VariableSizeLookaheadIterator; 42be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport org.jf.dexlib2.iface.ClassDef; 430a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruverimport org.jf.dexlib2.iface.reference.FieldReference; 440a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruverimport org.jf.dexlib2.iface.reference.MethodReference; 450a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruverimport org.jf.dexlib2.immutable.reference.ImmutableFieldReference; 460a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruverimport org.jf.dexlib2.immutable.reference.ImmutableMethodReference; 47be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 48be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport javax.annotation.Nonnull; 49be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport javax.annotation.Nullable; 5012b970ed4dfad768002335503e49c348ea0ed69bBen Gruverimport java.util.Iterator; 5122c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruverimport java.util.Set; 52be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 53f81150ad43efac4d590f6b7ea1425896b7ffb011Ben Gruverpublic class DexBackedClassDef extends BaseTypeReference implements ClassDef { 5484c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver @Nonnull public final DexBackedDexFile dexFile; 55d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver private final int classDefOffset; 56be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 570a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private final int staticFieldsOffset; 580a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int instanceFieldsOffset = 0; 590a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int directMethodsOffset = 0; 600a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int virtualMethodsOffset = 0; 610a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 620a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private final int staticFieldCount; 630a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private final int instanceFieldCount; 640a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private final int directMethodCount; 650a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private final int virtualMethodCount; 66be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 67d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver @Nullable private AnnotationsDirectory annotationsDirectory; 68be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 6984c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver public DexBackedClassDef(@Nonnull DexBackedDexFile dexFile, 70be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver int classDefOffset) { 7184c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver this.dexFile = dexFile; 72d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver this.classDefOffset = classDefOffset; 730a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 74d8d16fd84428b0c420a7cc2e0f0862be3cbd0f47Ben Gruver int classDataOffset = dexFile.readSmallUint(classDefOffset + ClassDefItem.CLASS_DATA_OFFSET); 750a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (classDataOffset == 0) { 760a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver staticFieldsOffset = -1; 770a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver staticFieldCount = 0; 780a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver instanceFieldCount = 0; 790a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver directMethodCount = 0; 800a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver virtualMethodCount = 0; 810a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } else { 820a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver DexReader reader = dexFile.readerAt(classDataOffset); 830a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver staticFieldCount = reader.readSmallUleb128(); 840a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver instanceFieldCount = reader.readSmallUleb128(); 850a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver directMethodCount = reader.readSmallUleb128(); 860a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver virtualMethodCount = reader.readSmallUleb128(); 870a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver staticFieldsOffset = reader.getOffset(); 880a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 890a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 90d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver } 91be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 92d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver @Nonnull 93d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver @Override 94db389aa3a1d898d3a452f3f0b2220b334b23cb4cBen Gruver public String getType() { 95e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver return dexFile.getType(dexFile.readSmallUint(classDefOffset + ClassDefItem.CLASS_OFFSET)); 96d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver } 97be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 98d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver @Nullable 99d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver @Override 100d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver public String getSuperclass() { 101e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver return dexFile.getOptionalType(dexFile.readOptionalUint(classDefOffset + ClassDefItem.SUPERCLASS_OFFSET)); 102be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 103be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 104d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver @Override 105d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver public int getAccessFlags() { 106e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver return dexFile.readSmallUint(classDefOffset + ClassDefItem.ACCESS_FLAGS_OFFSET); 107d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver } 108be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 109d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver @Nullable 110d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver @Override 111d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver public String getSourceFile() { 112e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver return dexFile.getOptionalString(dexFile.readOptionalUint(classDefOffset + ClassDefItem.SOURCE_FILE_OFFSET)); 113d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver } 114be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 115be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver @Nonnull 116be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver @Override 11722c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver public Set<String> getInterfaces() { 118e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver final int interfacesOffset = dexFile.readSmallUint(classDefOffset + ClassDefItem.INTERFACES_OFFSET); 119be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver if (interfacesOffset > 0) { 12084c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver final int size = dexFile.readSmallUint(interfacesOffset); 12122c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver return new FixedSizeSet<String>() { 12225d385a441b95d56987c81f00f19297d799e1b31Ben Gruver @Nonnull 123be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver @Override 124be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver public String readItem(int index) { 12584c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver return dexFile.getType(dexFile.readUshort(interfacesOffset + 4 + (2*index))); 126be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 127be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 128be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver @Override public int size() { return size; } 129be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver }; 130be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 13122c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver return ImmutableSet.of(); 132be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 133be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 134be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver @Nonnull 135be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver @Override 13622c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver public Set<? extends DexBackedAnnotation> getAnnotations() { 137d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver return getAnnotationsDirectory().getClassAnnotations(); 138be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 139be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 140be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver @Nonnull 141be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver @Override 1420a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver public Iterable<? extends DexBackedField> getStaticFields() { 1438979759556f31af324257fec9ebd47d3444cede0Ben Gruver return getStaticFields(true); 1448979759556f31af324257fec9ebd47d3444cede0Ben Gruver } 1458979759556f31af324257fec9ebd47d3444cede0Ben Gruver 1468979759556f31af324257fec9ebd47d3444cede0Ben Gruver @Nonnull 1478979759556f31af324257fec9ebd47d3444cede0Ben Gruver public Iterable<? extends DexBackedField> getStaticFields(final boolean skipDuplicates) { 1480a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (staticFieldCount > 0) { 1490a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver DexReader reader = dexFile.readerAt(staticFieldsOffset); 1500a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 1510a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory(); 1520a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver final int staticInitialValuesOffset = 1530a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver dexFile.readSmallUint(classDefOffset + ClassDefItem.STATIC_VALUES_OFFSET); 1540a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver final int fieldsStartOffset = reader.getOffset(); 1550a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 1560a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return new Iterable<DexBackedField>() { 1570a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nonnull 1580a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Override 1590a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver public Iterator<DexBackedField> iterator() { 160902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver final AnnotationsDirectory.AnnotationIterator annotationIterator = 161902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver annotationsDirectory.getFieldAnnotationIterator(); 162902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver final StaticInitialValueIterator staticInitialValueIterator = 163902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver StaticInitialValueIterator.newOrEmpty(dexFile, staticInitialValuesOffset); 164902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver 1650a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return new VariableSizeLookaheadIterator<DexBackedField>(dexFile, fieldsStartOffset) { 1660a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int count; 1670a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nullable private FieldReference previousField; 1680a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int previousIndex; 1690a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 1700a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nullable 1710a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Override 1720a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver protected DexBackedField readNextItem(@Nonnull DexReader reader) { 1730a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver while (true) { 1740a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (++count > staticFieldCount) { 1750a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver instanceFieldsOffset = reader.getOffset(); 1760a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return null; 17787179940cbe7b0570f2fbdd9bc0b218e3535bcf7Ben Gruver } 1780a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 179a8e05220c14778d93c97911044ff5124aadbd77cBen Gruver DexBackedField item = new DexBackedField(reader, DexBackedClassDef.this, 1800a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver previousIndex, staticInitialValueIterator, annotationIterator); 1810a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver FieldReference currentField = previousField; 1820a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver FieldReference nextField = ImmutableFieldReference.of(item); 1830a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 1840a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver previousField = nextField; 1850a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver previousIndex = item.fieldIndex; 1860a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 1878979759556f31af324257fec9ebd47d3444cede0Ben Gruver if (skipDuplicates && currentField != null && currentField.equals(nextField)) { 1880a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver continue; 1890a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 1900a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 191be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver return item; 192be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 1930a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 1940a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver }; 1950a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 1960a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver }; 1970a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } else { 1980a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver instanceFieldsOffset = staticFieldsOffset; 1990a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return ImmutableSet.of(); 2000a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 2010a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 202be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 2030a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nonnull 2040a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Override 2050a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver public Iterable<? extends DexBackedField> getInstanceFields() { 2068979759556f31af324257fec9ebd47d3444cede0Ben Gruver return getInstanceFields(true); 2078979759556f31af324257fec9ebd47d3444cede0Ben Gruver } 2088979759556f31af324257fec9ebd47d3444cede0Ben Gruver 2098979759556f31af324257fec9ebd47d3444cede0Ben Gruver @Nonnull 2108979759556f31af324257fec9ebd47d3444cede0Ben Gruver public Iterable<? extends DexBackedField> getInstanceFields(final boolean skipDuplicates) { 2110a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (instanceFieldCount > 0) { 2120a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver DexReader reader = dexFile.readerAt(getInstanceFieldsOffset()); 2130a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 2140a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory(); 2150a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver final int fieldsStartOffset = reader.getOffset(); 2160a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 2170a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return new Iterable<DexBackedField>() { 2180a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nonnull 2190a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Override 2200a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver public Iterator<DexBackedField> iterator() { 221902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver final AnnotationsDirectory.AnnotationIterator annotationIterator = 222902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver annotationsDirectory.getFieldAnnotationIterator(); 223902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver 2240a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return new VariableSizeLookaheadIterator<DexBackedField>(dexFile, fieldsStartOffset) { 2250a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int count; 2260a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nullable private FieldReference previousField; 2270a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int previousIndex; 2280a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 2290a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nullable 2300a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Override 2310a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver protected DexBackedField readNextItem(@Nonnull DexReader reader) { 2320a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver while (true) { 2330a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (++count > instanceFieldCount) { 2340a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver directMethodsOffset = reader.getOffset(); 2350a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return null; 2360a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 2370a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 2380a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver DexBackedField item = new DexBackedField(reader, DexBackedClassDef.this, 2390a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver previousIndex, annotationIterator); 2400a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver FieldReference currentField = previousField; 2410a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver FieldReference nextField = ImmutableFieldReference.of(item); 2420a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 2430a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver previousField = nextField; 2440a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver previousIndex = item.fieldIndex; 2450a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 2468979759556f31af324257fec9ebd47d3444cede0Ben Gruver if (skipDuplicates && currentField != null && currentField.equals(nextField)) { 2470a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver continue; 2480a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 2490a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 2500a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return item; 2510a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 2520a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 2530a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver }; 2540a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 2550a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver }; 2560a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } else { 2570a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (instanceFieldsOffset > 0) { 2580a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver directMethodsOffset = instanceFieldsOffset; 259be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 2600a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return ImmutableSet.of(); 261be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 262be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 263be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 264be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver @Nonnull 265be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver @Override 2660a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver public Iterable<? extends DexBackedField> getFields() { 2670a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return Iterables.concat(getStaticFields(), getInstanceFields()); 2680a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 2690a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 2700a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nonnull 2710a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Override 2720a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver public Iterable<? extends DexBackedMethod> getDirectMethods() { 2738979759556f31af324257fec9ebd47d3444cede0Ben Gruver return getDirectMethods(true); 2748979759556f31af324257fec9ebd47d3444cede0Ben Gruver } 2758979759556f31af324257fec9ebd47d3444cede0Ben Gruver 2768979759556f31af324257fec9ebd47d3444cede0Ben Gruver @Nonnull 2778979759556f31af324257fec9ebd47d3444cede0Ben Gruver public Iterable<? extends DexBackedMethod> getDirectMethods(final boolean skipDuplicates) { 2780a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (directMethodCount > 0) { 2790a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver DexReader reader = dexFile.readerAt(getDirectMethodsOffset()); 2800a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 2810a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory(); 2820a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver final int methodsStartOffset = reader.getOffset(); 2830a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 2840a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return new Iterable<DexBackedMethod>() { 2850a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nonnull 2860a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Override 2870a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver public Iterator<DexBackedMethod> iterator() { 288902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver final AnnotationsDirectory.AnnotationIterator methodAnnotationIterator = 289902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver annotationsDirectory.getMethodAnnotationIterator(); 290902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver final AnnotationsDirectory.AnnotationIterator parameterAnnotationIterator = 291902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver annotationsDirectory.getParameterAnnotationIterator(); 292902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver 2930a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return new VariableSizeLookaheadIterator<DexBackedMethod>(dexFile, methodsStartOffset) { 2940a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int count; 2950a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nullable private MethodReference previousMethod; 2960a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int previousIndex; 2970a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 2980a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nullable 2990a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Override 3000a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver protected DexBackedMethod readNextItem(@Nonnull DexReader reader) { 3010a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver while (true) { 3020a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (++count > directMethodCount) { 3030a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver virtualMethodsOffset = reader.getOffset(); 3040a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return null; 30587179940cbe7b0570f2fbdd9bc0b218e3535bcf7Ben Gruver } 3060a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 307269c15688bb2a6bc7331b114ef830d5558af8fa6Ben Gruver DexBackedMethod item = new DexBackedMethod(reader, DexBackedClassDef.this, 3080a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver previousIndex, methodAnnotationIterator, parameterAnnotationIterator); 3090a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver MethodReference currentMethod = previousMethod; 3100a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver MethodReference nextMethod = ImmutableMethodReference.of(item); 3110a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 3120a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver previousMethod = nextMethod; 3130a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver previousIndex = item.methodIndex; 3140a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 3158979759556f31af324257fec9ebd47d3444cede0Ben Gruver if (skipDuplicates && currentMethod != null && currentMethod.equals(nextMethod)) { 3160a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver continue; 3170a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 3180a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 31963d840670311d96aa92c38f1d118ab2d7f590ce3Ben Gruver return item; 32063d840670311d96aa92c38f1d118ab2d7f590ce3Ben Gruver } 3210a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 3220a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver }; 3230a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 3240a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver }; 3250a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } else { 3260a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (directMethodsOffset > 0) { 3270a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver virtualMethodsOffset = directMethodsOffset; 32863d840670311d96aa92c38f1d118ab2d7f590ce3Ben Gruver } 3290a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return ImmutableSet.of(); 33063d840670311d96aa92c38f1d118ab2d7f590ce3Ben Gruver } 331be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 332d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver 3330a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nonnull 3348979759556f31af324257fec9ebd47d3444cede0Ben Gruver public Iterable<? extends DexBackedMethod> getVirtualMethods(final boolean skipDuplicates) { 3350a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (virtualMethodCount > 0) { 3360a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver DexReader reader = dexFile.readerAt(getVirtualMethodsOffset()); 3370a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 3380a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory(); 3390a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver final int methodsStartOffset = reader.getOffset(); 3400a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 3410a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return new Iterable<DexBackedMethod>() { 342902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver final AnnotationsDirectory.AnnotationIterator methodAnnotationIterator = 343902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver annotationsDirectory.getMethodAnnotationIterator(); 344902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver final AnnotationsDirectory.AnnotationIterator parameterAnnotationIterator = 345902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver annotationsDirectory.getParameterAnnotationIterator(); 346902ba7d72d694c93ff48b21181bf94b58131bf05Ben Gruver 3470a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nonnull 3480a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Override 3490a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver public Iterator<DexBackedMethod> iterator() { 3500a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return new VariableSizeLookaheadIterator<DexBackedMethod>(dexFile, methodsStartOffset) { 3510a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int count; 3520a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nullable private MethodReference previousMethod; 3530a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int previousIndex; 3540a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 3550a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nullable 3560a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Override 3570a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver protected DexBackedMethod readNextItem(@Nonnull DexReader reader) { 3580a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver while (true) { 3590a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (++count > virtualMethodCount) { 3600a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return null; 3610a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 3620a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 3630a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver DexBackedMethod item = new DexBackedMethod(reader, DexBackedClassDef.this, 3640a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver previousIndex, methodAnnotationIterator, parameterAnnotationIterator); 3650a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver MethodReference currentMethod = previousMethod; 3660a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver MethodReference nextMethod = ImmutableMethodReference.of(item); 3670a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 3680a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver previousMethod = nextMethod; 3690a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver previousIndex = item.methodIndex; 3700a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 3718979759556f31af324257fec9ebd47d3444cede0Ben Gruver if (skipDuplicates && currentMethod != null && currentMethod.equals(nextMethod)) { 3720a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver continue; 3730a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 3740a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return item; 3750a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 3760a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 3770a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver }; 3780a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 3790a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver }; 3800a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } else { 3810a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return ImmutableSet.of(); 382d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver } 3830a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 3840a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 3850a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Nonnull 3860a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver @Override 3878979759556f31af324257fec9ebd47d3444cede0Ben Gruver public Iterable<? extends DexBackedMethod> getVirtualMethods() { 3888979759556f31af324257fec9ebd47d3444cede0Ben Gruver return getVirtualMethods(true); 3898979759556f31af324257fec9ebd47d3444cede0Ben Gruver } 3908979759556f31af324257fec9ebd47d3444cede0Ben Gruver 3918979759556f31af324257fec9ebd47d3444cede0Ben Gruver @Nonnull 3928979759556f31af324257fec9ebd47d3444cede0Ben Gruver @Override 3930a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver public Iterable<? extends DexBackedMethod> getMethods() { 3940a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return Iterables.concat(getDirectMethods(), getVirtualMethods()); 395d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver } 396d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver 397d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver private AnnotationsDirectory getAnnotationsDirectory() { 398d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver if (annotationsDirectory == null) { 399e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver int annotationsDirectoryOffset = dexFile.readSmallUint(classDefOffset + ClassDefItem.ANNOTATIONS_OFFSET); 40084c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver annotationsDirectory = AnnotationsDirectory.newOrEmpty(dexFile, annotationsDirectoryOffset); 401d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver } 402d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver return annotationsDirectory; 403d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver } 4040a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 4050a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int getInstanceFieldsOffset() { 4060a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (instanceFieldsOffset > 0) { 4070a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return instanceFieldsOffset; 4080a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 4090a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver DexReader reader = new DexReader(dexFile, staticFieldsOffset); 410f939e912b53bccab66013c694442fa2f40d970e1Ben Gruver DexBackedField.skipFields(reader, staticFieldCount); 4110a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver instanceFieldsOffset = reader.getOffset(); 4120a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return instanceFieldsOffset; 4130a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 4140a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 4150a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int getDirectMethodsOffset() { 4160a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (directMethodsOffset > 0) { 4170a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return directMethodsOffset; 4180a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 4190a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver DexReader reader = dexFile.readerAt(getInstanceFieldsOffset()); 420f939e912b53bccab66013c694442fa2f40d970e1Ben Gruver DexBackedField.skipFields(reader, instanceFieldCount); 4210a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver directMethodsOffset = reader.getOffset(); 4220a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return directMethodsOffset; 4230a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 4240a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver 4250a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver private int getVirtualMethodsOffset() { 4260a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver if (virtualMethodsOffset > 0) { 4270a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return virtualMethodsOffset; 4280a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 4290a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver DexReader reader = dexFile.readerAt(getDirectMethodsOffset()); 430f939e912b53bccab66013c694442fa2f40d970e1Ben Gruver DexBackedMethod.skipMethods(reader, directMethodCount); 4310a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver virtualMethodsOffset = reader.getOffset(); 4320a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver return virtualMethodsOffset; 4330a18ea7f8b62e51945a79ac37802133a24c9a742Ben Gruver } 434be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver} 435