1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.cf.direct;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodsonimport com.android.dx.cf.attrib.AttBootstrapMethods;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttSourceFile;
21b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodsonimport com.android.dx.cf.code.BootstrapMethodsList;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.cst.ConstantPoolParser;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.Attribute;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.AttributeList;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.ClassFile;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.FieldList;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.MethodList;
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.ParseException;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.ParseObserver;
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.StdAttributeList;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.AccessFlags;
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.ConstantPool;
33333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilsonimport com.android.dx.rop.cst.CstString;
34fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.rop.cst.CstType;
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.StdConstantPool;
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.StdTypeList;
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type;
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeList;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.ByteArray;
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex;
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
4399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Class file with info taken from a {@code byte[]} or slice thereof.
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class DirectClassFile implements ClassFile {
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** the expected value of the ClassFile.magic field */
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int CLASS_FILE_MAGIC = 0xcafebabe;
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
5099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * minimum {@code .class} file major version
51de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
52092412605d5d500456e9fff475c90691e668b914Elliott Hughes     * See http://en.wikipedia.org/wiki/Java_class_file for an up-to-date
53092412605d5d500456e9fff475c90691e668b914Elliott Hughes     * list of version numbers. Currently known (taken from that table) are:
54de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
556988f303309054c572876156e2f46d539419a73dTobias Thierer     *     Java SE 9 = 53 (0x35 hex),
566988f303309054c572876156e2f46d539419a73dTobias Thierer     *     Java SE 8 = 52 (0x34 hex),
576988f303309054c572876156e2f46d539419a73dTobias Thierer     *     Java SE 7 = 51 (0x33 hex),
586988f303309054c572876156e2f46d539419a73dTobias Thierer     *     Java SE 6.0 = 50 (0x32 hex),
596988f303309054c572876156e2f46d539419a73dTobias Thierer     *     Java SE 5.0 = 49 (0x31 hex),
60092412605d5d500456e9fff475c90691e668b914Elliott Hughes     *     JDK 1.4 = 48 (0x30 hex),
61092412605d5d500456e9fff475c90691e668b914Elliott Hughes     *     JDK 1.3 = 47 (0x2F hex),
62092412605d5d500456e9fff475c90691e668b914Elliott Hughes     *     JDK 1.2 = 46 (0x2E hex),
63092412605d5d500456e9fff475c90691e668b914Elliott Hughes     *     JDK 1.1 = 45 (0x2D hex).
64de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Valid ranges are typically of the form
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * "A.0 through B.C inclusive" where A <= B and C >= 0,
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * which is why we don't have a CLASS_FILE_MIN_MINOR_VERSION.
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int CLASS_FILE_MIN_MAJOR_VERSION = 45;
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
71092412605d5d500456e9fff475c90691e668b914Elliott Hughes    /**
72092412605d5d500456e9fff475c90691e668b914Elliott Hughes     * maximum {@code .class} file major version
73092412605d5d500456e9fff475c90691e668b914Elliott Hughes     *
74092412605d5d500456e9fff475c90691e668b914Elliott Hughes     * Note: if you change this, please change "java.class.version" in System.java.
75092412605d5d500456e9fff475c90691e668b914Elliott Hughes     */
766988f303309054c572876156e2f46d539419a73dTobias Thierer    private static final int CLASS_FILE_MAX_MAJOR_VERSION = 53;
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
7899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** maximum {@code .class} file minor version */
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int CLASS_FILE_MAX_MINOR_VERSION = 0;
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
8299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code non-null;} the file path for the class, excluding any base directory
83de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * specification
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final String filePath;
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
8799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} the bytes of the file */
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final ByteArray bytes;
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * whether to be strict about parsing; if
9299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code false}, this avoids doing checks that only exist
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for purposes of verification (such as magic number matching and
94de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * path-package consistency checking)
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final boolean strictParse;
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
9999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the constant pool; only ever {@code null}
100de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * before the constant pool is successfully parsed
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private StdConstantPool pool;
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
10599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * the class file field {@code access_flags}; will be {@code -1}
106de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * before the file is successfully parsed
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int accessFlags;
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
11199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the class file field {@code this_class},
11299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * interpreted as a type constant; only ever {@code null}
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * before the file is successfully parsed
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private CstType thisClass;
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
11899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the class file field {@code super_class}, interpreted
119de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * as a type constant if non-zero
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private CstType superClass;
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
12499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the class file field {@code interfaces}; only
12599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * ever {@code null} before the file is successfully
126de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * parsed
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private TypeList interfaces;
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
13199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the class file field {@code fields}; only ever
132de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * {@code null} before the file is successfully parsed
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private FieldList fields;
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
13799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the class file field {@code methods}; only ever
138de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * {@code null} before the file is successfully parsed
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private MethodList methods;
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
14399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the class file field {@code attributes}; only
14499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * ever {@code null} before the file is successfully
145de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * parsed
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private StdAttributeList attributes;
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
14999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} attribute factory, if any */
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private AttributeFactory attributeFactory;
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
15299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} parse observer, if any */
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private ParseObserver observer;
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
15699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Returns the string form of an object or {@code "(none)"}
15799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * (rather than {@code "null"}) for {@code null}.
158de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
15999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param obj {@code null-ok;} the object to stringify
16099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the appropriate string form
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String stringOrNone(Object obj) {
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (obj == null) {
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "(none)";
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return obj.toString();
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance.
172de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
17399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param bytes {@code non-null;} the bytes of the file
17499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param filePath {@code non-null;} the file path for the class,
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * excluding any base directory specification
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param strictParse whether to be strict about parsing; if
17799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code false}, this avoids doing checks that only exist
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for purposes of verification (such as magic number matching and
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * path-package consistency checking)
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public DirectClassFile(ByteArray bytes, String filePath,
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                           boolean strictParse) {
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (bytes == null) {
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("bytes == null");
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (filePath == null) {
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("filePath == null");
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.filePath = filePath;
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.bytes = bytes;
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.strictParse = strictParse;
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.accessFlags = -1;
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance.
199de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
20099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param bytes {@code non-null;} the bytes of the file
20199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param filePath {@code non-null;} the file path for the class,
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * excluding any base directory specification
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param strictParse whether to be strict about parsing; if
20499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code false}, this avoids doing checks that only exist
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for purposes of verification (such as magic number matching and
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * path-package consistency checking)
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public DirectClassFile(byte[] bytes, String filePath,
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                           boolean strictParse) {
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this(new ByteArray(bytes), filePath, strictParse);
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the parse observer for this instance.
215de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
21699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param observer {@code null-ok;} the observer
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setObserver(ParseObserver observer) {
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.observer = observer;
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the attribute factory to use.
224de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
22599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param attributeFactory {@code non-null;} the attribute factory
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setAttributeFactory(AttributeFactory attributeFactory) {
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (attributeFactory == null) {
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("attributeFactory == null");
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.attributeFactory = attributeFactory;
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
2364c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche     * Gets the path where this class file is located.
2374c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche     *
2384c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche     * @return {@code non-null;} the filePath
2394c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche     */
2404c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche    public String getFilePath() {
2414c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche      return filePath;
2424c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche    }
2434c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche
2444c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche    /**
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the {@link ByteArray} that this instance's data comes from.
246de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
24799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the bytes
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ByteArray getBytes() {
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return bytes;
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
2549dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson    @Override
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMagic() {
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getMagic0();
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
2619dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson    @Override
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMinorVersion() {
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getMinorVersion0();
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
2689dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson    @Override
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMajorVersion() {
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getMajorVersion0();
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
2759dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson    @Override
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getAccessFlags() {
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return accessFlags;
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
2829dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson    @Override
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public CstType getThisClass() {
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return thisClass;
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
2899dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson    @Override
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public CstType getSuperclass() {
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return superClass;
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
2969dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson    @Override
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ConstantPool getConstantPool() {
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return pool;
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
3039dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson    @Override
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public TypeList getInterfaces() {
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return interfaces;
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
3109dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson    @Override
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public FieldList getFields() {
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToEndIfNecessary();
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return fields;
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
3179dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson    @Override
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public MethodList getMethods() {
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToEndIfNecessary();
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return methods;
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
3249dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson    @Override
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public AttributeList getAttributes() {
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToEndIfNecessary();
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return attributes;
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
331b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    @Override
332b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    public BootstrapMethodsList getBootstrapMethods() {
333b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson        AttBootstrapMethods bootstrapMethodsAttribute =
334b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson                (AttBootstrapMethods) getAttributes().findFirst(AttBootstrapMethods.ATTRIBUTE_NAME);
335b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson        if (bootstrapMethodsAttribute != null) {
336b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson            return bootstrapMethodsAttribute.getBootstrapMethods();
337b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson        } else {
338b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson            return BootstrapMethodsList.EMPTY;
339b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson        }
340b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    }
341b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson
342b7d748318354aba23ba03f76bdefc31fa6adc885Orion Hodson    /** {@inheritDoc} */
3439dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson    @Override
344333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilson    public CstString getSourceFile() {
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        AttributeList attribs = getAttributes();
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Attribute attSf = attribs.findFirst(AttSourceFile.ATTRIBUTE_NAME);
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (attSf instanceof AttSourceFile) {
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return ((AttSourceFile) attSf).getSourceFile();
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return null;
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs and returns an instance of {@link TypeList} whose
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * data comes from the bytes of this instance, interpreted as a
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * list of constant pool indices for classes, which are in turn
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * translated to type constants. Instance construction will fail
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * if any of the (alleged) indices turn out not to refer to
36199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * constant pool entries of type {@code Class}.
362de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param offset offset into {@link #bytes} for the start of the
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * data
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param size number of elements in the list (not number of bytes)
36699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} an appropriately-constructed class list
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public TypeList makeTypeList(int offset, int size) {
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (size == 0) {
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return StdTypeList.EMPTY;
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (pool == null) {
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException("pool not yet initialized");
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
376de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new DcfTypeList(bytes, offset, size, pool, observer);
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
38199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Gets the class file field {@code magic}, but without doing any
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * checks or parsing first.
383de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the magic value
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMagic0() {
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return bytes.getInt(0);
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
39199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Gets the class file field {@code minor_version}, but
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * without doing any checks or parsing first.
393de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the minor version
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMinorVersion0() {
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return bytes.getUnsignedShort(4);
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
40199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Gets the class file field {@code major_version}, but
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * without doing any checks or parsing first.
403de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the major version
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMajorVersion0() {
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return bytes.getUnsignedShort(6);
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Runs {@link #parse} if it has not yet been run to cover up to
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the interfaces list.
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void parseToInterfacesIfNecessary() {
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (accessFlags == -1) {
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            parse();
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Runs {@link #parse} if it has not yet been run successfully.
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void parseToEndIfNecessary() {
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (attributes == null) {
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            parse();
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Does the parsing, handing exceptions.
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void parse() {
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            parse0();
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ParseException ex) {
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ex.addContext("...while parsing " + filePath);
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw ex;
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (RuntimeException ex) {
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ParseException pe = new ParseException(ex);
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pe.addContext("...while parsing " + filePath);
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw pe;
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
44645fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin     * Sees if the .class file header magic has the good value.
447de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param magic the value of a classfile "magic" field
44945fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin     * @return true if the magic is valid
45045fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin     */
45145fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin    private boolean isGoodMagic(int magic) {
45245fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin        return magic == CLASS_FILE_MAGIC;
45345fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin    }
45445fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin
45545fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin    /**
45645fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin     * Sees if the .class file header version are within
45745fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin     * range.
45845fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin     *
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param minorVersion the value of a classfile "minor_version" field
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param majorVersion the value of a classfile "major_version" field
46145fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin     * @return true if the parameters are valid and within range
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
46345fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin    private boolean isGoodVersion(int minorVersion, int majorVersion) {
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* Valid version ranges are typically of the form
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * "A.0 through B.C inclusive" where A <= B and C >= 0,
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * which is why we don't have a CLASS_FILE_MIN_MINOR_VERSION.
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
46845fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin        if (minorVersion >= 0) {
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* Check against max first to handle the case where
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * MIN_MAJOR == MAX_MAJOR.
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (majorVersion == CLASS_FILE_MAX_MAJOR_VERSION) {
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (minorVersion <= CLASS_FILE_MAX_MINOR_VERSION) {
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return true;
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else if (majorVersion < CLASS_FILE_MAX_MAJOR_VERSION &&
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                       majorVersion >= CLASS_FILE_MIN_MAJOR_VERSION) {
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return true;
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Does the actual parsing.
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void parse0() {
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (bytes.size() < 10) {
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new ParseException("severely truncated class file");
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (observer != null) {
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, 0, 0, "begin classfile");
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, 0, 4, "magic: " + Hex.u4(getMagic0()));
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, 4, 2,
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            "minor_version: " + Hex.u2(getMinorVersion0()));
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, 6, 2,
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            "major_version: " + Hex.u2(getMajorVersion0()));
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (strictParse) {
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* Make sure that this looks like a valid class file with a
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * version that we can handle.
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
50645fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin            if (!isGoodMagic(getMagic0())) {
50745fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin                throw new ParseException("bad class file magic (" + Hex.u4(getMagic0()) + ")");
50845fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin            }
50945fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin
51045fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin            if (!isGoodVersion(getMinorVersion0(), getMajorVersion0())) {
51145fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin                throw new ParseException("unsupported class file version " +
51245fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin                                         getMajorVersion0() + "." +
51345fd158052a5ebfc57e7a063c6990da5ae019aacDelphine Martin                                         getMinorVersion0());
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ConstantPoolParser cpParser = new ConstantPoolParser(bytes);
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        cpParser.setObserver(observer);
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pool = cpParser.getPool();
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pool.setImmutable();
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int at = cpParser.getEndOffset();
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int accessFlags = bytes.getUnsignedShort(at); // u2 access_flags;
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int cpi = bytes.getUnsignedShort(at + 2); // u2 this_class;
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        thisClass = (CstType) pool.get(cpi);
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        cpi = bytes.getUnsignedShort(at + 4); // u2 super_class;
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        superClass = (CstType) pool.get0Ok(cpi);
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int count = bytes.getUnsignedShort(at + 6); // u2 interfaces_count
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (observer != null) {
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, at, 2,
532de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro                            "access_flags: " +
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            AccessFlags.classString(accessFlags));
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, at + 2, 2, "this_class: " + thisClass);
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, at + 4, 2, "super_class: " +
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            stringOrNone(superClass));
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, at + 6, 2,
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            "interfaces_count: " + Hex.u2(count));
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (count != 0) {
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                observer.parsed(bytes, at + 8, 0, "interfaces:");
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at += 8;
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        interfaces = makeTypeList(at, count);
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at += count * 2;
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (strictParse) {
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Make sure that the file/jar path matches the declared
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * package/class name.
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String thisClassName = thisClass.getClassType().getClassName();
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!(filePath.endsWith(".class") &&
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  filePath.startsWith(thisClassName) &&
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  (filePath.length() == (thisClassName.length() + 6)))) {
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new ParseException("class name (" + thisClassName +
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                         ") does not match path (" +
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                         filePath + ")");
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Only set the instance variable accessFlags here, since
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * that's what signals a successful parse of the first part of
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * the file (through the interfaces list).
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.accessFlags = accessFlags;
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FieldListParser flParser =
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            new FieldListParser(this, thisClass, at, attributeFactory);
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        flParser.setObserver(observer);
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fields = flParser.getList();
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at = flParser.getEndOffset();
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        MethodListParser mlParser =
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            new MethodListParser(this, thisClass, at, attributeFactory);
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mlParser.setObserver(observer);
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methods = mlParser.getList();
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at = mlParser.getEndOffset();
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        AttributeListParser alParser =
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            new AttributeListParser(this, AttributeFactory.CTX_CLASS, at,
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                    attributeFactory);
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        alParser.setObserver(observer);
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        attributes = alParser.getList();
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        attributes.setImmutable();
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at = alParser.getEndOffset();
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (at != bytes.size()) {
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new ParseException("extra bytes at end of class file, " +
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                     "at offset " + Hex.u4(at));
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (observer != null) {
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, at, 0, "end classfile");
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Implementation of {@link TypeList} whose data comes directly
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * from the bytes of an instance of this (outer) class,
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * interpreted as a list of constant pool indices for classes
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * which are in turn returned as type constants. Instance
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * construction will fail if any of the (alleged) indices turn out
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * not to refer to constant pool entries of type
60799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code Class}.
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static class DcfTypeList implements TypeList {
61099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        /** {@code non-null;} array containing the data */
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final ByteArray bytes;
612de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** number of elements in the list (not number of bytes) */
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final int size;
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
61699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        /** {@code non-null;} the constant pool */
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final StdConstantPool pool;
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Constructs an instance.
621de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro         *
62299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param bytes {@code non-null;} original classfile's bytes
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param offset offset into {@link #bytes} for the start of the
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * data
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param size number of elements in the list (not number of bytes)
62699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param pool {@code non-null;} the constant pool to use
62799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param observer {@code null-ok;} parse observer to use, if any
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public DcfTypeList(ByteArray bytes, int offset, int size,
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                StdConstantPool pool, ParseObserver observer) {
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (size < 0) {
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new IllegalArgumentException("size < 0");
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            bytes = bytes.slice(offset, offset + size * 2);
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.bytes = bytes;
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.size = size;
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.pool = pool;
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < size; i++) {
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                offset = i * 2;
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int idx = bytes.getUnsignedShort(offset);
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                CstType type;
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                try {
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    type = (CstType) pool.get(idx);
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } catch (ClassCastException ex) {
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // Translate the exception.
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    throw new RuntimeException("bogus class cpi", ex);
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (observer != null) {
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    observer.parsed(bytes, offset, 2, "  " + type);
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** {@inheritDoc} */
6579dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson        @Override
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public boolean isMutable() {
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** {@inheritDoc} */
6639dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson        @Override
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public int size() {
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return size;
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** {@inheritDoc} */
6699dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson        @Override
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public int getWordCount() {
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // It is the same as size because all elements are classes.
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return size;
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** {@inheritDoc} */
6769dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson        @Override
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public Type getType(int n) {
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int idx = bytes.getUnsignedShort(n * 2);
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return ((CstType) pool.get(idx)).getClassType();
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** {@inheritDoc} */
6839dbd802c8c96c3a66873bc600bc7d1374a1d08e5Orion Hodson        @Override
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public TypeList withAddedType(Type type) {
685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new UnsupportedOperationException("unsupported");
686de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        }
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
689